Stop Hardcoding API Keys in Python
Learn how to avoid accidentally exposing API keys by using environment variables, .env files, and secrets managers in Python. Simple steps to keep your code secure.
Here is the article body for PythonSkillset.com.
Stop Hardcoding API Keys in Python
We have all done it. You are in a hurry, testing a cool new API, and you just paste the key right into the script. It works. You push the code to GitHub. Then you get that terrifying email from a security bot telling you your secret is now public.
It happens to the best of us. But once you know the right tricks, you never go back.
The "Oh No" Moment
I remember a story from a developer at a small startup. They had a script connecting to a payment gateway. The API key was sitting right there at the top of the file, plain as day. They pushed it to a public repo for a "quick fix." Within an hour, someone scraped the key and tried to run up a bill.
That panic is completely avoidable. PythonSkillset is all about writing code that is not just smart, but safe. So, let's look at the simple ways to keep those keys out of your codebase.
The Obvious Fix: Environment Variables
The first step is the most common and effective. You do not store the key in the .py file. You store it in the operating system.
On Linux or macOS, you can add this to your ~/.bashrc or ~/.zshrc file:
export MY_API_KEY="your-actual-secret-key-here"
Then, you reload your shell (source ~/.bashrc) or restart your terminal.
In your Python script, you grab it like this:
import os
api_key = os.getenv("MY_API_KEY")
if api_key is None:
raise ValueError("No API key found. Set the MY_API_KEY env variable.")
That is it. Your key is now a system variable, not a string in your code.
The .env File Trick
Environment variables are great, but they can be a pain to manage if you have multiple projects. That is where .env files come in.
Make a file called .env in your project's root folder:
MY_API_KEY=your-actual-secret-key-here
DATABASE_PASSWORD=my-super-secret-password
Now, you need a tiny library called python-dotenv. Install it with pip install python-dotenv.
In your code:
from dotenv import load_dotenv
import os
load_dotenv() # This loads the .env file
api_key = os.getenv("MY_API_KEY")
Here is the golden rule: Add .env to your .gitignore file immediately. If you don't, Git will track that file and upload your secrets to the repository.
What About Config Files?
Some projects use JSON or YAML config files. This is fine, but with one rule: never store the actual key in the file that gets committed.
Instead of this:
// config.json -- DO NOT COMMIT THIS
{
"api_key": "12345"
}
Do this:
// config.json -- This is safe to commit
{
"api_key": "${MY_API_KEY}"
}
Then, in your Python code, you read the config, check for the placeholder, and fetch the real value from the environment.
import json
import os
import re
with open("config.json") as f:
config = json.load(f)
key = config.get("api_key")
# Check if it's a placeholder
if key and key.startswith("${"):
var_name = key.strip("${}")
key = os.getenv(var_name)
# Now use the key
client = SomeAPIClient(api_key=key)
A Real-World Example for PythonSkillset
Imagine you are building a bot for PythonSkillset that automatically fetches the latest tutorial titles from an API.
Your main.py should look clean:
import os
import requests
def get_latest_titles():
api_key = os.getenv("PYTHONSKILLSET_API_KEY")
if not api_key:
print("Error: API key not found. Set PYTHONSKILLSET_API_KEY.")
return None
headers = {"Authorization": f"Bearer {api_key}"}
response = requests.get("https://api.pythonskillset.com/titles", headers=headers)
if response.status_code == 200:
return response.json()["titles"]
else:
print(f"Failed to fetch: {response.status_code}")
return None
Your .env file (which is ignored by Git) holds the key. Your colleagues can clone the repo, create their own .env file, and the code works perfectly without ever exposing a secret.
One More Thing: Use a Secrets Manager
For production apps, you can go one step further. Services like AWS Secrets Manager or HashiCorp Vault let you store secrets securely in the cloud. Your Python code fetches the key at runtime.
It sounds fancy, but the concept is the same: your code never contains the actual secret.
Here is a quick example using boto3 for AWS:
import boto3
import json
from botocore.exceptions import ClientError
def get_secret():
secret_name = "pythonskillset/api-key"
region_name = "us-west-2"
session = boto3.session.Session()
client = session.client(service_name="secretsmanager", region_name=region_name)
try:
response = client.get_secret_value(SecretId=secret_name)
secret = response["SecretString"]
return json.loads(secret)["api_key"]
except ClientError as e:
print(f"Could not retrieve secret: {e}")
return None
Final Thoughts
Saving an API key directly in your Python script is like leaving your house key under the doormat. It works until someone looks under the mat.
Environment variables, .env files, or a secrets manager are all simple and effective ways to keep your code secure. Your collaborators will thank you, and you will sleep better knowing your payment gateway key is not floating around in a public repository.
Get into the habit now. It takes thirty seconds to set up, and it saves hours of headache later.
Comments
Questions, corrections, and tips stay visible for everyone reading this page.
Join the discussion
No comments yet
Be the first to leave a note — it helps the next reader.