The FastAPI application exposes two endpoints on port 8000. TheDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/characat0/mlops-fundamentals-homework/llms.txt
Use this file to discover all available pages before exploring further.
/health endpoint provides a simple liveness signal for load balancers and CI pipelines, while the /predict endpoint accepts the full set of Spotify audio features and returns a genre classification with a model confidence score. All request bodies are validated by Pydantic before inference runs — malformed or incomplete payloads are rejected automatically with HTTP 422.
SpotifyFeatures Request Schema
EveryPOST /predict call must include a JSON body that matches the SpotifyFeatures Pydantic model. All 12 fields are required; omitting any field or passing the wrong type returns HTTP 422.
How suitable a track is for dancing. Range: 0.0–1.0.
Perceptual measure of intensity and activity. Range: 0.0–1.0.
The key the track is in, mapped to standard Pitch Class notation (e.g. 0 = C, 1 = C♯/D♭). Range: 0–11.
Overall loudness of a track in decibels (dB). Typical range: −60.0–0.0.
Modality of the track. 1 = major, 0 = minor.
Presence of spoken words in a track. Range: 0.0–1.0. Values above 0.66 indicate tracks made entirely of spoken words.
Confidence measure of whether the track is acoustic. Range: 0.0–1.0.
Predicts whether a track contains no vocals. Range: 0.0–1.0. Values above 0.5 represent instrumental tracks.
Detects the presence of an audience in the recording. Range: 0.0–1.0. Values above 0.8 indicate a live performance.
Musical positiveness conveyed by a track. Range: 0.0–1.0. High valence sounds more positive (happy, cheerful); low valence sounds more negative (sad, angry).
Overall estimated tempo of the track in beats per minute (BPM).
Duration of the track in milliseconds.
GET /health
A lightweight liveness probe. Use this endpoint to verify the API process is up before sending prediction traffic.Student TODO: The
GET /health route is not yet implemented in app/main.py. Students must add the endpoint decorated with @app.get("/health") that returns {"status": "healthy"} with HTTP 200.| Property | Value |
|---|---|
| Method | GET |
| Path | /health |
| Auth | None |
| Response | {"status": "healthy"} |
| Status | HTTP 200 |
POST /predict
Accepts a fullSpotifyFeatures payload, runs inference using the baked-in @champion model via predict_genre(), and returns the predicted genre and confidence score.
| Property | Value |
|---|---|
| Method | POST |
| Path | /predict |
| Content-Type | application/json |
| Request body | SpotifyFeatures (all 12 fields required) |
| Response model | PredictionResponse |
| Success status | HTTP 200 |
Request Example
Response Example
PredictionResponse Fields
PredictionResponse is defined in app/main.py as a complete Pydantic model (no student changes needed):
Predicted genre name returned by the model (e.g. “Pop”, “Rock”, “Electronic”).
Model confidence score for the prediction (0.0–1.0), defaulting to
0.0. When fully implemented, this is the max value from model.predict_proba().Request Logging Middleware
EveryPOST /predict request is intercepted by an HTTP middleware that appends a JSON line to logs/api_requests.jsonl before forwarding the request to the endpoint. The logs/ directory is created automatically if it does not exist.
Student TODO: The
log_requests middleware in app/main.py is currently a skeleton that calls call_next immediately without logging. Students must implement the body-reading, JSON-parsing, timestamp-stamping, and JSONL-appending steps described in the inline comments.timestamp field in ISO 8601 format:
The
logs/api_requests.jsonl file is the data source for the drift monitoring pipeline when running in online mode. Each prediction appended here is consumed by the monitoring component to detect distribution shift between live traffic and the training baseline./predict endpoint can still parse it correctly — a necessary step because HTTP request bodies are single-use streams.
Error Handling
| Status Code | Condition |
|---|---|
200 OK | Prediction completed successfully. Response body contains genre and confidence. |
422 Unprocessable Entity | Validation error — one or more required fields are missing, have the wrong type, or the body is not valid JSON. Response body contains Pydantic’s detailed validation error. |
500 Internal Server Error | Prediction failed due to a model or runtime error. The exception is logged server-side; the response body contains {"detail": "Prediction failed"}. |
Running Tests
The test suite lives inmodel_serving/tests/ and uses pytest with FastAPI’s built-in TestClient:
| Test | What It Covers |
|---|---|
test_health_check | Calls GET /health and asserts HTTP 200 with body {"status": "healthy"}. |
test_predict_endpoint_valid_payload | Posts a complete 12-field payload to POST /predict, asserts HTTP 200, and verifies both genre and confidence keys are present in the response. |
test_predict_endpoint_invalid_payload | Posts a payload with only danceability (11 required fields missing), asserts HTTP 422 to confirm Pydantic validation is active. |