ML10: Capstone: three AI projects for DakDost
Project 2: a model people can call
🎯You'll be able to
Serve Project 1's model through an API that rejects bad input, matches the offline model, reports its health and watches for drift.
🏠The everyday picture
A pharmacy counter checks each prescription, gives the right medicine with clear instructions, keeps a record without gossiping about patients, and notices when an unusual number of the same prescription starts arriving.
📘What it really is
- What's wrong in the starter (marked
STARTER:): - it accepts any JSON (ML8 Lesson 2);
- it computes the booking hour in UTC while training used India time (ML8 Lesson 3);
- it answers only "late: true/false" with no probability, threshold or request id;
- it logs the whole request, including any phone number (ML7 Lesson 3);
-
no batch endpoint, no
/metrics, and no drift check (ML8 Lesson 4, ML9 Lessons 3 and 4). -
What the tests check:
/healthwith a version; a full response;422for a missing field and for out-of-range, unknown or personal inputs; the same probability as the offline model at four booking times; a batch of 100 accepted and 101 refused with413; request counts and timings in/metrics; a log with request id, version and probability but no names or phone numbers; no drift for July and drift onaddress_qualityanddest_zonefor August; and p95 latency under 150 ms.
📝A worked example
Input: the reference API (2 November 2026).
Expected output:
-
the example parcel (remote, evening, cash on delivery, address score 0.31) returns probability 0.8533,
likely_late: true, threshold 0.3 and version2026.07.1; -
a request without
address_qualityreturns422naming the field; /metricsshowsdakdost_requests_total{endpoint="predict",status="200"}rising with each call;python -m dakdost.drift raw/new/2026-08-monsoon.csvexits 1, namingaddress_quality, dest_zone;- 200 calls: p50 36.8 ms, p95 45.3 ms, in-process on a 4-core Linux machine.
🌍Where it's used
- Product integration: the booking screen's developers rely on this contract.
- Operations: the metrics and drift report feed dashboards and alerts.
- Privacy reviews: the log policy is what a reviewer checks first.
📝Case scenario
A learner's API passes everything except test 5, the comparison with the offline model. They spend an hour on the model before noticing
that their API builds features with its own code. Switching to the shared build_frame fixes it in one line, and they add a sentence on
training/serving skew to their case study.
🖱️Try it
Start your API with uvicorn dakdost.serve:app --port 8000 and try /docs in a browser: send one good request, one with a negative weight
and one batch of 101. Success: you see a probability, a 422 with a reason and a 413.
⚠️Common mistakes
- Validation by hand-written
ifstatements. Sign: some fields unchecked. Fix: one pydantic schema. - Logging "just in case". Sign: whole requests in the log. Fix: log only what the tests and monitoring need.
- A drift check that alarms on a normal month. Sign: July fails. Fix: check your bins (ML9 Lesson 4).
🛠️For your project
This lesson is Project 2. Its page has the marking guide and the evidence to submit.
✅Quick check
Why must the API use the same feature code as training?
Show the answer
Otherwise the model gets inputs prepared differently from the ones it learned from: training/serving skew.
What should August's drift report name?
Show the answer
address_quality and dest_zone.
