data/sample-service/, generated by reading the code and running its tests.app/main.py, tests/test_orders.py, and an actual pytest -q run — nothing here is invented.
The whole service: a FastAPI app, a hardcoded 3-order in-memory store, one helper (order_total), and both endpoints. 34 lines.
Empty. Makes app importable as a package.
5 tests against a FastAPI TestClient. Covers both endpoints' happy paths and one 404.
order_id — path string, e.g. A-1001total{"detail": "order not found"}account — path string, e.g. Account A (exact match, case-sensitive){account, orders: count, total}{"detail": "account not found"}app/main.py's file timestamp is newer than the rest of the kit, which points to the seeded bug already having been fixed in an earlier pass over this same folder. Rather than fabricate a failure to match the README, this run reports what actually happened: 5/5 green.
/accounts/{account}/total, and the order test only checks id — it never asserts the computed total in the response body.
Anyone who can reach the service reads every order's line items and every account's running total. Nothing scopes a caller to their own account, and there's no key, token, or session check anywhere in the file. Worst of the three because it's a live data-exposure path, not a latent one.
Proposed fix (draft — not applied)from fastapi import FastAPI, HTTPException +from fastapi import FastAPI, HTTPException, Header, Depends +import hmac +import os + +API_KEY = os.environ.get("SAMPLE_SERVICE_API_KEY", "") + +def require_api_key(x_api_key: str = Header(default="")): + if not API_KEY or not hmac.compare_digest(x_api_key, API_KEY): + raise HTTPException(status_code=401, detail="missing or invalid API key") app = FastAPI(title="sample-service") ... -@app.get("/orders/{order_id}") +@app.get("/orders/{order_id}", dependencies=[Depends(require_api_key)]) def get_order(order_id: str): ... -@app.get("/accounts/{account}/total") +@app.get("/accounts/{account}/total", dependencies=[Depends(require_api_key)]) def account_total(account: str):
total += line["qty"] * line["unit"] accumulates in a plain float. Repeated addition can drift for prices that aren't exact binary fractions (like $19.99), and the closing round(total, 2) on the next line only rounds the final, already-drifted sum — it doesn't prevent the drift. The current fixture prices (1200.0, 45.0) are exact in binary, so no test exposes this; it would show up the first time someone adds a real-world price.
A typo'd account name and a real account that happens to have zero orders return the identical "account not found". Today the store never empties, so this can't happen yet — but the moment orders become deletable, a caller can no longer tell "this account doesn't exist" from "this account has nothing right now" without extra lookups.
TestClient. Bad — SQL-like strings, path traversal (../../etc/passwd), emoji, wrong-case and space-padded account names: all correctly 404 through the app's own handler; it's a dict lookup, not a query, so there's no injection surface. Empty — a blank order_id or account 404s at the routing layer before app code runs. Huge — a 100,000-character order_id/account: the HTTP client itself refused to build a request that long ("URL too long"), and in production a reverse proxy or the ASGI server's own max-URL-length limit sits in front of this route before app code ever sees it; even if one got through, the lookup is against a 3-entry dict, so a long key costs nothing extra. No bug found in the app under any of the three.
<details> elements — open with a click, a tap, or the keyboard, work with zero JavaScript, and can't overflow.