diff --git a/sanic/blueprint_group.py b/sanic/blueprint_group.py index 45f30894..1c7052af 100644 --- a/sanic/blueprint_group.py +++ b/sanic/blueprint_group.py @@ -1,6 +1,7 @@ from __future__ import annotations from collections.abc import MutableSequence +from functools import partial from typing import TYPE_CHECKING, List, Optional, Union @@ -229,3 +230,15 @@ class BlueprintGroup(MutableSequence): args = list(args)[1:] return register_middleware_for_blueprints(fn) return register_middleware_for_blueprints + + def on_request(self, middleware=None): + if callable(middleware): + return self.middleware(middleware, "request") + else: + return partial(self.middleware, attach_to="request") + + def on_response(self, middleware=None): + if callable(middleware): + return self.middleware(middleware, "response") + else: + return partial(self.middleware, attach_to="response") diff --git a/tests/test_blueprint_group.py b/tests/test_blueprint_group.py index 77ddf44c..99f5cf95 100644 --- a/tests/test_blueprint_group.py +++ b/tests/test_blueprint_group.py @@ -116,6 +116,16 @@ def test_bp_group(app: Sanic): global MIDDLEWARE_INVOKE_COUNTER MIDDLEWARE_INVOKE_COUNTER["request"] += 1 + @blueprint_group_1.on_request + def blueprint_group_1_convenience_1(request): + global MIDDLEWARE_INVOKE_COUNTER + MIDDLEWARE_INVOKE_COUNTER["request"] += 1 + + @blueprint_group_1.on_request() + def blueprint_group_1_convenience_2(request): + global MIDDLEWARE_INVOKE_COUNTER + MIDDLEWARE_INVOKE_COUNTER["request"] += 1 + @blueprint_3.route("/") def blueprint_3_default_route(request): return text("BP3_OK") @@ -129,6 +139,16 @@ def test_bp_group(app: Sanic): global MIDDLEWARE_INVOKE_COUNTER MIDDLEWARE_INVOKE_COUNTER["response"] += 1 + @blueprint_group_2.on_response + def blueprint_group_2_middleware_convenience_1(request, response): + global MIDDLEWARE_INVOKE_COUNTER + MIDDLEWARE_INVOKE_COUNTER["response"] += 1 + + @blueprint_group_2.on_response() + def blueprint_group_2_middleware_convenience_2(request, response): + global MIDDLEWARE_INVOKE_COUNTER + MIDDLEWARE_INVOKE_COUNTER["response"] += 1 + app.blueprint(blueprint_group_2) @app.route("/") @@ -147,8 +167,8 @@ def test_bp_group(app: Sanic): _, response = app.test_client.get("/api/bp3") assert response.text == "BP3_OK" - assert MIDDLEWARE_INVOKE_COUNTER["response"] == 3 - assert MIDDLEWARE_INVOKE_COUNTER["request"] == 4 + assert MIDDLEWARE_INVOKE_COUNTER["response"] == 9 + assert MIDDLEWARE_INVOKE_COUNTER["request"] == 8 def test_bp_group_list_operations(app: Sanic): diff --git a/tests/test_middleware.py b/tests/test_middleware.py index cc7edae2..1ae8fb6e 100644 --- a/tests/test_middleware.py +++ b/tests/test_middleware.py @@ -37,14 +37,19 @@ def test_middleware_request_as_convenience(app): async def handler1(request): results.append(request) - @app.route("/") + @app.on_request() async def handler2(request): + results.append(request) + + @app.route("/") + async def handler3(request): return text("OK") request, response = app.test_client.get("/") assert response.text == "OK" assert type(results[0]) is Request + assert type(results[1]) is Request def test_middleware_response(app): @@ -79,7 +84,12 @@ def test_middleware_response_as_convenience(app): results.append(request) @app.on_response - async def process_response(request, response): + async def process_response_1(request, response): + results.append(request) + results.append(response) + + @app.on_response() + async def process_response_2(request, response): results.append(request) results.append(response) @@ -93,6 +103,8 @@ def test_middleware_response_as_convenience(app): assert type(results[0]) is Request assert type(results[1]) is Request assert isinstance(results[2], HTTPResponse) + assert type(results[3]) is Request + assert isinstance(results[4], HTTPResponse) def test_middleware_response_as_convenience_called(app):