PythiloLesson 15 of 15 · progress kept in this browser

Configuration and wiring

A function that reads os.environ deep inside is configured by a global: tests have to patch it, and nobody can see which settings exist. Read configuration once, at start-up, into a frozen object, and pass it to whatever needs it.

from dataclasses import dataclass

@dataclass(frozen=True)
class Settings:
    db_path: str = ":memory:"
    page_size: int = 20

    @classmethod
    def from_env(cls, env):
        path = env.get("DB", ":memory:")
        size = env.get("PAGE_SIZE", "20")
        return cls(path, int(size))

print(Settings.from_env({"PAGE_SIZE": "5"}))

from_env takes any mapping, so a test passes a plain dict and the program passes os.environ.

Your task

Write a frozen Settings(db_path, page_size) with from_env(env) reading SHOP_DB (default ":memory:") and SHOP_PAGE_SIZE (default 20), raising a ValueError that names the variable when the size is not a positive whole number. Write build_app(settings, repo=None) returning an App whose repo is the one given or a new SqliteRepo(settings.db_path), and whose catalog is a Catalog sharing that repo with the configured page size.

All lessons