Web applications relies on several number of parameters to run properly on different environments. To name a few from a Django app settings: database url, password, secret key, debug status, email host, allowed hosts. Most of these parameters are environment-specific. On a development environment you might want to run your application with debug mode on. Also, it’s a clever idea to keep your secret key in a safe place (not in your git repository).
Python Decouple is a great library that helps you strictly separate the settings parameters from your source code. The idea is simple: Parameters related to the project, goes straight to the source code. Parameters related to an instance of the project, goes to an environment file.
The following is a quick start of how to use the Python Decouple library.
Or download it from PyPI if you prefer.
Let’s consider the following
settings.py file, to explain how to use the library.
First create a file named
.env in the root of your project. You can also use a
.ini file, in case the
.env isn’t suitable for your use case. See the documentation for further instructions.
If you are working with Git, update your
.gitignore adding the
.env file so you don’t commit any sensitive data to your remote repository.
Now import the library:
Retrieve the settings parameters:
Casting the data
Attention to the cast argument. Django expects
DEBUG to be a boolean. In a similar way it expects
EMAIL_PORT to be an integer.
Actually, the cast argument can receive any callable, that will transform the string value into something else. In the case of the
ALLOWED_HOSTS, Django expects a list of hostname.
.env file you can put it like this:
And then in your
settings.py you can retrieve it this way:
Looks complicated, right? Actually the library comes with a Csv Helper, so you don’t need to write all this code. The better way to do it would be:
You can add an extra argument to the
config function, to define a default value, in case there is an undefined value in the
Meaning you won’t need to define the
DEBUG parameter in the
.env file in the development environment for example.
Overriding config files
In case you want to temporarily change some of the settings parameter, you can override it with environment variables:
Deploying to Heroku
If you are deploying your application to Heroku using Git, you can’t have an
.env file in your project root. That’s not a problem, because Python Decouple will retreive the environment variables, and Heroku let you define those variables on it’s dashboard.
Inside Heroku’s dashboard, first select your app and click on the Settings tab.
Inside the Settings tab click on the Reveal Config Vars button and add your variables as you would do in the
That’s it! You are all set up.
Tip for a easier setup
Since we don’t commit our
.env file to the remote repository, and it’s required for the project to run properly, it can be confusing for newcomers who aren’t familiar with Python Decouple to setup and run your project.
One thing I like to do in my open source projects is to commit a sample file, usually I name it
.env.example, in the project root, with some sample data. So the one who is trying to run the project must just rename the file to
.env and put the proper values.
You can see a real use case checking the Parsifal repository.
Integrating with Travis CI
The previous tip can be useful if you are integrating with Travis CI. Actually I fill my project’s
.env.example file with the required parameters to run on the Travis CI environment. Then all you have to do, is to run a
before_script renaming the
.env.example file to
.travis.yml sample file
See in practice
As I stated before in this article, I use Python Decouple in all my Django projects. So if you want to see some examples, visit the links below:
Python Decouple is a must have app if you are developing with Django. Personally I use it in all my Django projects. It’s important to keep your application credentials like API Keys, Amazon S3, email parameters, database parameters safe, specially if it’s an open source repository. Also no more
production_settings.py, use just one
settings.py for your whole project.