def test_errors_raised_in_callback_are_handled(api: API, when): class CustomError(Exception): pass @api.error_handler(CustomError) def handle_error(req, res, exception): res.text = "gotcha!" class MiddlewareWithErrors(Middleware): async def before_dispatch(self, req, res): if when == "before": raise CustomError async def after_dispatch(self, req, res): if when == "after": raise CustomError api.add_middleware(MiddlewareWithErrors) @api.route("/") async def index(req, res): pass client = api.build_client(raise_server_exceptions=False) r = client.get("/") assert r.status_code == 200 assert r.text == "gotcha!"
def test_if_middleware_is_added_then_it_is_called(api: API): with build_middleware() as middleware: api.add_middleware(middleware) @api.route("/") async def index(req, res): pass api.client.get("/")
def test_callbacks_can_be_sync(api: API): with build_middleware(sync=True) as middleware: api.add_middleware(middleware) @api.route("/") async def index(req, res): pass response = api.client.get("/") assert response.status_code == 200
def test_only_before_dispatch_is_called_if_method_not_allowed(api: API): with build_middleware(expect_call_after=False) as middleware: api.add_middleware(middleware) @api.route("/") async def index(req, res): pass response = api.client.put("/") assert response.status_code == 405
def test_can_pass_extra_kwargs(api: API): kwargs = {"foo": "bar"} with build_middleware(expect_kwargs=kwargs) as middleware: api.add_middleware(middleware, **kwargs) @api.route("/") async def index(req, res): pass api.client.get("/")
def test_return_response_in_before_hook(api: API): class NopeMiddleware(Middleware): async def before_dispatch(self, req, res): res.text = "Foo" return res api.add_middleware(NopeMiddleware) @api.route("/") async def index(req, res): # Should not be called assert False r = api.client.get("/") assert r.status_code == 200 assert r.text == "Foo"
def test_middleware_uses_registered_http_error_handler(api: API): @api.error_handler(HTTPError) def custom(req, res, exc: HTTPError): res.status_code = exc.status_code res.text = "Foo" class NopeMiddleware(Middleware): async def before_dispatch(self, req, res): raise HTTPError(401) api.add_middleware(NopeMiddleware) @api.route("/") async def index(req, res): pass response = api.client.get("/") assert response.status_code == 401 assert response.text == "Foo"
if field not in data: raise HTTPError(400, detail=f"{field} is a required field") # Now, let's assemble the actual application, shall we? api = API( # Built-in CORS, HSTS and GZip! enable_cors=True, enable_hsts=False, # the default enable_gzip=True, gzip_min_size=1024, # the default ) # Register the token middleware. api.add_middleware(TokenMiddleware) # Instanciate helper backends. storage = Storage() analytics = Analytics() # Routes! Views! Jinja templates! Static files! @api.route("/") async def index(req, res): courses = storage.list() # Notes: # - Templates are loaded from the `./templates` # directory by default. # - Static files (powered by WhiteNoise) are # served by default at `/static` from the