* `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'
+```
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
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(
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]
-import html
import asyncio
+import html
import inspect
import traceback
import typing
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
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