Configuration¶
Two TOML files. One function each. Fail loud, fail fast.
Constants¶
Used as the default argument for both load_cameras_config() and load_webhooks_config(). Overridden via --config CLI flag.
TOML Parsing¶
Argus uses tomllib from the Python 3.11+ stdlib. No third-party TOML library. Files are opened in binary mode ("rb") as required by tomllib.
load_cameras_config()¶
def load_cameras_config(
config_dir: Path = DEFAULT_CONFIG_DIR,
) -> tuple[Settings, list[CameraConfig]]:
Behavior¶
- Resolves
{config_dir}/cameras.toml. - Checks existence — raises
FileNotFoundErrorif missing. - Parses TOML into a raw dict.
- Extracts
[settings]section, fills defaults for missing keys. - Constructs
Settings()—__post_init__fires here, raisingValueErroron invalid ranges. - Extracts
[cameras]section. RaisesValueErrorif empty. - For each camera: requires
urlfield, fillsnamefrom config or defaults to the key. - Returns
(settings, list[CameraConfig]).
Error Cases¶
| Condition | Exception | When |
|---|---|---|
cameras.toml missing |
FileNotFoundError |
Path doesn't exist |
Empty [cameras] section |
ValueError("No cameras defined in cameras.toml") |
TOML parses but no camera entries |
Missing url field |
ValueError("Camera '{id}' is missing required 'url' field") |
Camera entry has no url |
Invalid frame_scale |
ValueError("frame_scale must be in (0, 1], ...") |
Settings.__post_init__ |
Invalid tolerance |
ValueError("tolerance must be in (0, 1], ...") |
Settings.__post_init__ |
Invalid detection_interval |
ValueError("detection_interval must be > 0, ...") |
Settings.__post_init__ |
All exceptions propagate to main.py, which catches (FileNotFoundError, ValueError) and calls sys.exit(1).
Example cameras.toml¶
[settings]
detection_interval = 0.5
tolerance = 0.6
frame_scale = 0.25
[cameras.cam_01]
name = "Front Door"
url = "rtsp://192.168.1.100:554/stream"
[cameras.cam_02]
url = "rtsp://192.168.1.101:554/stream" # name defaults to "cam_02"
load_webhooks_config()¶
Behavior¶
- Resolves
{config_dir}/webhooks.toml. - If missing — logs a warning and returns
[]. Does not crash. Webhooks are optional. - Parses TOML.
- For each entry under
[webhooks]: constructsWebhookConfig, uppercasesmethod. - Filtering logic: only includes webhooks where
enabled == Trueandurlis non-empty. - Enabled webhooks with empty URLs get a warning log and are skipped.
Filtering Truth Table¶
enabled |
url |
Result |
|---|---|---|
True |
non-empty | Included |
True |
"" |
Skipped + warning |
False |
anything | Silently skipped |
Example webhooks.toml¶
[webhooks.my_server]
enabled = true
url = "http://127.0.0.1:8000/webhook"
method = "POST"
headers = { "X-Api-Key" = "secret" }
body_template = '{"person": "{name}", "camera": "{camera}", "confidence": {confidence}}'
The Validation Chain¶
TOML file
→ tomllib.load() (raw dict)
→ Settings(...) (constructs dataclass)
→ __post_init__() (validates ranges)
→ ValueError (propagates up)
→ main.py catches (exits with code 1)
The validation is eager and terminal. Argus does not guess, default silently, or attempt recovery. If your config is wrong, it tells you exactly what and exits.