Python Decouple Module Made Simple

In this article, we will learn about the “Decouple Module” in python. We will see its usage and learn to set up a secure environment to protect our information from vulnerabilities. So, Let’s get started,

What does Decouple represents?

So, before learning about the module, let’s see what does decouple represents. So, as the name suggests, separating things from others is known as decoupling.

Similarly, in python, separating settings from the rest of the source code is needed as it contains some information that should not be exposed. Some of them are Secret Key, Middlewares, and Installed Apps; resource handles to the database, Memcached, and other backing services or credentials to external services such as Amazon S3 or Twitter. Exposing these pieces of information may cause vulnerabilities or cyberattacks on the applications. To secure that information, python developers created Decouple Module.

Decouple Module

Initially, this module was created to secure Django-based applications; however, it is used at various other resources due to its secure and compatible functionality. Before going to its usage, let’s see its installation first.

Installation

PIP

To install Decouple module using pip, run the following command.

pip install python-decouple

Anaconda

To install it using conda, run one of the following commands,

conda install -c conda-forge python-decouple
conda install -c conda-forge/label/gcc7 python-decouple
conda install -c conda-forge/label/cf201901 python-decouple
conda install -c conda-forge/label/cf202003 python-decouple

Django-environ vs Python-decouple

However, using both could be equally effective to secure your application, but the point to notice is that you can only secure your Django-based application using “django-environ,” but the “python-decouple” module can be used for other purposes too. Moreover, we can also say that python-decouple can be easily handled and comes with more functionalities that we will see in a few seconds.

Django and Decouple Module

As we know, the primary reason for the development of Decouple module is to secure Django applications. Let’s discuss how can we do it;

As we already know that “settings.py” is a core file in Django projects. It holds all the configuration values that a web app needs to run. It may be database settings, logging configurations, API Keys, or references to static files. All these pieces of information are present in the “settings.py” file. To separate them from the project code, we create a file named “.env” in the root directory of our project along with dbsqlite3 and manage.py. Let’s see the directory structure,

Project name : myapp

myapp
  |
  |--- myapp
  |       |-----settings.py
  |       |----- (other files)
  |
  |--- manage.py
  |--- dbsqlite3
  |--- .env
  |--- ....(other apps)

Now, edit the “settings.py” file as discussed below, where we will secure “Debug,” “TEMPLATE_DEBUG,” and “SECRET_KEY.”

myapp/myapp/settings.py
"""
Django settings for mysite project.

Generated by 'django-admin startproject' using Django 3.0.8.

For more information on this file, see
https://docs.djangoproject.com/en/3.0/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/3.0/ref/settings/
"""


import os
from decouple import config   # import config method from decouple module

...
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = config('SECRET_KEY')

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = config('DEBUG', cast=bool)
TEMPLATE_DEBUG = config('TEMPLATE_DEBUG', cast=bool)

Now let’s edit the “.env” file.

myapp/.env
#env file

SECRET_KEY =sdjioerb43buhjghjgjjgh459p

DEBUG =True
TEMPLATE_DEBUG = True

[ Note:- It is important not to assign values in the quotation in .env file]

Understanding config()

So, in the above example, we discussed how we could use decouple modules in our Django application. So, move ahead and discuss the “config()” method we used in the settings.py file. We can pass three arguments in the “cast()” method in which two are optional. Let’s discuss each of them.

Syntax:-

config("<value>",default = "", cast="")
  • value = This is the first argument and and is mandatory to pass. It contains the string whose value we are looking for in “.env” file.
  • default = This is optional argument. Value of this argument is returned if it hasn’t find any value in “.env” file refering to the first argument.
  • cast = By default, all values returned by decouple are strings, as they read from text file, but it is not necessary that we needstring only as python supports different datatypes like boolean, integers e.t.c also. In order to specify our requirement we specify cast agument. In the above example, we need secret key as string hence we haven’t specified cast there but for “Debug” we need it as a boolean value so we cast it as “bool”.

Understanding Cast Argument

Although we have discussed one of the functionalities of the cast argument, its scope is not limited to this only. We can configure it more using “CSV helper” or “Choice helper.” Let’s try to understand it with examples,

Using CSV Helper

>>> os.environ['LIST_OF_INTEGERS'] = '1,2,3,4,5'
>>> config('LIST_OF_INTEGERS', cast=Csv(int))
[1, 2, 3, 4, 5]

In the above example, we used CSV() to apply cast to the whole list of integers, making the cast argument more powerful. We can also apply CSV’s to complex strings using the lambda function.

os.environ['COMPLEX_STRING'] = '%virtual_env%\t *important stuff*\t   trailing spaces   '

>>> csv = Csv(cast=lambda s: s.upper(), delimiter='\t', strip=' %*')
>>> csv(os.environ['COMPLEX_STRING'])

['VIRTUAL_ENV', 'IMPORTANT STUFF', 'TRAILING SPACES']

Using Choices Helper

We can also use “Choices” with cast argument to allow cast and validation based on a list of choices. Let’s see an example of it,

>>> from decouple import config, Choices
>>> os.environ['CONNECTION_TYPE'] = 'usb'
>>> config('CONNECTION_TYPE', cast=Choices(['eth', 'usb', 'bluetooth']))
'usb'

If the value is not present in the choices list, it raises “Value Error.”

>>> os.environ['CONNECTION_TYPE'] = 'serial'
>>> config('CONNECTION_TYPE', cast=Choices(['eth', 'usb', 'bluetooth']))
Traceback (most recent call last):
 ...
ValueError: Value not in list: 'serial'; valid values are ['eth', 'usb', 'bluetooth']

Import Error: no module named decouple.

Usually, this error occurs when you haven’t installed “Decouple Module” in your system or virtual environment. Try installing it. Given Procedure is discussed above.
Learn How To Import Modules, Click Here

How to install decouple in Django?

You can install decouple in Django using the following command.
A) PIP
pip install django-decouple

B) Conda
Installing python-decouple from the conda-forge channel can be achieved by adding conda-forge to your channels with:
>>>conda config –add channels conda-forge
Once the conda-forge the channel has been enabled, python-decouple can be installed with:
>>>conda install python-decouple

Cannot import name ‘config’ from ‘decouple.’

This error usually occurs when you haven’t installed “Decouple Module” in your system or virtual environment or forget to import it into your file.
Try installing it in your file or import it using “from decouple import config.”

decouple.undefinedvalueerror: secret_key not found. declare it as envvar or define a default value.

The reason for the given error might be the following:
1) “Secret Key” is not defined in the “.env” file.
2) If not defined in the “.env” file, you haven’t assigned a default value for the third parameter.
3) You specified “Secret_Key” in a quote that is unsuitable to do. Try removing the quotes for it.

Conclusion

So, In this article, we learned about Decouple Module and how we can secure our application using it. We also looked at how we can configure our settings.py file using the config() method.

Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments