python 44 lines · 8 steps

A parameterized query-param decorator in Flask

A decorator factory validates and casts query-string parameters before a Flask view ever runs.

Explained by highlit
1from functools import wraps
2from flask import request, jsonify
3 
4 
5def query_params(*required, **optional):
6 def decorator(view):
7 @wraps(view)
8 def wrapper(*args, **kwargs):
9 parsed = {}
10 missing = [name for name in required if name not in request.args]
11 if missing:
12 return jsonify(error="missing required parameters", params=missing), 400
13 
14 for name in required:
15 parsed[name] = request.args[name]
16 
17 for name, caster in optional.items():
18 raw = request.args.get(name)
19 if raw is None:
20 parsed[name] = None
21 continue
22 try:
23 parsed[name] = caster(raw) if callable(caster) else raw
24 except (ValueError, TypeError):
25 return jsonify(error=f"invalid value for '{name}'", value=raw), 400
26 
27 kwargs["params"] = parsed
28 return view(*args, **kwargs)
29 
30 return wrapper
31 
32 return decorator
33 
34 
35@app.route("/reports")
36@query_params("account_id", page=int, per_page=int, active=lambda v: v.lower() == "true")
37def list_reports(params):
38 page = params["page"] or 1
39 per_page = params["per_page"] or 25
40 query = Report.query.filter_by(account_id=params["account_id"])
41 if params["active"] is not None:
42 query = query.filter_by(active=params["active"])
43 reports = query.paginate(page=page, per_page=per_page)
44 return jsonify(items=[r.to_dict() for r in reports.items], total=reports.total)
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1A decorator factory takes arguments and returns the actual decorator, letting one wrapper adapt to per-route rules.
  2. 2Centralizing parameter validation keeps view functions focused on business logic instead of request parsing.
  3. 3Returning early with a 400 on bad input guarantees the view only runs with clean, typed data.

Related explainers

Share this explainer

Here's the card — post it anywhere.

A parameterized query-param decorator in Flask — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code