Skip to content

REST API

FastAPI application exposing the SeqChain engine over HTTP. Tracks are immutable UUID-keyed resources — every computation produces a new track. Results are cached by provenance (identical operation + inputs + params returns the same track ID).

Design: generic method dispatch

The API has no per-method handlers. Instead, a declarative registry (METHOD_REGISTRY in routes/methods.py) maps method IDs to:

  • Discovery fields: name, description, parameter schema, return type. Serialized as JSON for hubs to build UI from.
  • Dispatch fields: the callable, input specs (which store to load from), and parameter names. Never serialized — internal to the dispatcher.

The generic dispatcher does the same thing for every method:

  1. Look up method in registry (404 if missing)
  2. For each input: load from the declared store (track or genome), 404 if missing
  3. Collect params from request body
  4. Call the registered function
  5. Store result with provenance
  6. Return {track_id}

Adding a new method = one registry entry. Zero handler code.

Sidecar protocol

SeqChain runs as a sidecar service. A frontend hub discovers and calls methods without hardcoding knowledge of engine internals.

Hub                                SeqChain
───                                ────────
1. GET  /api/methods          →    method catalog with parameter schemas
2. POST /api/tracks           →    upload data, receive track_id
3. POST /api/methods/{id}     →    call method with track_ids → result_id
4. GET  /api/tracks/{id}      →    download result

Parameter types tell the hub how to render each field:

Type Hub behavior
track Show file/track picker, upload to /api/tracks, use returned ID
genome Show genome picker, upload to /api/genomes, use returned ID
string Show text input, pass value directly
number Show number input, pass value directly
boolean Show toggle, pass value directly
object Show structured input (JSON), pass value directly

The engine never knows what UI the hub builds. The hub never knows what the engine does internally. The contract is the method schema.

Quick start

seqchain serve --port 8000
# Health check
curl localhost:8000/api/health

# Discover available methods
curl localhost:8000/api/methods

# Describe a single method
curl localhost:8000/api/methods/overlay

# Upload two tracks
QID=$(curl -s -X POST localhost:8000/api/tracks/upload \
  -F "file=@query.bed" | jq -r .track_id)
RID=$(curl -s -X POST localhost:8000/api/tracks/upload \
  -F "file=@reference.bed" | jq -r .track_id)

# Call a method
curl -X POST localhost:8000/api/methods/overlay \
  -H 'Content-Type: application/json' \
  -d "{\"query_track_id\": \"$QID\", \"reference_track_id\": \"$RID\"}"

# Download result
curl localhost:8000/api/tracks/$RESULT_ID

Endpoints

Endpoint Method Purpose
/api/health GET Liveness probe
/api/methods GET List all available methods
/api/methods/{id} GET Describe a single method
/api/methods/{id} POST Generic method dispatch
/api/tracks CRUD Track management (upload, export, query)
/api/genomes CRUD Genome management (upload, metadata, features)

Pages

  • App Factorycreate_app() and router wiring
  • StoresTrackStore, GenomeStore, provenance caching
  • Serializers — Track/Region → JSON via public protocol