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 broadcastingStatusUpdateevents (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 indata_model.py:PacketTMPacketTC— carries thesent/sent_atuplink flags,execution_timeandrequest_idfor scheduled commands, and a per-stageverificationdict.ParamTM— one row per decoded parameter, foreign-keyed to itsPacketTM.
- 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 thePacketTCit 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.