Application state

This commit is contained in:
Tom Christie 2019-08-27 09:41:04 +01:00
parent cba5eb87bd
commit bc7f4bd3d3
5 changed files with 41 additions and 21 deletions

View File

@ -76,3 +76,14 @@ exceptions that occur within the application:
* `app.add_exception_handler(exc_class_or_status_code, handler)` - Add an error handler. The handler function may be either a coroutine or a regular function, with a signature like `func(request, exc) -> response`.
* `@app.exception_handler(exc_class_or_status_code)` - Add an error handler, decorator style.
* `app.debug` - Enable or disable error tracebacks in the browser.
### Storing state on the app instance
You can store arbitrary extra state on the application instance, using the
generic `app.state` attribute.
For example:
```python
app.state.ADMIN_EMAIL = 'admin@example.org'
```

View File

@ -1,6 +1,6 @@
import typing
from starlette.datastructures import URLPath
from starlette.datastructures import State, URLPath
from starlette.exceptions import ExceptionMiddleware
from starlette.middleware.base import BaseHTTPMiddleware
from starlette.middleware.errors import ServerErrorMiddleware
@ -13,6 +13,7 @@ class Starlette:
self, debug: bool = False, routes: typing.List[BaseRoute] = None
) -> None:
self._debug = debug
self.state = State()
self.router = Router(routes)
self.exception_middleware = ExceptionMiddleware(self.router, debug=debug)
self.error_middleware = ServerErrorMiddleware(

View File

@ -628,3 +628,29 @@ class MutableHeaders(Headers):
if existing is not None:
vary = ", ".join([existing, vary])
self["vary"] = vary
class State(object):
"""
An object that can be used to store arbitrary state.
Used for `request.state` and `app.state`.
"""
def __init__(self, state: typing.Dict = None):
if state is None:
state = {}
super(State, self).__setattr__("_state", state)
def __setattr__(self, key: typing.Any, value: typing.Any) -> None:
self._state[key] = value
def __getattr__(self, key: typing.Any) -> typing.Any:
try:
return self._state[key]
except KeyError:
message = "'{}' object has no attribute '{}'"
raise AttributeError(message.format(self.__class__.__name__, key))
def __delattr__(self, key: typing.Any) -> None:
del self._state[key]

View File

@ -1,5 +1,5 @@
import html
import asyncio
import html
import inspect
import traceback
import typing

View File

@ -4,7 +4,7 @@ import json
import typing
from collections.abc import Mapping
from starlette.datastructures import URL, Address, FormData, Headers, QueryParams
from starlette.datastructures import URL, Address, FormData, Headers, QueryParams, State
from starlette.formparsers import FormParser, MultiPartParser
from starlette.types import Message, Receive, Scope
@ -18,24 +18,6 @@ class ClientDisconnect(Exception):
pass
class State(object):
def __init__(self, state: typing.Dict = {}):
super(State, self).__setattr__("_state", state)
def __setattr__(self, key: typing.Any, value: typing.Any) -> None:
self._state[key] = value
def __getattr__(self, key: typing.Any) -> typing.Any:
try:
return self._state[key]
except KeyError:
message = "'{}' object has no attribute '{}'"
raise AttributeError(message.format(self.__class__.__name__, key))
def __delattr__(self, key: typing.Any) -> None:
del self._state[key]
class HTTPConnection(Mapping):
"""
A base class for incoming HTTP connections, that is used to provide