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

  1. Make sure our repository has a proper .gitignore
  2. Create a separate .env file to store our API keys (and any other secrets) in
  3. Read the variables out of that file as “environment variables”
  4. 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 with pip 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.