Creates an Starlette application.
| 17 | |
| 18 | |
| 19 | class Starlette: |
| 20 | """Creates an Starlette application.""" |
| 21 | |
| 22 | def __init__( |
| 23 | self: AppType, |
| 24 | debug: bool = False, |
| 25 | routes: Sequence[BaseRoute] | None = None, |
| 26 | middleware: Sequence[Middleware] | None = None, |
| 27 | exception_handlers: Mapping[Any, ExceptionHandler] | None = None, |
| 28 | lifespan: Lifespan[AppType] | None = None, |
| 29 | ) -> None: |
| 30 | """Initializes the application. |
| 31 | |
| 32 | Parameters: |
| 33 | debug: Boolean indicating if debug tracebacks should be returned on errors. |
| 34 | routes: A list of routes to serve incoming HTTP and WebSocket requests. |
| 35 | middleware: A list of middleware to run for every request. A starlette |
| 36 | application will always automatically include two middleware classes. |
| 37 | `ServerErrorMiddleware` is added as the very outermost middleware, to handle |
| 38 | any uncaught errors occurring anywhere in the entire stack. |
| 39 | `ExceptionMiddleware` is added as the very innermost middleware, to deal |
| 40 | with handled exception cases occurring in the routing or endpoints. |
| 41 | exception_handlers: A mapping of either integer status codes, |
| 42 | or exception class types onto callables which handle the exceptions. |
| 43 | Exception handler callables should be of the form |
| 44 | `handler(request, exc) -> response` and may be either standard functions, or |
| 45 | async functions. |
| 46 | lifespan: A lifespan context function, which can be used to perform |
| 47 | startup and shutdown tasks. This is a newer style that replaces the |
| 48 | `on_startup` and `on_shutdown` handlers. Use one or the other, not both. |
| 49 | """ |
| 50 | self.debug = debug |
| 51 | self.state = State() |
| 52 | self.router = Router(routes, lifespan=lifespan) |
| 53 | self.exception_handlers = {} if exception_handlers is None else dict(exception_handlers) |
| 54 | self.user_middleware = [] if middleware is None else list(middleware) |
| 55 | self.middleware_stack: ASGIApp | None = None |
| 56 | |
| 57 | def build_middleware_stack(self) -> ASGIApp: |
| 58 | debug = self.debug |
| 59 | error_handler = None |
| 60 | exception_handlers: dict[Any, ExceptionHandler] = {} |
| 61 | |
| 62 | for key, value in self.exception_handlers.items(): |
| 63 | if key in (500, Exception): |
| 64 | error_handler = value |
| 65 | else: |
| 66 | exception_handlers[key] = value |
| 67 | |
| 68 | middleware = ( |
| 69 | [Middleware(ServerErrorMiddleware, handler=error_handler, debug=debug)] |
| 70 | + self.user_middleware |
| 71 | + [Middleware(ExceptionMiddleware, handlers=exception_handlers, debug=debug)] |
| 72 | ) |
| 73 | |
| 74 | app = self.router |
| 75 | for cls, args, kwargs in reversed(middleware): |
| 76 | app = cls(app, *args, **kwargs) |
no outgoing calls