Finish moving some more logic to mixins

This commit is contained in:
Adam Hopkins
2021-01-27 15:57:21 +02:00
parent dadf76ce72
commit e9459792a4
9 changed files with 157 additions and 88 deletions

View File

@@ -0,0 +1,38 @@
from enum import Enum, auto
from functools import partial
from typing import Set
from sanic.models.futures import FutureException
class ExceptionMixin:
def __init__(self, *args, **kwargs) -> None:
self._future_exceptions: Set[FutureException] = set()
def _apply_exception_handler(self, handler: FutureException):
raise NotImplementedError
def exception(self, *exceptions, apply=True):
"""
This method enables the process of creating a global exception
handler for the current blueprint under question.
:param args: List of Python exceptions to be caught by the handler
:param kwargs: Additional optional arguments to be passed to the
exception handler
:return a decorated method to handle global exceptions for any
route registered under this blueprint.
"""
def decorator(handler):
nonlocal apply
nonlocal exceptions
future_exception = FutureException(handler, exceptions)
self._future_exceptions.add(future_exception)
if apply:
self._apply_exception_handler(future_exception)
return handler
return decorator

55
sanic/mixins/listeners.py Normal file
View File

@@ -0,0 +1,55 @@
from enum import Enum, auto
from functools import partial
from typing import Set
from sanic.models.futures import FutureListener
class ListenerEvent(str, Enum):
def _generate_next_value_(name: str, *args) -> str: # type: ignore
return name.lower()
BEFORE_SERVER_START = auto()
AFTER_SERVER_START = auto()
BEFORE_SERVER_STOP = auto()
AFTER_SERVER_STOP = auto()
class ListenerMixin:
def __init__(self, *args, **kwargs) -> None:
self._future_listeners: Set[FutureListener] = set()
def _apply_listener(self, listener: FutureListener):
raise NotImplementedError
def listener(self, listener_or_event, event_or_none=None, apply=True):
"""Create a listener from a decorated function.
:param event: Event to listen to.
"""
def register_listener(listener, event):
nonlocal apply
future_listener = FutureListener(listener, event)
self._future_listeners.add(future_listener)
if apply:
self._apply_listener(future_listener)
return listener
if callable(listener_or_event):
return register_listener(listener_or_event, event_or_none)
else:
return partial(register_listener, event=listener_or_event)
def before_server_start(self, listener):
return self.listener(listener, "before_server_start")
def after_server_start(self, listener):
return self.listener(listener, "after_server_start")
def before_server_stop(self, listener):
return self.listener(listener, "before_server_stop")
def after_server_stop(self, listener):
return self.listener(listener, "after_server_stop")

View File

@@ -23,12 +23,14 @@ class MiddlewareMixin:
identifying which type of middleware is being registered.
"""
def register_middleware(_middleware, attach_to="request"):
future_middleware = FutureMiddleware(_middleware, attach_to)
def register_middleware(middleware, attach_to="request"):
nonlocal apply
future_middleware = FutureMiddleware(middleware, attach_to)
self._future_middleware.add(future_middleware)
if apply:
self._apply_middleware(future_middleware)
return _middleware
return middleware
# Detect which way this was called, @middleware or @middleware('AT')
if callable(middleware_or_request):
@@ -39,3 +41,9 @@ class MiddlewareMixin:
return partial(
register_middleware, attach_to=middleware_or_request
)
def on_request(self, middleware):
return self.middleware(middleware, "request")
def on_response(self, middleware):
return self.middleware(middleware, "response")

View File

@@ -1,9 +1,7 @@
from functools import partial
from inspect import signature
from pathlib import PurePath
from typing import List, Set, Union
import websockets
from typing import Set, Union
from sanic_routing.route import Route