Coverage for src/lexigram/web/interceptors/builtin/transform.py: 47%
19 statements
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-25 04:37 +0800
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-25 04:37 +0800
1"""Transform interceptor for response transformation.
3Allows transformation of handler responses before they're returned.
4"""
6from __future__ import annotations
8from typing import TYPE_CHECKING, Any
10from lexigram.web.protocols import (
11 CallHandlerProtocol,
12 ExecutionContextProtocol,
13 WebInterceptorProtocol,
14)
16if TYPE_CHECKING:
17 from collections.abc import Callable
20class TransformInterceptor(WebInterceptorProtocol):
21 """Interceptor that transforms handler responses.
23 Can wrap, envelope, or restructure responses before they're returned.
24 Useful for standardizing API response formats.
26 Example:
27 ```python
28 # Wrap all responses in a standard envelope
29 class EnvelopeInterceptor(TransformInterceptor):
30 def transform(self, data: Any) -> dict:
31 return {"success": True, "data": data}
33 router.add_interceptor(EnvelopeInterceptor())
34 ```
35 """
37 def __init__(
38 self,
39 transform: Callable[[Any], Any] | None = None,
40 wrap_response: bool = False,
41 ):
42 """Initialize the transform interceptor.
44 Args:
45 transform: Optional custom transform function.
46 wrap_response: If True, wraps response in a standard format.
47 """
48 self._transform = transform
49 self._wrap_response = wrap_response
51 async def intercept(
52 self,
53 context: ExecutionContextProtocol,
54 next_handler: CallHandlerProtocol,
55 ) -> Any:
56 """Intercept and transform the response.
58 Args:
59 context: The execution context.
60 next_handler: The next handler in the chain.
62 Returns:
63 Transformed response.
64 """
65 result = await next_handler.handle()
67 # Apply transformation
68 if self._transform:
69 return self._transform(result)
71 # Default wrap behavior
72 if self._wrap_response:
73 return self._wrap(result)
75 return result
77 def transform(self, data: Any) -> Any:
78 """Transform the data.
80 Override this in subclasses to provide custom transformation.
82 Args:
83 data: The data to transform.
85 Returns:
86 Transformed data.
87 """
88 return data
90 def _wrap(self, data: Any) -> dict[str, Any]:
91 """Wrap data in standard response format.
93 Args:
94 data: The data to wrap.
96 Returns:
97 Wrapped response.
98 """
99 return {
100 "success": True,
101 "data": data,
102 }
105__all__ = ["TransformInterceptor"]