I created environment variables for my django project within my pipenv virtual envronment bin/activate (linux) or scripts\activate(windows) file , i made necessary changes in settings file as well as exiting and re activating the virtual environment but im still getting a keyerror (I'm working on a windows machine)
variables in settings.py
SECRET_KEY = os.environ['SECRET_KEY']
EMAIL_HOST_PASSWORD = os.environ['EMAIL_HOST_PASSWORD']
evnvironment variables in virtualenv\scripts\activate file
export SECRET_KEY= "mysecretkey"
export EMAIL_HOST_PASSWORD= "mypassword"
error
File "C:\Users\Dell\.virtualenvs\team-272-SMES-Server-dSgdZ4Ig\lib\os.py", line 673, in __getitem__
raise KeyError(key) from None
KeyError: 'SECRET_KEY'
Make sure you have "SECRET_KEY" in your os.environ
Use this code to check if you have "SECRET_KEY" there:
import os
import pprint
# Get the list of user's
# environment variables
env_var = os.environ
# Print the list of user's
# environment variables
print("User's Environment variable:")
pprint.pprint(dict(env_var), width = 1)
You are probably missing "SECRET_KEY" in the environment variable list. You can add a variable:
# importing os module
import os
# Add a new environment variable
os.environ['GeeksForGeeks'] = 'www.geeksforgeeks.org'
source
On a Windows server, I recommend creating a JSON (or YAML) file with all your database and app secrets. I personally prefer JSON, so an example of one is
{
"SECRET_KEY": "...",
"MYSQL_DBUSER": "jon"
"MYSQL_PW": "..."
...
}
Then in your settings.py you should add something like
import json
with open("config.json") as config:
config = json.load(config)
Then to simply load in your project's secrets, index them by the variable name like
SECRET_KEY = config['SECRET_KEY']
Related
I have the following code in one of my views.py:
tl_key = os.getenv("TRANSLOADIT_KEY")
tl_secret = os.getenv("TRANSLOADIT_SECRET")
if not tl_key:
logger.critical("TRANSLOADIT_KEY not set")
raise ImproperlyConfigured
if not tl_secret:
logger.critical("TRANSLOADIT_SECRET not set")
raise ImproperlyConfigured
I know that if Django doesn't find SECRET_KEY or DEBUG environment variable, it will raise ImproperlyConfigured exception. Is there a way I can specify which env variables are required so that the said exception is raised automatically?
You can create a list of items which is required in env file and paste this in your main settings.py or dev settings
required_env_items=["TRANSLOADIT_KEY","TRANSLOADIT_SECRET"]
for item in required_env_items:
if not os.getenv(item):
raise ImproperlyConfigured("please add {} in env file".format(item))
You can add another environment variable defining your need, something like APP_ENVIRONMENT=dev|prod, that way you can check that var and raise ImproperlyConfigured or assign a default value in your code
I have a Django project I have been working on offline and now I have hosted it on Heroku and it works well on Heroku but fails on my local machine with this error.
File "/usr/lib/python3.9/os.py", line 679, in __getitem__
raise KeyError(key) from None
KeyError: 'DEBUG'
and I think it is because I used environment variables like this.
from boto.s3.connection import S3Connection
import os
DEBUG = S3Connection(os.environ['DEBUG'], os.environ['DEBUG'])
I also have a .env file in my root(project folder) with the environment variables like this.
export JWT_SECRET_KEY = "dfge..."
export DEBUG = 1
What is the right way to store the environment variables on my local machine?
I have local file secret.py added to .gitignore with all keys, env values needed:
#secret.py
DEBUG = 1
Then in settings.py:
# settings.py
try:
import secret
DEBUG = secret.DEBUG
except ModuleNotFoundError:
DEBUG = S3Connection(os.environ['DEBUG'], os.environ['DEBUG'])
I can't seem to access my env variables' values inside my app. I'm loading my env variables into my app with a .env file and the dotenv package; I learned about it here.
My .env
FLASK_ENV=development
FLASK_APP=app.py
DEBUG=ON
TESTING=False
I want to use the value of the TESTING variable inside my app and run certain code based on whether it is True or False.
How can I get these values? The docs say
Certain configuration values are also forwarded to the Flask object so
you can read and write them from there: app.testing = True
But I get module 'app' has no attribute 'testing'
When I log app by itself I see a Flask object. When I log this out like app.Flask, I see the env variables, but these appear like this, with no refernce to the current value.
{'__name__': 'TESTING', 'get_converter': None}
I want to be able to do something like:
app.testing => False
app.FLASK_ENV => development
and then eventually:
if app.testing == True:
<do something>
PS - I know the app loads this .env file okay because if I remove the values the environment changes back to production, the default.
#settings.py
from pathlib import Path # python3 only
from dotenv import load_dotenv
load_dotenv(verbose=True)
env_path = Path('.') / '.env'
load_dotenv(dotenv_path=env_path)
import os
print(os.environ['TESTING'])
Equivalent in JS is process.env
I have a webapp which is not yet complete but I recently deployed it to heroku. It uses:
Django
Rest-framework
Reactjs
Now, I have deployed deploy-heroku branch of my project to master of heroku.
The only difference between my project's master branch and deploy-heroku branch is that I have made additional changes in settings.py (adding prostgre sql settings and all) in the deploy-heroku branch.
I want to add more features to my webapp so should I work on master and later copy-paste those changes to deploy-heroku. This seems redundant !! Is there any other better way to do this?
You could just let Heroku automatic deploy on master and use a ".env" file with Django-environ (https://github.com/joke2k/django-environ) to change your settings.py. You should be able to create a local Django setting and a Heroku prod setting.
Example :
.env :
DEBUG=on
SECRET_KEY=your-secret-key
DATABASE_URL=psql://urser:un-githubbedpassword#127.0.0.1:8458/database
SQLITE_URL=sqlite:///my-local-sqlite.db
setting.py:
import environ
env = environ.Env(
# set casting, default value
DEBUG=(bool, False)
)
# reading .env file
environ.Env.read_env()
# False if not in os.environ
DEBUG = env('DEBUG')
# Raises django's ImproperlyConfigured exception if SECRET_KEY not in os.environ
SECRET_KEY = env('SECRET_KEY')
# Parse database connection url strings like psql://user:pass#127.0.0.1:8458/db
DATABASES = {
# read os.environ['DATABASE_URL'] and raises ImproperlyConfigured exception if not found
'default': env.db(),
# read os.environ['SQLITE_URL']
'extra': env.db('SQLITE_URL', default='sqlite:////tmp/my-tmp-sqlite.db')
}
Don't forget to add the .env file to your .gitignore and to update your Heroku environment variables in your app -> settings -> Reveal config vars
You can merge branches.
Here is a good explanation of how it works
I'm following the project structure as laid out by Zachary Voase, but I'm struggling with one specific issue.
I'd very much like to have a custom settings boolean variable (let's call it SEND_LIVE_MAIL) that I would be using in the project. Basically, I'd like to use this settings variable in my code and if SEND_LIVE_MAIL is True actually send out a mail, whereas when it is set to False just print its contents out to the console. The latter would apply to the dev environment and when running unittests.
What would be a good way of implementing this? Currently, depending on the environment, the django server uses dev, staging or prd settings, but for custom settings variables I believe these need to be imported 'literally'. In other words, I'd be using in my views something like
from settings.development import SEND_LIVE_MAIL
which of course isn't what I want. I'd like to be able to do something like:
from settings import SEND_LIVE_MAIL
and depending on the environment, the correct value is assigned to the SEND_LIVE_MAIL variable.
Thanks in advance!
You shouldn't be importing directly from your settings files anyways. Use:
>>> from django.conf import settings
>>> settings.SEND_LIVE_MAIL
True
The simplest solution is to have this at the bottom of your settings file:
try:
from local_settings import *
except ImportError:
pass
And in local_settings.py specify all your environment-specific overrides. I generally don't commit this file to version control.
There are more advanced ways of doing it, where you end up with a default settings file and a per-environment override.
This article by David Cramer covers the various approaches, including both of the ones I've mentioned: http://justcramer.com/2011/01/13/settings-in-django/
import os
PROJECT_PATH = os.path.dirname(__file__)
try:
execfile(os.path.join(PROJECT_PATH, local_settings.py'))
except IOError:
pass
Then you can have your local_settings.py behave as if it was pasted directly into your settings.py:
$ cat local_settings.py
INSTALLED_APPS += ['foo']
You can do something like this for a wide variety of environment based settings, but here's an example for just SEND_LIVE_MAIL.
settings_config.py
import re
import socket
class Config:
def __init__(self):
fqdn = socket.getfqdn()
env = re.search(r'(devhost|stagehost|prodhost)', fqdn)
env = env and env.group(1)
env = env or 'devhost'
if env == 'devhost':
self.SEND_LIVE_MAIL = # whatever
elif env == 'stagehost':
self.SEND_LIVE_MAIL = # whatever
elif env == 'prodhost':
self.SEND_LIVE_MAIL = # whatever
config = Config()
settings.py
from settings_config import config
SEND_LIVE_MAIL = config.SEND_LIVE_MAIL