Skip to content

The API service

This page covers how the spacecraft model and the TM/TC pipelines get wired into a running FastAPI process.

Startup and wiring

api.py is the entrypoint (minmcs.api:app). On import, it builds one global MinMCS instance for the mission named by MINMCS_MISSION (default minscs). MinMCS is a thin facade: it wires together a Mission and three handlers — tph (TM packet handler), th (TM parameter reader), and tch (TC handler).

core.py::Mission holds the Spacecraft model and owns the SQL engine. Its db_url comes from MINMCS_DATABASE, falling back to the back-compat MINMCS_DB_URL, and finally to a per-mission SQLite file if neither is set. The live mission, missions/xtce.py::XTCEMission, builds the Spacecraft model at load time from the XTCE database.

Endpoints

Grouped by area — see api.py for the full signatures:

  • TM: POST /packet/tm/submit, GET /packet/tm/list, GET /tm/last, GET /tm/subsystems.
  • TC: POST /packet/tc/submit, GET /packet/tc/list, GET /packet/tc/pending / POST /packet/tc/{id}/sent (the uplink hand-off queue the ground-link bridge drains and acks).
  • Spacecraft model: GET /spacecraft_model/telemetry_parameters, /telemetry_containers, /telecommands, /telecommands_containers, /summary.
  • Status/config: GET /status (link flow, whether scheduling is offered), GET /config (mission/db/link settings), GET /links + POST /links/status (the bridge’s heartbeat — the API never opens a socket itself, so this is the only way it learns the ground-link TCP connections are up).
  • GET /ws — a WebSocket broadcasting StatusUpdate events (ws.py::ConnectionManager) on new TM/TC, so the UI can refresh reactively instead of polling.

Persistence — two stores

  • Relational (stores.py::PacketStore) — SQLModel over SQLite or Postgres/TimescaleDB. The tables live in data_model.py:
    • PacketTM
    • PacketTC — carries the sent/sent_at uplink flags, execution_time and request_id for scheduled commands, and a per-stage verification dict.
    • ParamTM — one row per decoded parameter, foreign-keyed to its PacketTM.
  • Time-series — InfluxDB, via telemetry.py::TelemetryStore. See Telemetry ingest for when it’s active.

PacketStore also owns two pieces of TC-specific bookkeeping:

  • tc_max_sequence_count, so a restarted API resumes numbering instead of colliding with commands it already sent.
  • tc_apply_verification, which correlates an incoming verification report to the PacketTC it confirms — see Telecommand uplink.

There is no migration tooling: SQLModel.metadata.create_all only creates missing tables, it never adds columns to an existing one. After a schema change, delete the SQLite file (or, for the compose Postgres, add the column by hand) rather than trying to reuse it — see Configuration.

Last updated on