Motivation
Type validation and conversion are essential aspects of configuration management in Python applications, ensuring that settings are not only loaded but also conform to expected data types and formats.
Without proper type validation, developers need to manually convert and validate configuration values, which can lead to runtime errors and inconsistent behavior.
import os
DATABASE_URL = os.getenv('DATABASE_URL', 'postgresql://localhost:5432/db')
MAX_CONNECTIONS = os.getenv('MAX_CONNECTIONS', '10') # Need manual conversion to string
DEBUG = bool(os.getenv('DEBUG', 'False')) # Need manual conversion to boolean
print(f"Database URL: {DATABASE_URL}")
print(f"Max Connections: {MAX_CONNECTIONS}")
print(f"Debug Mode: {DEBUG}")
Output:
Database URL: 'postgresql://localhost:5432/db'
Max Connections: 10
Debug Mode: False
Introduction to pydantic-settings
Pydantic-settings is a powerful settings management library that builds on Pydantic’s validation capabilities to provide secure, type-safe configuration management. Install it using:
pip install "pydantic-settings"
Settings Management
Pydantic-settings provides type validation, environment variable support, and secure configuration management through:
from pydantic_settings import BaseSettings, SettingsConfigDict
from pydantic import PostgresDsn
from typing import Optional
class DatabaseSettings(BaseSettings):
model_config = SettingsConfigDict(env_prefix='DB_')
url: PostgresDsn = PostgresDsn('postgresql://localhost:5432/db')
max_connections: int = 10
debug: bool = False
Set environment variables on your terminal:
export DB_URL=postgresql://localhost:5432/production
export DB_MAX_CONNECTIONS=20
export DB_DEBUG=True
Access settings:
# Load settings from environment variables
settings = DatabaseSettings()
print(f"Database URL: {settings.url}")
print(f"Max Connections: {settings.max_connections}")
print(f"Debug Mode: {settings.debug}")
Output:
Database URL: postgresql://localhost:5432/production
Max Connections: 20
Debug Mode: True
Pydantic-settings vs Python-dotenv
Python-dotenv, covered in this article, provides basic environment variable loading, while pydantic-settings offers additional features:
Python-dotenv approach:
from dotenv import load_dotenv
import os
load_dotenv()
database_url = os.getenv('DATABASE_URL') # No type validation
debug = bool(os.getenv('DEBUG')) # Returns string, manual conversion needed
Pydantic-settings advantages:
- Automatic type validation and conversion
- URL format validation with PostgresDsn
- Environment variable prefix support (DB_)
- Default values with proper types
Conclusion
Pydantic-settings provides a type-safe, validated way to manage application configuration. It eliminates common configuration-related bugs and reduces boilerplate code while providing excellent developer experience through type hints and documentation.