Managing settings for a FastAPI project can get messy if you spread configuration across multiple files or hard-code secrets. The best way is to keep all your settings in one place and load them from a .env
file. Pydantic Settings provides optional Pydantic features for loading a settings or config class from environment variables or secrets files. Pydantic v2 and pydantic-settings
make this easy and reliable.
Centralizing settings means you have a single source of truth for your app’s configuration. You avoid mistakes, make your code easier to maintain, and keep secrets out of your source code.
To use pydantic-settings
with Pydantic v2, you need to install it first. Run this command in your project directory:
pip install pydantic-settings
Make sure you have Pydantic v2 installed as well:
pip install pydantic
Here’s a simple settings module using Pydantic v2 and pydantic-settings
. This reads values from a .env
file and makes them available throughout your app.
from enum import Enum from functools import lru_cache from pydantic import Field from pydantic_settings import BaseSettings class EnvironmentEnum(str, Enum): TEST = "TEST" PRODUCTION = "PRODUCTION" class Settings(BaseSettings): # Environment settings DEBUG: bool = Field(default=False, validation_alias="DEBUG", alias_priority=2) RELOAD: bool = Field(default=False, validation_alias="RELOAD", alias_priority=2) ENVIRONMENT: str = Field(default=EnvironmentEnum.TEST, validation_alias="ENVIRONMENT", alias_priority=2) # POSTGRES DATABASE POSTGRES_USER: str = Field(default="", validation_alias="POSTGRES_USER", alias_priority=2) POSTGRES_PASSWORD: str = Field(default="", validation_alias="POSTGRES_PASSWORD", alias_priority=2) POSTGRES_HOST: str = Field(default="", validation_alias="POSTGRES_HOST", alias_priority=2) POSTGRES_PORT: str = Field(default="", validation_alias="POSTGRES_PORT", alias_priority=2) POSTGRES_DATABASE_NAME: str = Field(default="", validation_alias="POSTGRES_DATABASE_NAME", alias_priority=2) SECRET_KEY: str = Field(default="", validation_alias="SECRET_KEY", alias_priority=2) class Config: env_file = ".env" env_file_encoding = "utf-8" extra = "ignore" @lru_cache def get_settings(): return Settings()
When you use Pydantic’s Field
, you can set a validation_alias
. This tells Pydantic to look for a specific name in your environment variables or input data, even if your Python attribute has a different name. It’s useful if your config keys don’t match your Python variable names.
alias_priority
comes into play when you have multiple possible aliases for a field. The priority number decides which alias Pydantic should prefer if more than one is present. A lower number means higher priority.
In short, validation_alias
lets you map your Python settings to environment variable names, and alias_priority
helps Pydantic choose the right one if there are several options.
True
, FastAPI will show detailed error messages and enable debug features. This is useful during development but should be False
in production.True
, FastAPI will automatically reload the server when you change your code. This is handy for development but not for production.The @lru_cache
decorator makes sure your settings are only loaded once. This is important because you don’t want to read and parse your .env file every time you need a setting. It saves memory and speeds up your app.
You can access your settings anywhere in your app by importing and calling get_settings(). Here’s an example:
from app.config.main import get_settings settings = get_settings() print(settings.POSTGRES_USER)
This gives you access to all your configuration values, and you know they’re coming from your centralized settings.
Want to see a real-world example of using these settings in action? Check out my blog post on connecting FastAPI to a serverless database with pool_pre_ping in SQLAlchemy.
Here’s what your .env file might look like:
DEBUG=True RELOAD=True ENVIRONMENT=TEST POSTGRES_USER=your_user POSTGRES_PASSWORD=your_password POSTGRES_HOST=localhost POSTGRES_PORT=5432 POSTGRES_DATABASE_NAME=your_database SECRET_KEY=your_secret_key
Note:
For production environments, you should not store sensitive credentials like database passwords in your .env
file or commit them to version control/GitHub. Instead, use a secure service such as Google Secret Manager to manage secrets safely.
You can read more about using Google Secret Manager in my blog post on running database migrations with Alembic in Google Cloud Build.
Centralizing your settings with Pydantic and a .env
file is a simple way to keep your FastAPI project organized. It’s not complicated, and it saves you headaches down the road. Use lru_cache to avoid repeated reads, and keep your secrets out of your codebase. If you’re still hard-coding settings, it’s time to switch.
David Muraya is a Solutions Architect specializing in Python, FastAPI, and Cloud Infrastructure. He is passionate about building scalable, production-ready applications and sharing his knowledge with the developer community. You can connect with him on LinkedIn.
Enjoyed this blog post? Check out these related posts!
Advanced Performance Tuning for FastAPI on Google Cloud Run
From Cold Starts to Concurrency: A Deep Dive into FastAPI Performance on Cloud Run.
Read More..
Optimizing Reflex Performance on Google Cloud Run
A Comparison of Gunicorn, Uvicorn, and Granian for Running Reflex Apps
Read More..
Full-Text Search: Using the Trigram Tokenizer Algorithm to Match Peoples Names
Leveraging Full Text Search and Trigram Tokenization for Efficient Name Matching
Read More..
Running Database Migrations with Alembic in Google Cloud Build
How to Organize and Load FastAPI Settings from a .env File Using Pydantic v2
Read More..
Have a project in mind? Send me an email at hello@davidmuraya.com and let's bring your ideas to life. I am always available for exciting discussions.