Start learning free

LESSON 131 OF 165 · MACHINE LEARNING: SERVING A MODEL

Refuse Bad Input in Python

Practice

A model has no idea what bad input looks like. If a field is missing or null, the empty cell makes the model raise an error and the client gets a 500, as if your server broke. If a field is true, pandas reads it as the number 1, and the client gets a real-looking prediction for a customer nobody described. A wrong answer with a 200 is the worst kind: nobody notices it.

The fix is to validate the body before the model sees it, and answer 400 Bad Request naming the field to fix. data.get(name) gives None for a missing key instead of raising, and type() gives a value's exact type. That matters for True, which Python counts as an int:

print(type(110.5) in (int, float))   # True
print(type("4") in (int, float))     # False: a string
print(type(None) in (int, float))    # False: missing or null
print(isinstance(True, int))         # True!
print(type(True) in (int, float))    # False: its type is bool

Check the fields in the order of COLUMNS and stop at the first one that fails. Your finished route must answer:

POST /predict  {"customer_id": 42, "returned_item": 0, "days_since_last": 40, "spent": 160, "orders": 3, "visits": 7}
   →  200  {"bought_again": 1, "probability": 0.701}
POST /predict  {"visits": 7, "orders": 3, "days_since_last": 40, "returned_item": 0}
   →  400  {"error": "Missing or not a number", "field": "spent"}
POST /predict  {"visits": "twelve", "orders": 4, "spent": 260, "days_since_last": 15, "returned_item": 0}
   →  400  {"error": "Missing or not a number", "field": "visits"}
POST /predict  {"visits": true, "orders": 4, "spent": 260, "days_since_last": 15, "returned_item": 0}
   →  400  {"error": "Missing or not a number", "field": "visits"}
POST /predict  {"visits": 10, "orders": "4", "spent": 260, "days_since_last": 15, "returned_item": 0}
   →  400  {"error": "Missing or not a number", "field": "orders"}
POST /predict  {"visits": 10, "orders": 4, "spent": 260, "days_since_last": null, "returned_item": 0}
   →  400  {"error": "Missing or not a number", "field": "days_since_last"}
POST /predict  {"visits": 7, "orders": 2, "spent": 110.5, "days_since_last": 60, "returned_item": 0}
   →  200  {"bought_again": 1, "probability": 0.536}

Your task: in predict, right after the data line, check every name in COLUMNS: if its value is missing or isn't exactly an int or a float, answer 400 with {"error": "Missing or not a number", "field": name}.


Assignment
Follow the Coding Tutorial to check every field of the body before the model sees it.


Hint
A return inside the loop ends the function at the first bad field. Return jsonify(...), a comma, then 400 to set the status.


STEP 1 OF 3
    Ctrl + Enter to check

    Serve Validate 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