Skip to main content

Creating Your First Config

In this tutorial, you will learn how to initialize the configuration system for the Pagemark API and create a custom configuration by overriding default values. You will use the built-in configuration classes to manage environment-specific settings like debug modes, page sizes, and secret keys.

Prerequisites

To follow this tutorial, you need the following components from the codebase:

  • The app/config.py file containing the configuration classes.
  • The app/__init__.py file which contains the application factory.
  • A basic understanding of Python dataclasses.

Step 1: Understand the Base Configuration

The foundation of the configuration system is the BaseConfig class. It defines the default settings shared across all environments.

from dataclasses import dataclass, field
import os
from app.config import DEFAULT_PAGE_SIZE

@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:
"""Return cache settings for this environment."""
return {"ttl_seconds": 300, "max_entries": 1024, "eviction": "lru"}

The BaseConfig class uses a default_factory for the SECRET_KEY to safely attempt to pull from the environment while providing a fallback. It also sets a default PAGE_SIZE of 25 (defined by DEFAULT_PAGE_SIZE).

Step 2: Use the Development Defaults

For local work, the project provides DevelopmentConfig. This class inherits from BaseConfig and overrides specific values to make development easier, such as enabling debug mode and reducing the page size for easier testing of pagination.

from app.config import DevelopmentConfig

# Inspecting the development defaults
config = DevelopmentConfig()
print(f"Debug Mode: {config.DEBUG}") # Output: True
print(f"Page Size: {config.PAGE_SIZE}") # Output: 10

By default, the application factory in app/__init__.py uses this class:

from flask import Flask
from app.config import DevelopmentConfig

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

Step 3: Create a Custom Configuration

You can create your own configuration by inheriting from BaseConfig. This is useful if you need to enforce specific constraints or change settings for a unique environment.

In this example, we will create a LocalStagingConfig that overrides the PAGE_SIZE and provides a custom cache configuration.

from dataclasses import dataclass
from app.config import BaseConfig, _build_cache_config

@dataclass
class LocalStagingConfig(BaseConfig):
"""Custom configuration for a local staging environment."""

PAGE_SIZE: int = 50
SECRET_KEY: str = "local-staging-only-secret"

def get_cache_config(self) -> dict:
# Use the internal helper to build a custom cache
return _build_cache_config(ttl=60, max_size=512)

Note: When overriding PAGE_SIZE, be aware of the internal _validate() method in BaseConfig. It ensures that PAGE_SIZE does not exceed MAX_PAGE_SIZE (100). If you set a value higher than 100, internal validation will fail.

Step 4: Initialize the App with Your Config

Once you have defined your custom class, pass it to the create_app factory. This allows you to swap configurations without changing the core application logic.

from app import create_app
# Import your custom config class
# from my_configs import LocalStagingConfig

# Initialize the app with the custom configuration
app = create_app(config_class=LocalStagingConfig)

if __name__ == "__main__":
# The app now uses PAGE_SIZE=50 and your custom secret key
app.run()

Summary

You have successfully:

  1. Explored the BaseConfig defaults.
  2. Identified how DevelopmentConfig overrides settings for local use.
  3. Created a custom configuration class by inheriting from BaseConfig.
  4. Initialized the Flask application using your custom settings via the application factory.

For your next steps, try creating a configuration that pulls all its values from a .env file using os.environ.get().