Lab 5: Flask — Serving a Scoring Model via REST API
What is an API?
Think of a restaurant. You (the customer) don’t walk into the kitchen and cook yourself — you order through a waiter. The waiter takes your request, passes it to the kitchen, and comes back with a response.
An API (Application Programming Interface) works the same way: - You send a request — e.g. “score this transaction” - The API processes it (runs the model, checks rules) - It returns a response — e.g. {"fraud": true, "score": 0.92}
This lets an ML model run as a separate service that can be called by a Kafka consumer, a mobile app, a dashboard — anything.
What is REST and HTTP?
HTTP is the communication protocol — the same one your browser uses. Each request has: - a method: GET (fetch data) or POST (send data for processing) - a URL: e.g. http://localhost:5000/score - optionally a body: JSON data
REST is a design style for APIs — each resource has its own URL, HTTP methods have defined meanings.
Transaction scoring — business rules through the API
Part 1: First API
Flask is a minimal web framework for Python — a few lines of code and you have a running server.
We use %%file to save the code to a file, then start the server in the background so the notebook keeps working.
%%file app.pyfrom flask import Flaskapp = Flask(__name__)@app.route("/") # URL: http://localhost:5000/def home():return"Welcome to the transaction monitoring system!"if__name__=="__main__": app.run(host="0.0.0.0", port=5000)
Writing app.py
import subprocess, time, requestsserver = subprocess.Popen(["python", "app.py"])time.sleep(2) # give the server a moment to startresponse = requests.get("http://localhost:5000/")print(f"Status: {response.status_code}")print(f"Body: {response.text}")
Status: 200
Body: Welcome to the transaction monitoring system!
Status 200 means success. Other codes you will encounter:
Code
Meaning
200
OK — request handled successfully
400
Bad Request — invalid input data
404
Not Found — this URL does not exist
500
Internal Server Error — bug in server code
Part 2: URL Parameters and Path Variables
An API can receive data in two ways: - query parameters: ?name=Anna — appended to the URL after ? - path variables: /transaction/TX001 — embedded in the URL
Task 2.1 — Endpoint with query parameter
server.kill()
%%file app.pyfrom flask import Flask, request, jsonifyapp = Flask(__name__)@app.route("/")def home():return"Welcome to the transaction monitoring system!"@app.route("/hello") # GET /hello?name=Annadef hello(): name = request.args.get("name", "stranger") # read query parameterreturnf"Hello, {name}!"@app.route("/transaction/<tx_id>") # GET /transaction/TX0042def get_transaction(tx_id):return jsonify({"tx_id": tx_id, "status": "found"})if__name__=="__main__": app.run(host="0.0.0.0", port=5000)
Try calling /echo with GET instead of POST. What does the server return? What status code?
r_bad = requests.get("http://localhost:5000/echo")print(f"Status: {r_bad.status_code}")# Answer in a comment: what does this status code mean?# ANSWER:
Status: 405
Part 4: Transaction Scoring via API
Now we connect Flask to business logic. The /score endpoint accepts a transaction and returns a risk assessment.
We use rules for now — the ML model comes in Lab 6.
Send a request without the amount field. Check the status code and response body.
# YOUR CODE# r = requests.post("http://localhost:5000/score", json={"tx_id": "TX000"})# print(r.status_code, r.json())
Task 4.4 — Review questions
# 1. What is the difference between GET and POST?# ANSWER:# 2. Why use jsonify() instead of return {"key": "value"}?# Hint: try both and compare the response headers.# ANSWER:# 3. What happens if two people call /score at the same time?# ANSWER:
server.kill()print("Server stopped.")
Homework
Add endpoint GET /stats that returns: how many requests the server handled, how many were HIGH/CRITICAL.
(Hint: use a global dict as a counter — counters = {"total": 0, "high": 0})
Add validation: if amount is negative — return a 400 error.
Call /score with 10 transactions in a loop and print a summary table.
Next lab: Replace rules with a real ML model — train a RandomForest and load it into Flask.