Securely Managing Database Credentials in Python with dotenv

Securely Managing Database Credentials in Python with dotenv


Introduction

Before pushing your code to GitHub, you may want to hide some sensitive information from the public eye 👀.
We can make use of the ‘dotenv’ module in Python.

The dotenv Python module helps us to load environment variables from a ‘.env’ file. The environment variables will serve as containers that will store the ‘sensitive credentials’ so we don’t put them directly in our code.

This means that the ‘.env. file at no circumstance is supposed to make to GitHub like the rest of our code.
In order to hide it, we will need a ‘.gitignore’ file. In the ‘.gitignore’ file we will specify any file we want git to ignore when pushing our code to GitHub.

Implementing dotenv for Secure Database Connections in Python

Installing the dotenv module

To get started, we will have to install the ‘dotenv’ module.
I am installing it directly on the Ubuntu system and not in the virtual environment.

# Run code below
sudo apt install python3-dotenv

Creating the .env and .gitignore files

The next thing is to create two files, the ‘.env’ and ‘.gitignore’ files

# Creting files
touch .env .gitignore

Adding environment variables

In the .env file we just created, we are going to create environmental variable that we will store our credential or sensitive data within. In our case, we want to hide our username, password and database name in our database connection string.

Add the following variables in the ‘.env’ file. Note that the variables are in all capital letters and there is no space before or after the equal to sign

# Environment Variable
DB_USERNAME='your-database-username'
DB_PASSWORD='your-database-password'
DB_NAME='the-name-of-the-database-in-use'

# Replace values with your credentials

Getting git to ignore the ‘.env’ file

After adding our environment variable, we need a way to tell git that, ‘Hey, this file should be ignored when pushing our code to GitHub”.
That is what the ‘.gitignore’ file is for. Its purpose is in the name of the file.
Now, in the ‘.gitignore’ file, we need to specify the file to ignore, which in our case is the ‘.env’ file.

# Specify the .env file by just typing the file name
.env

Importing the dotenv module into our code

Say you have a file, ‘config.py’ which contains your database configuration code, where the connection string exists. Import the dotenv module into that file. Now we only need a section of the entire module called ‘load_dotenv’. After importing it, we need to initialize it as well.

# import the module
from dotenv import load_dotenv

# Initialize the load_dotenv
load_dotenv()

Importing ‘os’

We need to import ‘os’ which will git the dotenv module access to our operating system. It is on our operating system that we have the ‘.env’ file saved. We need to be able to access it so we can load the environment variables into our ‘config.py’ file.

# import os
import os

Accessing the environmental variables

Now that we have imported the load_dotenv module and os, we can go on to load the environment variables into the ‘config.py‘ file.

You may go on to print them to the terminal to be sure they have been loaded and can be accessed from the ‘config.py’ file.

# Access the environment variables
database_username = os.getenv("DB_USERNAME")
database_password = os.getenv("DB_PASSWORD")
database_name = os.getenv('DB_NAME')

# print env variables for testing reasons
print(database_username, database_password, database_name)

Replacing the credential with the variables

Next, we replace all that sensitive data with their corresponding variables in our connection string.
We use the f-string to format the string and pass the variable in curly braces{} into the string.

# Replace values in connection string
connection_str = f'mysql+mysqlconnector://{database_username}:{database_password}@localhost/{database_name}'

Final config.py file

When you are done replacing the values with the variables, your final config.py file should look something like this:

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from dotenv import load_dotenv
import os

# Load environment variables from the .env file
load_dotenv()

# Access the environment variables
database_username = os.getenv("DB_USERNAME")
database_password = os.getenv("DB_PASSWORD")
database_name = os.getenv('DB_NAME')

#print(database_username, database_password, database_name)

connection_str = f'mysql+mysqlconnector://{database_username}:{database_password}@localhost/{database_name}'

engine = create_engine(connection_str)

try:
    #establishes an active connection to our dtabase
    connection = engine.connect()
    print('Located and connected to database')
    # Closing the open connection
    connection.close()
except Exception as e:
    print(f'An error occured: {e}')

DBSession = sessionmaker(bind = engine)
session = DBSession()

Conclusion

Managing sensitive information in our Python projects is very important, especially when sharing code on GitHub. This article introduces the dotenv module, which allows us to securely store sensitive credentials (like database usernames and passwords) in a .env file. These credentials are then accessed through environment variables instead of being hardcoded into your scripts.

The steps covered include:

  • Installing the dotenv module.

  • Creating a .env file to store sensitive information and a .gitignore file to ensure the .env file is not pushed to GitHub.

  • Loading and accessing the environment variables using the dotenv and os modules.

  • Replacing sensitive information in our database connection string with these variables.

By following this guide, we can ensure our credentials remain secure while keeping our codebase clean and professional.