Start learning free

LESSON 142 OF 188 · BACKEND: TESTS AND RUNNING IT

A Request ID in Python

Practice

When many customers order at the same time, their log lines get mixed together. When one of them writes that their order went wrong, you can't tell which lines are theirs. The fix is a request ID: a random name made for each request, sent back with the answer in a header and written in every log line about that request. The customer gives you the id, and you search the log for it.

Flask can run code around every request. A function marked @app.before_request runs before the route, and one marked @app.after_request gets the answer and returns what is sent, as you did for ETags. Values that belong to the request being handled go in g: each request gets its own empty g. For example, to remember when each request started:

@app.before_request
def remember_start():
    g.started = time.time()

Every function can read g.started until that answer is sent. For the id itself, uuid.uuid4().hex makes 32 random characters of 0–9 and a–f, practically never the same twice. A test can't know a random id in advance, so it checks a part: self.assertIn(a, b) passes when a is found inside b.

The check sends four requests. The ids are random, so it shows them as <id 1>, <id 2> and so on:

POST /orders {"product_id": 1, "quantity": 2}  →  201 | X-Request-Id: <id 1>
  log: INFO:root:[<id 1>] Order placed: 2 x Mug, total 24
POST /orders {"product_id": 3, "quantity": 1}  →  201 | X-Request-Id: <id 2>
  log: INFO:root:[<id 2>] Order placed: 1 x Lamp, total 29
POST /orders {"product_id": 99, "quantity": 1}  →  404 | X-Request-Id: <id 3>
GET /about  →  404 | X-Request-Id: <id 4>

Your task: make an id before every request, send it back in the X-Request-Id header, and write it in square brackets at the start of the order's log line. Then write test_log_has_request_id, which checks that the header's id is in the log line. The check runs it on the shop, where it must pass, and on two broken copies, one that leaves the id out of the log and one that makes a second id for the answer, where it must fail.


Assignment
Follow the Coding Tutorial to give every request an id, put it in the answer's header and in the order's log line, and test that the two match.


Hint
Keep the id in g.request_id, so the route and the after_request function can both read it. In the test, keep the answer of the post in response: its X-Request-Id header holds the id.


STEP 1 OF 12
    Ctrl + Enter to check

    Log Request Id 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