Skip to content

aether_quant.monitoring

Monitoring's views and the API's access rule (the web server stays in monitoring/api_server.py).

Monitoring's views and the API's access rule (the web server stays in monitoring/api_server.py).

Role

Bases: IntEnum

Ordered roles: a viewer reads, an operator may also lock trading, an admin may also unlock it.

ADMIN class-attribute instance-attribute

ADMIN = 3

OPERATOR class-attribute instance-attribute

OPERATOR = 2

VIEWER class-attribute instance-attribute

VIEWER = 1

parse classmethod

parse(text: str) -> Role

User dataclass

accounts is ("*",) for every account, else the ids this user may act on.

accounts class-attribute instance-attribute

accounts: tuple[str, ...] = ('*',)

name instance-attribute

name: str

role instance-attribute

role: Role

salt instance-attribute

salt: str

token_hash instance-attribute

token_hash: str

may_access

may_access(account: str | None) -> bool

authorize

authorize(user: User | None, required: Role, account: str | None = None, *, auth_required: bool) -> bool

May user do something that needs required on account? With auth off, reads are open and nothing that writes is: a write always needs an authenticated user of the right role and scope.

build_evaluation_state

build_evaluation_state(ml_dir: Path | None = None) -> dict[str, Any]

Reads ml/evaluation/{rank_book_simulation,capacity_report, cost_stress_report,ablation_report,book_spread_calibration, book_history_reconciliation,kill_switch_replay}.json plus the newest ml/versions/walk-forward-*/walk_forward_summary.json (Phase 4 - absent until that phase ships, degrades the same way). Every section is independently optional; a partial aq evaluate run (e.g. just --rank-book) still produces a fully-formed response with the unreported sections marked not_evaluated rather than omitted.

build_generations_state

build_generations_state(ml_dir: Path | None = None) -> dict[str, Any]

V6.6.1 - what aq cycle status wrote: the generations, their shares and what is due. A fresh checkout has no status yet, which is not an error.

build_strategy_catalog

build_strategy_catalog() -> dict[str, Any]

Returns {"strategies": [{"name", "leg_count", "risk_tier", "shape_family", "has_expiry_pair"}, ...], "total_count": int} - sorted by name for a stable, deterministic response.

hash_token

hash_token(token: str, salt: str, iterations: int = ITERATIONS) -> str

PBKDF2-SHA256 of a token under a salt, hex-encoded.

make_user

make_user(name: str, role: Role, token: str, *, accounts: Iterable[str] = ('*',), salt: str | None = None) -> User

A user whose token is stored salted and hashed; accounts scopes it (* for all). Raises on a bad name.

new_salt

new_salt() -> str

A fresh random 16-byte salt, hex-encoded.

new_token

new_token() -> str

A fresh random bearer token (32 bytes, URL-safe); shown once, stored only as a hash.

parse_users

parse_users(doc: Mapping[str, Any]) -> tuple[User, ...]

{"users": [{"name", "role", "salt", "token_hash", "accounts"}]} to users. Raises ValueError on a bad or duplicate entry.

users_document

users_document(users: Iterable[User]) -> dict[str, Any]

The JSON the users file holds (hashes only).

verify_token

verify_token(users: Iterable[User], token: str | None) -> User | None

The user whose token this is, or None. Every user is checked, whatever matched first.