Reading Environment Variables in Python: A Security Best Practice
Learn how to use Python's os module to read environment variables. Stop hardcoding secrets and start managing your application configuration securely.

Previously in this course, we explored Advanced Error Handling to keep our applications robust. Now, we'll shift our focus to security: specifically, how to manage sensitive information like API keys and database credentials without exposing them in your source code.
Why Environment Variables Matter
When you build applications, you often need settings that change based on where the code is running—such as a database URL for your local machine versus a production server. Hardcoding these values is a significant security risk. If you push your code to a repository, anyone with access can see those secrets.
Environment variables are key-value pairs managed by the operating system. By storing configuration here, your Python code becomes "environment-aware" without needing to know the specific, sensitive values beforehand. This is the industry-standard way to handle configuration, similar to how developers manage secrets in Node.js applications or Next.js projects.
Accessing Variables with the os Module
Python includes the os module in its standard library, which provides a way to interact with the underlying operating system. Specifically, the os.environ object acts like a dictionary containing all the environment variables available to your process.
Worked Example: Fetching a Configuration Value
Let’s look at how to read a hypothetical API_KEY from your environment.
PYTHONimport os # Access an environment variable # Use .get() to provide a default if the variable is missing api_key = os.environ.get("API_KEY", "default_secret_key") if api_key == "default_secret_key": print("Warning: Using default API key. Check your environment setup.") else: print("API Key successfully loaded.")
In this example, os.environ.get() is safer than using direct dictionary access (os.environ["API_KEY"]). If the key doesn't exist, direct access raises a KeyError, whereas .get() returns None (or your provided default), allowing you to handle the missing configuration gracefully.
Keeping Secrets Out of Code
To truly secure your application, you should never store sensitive values in plain text within your files. Instead, use a local .env file for development and inject variables into your environment in production.
| Strategy | Security Level | Best Use Case |
|---|---|---|
| Hardcoding | Dangerous | Never |
.env file | Moderate | Local development |
| OS Variables | High | Production / CI/CD pipelines |
When working with local files, developers often use the python-dotenv package to load variables automatically. You can install it with pip install python-dotenv. Once installed, you simply add from dotenv import load_dotenv; load_dotenv() at the very top of your main.py file to populate os.environ from your local .env file.
Hands-on Exercise
- Create a file named
.envin your project folder. Add a line:DB_PASSWORD=supersecret123. - Install the
python-dotenvlibrary using pip. - Write a script that imports
load_dotenvandos. - Use
os.environ.get("DB_PASSWORD")to print the password to the console. - Ensure you add
.envto your.gitignorefile so it never gets committed to source control.
Common Pitfalls
- Committing Secrets: The most common mistake is accidentally pushing your
.envfile to GitHub. Always update your.gitignorefile immediately. - Type Mismatch: Environment variables are always read as strings. If you store a port number (e.g.,
8000), you must cast it:int(os.environ.get("PORT", 8000)). - Case Sensitivity: Environment variables are often case-sensitive depending on the OS. Always use uppercase keys (e.g.,
DATABASE_URL) to follow standard conventions.
FAQ
Q: Can I use os.environ to set variables?
A: Yes, you can do os.environ["NEW_VAR"] = "value", but this only affects the current process and its children. It will not persist system-wide.
Q: Is .env secure enough for production?
A: No. In production, use your hosting provider’s secret management dashboard (like AWS Secrets Manager or GitHub Actions secrets) to inject these values directly into the environment.
Recap
We’ve learned that environment variables are the backbone of secure application configuration. By using the os module, we can keep our credentials out of our source code, making our applications safer and more portable across different environments. Remember: if it's a secret, don't hardcode it.
Up next: We will learn about Type Hinting to make our code more readable and catch errors before we even run our scripts.
Work with me

Laravel REST API Development
Clean, secure, well-documented Laravel REST APIs — the backend engine for your app, mobile client, or SaaS. Built by an API specialist.

FilamentPHP Admin Panel & Dashboard Development
A powerful admin panel for your Laravel app — built with FilamentPHP so you can manage everything without touching the database.


