Start learning free

LESSON 134 OF 165 · MACHINE LEARNING: SERVING A MODEL

Project: Know What You Predicted in Python

Practice

Right now your API answers a prediction and then forgets it. A real prediction service keeps a record of every answer: what was sent, what the model said, and which model said it. With that record you can answer questions later, such as how many customers the model expected to buy again. If the share predicted 1 moves a lot while the model stays the same, you know the customers you are sent have changed.

A list every request shares: a list made at the top of the file is created once, when the app starts, and every request can append to it. Here is the idea in another app, which keeps every name it greets:

greeted = []

@app.get("/hello/<name>")
def hello(name):
    greeted.append(name)
    return jsonify({"message": "Hello, " + name})

@app.get("/greeted/count")
def greeted_count():
    return jsonify({"count": len(greeted)})

The list lives in memory, so it is empty again whenever the app restarts. Your summary route reads it and answers two numbers: count, how many predictions were kept, and share_bought_again, the share of them that said 1. Every bought_again is 0 or 1, so adding them up counts the 1s. Before any prediction the list is empty and dividing by 0 would crash, so the share is None, which JSON shows as null.

The requests below run in this order. The refused request never reaches the model, so it isn't kept: that leaves 3 predictions, 2 of them 1.

GET  /predictions/summary  →  200  {"count": 0, "share_bought_again": null}
POST /predict        {"visits": 10, "orders": 4, "spent": 260, …}
                     →  200  {"bought_again": 1, "probability": 0.928}
POST /predict        {"visits": "twelve", "orders": 4, …}
                     →  400  {"error": "Missing or not a number", "field": "visits"}
POST /predict/batch  [2 customers]
                     →  200  [{"bought_again": 0, "probability": 0.008}, {"bought_again": 1, "probability": 0.701}]
GET  /predictions/summary  →  200  {"count": 3, "share_bought_again": 0.667}

Your task: keep a module-level list predictions. In predict and in predict_batch, append one dictionary per answer with "input", "answer" and "version". Then add GET /predictions/summary, answering the count and the share predicted 1, with null when nothing was predicted yet.


Assignment
Follow the Coding Tutorial to keep every prediction and build the /predictions/summary route.


Hint
The list lives below the model line so every request adds to the same one. In the batch loop, customer i's input is rows[i] and their answer is answers[i]. Check for an empty list before you divide.


STEP 1 OF 12
    Ctrl + Enter to check

    Serve Log Project in Python

    Keep going with Python1,600+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free