Why Use Settings Management?
Environment variables are essential for:- Security: Keeping secrets out of your codebase
- Flexibility: Different settings for development, staging, and production
- Portability: Easy deployment across different environments
- 12-Factor App compliance: Following modern application best practices
Understanding Environment Variables
Environment variables are text strings stored outside your application code. They’re accessible to your application at runtime but can only be read as strings.The Challenge
Pydantic Settings
Pydantic Settings provides automatic type conversion, validation, and IDE support for your application configuration.Installation
First, install thepydantic-settings package:
The
pydantic-settings package is a separate package from Pydantic itself and must be installed explicitly.Creating a Settings Class
Create a settings class by inheriting fromBaseSettings:
- ✅ Read environment variables (case-insensitive)
- ✅ Convert types automatically (string → int, bool, etc.)
- ✅ Validate required fields
- ✅ Use default values when not provided
- ✅ Raise errors for invalid data
Using Settings in FastAPI
Here’s a complete example:Running with Environment Variables
Organizing Settings in Modules
For larger applications, separate your settings into dedicated modules.config.py
main.py
Settings as Dependencies
Using settings as a dependency makes testing easier and provides better control:The
@lru_cache decorator ensures the settings are only loaded once, improving performance. Without it, settings would be reloaded on every request.Benefits of Dependency Injection
- Easier testing: Override settings in tests
- Better isolation: Each test can have different settings
- Explicit dependencies: Clear what each endpoint needs
Testing with Settings Dependencies
Reading from .env Files
For local development, you can store environment variables in a.env file.
Creating a .env File
Configuring Settings to Read .env
Install python-dotenv:.env file.
Multiple Environment Files
You can use different.env files for different environments:
.env.developmentfor local development.env.stagingfor staging environment.env.productionfor production
Optimizing Settings Loading with lru_cache
Reading settings (especially from files) is expensive. Use@lru_cache to load them only once:
How lru_cache Works
@lru_cache is from Python’s functools module. It caches function results based on arguments. Since get_settings() has no arguments, it always returns the same cached result.Advanced Configuration
Field Validation
Environment Variable Prefixes
Use prefixes to namespace your environment variables:Nested Settings
Real-World Example
Here’s a complete, production-ready settings configuration:Best Practices
1. Use Type Hints
2. Provide Sensible Defaults
3. Use Field Validators
4. Document Your Settings
5. Never Commit Secrets
Add to.gitignore:
Deployment Considerations
Container Environments (Docker, Kubernetes)
Cloud Platforms (AWS, GCP, Azure)
Most cloud platforms provide environment variable management:- AWS: Parameter Store, Secrets Manager
- GCP: Secret Manager
- Azure: Key Vault
- Heroku: Config Vars
Always use your platform’s secret management service for sensitive data in production.
Summary
Pydantic Settings provides: ✅ Type safety: Automatic type conversion and validation ✅ IDE support: Full autocomplete and type checking✅ Easy testing: Dependency injection for test overrides ✅ File support: Read from
.env files
✅ Performance: Cache with @lru_cache
✅ Validation: Field validators and constraints
Learn More
- Pydantic Settings Documentation
- Environment Variables Guide
- 12-Factor App Methodology
- FastAPI Dependencies
Settings management is crucial for production applications. Always validate and type-check your configuration to catch errors early.