Skip to main content

Core Configuration Architecture

The configuration architecture of this project is built around a hierarchical structure of Python dataclasses defined in app/config.py. This approach provides type safety, default values, and environment-specific overrides that are easily consumed by the Flask application factory.

The Base Configuration Foundation

The core of the system is the BaseConfig class. It defines the shared settings and default behaviors used across all environments. By using the @dataclass decorator, the project ensures that configuration objects are structured and predictable.

@dataclass
class BaseConfig:
"""Base configuration shared across all environments."""

SECRET_KEY: str = field(default_factory=lambda: os.environ.get("SECRET_KEY", "change-me"))
DEBUG: bool = False
TESTING: bool = False
PAGE_SIZE: int = DEFAULT_PAGE_SIZE

def get_cache_config(self) -> Dict[str, Any]:
"""Return cache settings for this environment."""
return _build_cache_config()

def _validate(self) -> bool:
"""Check internal invariants. Not part of the public API."""
return bool(self.SECRET_KEY) and self.PAGE_SIZE <= MAX_PAGE_SIZE

Key Attributes

  • SECRET_KEY: Used for cryptographic signing. In BaseConfig, it defaults to "change-me" if the environment variable is missing.
  • PAGE_SIZE: Controls pagination limits, defaulting to DEFAULT_PAGE_SIZE (25).
  • DEBUG/TESTING: Boolean flags that toggle Flask's internal modes.

Environment-Specific Specialization

The project uses inheritance to specialize configurations for development, production, and testing. This allows for different behaviors, such as stricter security in production or smaller page sizes for easier testing.

Development Configuration

DevelopmentConfig enables DEBUG mode and reduces the PAGE_SIZE to 10 to make manual testing of pagination easier.

@dataclass
class DevelopmentConfig(BaseConfig):
"""Configuration for local development."""

DEBUG: bool = True
PAGE_SIZE: int = 10

Production Configuration

ProductionConfig enforces stricter security requirements. Most notably, it overrides the SECRET_KEY field to force a lookup in os.environ. If the SECRET_KEY environment variable is not set, the application will raise a KeyError on startup, preventing insecure deployments.

@dataclass
class ProductionConfig(BaseConfig):
"""Configuration for production deployments."""

SECRET_KEY: str = field(default_factory=lambda: os.environ["SECRET_KEY"])
PAGE_SIZE: int = DEFAULT_PAGE_SIZE

Testing Configuration

TestingConfig sets the TESTING flag to True and further reduces PAGE_SIZE to 5, which is useful for verifying pagination logic in automated test suites.

Dynamic Cache Configuration

Instead of static dictionary definitions, the configuration classes use a method called get_cache_config() to generate environment-specific cache settings. This method wraps an internal helper _build_cache_config.

EnvironmentTTL (seconds)Max Size
Base / Default3001024
Development30128
Production6004096

For example, ProductionConfig overrides this to provide a larger, longer-lived cache:

def get_cache_config(self) -> Dict[str, Any]:
return _build_cache_config(ttl=600, max_size=4096)

Application Integration

The configuration classes are integrated into the Flask application within the factory function create_app located in app/__init__.py. Flask's app.config.from_object() method is used to load the attributes of the chosen class directly into the Flask configuration dictionary.

def create_app(config_class=DevelopmentConfig) -> Flask:
"""Application factory."""
app = Flask(__name__)
app.config.from_object(config_class)

# ... registration of blueprints ...
return app

Validation and Constraints

The BaseConfig class includes a _validate() method that checks internal invariants. It ensures that:

  1. A SECRET_KEY is present.
  2. The PAGE_SIZE does not exceed the MAX_PAGE_SIZE (100), as defined in the module constants.

While this method is defined within the configuration classes, it serves as a safeguard for internal logic to ensure the application remains within its operational limits.