Keeping your API keys secret with dotenv
Using API keys is necessary to access many useful APIs, and storing your code on GitHub is a great social practice and portfolio builder. But the two together can be trouble!
Once you put your API keys up on GitHub where anyone can see your code, anyone can “borrow” your API keys and pretend to be you! So let’s figure out how to keep our API keys secret while still using them in our code.
The basic idea
# Bad code!
API_KEY = "3ebf52c0-3ebf52c0"
response = requests.get(f"https://example.com/api/?api_key={API_KEY}")
What we’re going to do is
- Make sure our repository has a proper
.gitignore
- Create a separate
.env
file to store our API keys (and any other secrets) in - Read the variables out of that file as “environment variables”
- Use the environment variables to fill in our API key
Make sure our repository has a proper .gitignore
file
The .gitignore
file hides certain files from git. This is great for really big files, temporary files, or super secret files!
When you’re creating a new repository with GitHub Desktop it asks if you’d like to add a .gitignore
- say yes, and make sure it’s a Python one. If you’ve already created your repository you can use a .gitignore generator to generate one for you.
For example, this is one for Python on OS X. Save it as .gitignore
in your project folder and you’ll be set.
If you’ve created your own .gitignore
, add .env
to it if it doesn’t include it already.
Create our .env
file
We’re going to store our secrets in a file called .env
.
I always create files in the wrong directory when I’m in the text editor, so I like to just create the file straight from my Jupyter notebook. You can use the !touch
command to create a new blank file in the same directory as your notebook.
!touch .env
If there’s already a .env
file don’t worry, it won’t erase it.
The contents of the .env
are pretty simple, it should look like this:
PROJECT_API_KEY=3ebf52c0-3ebf52c0
If you had multiple API keys, they would just be organized on separate lines.
PROJECT_API_KEY=3ebf52c0-3ebf52c0
LASTFM_API_KEY=0123456789abcdef
EVERYTHING_API_KEY=d34db33f-c4f3c4t
Read the API keys from the .env file and use them
We’ll be using the
dotenv
module. If you don’t have it installed, you can install it withpip install python-dotenv
. If you’d like to run that command from a notebook, you can add a!
in front of it.
Now we’ll use the dotenv
module to read in the .env
file. When you run load_dotenv()
it happens automatically, like magic!
import os
from dotenv import load_dotenv
load_dotenv()
API_KEY = os.getenv('PROJECT_API_KEY')
Your computer as a bunch of variables floating around in it that you can’t see, called environment variables. This includes things like where to look for commands you type on the command line and your default language settings.
You can get these variables by asking the os
package for them. For example os.getenv('PATH')
will get you the PATH a variable, which is the list of directories commands might be stored in.
When we run load_dotenv()
it reads the .env
file and adds all the variables inside to your environment. Now you can use os.getenv('PROJECT_API_KEY')
to get the PROJECT_API_KEY
from inside of your .env
file.
Using your API key
You can use one cell to read in the API key, that way you can cut and paste it between different projects, just changing your .env
file variable name.
import os
from dotenv import load_dotenv
load_dotenv()
API_KEY = os.getenv('PROJECT_API_KEY')
After that, you can just use your API_KEY
variable like normal.
# Good code!
response = requests.get(f"https://example.com/api/?api_key={API_KEY}")
Words of caution
It’s good to look at API_KEY
or os.getenv('PROJECT_API_KEY')
to make sure your API key was successfully imported, but remember that you’ll be revealing it to everyone who reads your notebook! If you do check it by printing it out, it’s best to remove that line before you push to GitHub.