Skip to content

Configuration

Ports, database URLs, secrets — settings usually live in environment variables. Settings reads them for you: declare fields with types and defaults, get parsed values back.

Settings

from endocore import Settings
from pathlib import Path

class AppSettings(Settings):
    debug: bool = False
    db_url: str = "sqlite://app.db"
    port: int = 8000
    allowed_hosts: list = []
    data_dir: Path = Path(".")

settings = AppSettings()   # reads DEBUG, DB_URL, PORT, ALLOWED_HOSTS, DATA_DIR from env
  • Each attribute is read from the UPPERCASED environment variable, cast to its annotation, falling back to the declared default.
  • Supported casts: bool (1/true/yes/on), int, float, Path, list/tuple/set (comma-separated), str.
  • Override at construction: AppSettings(port=9000).
  • Secret-looking fields (name contains secret, password, passwd, token, key, or dsn) are masked in repr, so settings never leak into logs.

Add a prefix if you want namespaced vars:

class AppSettings(Settings):
    _env_prefix = "APP_"      # reads APP_DEBUG, APP_PORT, ...
    debug: bool = False

Expose it via DI:

# providers.py
from Config import AppSettings
providers = {AppSettings: AppSettings}

.env files

from endocore import load_dotenv
load_dotenv(".env")           # KEY=VALUE lines -> os.environ (won't override existing)

env() helper

from endocore import env
env("PORT", default=8000, cast=int)
env("DEBUG", cast=lambda v: v.lower() in {"1", "true", "yes"})

Application options

Application (built by endo dev / the ASGI factory) accepts:

Option Default Meaning
dev False enable the in-process reload watcher
default_version None "latest" resolves version-less paths
max_body_size 16 MB reject larger request bodies (413)
openapi None serve /openapi.json and /docs; None = only when dev=True (opt in for production with openapi=True / ENDOCORE_OPENAPI=1)
openapi_title "EndoCore API" title in the schema

endo dev exposes the common ones as flags (--default-version, --no-reload).