To organize your settings to have different parameters in your different environments like development and production you need to work with environment variables.

What is python-decouple

python-decouple is a generic python library that helps to organize settings (development, production, stage, etc) without having to redeploy the app.

It was specifically built for Django but now is used to manage multiple environments or settings across python development.

Here are the advantages of using python-decouple:

  • You can store variables in .env or ini files.
  • Setting default environment values.
  • Conversion of environment values to correct data type.

Why not just use os.environ

ItĀ works, but sinceĀ os.environĀ only returns strings, itā€™s tricky.

Letā€™s say you have anĀ environment variableĀ DEBUG=False. If you run

if os.environ['DEBUG']: 
  print(True) 
else: 
  print(False)

It outputsĀ True, becauseĀ os.environ['DEBUG']Ā returns theĀ stringĀ "False". Since itā€™s a non-empty string, it will be evaluated as True.

Python DecoupleĀ provides a solution that solves this problem like this

from decouple import config
DEBUG = config('DEBUG',Ā cast=bool)

Why use environment variables

A web application whether small or large will have a lot of app secrets such as SECRET_KEY, API keys, database credentials etc.

The convenient way for anyone to use these is to hardcode them in the source code. It works, but it is also the most insecure way. You often push the code to repositories for version management or share it among others resulting in exposing the app secrets.

The easiest and most secure way is to use these secrets as environment variables and import them directly into your app. Python decouple manages this for you. It also helps in managing application configurations and secrets based on the development environments.

How to install python decouple

You can install python-decouple using the command pip install python-decouple

Optional: If you are not using virtual environments to install third party packages, I would strongly advice you to learn about virtual environment to avoid version issues later.

How to use python decouple in django

Step 1: Create a .env file at the root level of your projectĀ 

project
--- project
------ settings.py
------ urls.py
------ wsgi.py
--- .env

Step 2: Set your environment variables inside .env file, I have set mine like this:

DEBUG=True
SECRET_KEY=ARANDOMSECRETKEY
DB_HOST=HOSTNAME
DB_PASSWORD=PASSWORD

Step3: In yourĀ settings.py, access your environment variables like this:

from decouple import config

SECRET_KEY = config('SECRET_KEY')
DEBUG = config('DEBUG', cast=bool)

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': config('DB_NAME'),
     'USER': config('DB_USER'),
        'PASSWORD': config('DB_PASSWORD'),
        'HOST': config('DB_HOST'),
        'PORT':''
    }
}

That's it for setting up a basic configuration, if you want to know more have a look at the python-decouple official doc.

Note:Ā Add .env file to .gitignore, every user should have their own seperate .env file which should not be pushed alongwith your repository.

A code snippet of python-decouple with django taken from the offical python-decouple doc.

# coding: utf-8
from decouple import config
from unipath import Path
from dj_database_url import parse as db_url


BASE_DIR = Path(__file__).parent

DEBUG = config('DEBUG', default=False, cast=bool)
TEMPLATE_DEBUG = DEBUG

DATABASES = {
    'default': config(
        'DATABASE_URL',
        default='sqlite:///' + BASE_DIR.child('db.sqlite3'),
        cast=db_url
    )
}

TIME_ZONE = 'America/Sao_Paulo'
USE_L10N = True
USE_TZ = True

SECRET_KEY = config('SECRET_KEY')

EMAIL_HOST = config('EMAIL_HOST', default='localhost')
EMAIL_PORT = config('EMAIL_PORT', default=25, cast=int)
EMAIL_HOST_PASSWORD = config('EMAIL_HOST_PASSWORD', default='')
EMAIL_HOST_USER = config('EMAIL_HOST_USER', default='')
EMAIL_USE_TLS = config('EMAIL_USE_TLS', default=False, cast=bool)

How to manage multiple django enviroment

Managing multiple environments is the most common requirement when we work in a team and across multiple servers like local or development, testing, staging, and production.

To solve this problem, you should have .env.template file at the root of your repository and this file should be pushed with your repository. Now any team member can follow this .env.template file to create .env file in their own system with their own set of values and the same with multiple servers.

That's it. I hope you can now manage environment variables.

You can also checkout these tutorials: