3. Securely Using API Keys#

The following are (opinionated) best practices to store and use API keys in your source code. If you disagree, please consider contributing.

3.1. Environment Variables#

An environment variable is a dynamic-named value that can be used to store information on a computer. For instance, an environment variable can be used to store settings and/or privileged information (e.g. API keys) on your local computer or server.

To set a environment variable to a new value, in Unix-like systems, you must pass a name and a value pair as shown below in the terminal.

export SECRET_API_KEY = <MY-SECRET_API_KEY>

The value is accessible by the name without being exposed throughout the system. In particular, in Python, the value can be retrieve as follows.

secret_api_key = os.getenv("SECRET_API_KEY")

Alternatively, it is customary to use a .env file to organize and load environments variables as needed. Packages such as dotenv and python-dotenv will automatically load environments variables for you from the .env file.

source .env

With Python,

from dotenv import load_dotenv

load_dotenv()

With Jupyter,

%load_ext dotenv
%dotenv

The template includes .env.example as an example; to use, simply rename it to .env and add your settings and secrets to it. Please note that .env must never be committed/versioned (for example, to GitHub) and should be ignored on .gitignore.

Tip

While environments variables are a convenient way to minimize the security risk, it is important to emphasize secrets are still stored in plaintext in your computer. It is strongly recommended to use instead a secret manager, such as AWS Secrets Manager or 1Password.

3.2. Astronomy Picture of the Day#

One of the most popular APIs is NASA’s Astronomy Picture of the Day. Let’s see in the following example how to use the NASA API with a secret API key.

Hide code cell content
import os

import httpx
from IPython.display import Image

First, you will have to generate your API key and set up the environment variable NASA_API_KEY with its value. Now you are ready to use it in your code. For instance, in this example, we assign it to api_key. Please note that the value is never exposed and the notebook can be securely shared with anyone.

api_key = os.getenv("NASA_API_KEY")

Now, we are ready to make the request to the NASA API. According to the documentation, the api_key is passed a parameter to the GET request.

async with httpx.AsyncClient() as client:
    r = await client.get(
        "https://api.nasa.gov/planetary/apod", params={"api_key": api_key}
    )

Voilà!

Image(url=r.json()["hdurl"])