Coverage for src/lexigram/web/dependencies/strategies.py: 19%

32 statements  

« prev     ^ index     » next       coverage.py v7.15.4, created at 2026-08-25 04:37 +0800

1"""Resolution strategies for web-related dependencies.""" 

2 

3from __future__ import annotations 

4 

5from typing import Any 

6 

7from lexigram.di.extensions.strategies import ResolutionStrategy 

8 

9 

10class WebParameterStrategy(ResolutionStrategy): 

11 """Resolves path params, query params, headers from the request. 

12 

13 This strategy is used by lexigram-web to inject web parameters 

14 (path, query, headers) alongside DI services. 

15 """ 

16 

17 def __init__( 

18 self, 

19 path_params: dict[str, str] | None = None, 

20 query_params: dict[str, str | list[str]] | None = None, 

21 headers: dict[str, str] | None = None, 

22 request: Any = None, 

23 ): 

24 self._path = path_params or {} 

25 self._query = query_params or {} 

26 self._headers = headers or {} 

27 self._request = request 

28 

29 async def resolve( 

30 self, 

31 param_name: str, 

32 param_type: type, 

33 default: Any, 

34 ) -> tuple[bool, Any]: 

35 # Path parameters 

36 if param_name in self._path: 

37 try: 

38 return True, param_type(self._path[param_name]) 

39 except (ValueError, TypeError): 

40 return True, self._path[param_name] 

41 

42 # Query parameters (handle both single and list values) 

43 if param_name in self._query: 

44 value = self._query[param_name] 

45 if isinstance(value, list): 

46 try: 

47 return True, [param_type(v) for v in value] 

48 except (ValueError, TypeError): 

49 return True, value 

50 else: 

51 try: 

52 return True, param_type(value) 

53 except (ValueError, TypeError): 

54 return True, value 

55 

56 # Header parameters (case-insensitive) 

57 header_key = param_name.lower().replace("_", "-") 

58 if header_key in self._headers: 

59 return True, self._headers[header_key] 

60 

61 # Request object - check if param_type matches 

62 if self._request is not None and ( 

63 param_type is type(self._request) 

64 or ( 

65 hasattr(param_type, "__name__") 

66 and param_type.__name__ == type(self._request).__name__ 

67 ) 

68 ): 

69 return True, self._request 

70 

71 return False, None