Coverage for src / lexigram / admin / params.py: 28%

18 statements  

« prev     ^ index     » next       coverage.py v7.13.5, created at 2026-08-13 22:14 +0800

1"""Widget parameter parsing — HTTP boundary helpers for admin widget requests.""" 

2 

3from __future__ import annotations 

4 

5from collections.abc import Mapping 

6 

7from lexigram.contracts.admin.types import WidgetParams 

8 

9 

10def parse_widget_params(query: Mapping[str, str]) -> WidgetParams: 

11 """Parse and validate HTTP query parameters into a typed ``WidgetParams``. 

12 

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. 

16 

17 Args: 

18 query: Raw query string parameters from the HTTP request. 

19 

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 

27 

28 try: 

29 page_size = min(100, max(1, int(query.get("page_size", 20)))) 

30 except (ValueError, TypeError): 

31 page_size = 20 

32 

33 try: 

34 time_window = max(1, int(query.get("time_window_minutes", 60))) 

35 except (ValueError, TypeError): 

36 time_window = 60 

37 

38 return WidgetParams( 

39 page=page, 

40 page_size=page_size, 

41 time_window_minutes=time_window, 

42 raw=tuple(query.items()), 

43 ) 

44 

45 

46__all__ = ["parse_widget_params"]