API reference · v0.2

The Tumor Sense
inference API.

A FastAPI server backing the workshops on this site: SVM tabular predictions, five image-classification networks, and a RAG-grounded explanation endpoint built on LangChain. Everything is JSON in, JSON out — interactive Swagger UI lives at http://localhost:8000/docs.

Open Swagger UIGET /healthbase URL · http://localhost:8000
01 · Quickstart

Three calls, end-to-end

Health check → SVM predict → RAG explanation, in one go. Substitute $API with the base URL above.

curl
export API="http://localhost:8000"

# 1. is the server up?
curl -s $API/health | jq

# 2. predict — minimum payload is just the kernel id; other features get
#    imputed with the dataset mean.
curl -s -X POST $API/api/predict \
  -H "Content-Type: application/json" \
  -d '{
    "model": "rbf",
    "features": {
      "radius_mean": 17.2,
      "concavity_mean": 0.18,
      "concave_points_mean": 0.10
    }
  }' | jq

# 3. explain — feed the prediction back in.
curl -s -X POST $API/api/explain \
  -H "Content-Type: application/json" \
  -d '{
    "model": "rbf",
    "features": { "radius_mean": 17.2, "concavity_mean": 0.18 },
    "prediction": {
      "label": "malignant",
      "decision": 1.34,
      "probability_malignant": 0.91,
      "confidence": 0.91
    },
    "top_k": 4
  }' | jq

Meta

Service info, schema, and the raw training metrics file.

GET/healthtry it

Service health

Reports which SVM kernels, image models, and RAG components are loaded. Use this as a deploy smoke check.

response
{
  "status": "ok",
  "svm_models_loaded": ["rbf", "linear", "poly", "sigmoid"],
  "image_models_available": ["baseline_cnn", "vgg16", "mobilenet_v2", "resnet18", "vit_tiny"],
  "rag_ready": true
}
GET/api/feature-namestry it

Feature schema

The 10 WDBC 'mean' features the workshop exposes, in canonical order.

response
{
  "feature_names": [
    "radius_mean", "texture_mean", "perimeter_mean",
    "area_mean", "smoothness_mean", "compactness_mean",
    "concavity_mean", "concave_points_mean",
    "symmetry_mean", "fractal_dimension_mean"
  ]
}
GET/api/metricstry it

SVM training metrics

Raw contents of backend/outputs/svm_out/metrics.json: per-kernel best_params, CV AUC, test AUC, confusion matrices and full classification reports.

response
{
  "rbf":    { "best_params": { "C": 10, "gamma": 0.01 }, "cv_auc": 0.9962, "test_auc": 0.9977, "confusion_matrix": [[41,1],[1,71]], "classification_report": { … } },
  "linear": { … },
  "poly":   { … },
  "sigmoid":{ … }
}

SVM

Inference against the four scikit-learn SVMs trained on the WDBC dataset.

GET/api/modelstry it

List SVM kernels

Returns the kernels backed by trained joblib bundles in backend/models.

response
{ "available_kernels": ["rbf", "linear", "poly", "sigmoid"] }
POST/api/predicttry it

SVM inference

Run a single prediction. Pass any subset of the 10 mean features — missing ones are imputed with the dataset mean. The original 30 WDBC features are reconstructed before scaling (the trained SVMs expect 30-dim input).

request body
{
  "model": "rbf",
  "features": {
    "radius_mean": 17.2,
    "perimeter_mean": 113.0,
    "area_mean": 904.0,
    "concavity_mean": 0.18,
    "concave_points_mean": 0.10
  }
}
response
{
  "label": "malignant",
  "decision": 1.34,
  "probability_malignant": 0.91,
  "confidence": 0.91,
  "meta": {
    "kernel": "rbf",
    "latency_ms": 1.2,
    "n_support_vectors": 78,
    "model_path": "backend/models/model_rbf.joblib"
  }
}

Image classification

