mirror of https://github.com/encode/starlette.git
Request state (#404)
* Add Mount(routes=...) * Lifespan route instance * Lifespan as a standard routing component * Linting * Linting * Version 0.10.6 * Release notes * Version 0.11.0 * Drop redundant import * Drop redundant database requirements * Include htmlcov in scripts/clean * Drop redundant import * Release notes * Linting * Add request.state
This commit is contained in:
parent
ff8336fb6b
commit
82c610559c
|
@ -5,6 +5,7 @@
|
|||
* Schema generation is no longer attached to the application instance. Use `schemas = SchemaGenerator(...)` and `return schemas.OpenAPIResponse(request=request)`
|
||||
* `LifespanMiddleware` is dropped in favor of router-based lifespan handling.
|
||||
* Application instances now accept a `routes` argument, `Starlette(routes=[...])`
|
||||
* Schema generation now includes mounted routes.
|
||||
|
||||
## 0.10.6
|
||||
|
||||
|
|
|
@ -115,3 +115,12 @@ will raise an error.
|
|||
In some cases such as long-polling, or streaming responses you might need to
|
||||
determine if the client has dropped the connection. You can determine this
|
||||
state with `disconnected = await request.is_disconnected()`.
|
||||
|
||||
#### Other state
|
||||
|
||||
If you want to store additional information on the request you can do so
|
||||
using `request.state`.
|
||||
|
||||
For example:
|
||||
|
||||
`request.state.time_started = time.time()`
|
||||
|
|
|
@ -18,6 +18,10 @@ class ClientDisconnect(Exception):
|
|||
pass
|
||||
|
||||
|
||||
class State:
|
||||
pass
|
||||
|
||||
|
||||
class HTTPConnection(Mapping):
|
||||
"""
|
||||
A base class for incoming HTTP connections, that is used to provide
|
||||
|
@ -88,16 +92,6 @@ class HTTPConnection(Mapping):
|
|||
), "SessionMiddleware must be installed to access request.session"
|
||||
return self._scope["session"]
|
||||
|
||||
@property
|
||||
def database(self) -> typing.Any: # pragma: no cover
|
||||
# NOTE: Pending deprecation. You probably want to look at the
|
||||
# stand-alone `databases` package instead.
|
||||
# https://github.com/encode/databases
|
||||
assert (
|
||||
"database" in self._scope
|
||||
), "DatabaseMiddleware must be installed to access request.database"
|
||||
return self._scope["database"]
|
||||
|
||||
@property
|
||||
def auth(self) -> typing.Any:
|
||||
assert (
|
||||
|
@ -112,6 +106,12 @@ class HTTPConnection(Mapping):
|
|||
), "AuthenticationMiddleware must be installed to access request.user"
|
||||
return self._scope["user"]
|
||||
|
||||
@property
|
||||
def state(self) -> State:
|
||||
if "state" not in self._scope:
|
||||
self._scope["state"] = State()
|
||||
return self._scope["state"]
|
||||
|
||||
def url_for(self, name: str, **path_params: typing.Any) -> str:
|
||||
router = self._scope["router"]
|
||||
url_path = router.url_path_for(name, **path_params)
|
||||
|
|
|
@ -280,6 +280,21 @@ def test_request_is_disconnected():
|
|||
assert disconnected_after_response
|
||||
|
||||
|
||||
def test_request_state():
|
||||
def app(scope):
|
||||
async def asgi(receive, send):
|
||||
request = Request(scope, receive)
|
||||
request.state.example = 123
|
||||
response = JSONResponse({"state.example": request["state"].example})
|
||||
await response(receive, send)
|
||||
|
||||
return asgi
|
||||
|
||||
client = TestClient(app)
|
||||
response = client.get("/123?a=abc")
|
||||
assert response.json() == {"state.example": 123}
|
||||
|
||||
|
||||
def test_request_cookies():
|
||||
def app(scope):
|
||||
async def asgi(receive, send):
|
||||
|
|
Loading…
Reference in New Issue