def __new__(cls, *args, **kwargs):
     # making a bold assumption here.
     # Assuming that if a sanic plugin is initialized using
     # `MyPlugin(app)`, then the user is attempting to do a legacy plugin
     # instantiation, aka Flask-Style plugin instantiation.
     if args and len(args) > 0 and \
             (isinstance(args[0], Sanic) or isinstance(args[0], Blueprint)):
         app = args[0]
         try:
             mod_name = cls.__module__
             mod = importlib.import_module(mod_name)
             assert mod
         except (ImportError, AssertionError):
             raise RuntimeError(
                 "Failed attempting a legacy plugin instantiation. "
                 "Cannot find the module this plugin belongs to.")
         # Get the spf singleton from this app
         from spf.framework import SanicPluginsFramework
         spf = SanicPluginsFramework(app)
         # catch cases like when the module is "__main__" or
         # "__call__" or "__init__"
         if mod_name.startswith("__"):
             # In this case, we cannot use the module to register the
             # plugin. Try to use the class method.
             assoc = spf.register_plugin(cls, *args, **kwargs)
         else:
             assoc = spf.register_plugin(mod, *args, **kwargs)
         return assoc
     self = super(SanicPlugin, cls).__new__(cls)
     try:
         self._initialized  # initialized may be True or Unknown
     except AttributeError:
         self._initialized = False
     return self
    def decorate(cls,
                 app,
                 *args,
                 run_middleware=False,
                 with_context=False,
                 **kwargs):
        """
        This is a decorator that can be used to apply this plugin to a specific
        route/view on your app, rather than the whole app.
        :param app:
        :type app: Sanic | Blueprint
        :param args:
        :type args: tuple(Any)
        :param run_middleware:
        :type run_middleware: bool
        :param with_context:
        :type with_context: bool
        :param kwargs:
        :param kwargs: dict(Any)
        :return: the decorated route/view
        :rtype: fn
        """
        from spf.framework import SanicPluginsFramework
        spf = SanicPluginsFramework(app)  # get the singleton from the app
        try:
            assoc = spf.register_plugin(cls, skip_reg=True)
        except ValueError as e:
            # this is normal, if this plugin has been registered previously
            assert e.args and len(e.args) > 1
            assoc = e.args[1]
        (plugin, reg) = assoc
        inst = spf.get_plugin(plugin)  # plugin may not actually be registered
        # registered might be True, False or None at this point
        regd = True if inst else None
        if regd is True:
            # middleware will be run on this route anyway, because the plugin
            # is registered on the app. Turn it off on the route-level.
            run_middleware = False
        req_middleware = deque()
        resp_middleware = deque()
        if run_middleware:
            for i, m in enumerate(plugin._middlewares):
                attach_to = m.kwargs.pop('attach_to', 'request')
                priority = m.kwargs.pop('priority', 5)
                with_context = m.kwargs.pop('with_context', False)
                mw_handle_fn = m.middleware
                if attach_to == 'response':
                    relative = m.kwargs.pop('relative', 'post')
                    if relative == "pre":
                        mw = (0, 0 - priority, 0 - i, mw_handle_fn,
                              with_context, m.args, m.kwargs)
                    else:  # relative = "post"
                        mw = (1, 0 - priority, 0 - i, mw_handle_fn,
                              with_context, m.args, m.kwargs)
                    resp_middleware.append(mw)
                else:  # attach_to = "request"
                    relative = m.kwargs.pop('relative', 'pre')
                    if relative == "post":
                        mw = (1, priority, i, mw_handle_fn, with_context,
                              m.args, m.kwargs)
                    else:  # relative = "pre"
                        mw = (0, priority, i, mw_handle_fn, with_context,
                              m.args, m.kwargs)
                    req_middleware.append(mw)

        req_middleware = tuple(sorted(req_middleware))
        resp_middleware = tuple(sorted(resp_middleware))

        def _decorator(f):
            nonlocal spf, plugin, regd, run_middleware, with_context
            nonlocal req_middleware, resp_middleware, args, kwargs

            async def wrapper(request, *a, **kw):
                nonlocal spf, plugin, regd, run_middleware, with_context
                nonlocal req_middleware, resp_middleware, f, args, kwargs
                # the plugin was not registered on the app, it might be now
                if regd is None:
                    _inst = spf.get_plugin(plugin)
                    regd = _inst is not None

                context = plugin.get_context_from_spf(spf)
                if run_middleware and not regd and len(req_middleware) > 0:
                    for (_a, _p, _i, handler, with_context, args, kwargs) \
                            in req_middleware:
                        if with_context:
                            resp = handler(request,
                                           *args,
                                           context=context,
                                           **kwargs)
                        else:
                            resp = handler(request, *args, **kwargs)
                        if isawaitable(resp):
                            resp = await resp
                        if resp:
                            return

                response = await plugin.route_wrapper(
                    f,
                    request,
                    context,
                    a,
                    kw,
                    *args,
                    with_context=with_context,
                    **kwargs)
                if isawaitable(response):
                    response = await response
                if run_middleware and not regd and len(resp_middleware) > 0:
                    for (_a, _p, _i, handler, with_context, args, kwargs) \
                            in resp_middleware:
                        if with_context:
                            _resp = handler(request,
                                            response,
                                            *args,
                                            context=context,
                                            **kwargs)
                        else:
                            _resp = handler(request, response, *args, **kwargs)
                        if isawaitable(_resp):
                            _resp = await _resp
                        if _resp:
                            response = _resp
                            break
                return response

            return update_wrapper(wrapper, f)

        return _decorator