Setting .env to store sensitive info without pushing to GitHub
Overview
FIRST steps for any project are:
- Go to the directory’s root and create
.gitignorefile. - Add
.env(dot env) to.gitignoreto hide from GitHub. - note: Use one
.envfile per project, you can store multiple API Keys, passwords and other sensitive info. - Best practice to store
.envon same root directory as.gitignore.
Setting up dotenv Files
Use Case: We have sensitive API Keys and Secret Keys we don’t want to put into version control, but we need to access.
The best practice is to create a .env file at the root of your project and store the keys in there, and most importantly, making sure to include .env in a .gitignore file so it does not get included in versioning.
source
The challenge is to install the dotenv module to access the load_dotenv function in order to access the data in the environment variable (.env).
First, here’s how the structure of the directory could look like:
.
├── .env
└── settings.py
└── .gitignore
└── project_directory_1
└── file.py
└── project_directory_2
└── another_file.py
The key things to pay attention here are .env, your_python_script.py and .gitignore.
For the present hypothetical project, here’s what needs to be in the .gitignore file:
#.gitignore
# Environents
.env
Here’s what needs to be in .env. The example here is accessing Twitter API. The first time you’re setting this up, I’d recommend using a “fake” CONSUMER_KEY (aka API Key) and CONSUMER_SECRET (API Secret Key) just to test it out and make sure that it doesn’t get inadvertently added to version control (note: see setting up .gitignore above).
# you'll put your actual API Keys and Secrete Keys here
TWITTER_CONSUMER_KEY=fakeconsumerkey
TWITTER_CONSUMER_SECRET=fakeconsumersecret
Within the your_python_script.py file, you’ll
have:
from dotenv import load_dotenv #for python-dotenv method
load_dotenv() #for python-dotenv method
import os
user_name = os.environ.get('USER')
password = os.environ.get('password')
print(user_name, password)
# output
username password
From there you’ll go into file.py and use the dotenv module to access environment variables (sensitive API Keys).
The example below accesses Twitter API.
#file.py
# for python-dotenv method of access environment variables
from twython import Twython
import webbrowser
import os
import dotenv
from dotenv import load_dotenv
load_dotenv()
###### TWITTER API ######
# IMPORTANT: PLUG YOUR KEY AND SECRET IN DIRECTLY (without os.environ.get())
CONSUMER_KEY = os.environ.get("TWITTER_CONSUMER_KEY") # API Key
CONSUMER_SECRET = os.environ.get("TWITTER_CONSUMER_SECRET") # API Secret Key
Assuming everything is setup properly, you should be able to run the following code within IPython and have CONSUMER_KEY return a string:
import os
import dotenv
from dotenv import load_dotenv
load_dotenv() # True
CONSUMER_KEY = os.environ.get("TWITTER_CONSUMER_KEY")
CONSUMER_KEY # 'fakeconsumerkey'
Installing dotenv module
This is the challenging part. I had installed dotenv but was unable to access it within settings.py and file.py.
First, because we’re using Python3, anything that involves pip install should be pip3 install.
I had to uninstall, then re-install dotenv, and what worked was following this
Stack Overflow answer:
# update Nov 17, 2021, this works
$ pip3 install -U python-dotenv
# old installation
conda install -c conda-forge python-dotenv
Sometimes having both dotenv and python-dotenv install can cause conflict. In which case, in your virtual environment, try below. Based on
this answer.
# update Nov 17, 2021 - use python-dotenv method
pip3 uninstall dotenv
pip3 uninstall python-dotenv
pip3 install python-dotenv
You’ll know you have something working when you run the following code in the command line:
dotenv --version # dotenv, version 0.19.2 (Nov 17, 2021)
NOTE: Sometimes a virtual environment will have different python-dotenv installed:
pip3 show python-dotenv