context.py 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. # (c) Nelen & Schuurmans
  2. from contextvars import ContextVar
  3. from fastapi import Request
  4. from ..oauth2 import Claims
  5. __all__ = ["ctx", "RequestMiddleware"]
  6. class Context:
  7. def __init__(self):
  8. self._request_value: ContextVar[Request] = ContextVar("request_value")
  9. self._claims_value: ContextVar[Claims] = ContextVar("claims_value")
  10. @property
  11. def request(self) -> Request:
  12. return self._request_value.get()
  13. @request.setter
  14. def request(self, value: Request) -> None:
  15. self._request_value.set(value)
  16. @property
  17. def claims(self) -> Claims:
  18. return self._claims_value.get()
  19. @claims.setter
  20. def claims(self, value: Claims) -> None:
  21. self._claims_value.set(value)
  22. ctx = Context()
  23. class RequestMiddleware:
  24. """Save the current request in a context variable.
  25. We were experiencing database connections piling up until PostgreSQL's
  26. max_connections was hit, which has to do with BaseHTTPMiddleware not
  27. interacting properly with context variables. For more details, see:
  28. https://github.com/tiangolo/fastapi/issues/4719. Writing this
  29. middleware as generic ASGI middleware fixes the problem.
  30. """
  31. def __init__(self, app):
  32. self.app = app
  33. async def __call__(self, scope, receive, send):
  34. if scope["type"] == "http":
  35. ctx.request = Request(scope, receive)
  36. await self.app(scope, receive, send)