Env. variables as a file

Photo by Maksym Kaharlytskyi on Unsplash

Photo by Maksym Kaharlytskyi on Unsplash

How to store secrets in github projects
Updated 29. May 2023

GitHub is an amazing place to store your projects for safekeeping and sharing with others. I personally use it for all my hobby projects and study projects.

But when you need to store API keys and other secrets it can be a bit bothersome to add system environment variables for each project.

Thankfully there are simple and easy solutions that allow you to use a git-ignored file to store the secrets.

In this article, I will show a common method used to set up a simple, and effective solution to store your secrets in git-based Python projects.

.env

A simple place to store your secrets

Start by creating a file named ".env" at the root of your project. In this file, every secret will be stored as key-value pairs. Below is an example of such a file.

vim .env
.env
[API]
CAT=secret_api_key_that_will_be_billed_by_usage

[WEB]
DB_HOST=127.0.0.1
DB_USER=stanley
DB_PASS=p@ssw0rd!
DB_DATABASE=haxor_no

The env file above has an API key and information on how to connect to a database server.

Each group of information is divided into chapters, identified by square-bracketed names.

.gitignore

With this file created it's important to add the file to the projects ".gitignore" file. When the file is git-ignored, it will not be tracked by git, and will therefore never accidentally be committed to the git repo.

vim .gitignore
.gitignore
.env

.env.example

A friendly reminder

Because the .env file now is not a part of the git repo, it's normal to create a ".env.example" file with placeholder values.

This file is normally committed to the project and is designed to help project contributors quickly learn what secret information they should get from project owners or others that could provide the secrets.

vim .env.example
.env.example
[API]
CAT=<api-key>

[WEB]
DB_HOST=<ip-addres>
DB_USER=<username-on-db-server>
DB_PASS=<password-on-db-server>
DB_DATABASE=<database-name>

Python usage

How to access the env variables

Once the .env file and the supporting .env.example is created, and you are sure the .env file is git ignored, your project is ready to make use of the env-variables in your Python script.

To do this I like to use the configparser package. This can be installed with pip.

pip install configparser # when only one version of python is installed
python3.10 -m pip install configparser  # to install using a specific python version

Once installed you can import and use the package in your script.

vim api_test.py
api_test.py
from configparser import ConfigParser

# Get API key form .env file
config = ConfigParser()
config.read('.env')
API_KEY = config['API']['CAT']

In the script above you can see that the config parser loaded the .env file, read the variable called "CAT", in the "API" chapter, and stored the value as a variable called "API_KEY".

Now you can use the API_KEY variable in your API calls.

api_test.py
from configparser import ConfigParser
import requests

# Get API key form .env file
config = ConfigParser()
config.read('.env')
API_KEY = config['API']['CAT']


def get_dog_image():
    url = 'https://api.thedogapi.com/v1/images/search'
    headers = {
        'x-api-key': API_KEY
    }

    try:
        response = requests.get(url, headers=headers)
        dog_info = response.json()
        print(dog_info)

    except:
        print('Whoops, something went wrong with the API call')


if __name__ == '__main__':
    get_dog_image()

Congratulations, you have now learned how to set up and use environment variables stored in files in a safe way. 🎉