def test_asgi_middleware(app: App, client): params = None received_app = False called = False class Middleware: def __init__(self, app, **kwargs): nonlocal params, received_app params = kwargs received_app = isinstance(app, App) self.app = app async def __call__(self, scope, receive, send): nonlocal called await self.app(scope, receive, send) called = True app.add_asgi_middleware(Middleware, hello="world") assert not received_app assert params == {"hello": "world"} @app.route("/") async def index(req, res): pass client.get("/") assert called
def test_pure_asgi_middleware(app: App, client): initialized = False called = False class Middleware: def __init__(self, inner): nonlocal initialized self.inner = inner initialized = True def __call__(self, scope: dict): nonlocal called called = True return self.inner(scope) app.add_asgi_middleware(Middleware) assert initialized @app.route("/") async def index(req, res): pass client.get("/") assert called
def test_asgi_middleware(app: App, client): params = None received_app = False called = False class Middleware(ASGIMiddleware): def __init__(self, inner, app: App, **kwargs): super().__init__(inner, app) nonlocal params, received_app params = kwargs received_app = isinstance(app, App) def __call__(self, scope): nonlocal called called = True return super().__call__(scope) app.add_asgi_middleware(Middleware, hello="world") assert received_app assert params == {"hello": "world"} @app.route("/") async def index(req, res): pass client.get("/") assert called
def test_asgi2_middleware_not_supported(app: App): class Middleware: def __init__(self, app): pass def __call__(self, scope): pass with pytest.raises(ValueError) as ctx: app.add_asgi_middleware(Middleware) error = str(ctx.value).lower() for phrase in "asgi2", "please upgrade", "asgi3", "scope, receive, send": assert phrase in error
def use_authentication(app: App) -> None: backend = get_default_backend() if backend is None: return @app.error_handler(AuthenticationError) async def on_auth_error(req, res, exc): raise HTTPError(401, detail=str(exc)) @app.error_handler(InvalidCredentials) async def on_invalid_crendentials(req, res, exc: InvalidCredentials): headers = {} if exc.scheme.lower() in ("basic", "bearer"): headers["WWW-Authenticate"] = exc.scheme.capitalize() raise HTTPError(401, detail=str(exc), headers=headers) # TODO: use `.add_middleware` once Bocadillo supports ASGI-compatible # middleware with error handling. app.add_asgi_middleware(AuthMiddleware, backend=backend)