Skip to main content

Configuration Management

Manage environment-specific settings, cache configurations, and security keys using the project's dataclass-based configuration system.

Configure the Application Factory

The application factory create_app in app/__init__.py accepts a configuration class to initialize the Flask application. By default, it uses DevelopmentConfig.

from app import create_app
from app.config import ProductionConfig

# Initialize for production
app = create_app(config_class=ProductionConfig)

Configuration Classes

Settings are defined in app/config.py using Python dataclasses. This provides type safety and structured access to environment variables.

Base Configuration

The BaseConfig class contains shared settings used across all environments.

@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()

Environment Specializations

Inherit from BaseConfig to override settings for specific environments:

  • DevelopmentConfig: Enables DEBUG mode and uses a smaller PAGE_SIZE (10) and cache limit (128).
  • TestingConfig: Sets the TESTING flag and minimal PAGE_SIZE (5) for test isolation.
  • ProductionConfig: Enforces strict security and higher performance limits.
@dataclass
class ProductionConfig(BaseConfig):
"""Configuration for production deployments."""

# Raises KeyError if SECRET_KEY is missing from environment
SECRET_KEY: str = field(default_factory=lambda: os.environ["SECRET_KEY"])
PAGE_SIZE: int = DEFAULT_PAGE_SIZE

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

Cache Configuration

The get_cache_config() method on configuration classes returns a dictionary generated by the internal _build_cache_config helper. This dictionary includes ttl_seconds, max_entries, and the eviction strategy (defaulting to "lru").

# Internal helper used by config classes
def _build_cache_config(ttl: int = 300, max_size: int = 1024) -> Dict[str, Any]:
return {"ttl_seconds": ttl, "max_entries": max_size, "eviction": "lru"}

Troubleshooting

Missing Production Secret Key

The ProductionConfig uses os.environ["SECRET_KEY"] without a default value. If the SECRET_KEY environment variable is not set, the application will fail to start with a KeyError. Ensure this is exported in your production environment:

export SECRET_KEY="your-secure-random-string"

Cache Configuration Ignored

While BaseConfig and its subclasses define cache parameters via get_cache_config(), the current implementation of BookmarkService in app/services/bookmark_service.py uses a hardcoded cache size:

# app/services/bookmark_service.py
def _init_services(self) -> None:
self._repo = BookmarkRepository()
# WARNING: This ignores the max_size defined in app.config
self._cache: LRUCache[Bookmark] = LRUCache(max_size=256)
self._search = SearchIndex(self._repo)

Page Size Validation

The BaseConfig includes a _validate() method that ensures PAGE_SIZE does not exceed MAX_PAGE_SIZE (100). However, this method is not automatically called during Flask initialization. If you are manually instantiating config classes, call _validate() to ensure settings are within bounds.