mirror of
https://github.com/azaion/gps-denied-onboard.git
synced 2026-06-21 08:31:13 +00:00
c3650d979d
Provide deterministic geometry/time-sync helpers and structured config, error, health, and telemetry primitives for downstream runtime components. Co-authored-by: Cursor <cursoragent@cursor.com>
60 lines
1.8 KiB
Python
60 lines
1.8 KiB
Python
"""Runtime profile configuration and readiness validation."""
|
|
|
|
from typing import Literal
|
|
|
|
from pydantic import BaseModel, ConfigDict, Field, ValidationError, model_validator
|
|
|
|
from shared.errors import ErrorEnvelope, ResultEnvelope
|
|
|
|
|
|
class RuntimeProfile(BaseModel):
|
|
model_config = ConfigDict(extra="forbid", frozen=True)
|
|
|
|
environment: Literal["development", "ci", "staging", "jetson", "production"]
|
|
config_dir: str = Field(min_length=1)
|
|
cache_dir: str | None = None
|
|
fdr_dir: str | None = None
|
|
database_url: str | None = None
|
|
mavlink_url: str | None = None
|
|
camera_source: str | None = None
|
|
signing_key_ref: str | None = None
|
|
|
|
@model_validator(mode="after")
|
|
def production_requires_runtime_paths(self) -> "RuntimeProfile":
|
|
if self.environment != "production":
|
|
return self
|
|
|
|
missing = [
|
|
name
|
|
for name in (
|
|
"cache_dir",
|
|
"fdr_dir",
|
|
"database_url",
|
|
"mavlink_url",
|
|
"camera_source",
|
|
"signing_key_ref",
|
|
)
|
|
if getattr(self, name) in (None, "")
|
|
]
|
|
if missing:
|
|
raise ValueError(f"production profile missing required settings: {', '.join(missing)}")
|
|
return self
|
|
|
|
|
|
def readiness_error(component: str, message: str) -> ErrorEnvelope:
|
|
return ErrorEnvelope(
|
|
component=component,
|
|
category="configuration",
|
|
message=message,
|
|
severity="critical",
|
|
retryable=False,
|
|
)
|
|
|
|
|
|
def validate_runtime_profile(component: str, payload: dict[str, object]) -> ResultEnvelope:
|
|
try:
|
|
RuntimeProfile.model_validate(payload)
|
|
except ValidationError as error:
|
|
return ResultEnvelope.failure(readiness_error(component, str(error)))
|
|
return ResultEnvelope.success()
|