Skip to content

Latest commit

 

History

History
103 lines (87 loc) · 7.24 KB

api_reference.md

File metadata and controls

103 lines (87 loc) · 7.24 KB

PhysioTwin Engine API: v1 (schema 1.0.0)

  • Base URL: http://127.0.0.1:8765 (local only). Configure with PHYSIOTWIN_HOST / PHYSIOTWIN_PORT.
  • Interactive OpenAPI docs while the server runs: http://127.0.0.1:8765/docs.
  • Implementation: physiology_engine/app/api/routes.py. Schemas: app/schemas/api.py. Tests: tests/test_api_export.py.
  • All bodies are JSON. Unknown request fields are rejected (extra="forbid"). Most requests take session_id (default "default", pattern ^[A-Za-z0-9_-]{1,40}$), and at most 16 sessions can exist.

Data contract: VariableValue

{"id": "cardiovascular.heart_rate", "label": "Heart Rate", "value": 70.0, "unit": "beats/min",
 "time_s": 10.0, "source": "cardiovascular_model", "status": "simulated",
 "reference_range": null, "uncertainty": null}

(This is an example of the format, not a claim about a particular run.)

  • status is one of simulated | measured | ai_estimate. The v0.1 engine only ever emits simulated. The other two values are reserved so that measured data and future AI estimates always stay distinguishable. The Godot client rejects any state that contains non-simulated values.
  • A value of null means not finite or not available. Clients must show "Not available", never a placeholder.
  • reference_range and uncertainty are reserved, optional fields. They are not populated in v0.1.

Errors

HTTP detail.error When
422 validation_error Malformed body, unknown field, unknown parameter id, value outside its operating bounds, non-adjustable parameter, *_initial parameter applied live
404 not_found / message Unknown scenario, experiment, organ or session
409 simulation_error / running Simulation failed (solver or invalid state), or step called while the real-time clock runs
429 too_many_sessions More than 16 sessions
501 not_implemented POST /api/v1/ai/predict (no AI module, by design)

Error body: {"detail": {"error": "...", "messages": ["human readable", ...]}}.

Endpoints

Metadata

Method Path Description
GET /health status, software_version, model_version, api_schema_version, ai_contract_version, ai_module: "not_implemented"
GET /api/v1/models Subsystem metadata: states and units, parameters, inputs, solver note, evaluation order
GET /api/v1/variables Variable registry (id, label, unit, source, organs, equation, display scale and unit), organ→subsystem map, allowed statuses
GET /api/v1/parameters Parameter and input metadata (unit, default, min/max, source_type, source, user_adjustable, validation_status)
GET /api/v1/scenarios Scenario list
GET /api/v1/scenarios/{id} Full scenario: changes, events, expected behaviour, acceptance criteria, limitations, interpretation
GET /api/v1/organs/{organ}?session_id= Organ info, the variables it supports, current simulated values. Organs with no model have implemented: false

Simulation control

Method Path Body Notes
POST /api/v1/simulation/initialize {session_id?, scenario_id?, parameters{}, inputs{}, initial_conditions{blood_volume_ml?, interstitial_volume_ml?}, solver{method, rtol, atol_scale, max_step_s, sample_interval_s}} Creates or replaces the session. The initial state is the model's steady state
POST /api/v1/scenarios/load {scenario_id, session_id?, parameters{}, inputs{}, solver{}} Same as initialize, with a scenario
POST /api/v1/simulation/start {session_id?, speed: (0, 120]} Server-side real-time clock, speed simulated s per wall-clock s
POST /api/v1/simulation/pause {session_id?}
POST /api/v1/simulation/reset {session_id?} Back to t = 0. Scenario events are kept; user live changes are discarded
POST /api/v1/simulation/step {session_id?, duration_s: (0, 604800]} Rounded to whole sample intervals. Returns 409 while running
POST /api/v1/simulation/change {session_id?, parameters{}, inputs{}, label} Live change at the current time. Only user_adjustable ids are accepted; *_initial ids are rejected. Logged as a user event so the run stays reproducible
GET /api/v1/simulation/state?session_id= {session_id, simulation_id, scenario_id, status, time_s, variables[VariableValue], warnings, pending_events, running, speed, validity_note}
GET /api/v1/simulation/history?session_id=&variables=a,b&since_s=&max_points= {time_s[], series{id:{unit, values[], status}}}, downsampled to max_points (always includes the latest sample)
GET /api/v1/simulation/metadata?session_id= Reproducibility metadata: ids, model and software versions, parameters, inputs, configuration, initial state, solver, events applied, warnings, data_type, validation_status
WS /api/v1/simulation/stream?session_id= Pushes the same payload as /state after every clock tick or change

Data and experiments

Method Path Body Notes
POST /api/v1/data/export {session_id?, formats["csv","json"], variables?[]} Writes <stem>_timeseries.csv, _timeseries.json and _metadata.json to PHYSIOTWIN_EXPORT_DIR
POST /api/v1/experiments/save {session_id?, name, notes?} Saves the configuration and metadata to SQLite and exports the CSV
GET /api/v1/experiments List
GET /api/v1/experiments/{id} Full record, including config and metadata
POST /api/v1/experiments/{id}/load {session_id?, run_to_saved_duration} Rebuilds the session from the saved config; optionally replays it to the saved time
POST /api/v1/experiments/compare {experiment_a, experiment_b?, session_id?, variables?[]} B interpolated onto A's time grid: final values, final difference, max abs and RMS difference. Without experiment_b, compares with the live session

Future AI (contract only)

Method Path Notes
GET /api/v1/ai/contract JSON schemas of AIPredictionRequest / AIPredictionResponse (contract ai-contract-0.1)
POST /api/v1/ai/predict Validates the request body, then always 501 in v0.1

See docs/future_ai/ai_integration_api.md.

Typical client sequence

GET  /health
GET  /api/v1/variables, /api/v1/parameters, /api/v1/scenarios
POST /api/v1/scenarios/load        {"scenario_id": "exercise_moderate"}
POST /api/v1/simulation/start      {"speed": 10}
GET  /api/v1/simulation/state      (poll ~4 Hz)  or  WS /api/v1/simulation/stream
POST /api/v1/simulation/change     {"inputs": {"input.workload_w": 150}}
POST /api/v1/simulation/pause
POST /api/v1/experiments/save      {"name": "my run"}
POST /api/v1/data/export           {"formats": ["csv", "json"]}

Storage schema

SQLite table experiments (see the docstring of app/storage/store.py): id, name, notes, created_at_utc, scenario_id, simulation_id, model_version, duration_s, config_json, metadata_json, timeseries_csv, data_type. data_type is always synthetic_simulation_output.

Export formats

  • CSV: header time_s,<variable ids…>, one row per sample. Units are in the metadata sidecar.
  • Metadata JSON: everything from /simulation/metadata, plus columns[{id, label, unit, source, status}] and n_samples.