Begin middleware revamp (#2550)
This commit is contained in:
@@ -1,11 +1,17 @@
|
||||
from collections import deque
|
||||
from functools import partial
|
||||
from operator import attrgetter
|
||||
from typing import List
|
||||
|
||||
from sanic.base.meta import SanicMeta
|
||||
from sanic.middleware import Middleware, MiddlewareLocation
|
||||
from sanic.models.futures import FutureMiddleware
|
||||
from sanic.router import Router
|
||||
|
||||
|
||||
class MiddlewareMixin(metaclass=SanicMeta):
|
||||
router: Router
|
||||
|
||||
def __init__(self, *args, **kwargs) -> None:
|
||||
self._future_middleware: List[FutureMiddleware] = []
|
||||
|
||||
@@ -13,7 +19,12 @@ class MiddlewareMixin(metaclass=SanicMeta):
|
||||
raise NotImplementedError # noqa
|
||||
|
||||
def middleware(
|
||||
self, middleware_or_request, attach_to="request", apply=True
|
||||
self,
|
||||
middleware_or_request,
|
||||
attach_to="request",
|
||||
apply=True,
|
||||
*,
|
||||
priority=0
|
||||
):
|
||||
"""
|
||||
Decorate and register middleware to be called before a request
|
||||
@@ -30,6 +41,12 @@ class MiddlewareMixin(metaclass=SanicMeta):
|
||||
def register_middleware(middleware, attach_to="request"):
|
||||
nonlocal apply
|
||||
|
||||
location = (
|
||||
MiddlewareLocation.REQUEST
|
||||
if attach_to == "request"
|
||||
else MiddlewareLocation.RESPONSE
|
||||
)
|
||||
middleware = Middleware(middleware, location, priority=priority)
|
||||
future_middleware = FutureMiddleware(middleware, attach_to)
|
||||
self._future_middleware.append(future_middleware)
|
||||
if apply:
|
||||
@@ -46,7 +63,7 @@ class MiddlewareMixin(metaclass=SanicMeta):
|
||||
register_middleware, attach_to=middleware_or_request
|
||||
)
|
||||
|
||||
def on_request(self, middleware=None):
|
||||
def on_request(self, middleware=None, *, priority=0):
|
||||
"""Register a middleware to be called before a request is handled.
|
||||
|
||||
This is the same as *@app.middleware('request')*.
|
||||
@@ -54,11 +71,13 @@ class MiddlewareMixin(metaclass=SanicMeta):
|
||||
:param: middleware: A callable that takes in request.
|
||||
"""
|
||||
if callable(middleware):
|
||||
return self.middleware(middleware, "request")
|
||||
return self.middleware(middleware, "request", priority=priority)
|
||||
else:
|
||||
return partial(self.middleware, attach_to="request")
|
||||
return partial(
|
||||
self.middleware, attach_to="request", priority=priority
|
||||
)
|
||||
|
||||
def on_response(self, middleware=None):
|
||||
def on_response(self, middleware=None, *, priority=0):
|
||||
"""Register a middleware to be called after a response is created.
|
||||
|
||||
This is the same as *@app.middleware('response')*.
|
||||
@@ -67,6 +86,57 @@ class MiddlewareMixin(metaclass=SanicMeta):
|
||||
A callable that takes in a request and its response.
|
||||
"""
|
||||
if callable(middleware):
|
||||
return self.middleware(middleware, "response")
|
||||
return self.middleware(middleware, "response", priority=priority)
|
||||
else:
|
||||
return partial(self.middleware, attach_to="response")
|
||||
return partial(
|
||||
self.middleware, attach_to="response", priority=priority
|
||||
)
|
||||
|
||||
def finalize_middleware(self):
|
||||
for route in self.router.routes:
|
||||
request_middleware = Middleware.convert(
|
||||
self.request_middleware,
|
||||
self.named_request_middleware.get(route.name, deque()),
|
||||
location=MiddlewareLocation.REQUEST,
|
||||
)
|
||||
response_middleware = Middleware.convert(
|
||||
self.response_middleware,
|
||||
self.named_response_middleware.get(route.name, deque()),
|
||||
location=MiddlewareLocation.RESPONSE,
|
||||
)
|
||||
route.extra.request_middleware = deque(
|
||||
sorted(
|
||||
request_middleware,
|
||||
key=attrgetter("order"),
|
||||
reverse=True,
|
||||
)
|
||||
)
|
||||
route.extra.response_middleware = deque(
|
||||
sorted(
|
||||
response_middleware,
|
||||
key=attrgetter("order"),
|
||||
reverse=True,
|
||||
)[::-1]
|
||||
)
|
||||
request_middleware = Middleware.convert(
|
||||
self.request_middleware,
|
||||
location=MiddlewareLocation.REQUEST,
|
||||
)
|
||||
response_middleware = Middleware.convert(
|
||||
self.response_middleware,
|
||||
location=MiddlewareLocation.RESPONSE,
|
||||
)
|
||||
self.request_middleware = deque(
|
||||
sorted(
|
||||
request_middleware,
|
||||
key=attrgetter("order"),
|
||||
reverse=True,
|
||||
)
|
||||
)
|
||||
self.response_middleware = deque(
|
||||
sorted(
|
||||
response_middleware,
|
||||
key=attrgetter("order"),
|
||||
reverse=True,
|
||||
)[::-1]
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user