PyTorch image classification across BaselineCNN, VGG-16, MobileNet-V2, ResNet-18, and ViT-Tiny.

GET/api/image/modelstry it

List image architectures

Returns the 5 image-classification models, with weights paths and whether each one has been lazily loaded into memory yet.

response
[
  { "id": "baseline_cnn", "name": "Baseline 3-layer CNN", "family": "cnn", "params": 297218, "weights_path": ".../BaselineCNN_weights.pth", "weights_loaded": false },
  { "id": "vgg16",        "name": "VGG-16 (slim head)",   "family": "vgg",     … },
  { "id": "mobilenet_v2", "name": "MobileNet-V2",         "family": "mobilenet", … },
  { "id": "resnet18",     "name": "ResNet-18 (custom fc)","family": "resnet",  … },
  { "id": "vit_tiny",     "name": "ViT-Tiny (224 upsample)","family": "vit",   … }
]
POST/api/image/predicttry it

Image inference · base64

Accepts a base64-encoded 50×50 RGB patch (or any size — it's resized internally) and returns class probabilities + latency.

request body
{
  "model": "resnet18",
  "image_base64": "iVBORw0KGgoAAAANSUh…"
}
response
{
  "label": "cancer",
  "predicted_class": 1,
  "probability_no_cancer": 0.07,
  "probability_cancer":    0.93,
  "confidence": 0.93,
  "meta": {
    "model": "resnet18",
    "latency_ms": 12.4
  }
}
POST/api/image/predict-filetry it

Image inference · multipart

Same as /api/image/predict but takes a raw image upload (multipart form-data). Useful for curl-from-the-terminal demos.

request body
curl -X POST $API/api/image/predict-file \
  -F "model=resnet18" \
  -F "file=@patch.png"
response
// identical schema to /api/image/predict

RAG

LangChain retrieval-augmented explanations, grounded in the corpus under backend/documents/.

POST/api/explaintry it

RAG-grounded explanation

Builds a natural-language rationale from the prediction + the user's adjusted features, grounded in the markdown corpus under backend/documents/. Returns the explanation plus the top-K retrieved passages with their similarity scores. Uses an OpenAI chat model when OPENAI_API_KEY is set, otherwise falls back to a deterministic template generator (still grounded on retrieval).

request body
{
  "model": "rbf",
  "features": {
    "radius_mean": 17.2,
    "concavity_mean": 0.18
  },
  "prediction": {
    "label": "malignant",
    "decision": 1.34,
    "probability_malignant": 0.91,
    "confidence": 0.91
  },
  "top_k": 4
}
response
{
  "explanation": "The model flagged this case as malignant with high confidence…",
  "bullets": ["radius_mean is above the malignant centroid", "…"],
  "retrieved": [
    {
      "id": "01_wolberg_mangasarian_1990",
      "title": "Wolberg & Mangasarian (1990): Multisurface method…",
      "source": "01_wolberg_mangasarian_1990.md",
      "summary": "Mean radius / perimeter / concave-points dominate…",
      "quote": "Across 569 fine-needle aspirates …",
      "tags": ["radius_mean", "perimeter_mean", "concave_points_mean"],
      "score": 0.812
    }
  ],
  "generator": "openai",
  "meta": { "model": "gpt-4o-mini", "retrieved_count": 4 }
}

Errors

standard FastAPI shape
400Bad request

Unknown model id, unknown feature name, or malformed image bytes.

404Not found

Returned by /api/metrics when the metrics.json file isn't bundled.

503Service unavailable

A model weight file is missing, or the LLM/embeddings backend isn't installed.

500Internal

Catch-all for unexpected inference failures. Check the server logs.

error body
{ "detail": "human-readable message" }

CORS & auth

CORS

Origin allow-list is configured via the TUMORSENSE_CORS_ORIGINS env var (comma-separated). Defaults to * for local development.

Auth

No authentication today — this server is meant for the in-site workshops and local exploration. For public deployment, gate behind a reverse proxy or sit it behind Cloudflare Access.