mirror of
https://github.com/azaion/gps-denied-onboard.git
synced 2026-06-22 20:11:14 +00:00
[AZ-489] C12 FlightsApiClient + offline JSON loader + bbox helper
ADR-010 primary cold-start path now has a real source for the cache bbox and the takeoff origin. Single concrete strategy (`HttpxFlightsApiClient`) behind a `@runtime_checkable` Protocol; offline JSON fallback (`load_flight_file`) shares the same DTO shape per FAC-INV-1. * `flights_api/interface.py` — `FlightsApiClient` Protocol + `FlightDto` + `WaypointDto` + `WaypointObjective` / `WaypointSource` enums (plain frozen-slotted dataclasses, matching project's LatLonAlt / PoseEstimate pattern). * `flights_api/errors.py` — 8-class hierarchy under `FlightsApiError`. * `flights_api/_parser.py` — shared JSON validator: range checks, lat/lon bounds, contiguous ordinals, finite floats, enum membership. * `flights_api/bbox.py` — `bbox_from_waypoints` envelopes lat/lon and inflates by a horizontal-distance buffer via WgsConverter ENU round-trip (NOT degree-space); `takeoff_origin_from_flight` passes waypoints[0] through unrounded. * `flights_api/file_loader.py` — orjson-backed offline loader. * `flights_api/httpx_client.py` — concrete client with ONE retry on transient 5xx + connect errors; token redaction at every log site; test-injectable transport + sleep. * `runtime_root/c12_factory.py` — `build_flights_api_client(config)`; re-exported from `runtime_root/__init__.py`. OperatorToolServices aggregate intentionally deferred to AZ-328 per scope discipline. * `pyproject.toml` — `httpx>=0.28,<1.0` added (chosen over `requests` for native `MockTransport` testing). Tests: 28 cases across AC-1..AC-18 plus extras (malformed JSON, negative buffer, zero buffer, missing top-level fields, negative ordinal, empty-flight takeoff). Full repo run: 713 passed, 2 skipped. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -24,6 +24,9 @@ from dataclasses import dataclass, field
|
||||
from typing import TYPE_CHECKING, Any, Final, Literal, get_args
|
||||
|
||||
from gps_denied_onboard.config import Config, load_config
|
||||
from gps_denied_onboard.runtime_root.c12_factory import (
|
||||
build_flights_api_client,
|
||||
)
|
||||
from gps_denied_onboard.runtime_root.fc_factory import (
|
||||
OutboundThreadAlreadyBoundError,
|
||||
bind_outbound_emit_thread,
|
||||
@@ -77,6 +80,7 @@ __all__ = [
|
||||
"bind_outbound_emit_thread",
|
||||
"bind_state_ingest_thread",
|
||||
"build_fc_adapter",
|
||||
"build_flights_api_client",
|
||||
"build_gcs_adapter",
|
||||
"build_pose_estimator",
|
||||
"build_state_estimator",
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
"""Composition-root factory for C12 operator-tooling services (AZ-489).
|
||||
|
||||
Currently exposes :func:`build_flights_api_client` — the
|
||||
:class:`FlightsApiClient` used by C12's pre-flight cache-build workflow
|
||||
(see AZ-326 / AZ-328 for downstream consumers).
|
||||
|
||||
The factory is intentionally tiny: there is only one concrete strategy
|
||||
(``HttpxFlightsApiClient``) and httpx already defaults to TLS verify ON
|
||||
and the system trust store, so the factory's job is to assemble the
|
||||
client without re-implementing those defaults.
|
||||
|
||||
The richer ``OperatorToolServices`` dataclass that aggregates this
|
||||
client with the rest of C12 (``CacheBuildWorkflow``,
|
||||
``OperatorReLocService``, etc.) is owned by AZ-328 and intentionally
|
||||
NOT created here per scope discipline.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from gps_denied_onboard.components.c12_operator_tooling.flights_api import (
|
||||
FlightsApiClient,
|
||||
HttpxFlightsApiClient,
|
||||
)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from gps_denied_onboard.config import Config
|
||||
|
||||
__all__ = ["build_flights_api_client"]
|
||||
|
||||
|
||||
def build_flights_api_client(config: Config) -> FlightsApiClient:
|
||||
"""Return the operator-tier :class:`FlightsApiClient`.
|
||||
|
||||
The current implementation is the production
|
||||
:class:`HttpxFlightsApiClient` with httpx defaults (TLS verify ON,
|
||||
system trust store). ``config`` is accepted for API parity with the
|
||||
other ``build_*`` factories; the client itself does not need
|
||||
composition-time configuration — the operator's base URL and auth
|
||||
token are resolved per-call by the CLI layer (AZ-326).
|
||||
"""
|
||||
_ = config # reserved for future composition-time tuning
|
||||
return HttpxFlightsApiClient()
|
||||
Reference in New Issue
Block a user