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.
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"])
