__init__.py 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637
  1. from __future__ import annotations
  2. from collections.abc import Awaitable, Callable, Iterator
  3. from typing import Any, ParamSpec, Protocol
  4. P = ParamSpec("P")
  5. _Scope = Any
  6. _Receive = Callable[[], Awaitable[Any]]
  7. _Send = Callable[[Any], Awaitable[None]]
  8. # Since `starlette.types.ASGIApp` type differs from `ASGIApplication` from `asgiref`
  9. # we need to define a more permissive version of ASGIApp that doesn't cause type errors.
  10. _ASGIApp = Callable[[_Scope, _Receive, _Send], Awaitable[None]]
  11. class _MiddlewareFactory(Protocol[P]):
  12. def __call__(self, app: _ASGIApp, /, *args: P.args, **kwargs: P.kwargs) -> _ASGIApp: ... # pragma: no cover
  13. class Middleware:
  14. def __init__(self, cls: _MiddlewareFactory[P], *args: P.args, **kwargs: P.kwargs) -> None:
  15. self.cls = cls
  16. self.args = args
  17. self.kwargs = kwargs
  18. def __iter__(self) -> Iterator[Any]:
  19. as_tuple = (self.cls, self.args, self.kwargs)
  20. return iter(as_tuple)
  21. def __repr__(self) -> str:
  22. class_name = self.__class__.__name__
  23. args_strings = [f"{value!r}" for value in self.args]
  24. option_strings = [f"{key}={value!r}" for key, value in self.kwargs.items()]
  25. name = getattr(self.cls, "__name__", "")
  26. args_repr = ", ".join([name] + args_strings + option_strings)
  27. return f"{class_name}({args_repr})"