Managing Environment Variables in FastAPI Applications

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:

  1. The Standard Library (os.environ)
  2. 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

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *