Skip to Content
Course content

104: Environment Variables in Python

Click on the "Edit" button in the top corner of the screen to edit your slide content.

Listen, there is one mistake almost every developer makes early in their career: hardcoding a password or an API key directly into their source code. I've done it. You might have done it. The problem is that once you push that code to a public repository like GitHub, that secret is out there forever—even if you delete the line in a later commit, it's still in the git history. It's a nightmare to clean up.

To avoid this, we use environment variables. These are values stored on the operating system itself, outside of your code, which your Python script can "look up" while it's running. Let's build a small script that fetches weather data from a hypothetical API to see how this works in practice.

The mistake we've all made: Hardcoding secrets

If I were just hacking something together quickly, I might be tempted to write something like this:

import requests

def get_weather(city):
    # This is the mistake. Never do this in a real project.
    api_key = "sk_live_51MzX82LpQz91kLp" 
    url = f"https://api.weather-service.com/v1/current?q={city}&key={api_key}"
    return requests.get(url).json()

print(get_weather("New York"))

It works perfectly! But if I share this script with a teammate or upload it to a server, my private API key goes with it. Now anyone who sees the code can use my paid account. I need to get that string out of my .py file and into the environment.

Moving the secret to the environment

First, I'll set the variable on my machine. If you're on Mac or Linux, you'd run export WEATHER_API_KEY='your_actual_key_here' in your terminal. On Windows, it's set WEATHER_API_KEY='your_actual_key_here'. Now the value lives in the shell's memory, not in my text editor.

Now, I'll use Python's built-in os module to grab it. I'm going to use os.environ, which acts like a dictionary containing all the environment variables available to the process.

import os
import requests

def get_weather(city):
    # Now I'm pulling the key from the OS environment
    api_key = os.environ["WEATHER_API_KEY"] 
    url = f"https://api.weather-service.com/v1/current?q={city}&key={api_key}"
    return requests.get(url).json()

print(get_weather("New York"))

This is much safer. The code describes how to use the key, but it doesn't actually contain the key.

Dealing with missing keys gracefully

Here's where I ran into a snag while testing this. If I run this script in a new terminal window where I forgot to run the export command, Python throws a KeyError: 'WEATHER_API_KEY' and the whole program crashes. That's a bit too aggressive for a production app.

Instead of using square brackets, I'll switch to os.getenv(). This method is better because if the variable doesn't exist, it returns None (or a default value you provide) instead of crashing your program. It allows me to handle the error politely.

import os
import requests

def get_weather(city):
    # .getenv() is safer than os.environ[]
    api_key = os.getenv("WEATHER_API_KEY")
    
    if api_key is None:
        print("Error: Please set the WEATHER_API_KEY environment variable.")
        return None

    url = f"https://api.weather-service.com/v1/current?q={city}&key={api_key}"
    return requests.get(url).json()

print(get_weather("New York"))

Now, if the key is missing, the user gets a helpful message instead of a wall of traceback text. It's a small change, but it's the difference between a script that feels like a toy and one that feels like professional software.




📋 Practical Task

Exercise: Building a Secure Database Connector

You are building a module that connects to a database. To keep the credentials secure, you must avoid hardcoding them. Create a Python script that does the following:

  • Uses os.getenv() to look for two environment variables: DB_USER and DB_PASSWORD.
  • If either variable is missing, the script should print a specific error message: "Missing database credentials. Please check your environment variables." and exit the function.
  • If both are present, the script should print a fake connection string in this format: "Connecting to database as [DB_USER] with password [DB_PASSWORD]..."

Testing your code: To test the success path, run export DB_USER=admin and export DB_PASSWORD=secret123 (or the Windows set equivalent) in your terminal before running your script.

Rating
0 0

There are no comments for now.

to be the first to leave a comment.