As a backend developer, one of the foundational best practices is to keep sensitive information such as API keys, database credentials, and configuration settings out of your codebase. Instead, we use environment variables. In this article, I’ll walk you through practical techniques for managing environment variables effectively in your FastAPI projects.
Why Use Environment Variables?
Environment variables provide a secure and flexible way to configure your application from outside the code. Storing secrets in version-controlled Python files risks accidental exposure and makes changing configurations across environments (development, staging, production) cumbersome.
Loading Environment Variables
Let’s consider a typical FastAPI setup. The two common approaches for loading environment variables are:
- The Standard Library (
os.environ
) - Third-party Packages (
python-dotenv
,pydantic
settings)
Using python-dotenv
for Local Development
The python-dotenv
package lets you define a .env
file in your project root:
DATABASE_URL=postgresql://user:pass@localhost/db
SECRET_KEY=supersecretkey
Then, load these variables at startup:
from dotenv import load_dotenv
import os
load_dotenv() # Loads variables from .env into the environment
DATABASE_URL = os.getenv("DATABASE_URL")
SECRET_KEY = os.getenv("SECRET_KEY")
Using Pydantic Settings Management
Pydantic (FastAPI’s favorite data validation library) provides a clean way to centralize app configuration:
from pydantic import BaseSettings
class Settings(BaseSettings):
database_url: str
secret_key: str
class Config:
env_file = ".env"
settings = Settings()
You can then import settings
wherever you need configuration values. This method also validates the types of your environment variables and falls back to system os.environ
if needed.
Injecting Settings into FastAPI Dependencies
A tidy way to use settings in your app is via dependency injection:
from fastapi import Depends, FastAPI
app = FastAPI()
def get_settings():
return settings
@app.get("/info")
def read_info(settings: Settings = Depends(get_settings)):
return {"db": settings.database_url}
This technique brings testability and configurability to your endpoints.
Summary Tips
- Never commit your
.env
file if it contains secrets. Add it to.gitignore
. - Leverage Pydantic settings for type safety and validation.
- Use dependency injection to make config available wherever you need it.
Managing environment variables well sets the foundation for robust, secure FastAPI services—whether you’re running locally or deploying to production.
Happy coding!
— Fast Eddy
Leave a Reply