# Python Config

> When to activate: configuration management, pydantic-settings, env files, feature flags, environment-specific settings

- Skill: `mattakushi432/python-config` (Agent Skill)
- Install (CLI): `npx skillmds@latest add mattakushi432/python-config`
- Raw SKILL.md: https://api.skillmd.com/api/skills/mattakushi432/python-config/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: Mattakushi432 (https://skillmd.com/u/mattakushi432)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/mattakushi432/python-config

---


# Python Configuration Patterns

## Pydantic Settings (12-Factor App)
```python
from pydantic import PostgresDsn, RedisDsn, SecretStr, AnyHttpUrl, field_validator
from pydantic_settings import BaseSettings, SettingsConfigDict
from functools import lru_cache

class Settings(BaseSettings):
    model_config = SettingsConfigDict(
        env_file=".env",
        env_file_encoding="utf-8",
        case_sensitive=False,
    )
    
    # Application
    app_name: str = "MyApp"
    environment: str = "development"  # development | staging | production
    debug: bool = False
    
    # Database
    database_url: PostgresDsn
    database_pool_size: int = 10
    database_max_overflow: int = 20
    
    # Cache
    redis_url: RedisDsn = "redis://localhost:6379/0"
    
    # Auth
    secret_key: SecretStr
    access_token_expire_minutes: int = 30
    
    # External services
    sendgrid_api_key: SecretStr | None = None
    stripe_secret_key: SecretStr | None = None
    
    @field_validator("environment")
    @classmethod
    def validate_env(cls, v: str) -> str:
        allowed = {"development", "staging", "production"}
        if v not in allowed:
            raise ValueError(f"environment must be one of {allowed}")
        return v
    
    @property
    def is_production(self) -> bool:
        return self.environment == "production"

@lru_cache
def get_settings() -> Settings:
    return Settings()

# Usage in FastAPI
settings = Annotated[Settings, Depends(get_settings)]
```

## Environment-Specific Settings
```python
# config/base.py
class BaseConfig(BaseSettings):
    debug: bool = False
    log_level: str = "INFO"
    database_url: PostgresDsn
    
# config/development.py
class DevelopmentConfig(BaseConfig):
    debug: bool = True
    log_level: str = "DEBUG"

# config/production.py
class ProductionConfig(BaseConfig):
    debug: bool = False
    # Production enforces certain required fields
    sentry_dsn: AnyHttpUrl

def get_config() -> BaseConfig:
    env = os.getenv("ENVIRONMENT", "development")
    configs = {
        "development": DevelopmentConfig,
        "production": ProductionConfig,
    }
    return configs.get(env, DevelopmentConfig)()
```

## Feature Flags
```python
from pydantic import BaseModel

class FeatureFlags(BaseSettings):
    model_config = SettingsConfigDict(env_prefix="FEATURE_")
    
    new_dashboard: bool = False
    ai_recommendations: bool = False
    beta_api: bool = False

flags = FeatureFlags()

# Usage
if flags.new_dashboard:
    return new_dashboard_response()

# Runtime flags from Redis (for fast toggling without redeploy)
async def is_enabled(feature: str, redis: Redis) -> bool:
    raw = await redis.get(f"feature:{feature}")
    return raw == b"true" if raw else False
```

