ndarville / pony-forum

A modern alternative to ancient forum CMSes like vBulletin and PHPBB in Python on Django. (Alpha stage.) (NB: dotCloud have since removed their free Sandbox tier.)
http://pony-forum.com
26 stars 7 forks source link

Can't call values from environment #59

Closed ndarville closed 12 years ago

ndarville commented 12 years ago

Changing or creating a key-value in the env environment does not change the value retrieved in settings.py:

>>> import json
>>> with open('/home/dotcloud/environment.json') as f:
...     env = json.load(f)
... 
>>> project_settings.EMAIL_HOST
'smtp.gmail.com'
>>> env['EMAIL_HOST']
Traceback (most recent call last):
  File "<console>", line 1, in <module>
KeyError: 'EMAIL_HOST'
>>> env['EMAIL_HOST'] = "foo"
>>> env['EMAIL_HOST']
'foo'
>>> project_settings.EMAIL_HOST
'smtp.gmail.com'
>>> project_settings.EMAIL_HOST == env['EMAIL_HOST']
False

settings.py:

try:
    import json
    with open('/home/dotcloud/environment.json') as f:
        env = json.load(f)
    LOCAL_DEVELOPMENT = False
except IOError:  # Local development---not on DotCloud
    LOCAL_DEVELOPMENT = True

# (...)

if not LOCAL_DEVELOPMENT:
    EMAIL_HOST           = env.get('EMAIL_HOST', 'smtp.gmail.com')
    EMAIL_HOST_USER      = env.get('EMAIL_HOST_USER', 'myusername@gmail.com')
    EMAIL_HOST_PASSWORD  = env.get('EMAIL_HOST_PASSWORD', '')
    EMAIL_PORT           = int(env.get('EMAIL_PORT', '587'))
    EMAIL_USE_TLS        = bool(env.get('EMAIL_USE_TLS', 'True'))

How often is settings.py run?

Replacing env with os.environ does not fix the problem:


>>> import os
>>> os.environ['EMAIL_HOST']
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/opt/ve/2.7/lib/python2.7/UserDict.py", line 23, in __getitem__
    raise KeyError(key)
KeyError: 'EMAIL_HOST'
>>> from django.conf import settings as project_settings
>>> project_settings.EMAIL_HOST
'smtp.gmail.com'
>>> os.environ['EMAIL_HOST'] = 'foo.yahoo.com'
>>> os.environ['EMAIL_HOST']
'foo.yahoo.com'
>>> project_settings.EMAIL_HOST
'smtp.gmail.com'

Question posted:

"""
In trying to find a place to store and save settings beyond settings.py
and the database, I used an environment.json for environment variables.
I import these in settings.py.

My problem is that when I try to change or store new values in my environment,
env, settings.py does not notice the change - perhaps because
the time and number of times settings.py is read by Django.

Is there a way I would be able to use my environment variables
the way I want like attempted below?
"""

# settings.py
import json
with open('/home/dotcloud/environment.json') as f:
    env = json.load(f)
EMAIL_HOST = env.get('EMAIL_PORT', '500')

# views.py
import json
def site_configuration(request):
    with open('/home/dotcloud/environment.json') as f:
        env = json.load(f)
    if request.method == 'POST':
        os.environ['EMAIL_PORT'] = request.POST['email_port']
    return render(request, ...)

# python manage.py shell demo
>>> import json
>>> with open('/home/dotcloud/environment.json') as f:
...     env = json.load(f)
... 
>>> project_settings.EMAIL_PORT
'500'
>>> env['EMAIL_PORT']
Traceback (most recent call last):
  File "<console>", line 1, in <module>
KeyError: 'EMAIL_PORT'
>>> env['EMAIL_PORT'] = "123"
>>> env['EMAIL_PORT']
'123'
>>> project_settings.EMAIL_PORT
'500'
>>> project_settings.EMAIL_PORT == env['EMAIL_PORT']
False
ndarville commented 12 years ago

Also change the README accordingly.

ndarville commented 12 years ago

Okay, so what are the alternatives to using environment variables for manipulable settings like e-mail:

production_settings.py

Implementations

  1. Placed in a private repo and used as a submodule?
  2. Created and uploaded alongside the rest of the project with rsync.
    • Create a checksum for all folders for every version to help people ensure they have updated the forum properly?
      • Run a on-deploy hook that compares checksum(s) to version number?

Problems

  1. Difficult to upgrade
  2. Difficult to use git and GitHub
  3. Security implications by storing e-mail settings
  4. Poor UX and near-impossible to set up for people new to shells and programming
ndarville commented 12 years ago

Got it working, because I'm a fucking idiot who forgot to do it through CLI and not try messing around with the Django shell.