Lab 5 — Deploy a model end-to-end¶

Goal. Wrap a model in FastAPI. Containerize. Deploy to Render or Railway free tier. Verify the endpoint from a fresh notebook.

What you ship. Public deployed endpoint that someone unfamiliar with the project can call. README with the curl example.

Setup¶

Install the dependencies (one-time).

In [ ]:
# !pip install fastapi uvicorn pydantic scikit-learn requests
In [ ]:
import requests
import json
from sklearn.datasets import load_iris
from sklearn.ensemble import RandomForestClassifier

What the notebook does vs what you do at the shell¶

In [ ]:
# This notebook runs end-to-end against a *deployed* endpoint at the end.
# The middle steps (writing the FastAPI app, containerizing, deploying)
# happen outside the notebook.
ENDPOINT = 'https://your-service.onrender.com'  # set after deployment
print('targeting:', ENDPOINT)

Exercise 1 — Train and save a model locally¶

In [ ]:
data = load_iris()
clf = RandomForestClassifier().fit(data.data, data.target)
import joblib
joblib.dump(clf, 'iris.joblib')
print('saved iris.joblib')

Exercise 2 — Write the FastAPI service¶

In [ ]:
# YOUR TURN
# In app/main.py:
# - load iris.joblib at startup
# - POST /predict expects a 4-vector, returns class index + probabilities
# - GET /health returns {'status': 'ok'}

Exercise 3 — Containerize and deploy¶

In [ ]:
# YOUR TURN
# Dockerfile + render.yaml (or railway.toml). Push to GitHub, connect repo,
# deploy. Update ENDPOINT above and run cells below.

Exercise 4 — Call the deployed endpoint¶

In [ ]:
# After deployment, run this against the live URL:
r = requests.get(f'{ENDPOINT}/health')
print('health:', r.json())
r = requests.post(f'{ENDPOINT}/predict', json={'features': [5.1, 3.5, 1.4, 0.2]})
print('predict:', r.json())

Done?¶

Submit per the cohort schedule. Peer review pairing announced the following Monday.