import os from granian import Granian from granian.constants import Interfaces, Loops from pydantic import BaseModel, PositiveInt from pydantic_settings import BaseSettings, SettingsConfigDict class WorkersSettings(BaseModel): per_core: PositiveInt = 1 max: PositiveInt | None = None exact: PositiveInt | None = None @property def count(self) -> int: # usage of "or" operator: values here are not allowed to be 0 base = self.exact or (self.per_core * (os.cpu_count() or 1)) return min(base, self.max or base) class BindSettings(BaseModel): host: str = "0.0.0.0" port: int = 8000 class Settings(BaseSettings): model_config = SettingsConfigDict( env_prefix="ADVENT22__", env_nested_delimiter="__", ) workers: WorkersSettings = WorkersSettings() bind: BindSettings = BindSettings() def start(): os.environ["ADVENT22__PRODUCTION_MODE"] = "true" settings = Settings() server = Granian( "advent22_api.app:app", address=settings.bind.host, port=settings.bind.port, workers=settings.workers.count, interface=Interfaces.ASGI, loop=Loops.uvloop, process_name="advent22", ) server.serve()