Add Request contextvars (#2475)
* Add Request contextvars * Add missing contextvar setter * Move location of context setter
This commit is contained in:
parent
a744041e38
commit
ce926a34f2
|
@ -265,6 +265,7 @@ class Http(metaclass=TouchUpMeta):
|
|||
transport=self.protocol.transport,
|
||||
app=self.protocol.app,
|
||||
)
|
||||
self.protocol.request_class._current.set(request)
|
||||
await self.dispatch(
|
||||
"http.lifecycle.request",
|
||||
inline=True,
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from contextvars import ContextVar
|
||||
from typing import (
|
||||
TYPE_CHECKING,
|
||||
Any,
|
||||
|
@ -35,7 +36,7 @@ from httptools.parser.errors import HttpParserInvalidURLError # type: ignore
|
|||
|
||||
from sanic.compat import CancelledErrors, Header
|
||||
from sanic.constants import DEFAULT_HTTP_CONTENT_TYPE
|
||||
from sanic.exceptions import BadRequest, BadURL, ServerError
|
||||
from sanic.exceptions import BadRequest, BadURL, SanicException, ServerError
|
||||
from sanic.headers import (
|
||||
AcceptContainer,
|
||||
Options,
|
||||
|
@ -82,6 +83,8 @@ class Request:
|
|||
Properties of an HTTP request such as URL, headers, etc.
|
||||
"""
|
||||
|
||||
_current: ContextVar[Request] = ContextVar("request")
|
||||
|
||||
__slots__ = (
|
||||
"__weakref__",
|
||||
"_cookies",
|
||||
|
@ -174,6 +177,13 @@ class Request:
|
|||
class_name = self.__class__.__name__
|
||||
return f"<{class_name}: {self.method} {self.path}>"
|
||||
|
||||
@classmethod
|
||||
def get_current(cls) -> Request:
|
||||
request = cls._current.get(None)
|
||||
if not request:
|
||||
raise SanicException("No current request")
|
||||
return request
|
||||
|
||||
@classmethod
|
||||
def generate_id(*_):
|
||||
return uuid.uuid4()
|
||||
|
|
|
@ -4,7 +4,7 @@ from uuid import UUID, uuid4
|
|||
import pytest
|
||||
|
||||
from sanic import Sanic, response
|
||||
from sanic.exceptions import BadURL
|
||||
from sanic.exceptions import BadURL, SanicException
|
||||
from sanic.request import Request, uuid
|
||||
from sanic.server import HttpProtocol
|
||||
|
||||
|
@ -217,3 +217,17 @@ async def test_request_scope_is_not_none_when_running_in_asgi(app):
|
|||
assert request.scope is not None
|
||||
assert request.scope["method"].lower() == "get"
|
||||
assert request.scope["path"].lower() == "/"
|
||||
|
||||
|
||||
def test_cannot_get_request_outside_of_cycle():
|
||||
with pytest.raises(SanicException, match="No current request"):
|
||||
Request.get_current()
|
||||
|
||||
|
||||
def test_get_current_request(app):
|
||||
@app.get("/")
|
||||
async def get(request):
|
||||
return response.json({"same": request is Request.get_current()})
|
||||
|
||||
_, resp = app.test_client.get("/")
|
||||
assert resp.json["same"]
|
||||
|
|
Loading…
Reference in New Issue
Block a user