Coverage for fastblocks/decorators.py: 100%
28 statements
« prev ^ index » next coverage.py v7.10.7, created at 2025-10-09 00:47 -0700
« prev ^ index » next coverage.py v7.10.7, created at 2025-10-09 00:47 -0700
1import functools
2import typing as t
3from collections.abc import Sequence
4from typing import TypeVar
6from starlette.types import ASGIApp
8from .caching import CacheDirectives, Rule
9from .middleware import CacheControlMiddleware, CacheMiddleware
11_P = t.ParamSpec("_P")
12T = TypeVar("T", bound=ASGIApp)
13_T = t.TypeVar("_T", bound=ASGIApp)
16class _MiddlewareFactory(t.Protocol[_P]):
17 def __call__(
18 self,
19 app: ASGIApp,
20 *args: _P.args,
21 **kwargs: _P.kwargs,
22 ) -> ASGIApp: ...
25def _wrap_in_middleware[T: ASGIApp](app: T, middleware: ASGIApp) -> T:
26 return t.cast(T, functools.wraps(app, updated=())(middleware))
29class _CacheMiddlewareDecorator:
30 def __call__(
31 self,
32 *,
33 cache: t.Any,
34 rules: Sequence[Rule] | None = None,
35 ) -> t.Callable[[_T], _T]:
36 def wrap(app: _T) -> _T:
37 middleware = CacheMiddleware(app, cache=cache, rules=rules)
38 return _wrap_in_middleware(app, middleware)
40 return wrap
43class _CacheControlMiddlewareDecorator:
44 def __call__(self, **kwargs: t.Unpack[CacheDirectives]) -> t.Callable[[_T], _T]:
45 def wrap(app: _T) -> _T:
46 middleware = CacheControlMiddleware(app, **kwargs)
47 return _wrap_in_middleware(app, middleware)
49 return wrap
52cached = _CacheMiddlewareDecorator()
53cache_control = _CacheControlMiddlewareDecorator()
54__all__ = ["_MiddlewareFactory", "cache_control", "cached"]