Skip to content

Commit

Permalink
Add signals before and after handler execution (sanic-org#2540)
Browse files Browse the repository at this point in the history
  • Loading branch information
ahopkins authored Sep 15, 2022
1 parent e501028 commit d352a41
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 0 deletions.
10 changes: 10 additions & 0 deletions sanic/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -894,9 +894,19 @@ async def handle_request(self, request: Request): # no cov
)

# Run response handler
await self.dispatch(
"http.handler.before",
inline=True,
context={"request": request},
)
response = handler(request, **request.match_info)
if isawaitable(response):
response = await response
await self.dispatch(
"http.handler.after",
inline=True,
context={"request": request},
)

if request.responded:
if response is not None:
Expand Down
4 changes: 4 additions & 0 deletions sanic/signals.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ class Event(Enum):
HTTP_LIFECYCLE_RESPONSE = "http.lifecycle.response"
HTTP_ROUTING_AFTER = "http.routing.after"
HTTP_ROUTING_BEFORE = "http.routing.before"
HTTP_HANDLER_AFTER = "http.handler.after"
HTTP_HANDLER_BEFORE = "http.handler.before"
HTTP_LIFECYCLE_SEND = "http.lifecycle.send"
HTTP_MIDDLEWARE_AFTER = "http.middleware.after"
HTTP_MIDDLEWARE_BEFORE = "http.middleware.before"
Expand All @@ -53,6 +55,8 @@ class Event(Enum):
Event.HTTP_LIFECYCLE_RESPONSE.value,
Event.HTTP_ROUTING_AFTER.value,
Event.HTTP_ROUTING_BEFORE.value,
Event.HTTP_HANDLER_AFTER.value,
Event.HTTP_HANDLER_BEFORE.value,
Event.HTTP_LIFECYCLE_SEND.value,
Event.HTTP_MIDDLEWARE_AFTER.value,
Event.HTTP_MIDDLEWARE_BEFORE.value,
Expand Down
2 changes: 2 additions & 0 deletions tests/test_asgi.py
Original file line number Diff line number Diff line change
Expand Up @@ -531,6 +531,8 @@ async def _request(request):
"http.lifecycle.handle",
"http.routing.before",
"http.routing.after",
"http.handler.before",
"http.handler.after",
"http.lifecycle.response",
# "http.lifecycle.send",
# "http.lifecycle.complete",
Expand Down
36 changes: 36 additions & 0 deletions tests/test_handler.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
from sanic.app import Sanic
from sanic.response import empty
from sanic.signals import Event


def test_handler_operation_order(app: Sanic):
operations = []

@app.on_request
async def on_request(_):
nonlocal operations
operations.append(1)

@app.on_response
async def on_response(*_):
nonlocal operations
operations.append(5)

@app.get("/")
async def handler(_):
nonlocal operations
operations.append(3)
return empty()

@app.signal(Event.HTTP_HANDLER_BEFORE)
async def handler_before(**_):
nonlocal operations
operations.append(2)

@app.signal(Event.HTTP_HANDLER_AFTER)
async def handler_after(**_):
nonlocal operations
operations.append(4)

app.test_client.get("/")
assert operations == [1, 2, 3, 4, 5]

0 comments on commit d352a41

Please sign in to comment.