Your /predict route scores one customer per request. A team that needs scores for a list of 400 customers would send 400 requests, and the model would run 400 times. A batch route takes the whole list in one request, builds one table, calls the model once and answers a list in the same order.
One table, one call: pd.DataFrame turns a list of dicts into a table with one row per dict, and columns= picks the columns and their order. Then you work on the whole table at once, not row by row:
@app.post("/totals/batch")
def totals_batch():
orders = request.get_json()
if len(orders) > 50:
return jsonify({"error": "Too many orders"}), 400
table = pd.DataFrame(orders, columns=["price", "quantity"])
totals = table["price"] * table["quantity"]
return jsonify(totals.tolist())
model.predict_proba(table) works the same way: one call gives back one row of two chances per customer, in the order of the table, so probabilities[i][1] is customer i's chance of 1. A size limit stops one huge request from keeping the server busy for everyone else, so it comes first, before any loop.
The requests your code must answer. The batch of 4 must call predict_proba exactly once; its third customer sends an extra customer_id and its keys in another order.
POST /predict/batch [4 customers]
→ 200 [{"bought_again": 1, "probability": 0.928}, {"bought_again": 0, "probability": 0.008},
{"bought_again": 1, "probability": 0.701}, {"bought_again": 0, "probability": 0.461}]
POST /predict/batch [2 customers, row 1 has "spent": "lots"]
→ 400 {"error": "Missing or not a number", "row": 1, "field": "spent"}
POST /predict/batch []
→ 400 {"error": "Send 1 to 100 customers"}
POST /predict/batch [101 customers]
→ 400 {"error": "Send 1 to 100 customers"}
Your task: add the constant MAX_ROWS = 100. In predict_batch, answer 400 with "Send 1 to 100 customers" when the list is empty or longer than MAX_ROWS. Then build one DataFrame table from all the rows, call model.predict_proba once, and fill answers with answer_for of each customer's chance of 1.
Assignment
Follow the Coding Tutorial to finish POST /predict/batch: a size limit, one table, one model call and a list of answers in the same order.
Hint
The size check goes right below the rows line, before the field loops. Call predict_proba before the for loop, not inside it: the loop only reads probabilities[i][1].
Free plan: 30 tutor messages. PRO is unlimited.
