Pycharm: set environment variable for run manage.py Task
I have moved my SECRET_KEY
value out of my settings file, and it gets set when I load my virtualenv. I can confirm the value is present from python manage.py shell
.
When I run the Django Console, SECRET_KEY
is missing, as it should. So in preferences, I go to Console>Django Console and load SECRET_KEY
and the appropriate value. I go back into the Django Console, and SECRET_KEY
is there.
As expected, I cannot yet run a manage.py Task because it has yet to find the SECRET_KEY
. So I go into Run>Edit Configurations to add SECRET_KEY
into Django server and Django Tests, and into the project server. Restart Pycharm, confirm keys.
When I run a manage.py Task, such as runserver
, I still get KeyError: 'SECRET_KEY'.
Where do I put this key?
Because Pycharm is not launching from a terminal, your environment will not be loaded. In short, any GUI program will not inherit the SHELL variables. See this for reasons (assuming a Mac).
However, there are several basic solutions to this problem. As @user3228589 posted, you can set this up as a variable within PyCharm. This has several pros and cons. I personally don't like this approach because it's not a single source
. To fix this, I use a small function at the top of my settings.py file which looks up the variable inside a local .env
file. I put all of my "private" stuff in there. I also can reference this in my virtualenv.
Here is what it looks like.
-- settings.py
def get_env_variable(var_name, default=False):
"""
Get the environment variable or return exception
:param var_name: Environment Variable to lookup
"""
try:
return os.environ[var_name]
except KeyError:
import StringIO
import ConfigParser
env_file = os.environ.get('PROJECT_ENV_FILE', SITE_ROOT + "/.env")
try:
config = StringIO.StringIO()
config.write("[DATA]\n")
config.write(open(env_file).read())
config.seek(0, os.SEEK_SET)
cp = ConfigParser.ConfigParser()
cp.readfp(config)
value = dict(cp.items('DATA'))[var_name.lower()]
if value.startswith('"') and value.endswith('"'):
value = value[1:-1]
elif value.startswith("'") and value.endswith("'"):
value = value[1:-1]
os.environ.setdefault(var_name, value)
return value
except (KeyError, IOError):
if default is not False:
return default
from django.core.exceptions import ImproperlyConfigured
error_msg = "Either set the env variable '{var}' or place it in your " \
"{env_file} file as '{var} = VALUE'"
raise ImproperlyConfigured(error_msg.format(var=var_name, env_file=env_file))
# Make this unique, and don't share it with anybody.
SECRET_KEY = get_env_variable('SECRET_KEY')
Then the env file looks like this:
#!/bin/sh
#
# This should normally be placed in the ${SITE_ROOT}/.env
#
# DEPLOYMENT DO NOT MODIFY THESE..
SECRET_KEY='XXXSECRETKEY'
And finally your virtualenv/bin/postactivate can source this file. You could go further and export the variables as described here if you'd like, but since settings file directly calls the .env, there isn't really a need.
To set your environment variables in PyCharm do the following:
- Open the 'File' menu
- Click 'Settings'
- Click the '+' sign next to 'Console'
- Click Python Console
- Click the '...' button next to environment variables
- Click the '+' to add environment variables
Another option that's worked for me:
- Open a terminal
- Activate the virtualenv of the project which will cause the hooks to run and set the environment variables
- Launch PyCharm from this command line.
Pycharm will then have access to the environment variables. Likely because of something having to do with the PyCharm process being a child of the shell.
You can set the manage.py task environment variables via:
Preferences| Languages&Frameworks| Django| Manage.py tasks
Setting the env vars via the run/debug/console configuration won't affect the built in pycharm's manage.py task.