Coverage for src/lexigram/admin/params.py: 28%
18 statements
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-24 23:39 +0800
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-24 23:39 +0800
1"""Widget parameter parsing — HTTP boundary helpers for admin widget requests."""
3from __future__ import annotations
5from collections.abc import Mapping
7from lexigram.contracts.admin.types import WidgetParams
10def parse_widget_params(query: Mapping[str, str]) -> WidgetParams:
11 """Parse and validate HTTP query parameters into a typed ``WidgetParams``.
13 Clamps values to safe ranges and applies defaults.
14 This is the only place where raw HTTP query strings are converted
15 to the typed contract object.
17 Args:
18 query: Raw query string parameters from the HTTP request.
20 Returns:
21 Validated ``WidgetParams`` with defaults applied for missing keys.
22 """
23 try:
24 page = max(1, int(query.get("page", 1)))
25 except (ValueError, TypeError):
26 page = 1
28 try:
29 page_size = min(100, max(1, int(query.get("page_size", 20))))
30 except (ValueError, TypeError):
31 page_size = 20
33 try:
34 time_window = max(1, int(query.get("time_window_minutes", 60)))
35 except (ValueError, TypeError):
36 time_window = 60
38 return WidgetParams(
39 page=page,
40 page_size=page_size,
41 time_window_minutes=time_window,
42 raw=tuple(query.items()),
43 )
46__all__ = ["parse_widget_params"]