def _register_helper(plugin, context, *args, _spf=None, _plugin_name=None, _url_prefix=None, **kwargs): error_str = "Plugin must be initialised using the " \ "Sanic Plugins Framework" assert _spf is not None, error_str assert _plugin_name is not None, error_str _app = _spf._app assert _app is not None, error_str reg = PluginRegistration(spf=_spf, plugin_name=_plugin_name, url_prefix=_url_prefix) context['log'] = partial(_spf.log, reg=reg) context['url_for'] = partial(_spf.url_for, reg=reg) continue_flag = plugin.on_before_registered(context, *args, **kwargs) if continue_flag is False: return plugin # Routes for r in plugin._routes: # attach the plugin name to the handler so that it can be # prefixed properly in the router if isinstance(_app, Blueprint): # blueprint always handles adding __blueprintname__ # So we identify ourselves here a different way. handler_name = r.handler.__name__ r.handler.__name__ = "{}.{}".format(_plugin_name, handler_name) else: r.handler.__blueprintname__ = _plugin_name # Prepend the plugin URI prefix if available uri = _url_prefix + r.uri if _url_prefix else r.uri _spf._plugin_register_route( r.handler, plugin, context, uri[1:] if uri.startswith('//') else uri, *r.args, **r.kwargs) # Middleware for m in plugin._middlewares: _spf._plugin_register_middleware(m.middleware, plugin, context, *m.args, **m.kwargs) # Exceptions for e in plugin._exceptions: _spf._plugin_register_exception(e.handler, plugin, context, *e.exceptions, **e.kwargs) # Listeners for event, listeners in plugin._listeners.items(): for listener in listeners: _spf._plugin_register_listener(event, listener, plugin) # # this should only ever run once! plugin.registrations.add(reg) plugin.on_registered(context, reg, *args, **kwargs) return reg
def _register_helper(plugin, context, *args, _spf=None, _plugin_name=None, _url_prefix=None, **kwargs): error_str = "Plugin must be initialised using the " \ "Sanic Plugins Framework." assert _spf is not None, error_str assert _plugin_name is not None, error_str _app = _spf._app assert _app is not None, error_str reg = PluginRegistration(spf=_spf, plugin_name=_plugin_name, url_prefix=_url_prefix) context['log'] = partial(_spf.log, reg=reg) context['url_for'] = partial(_spf.url_for, reg=reg) continue_flag = plugin.on_before_registered(context, *args, **kwargs) if continue_flag is False: return plugin # Routes [_spf._register_route_helper(r, _spf, plugin, context, _plugin_name, _url_prefix) for r in plugin._routes] # Websocket routes [_spf._register_websocket_route_helper(w, _spf, plugin, context, _plugin_name, _url_prefix) for w in plugin._ws] # Static routes [_spf._register_static_helper(s, _spf, plugin, context, _plugin_name, _url_prefix) for s in plugin._static] # Middleware [_spf._register_middleware_helper(m, _spf, plugin, context) for m in plugin._middlewares] # Exceptions for e in plugin._exceptions: _spf._plugin_register_exception( e.handler, plugin, context, *e.exceptions, **e.kwargs) # Listeners for event, listeners in plugin._listeners.items(): for listener in listeners: if isinstance(listener, tuple): listener, kwargs = listener _spf._plugin_register_listener( event, listener, plugin, context, **kwargs) # # this should only ever run once! plugin.registrations.add(reg) plugin.on_registered(context, reg, *args, **kwargs) return reg
def register_plugin(self, plugin, *args, name=None, skip_reg=False, **kwargs): assert not self._running, "Cannot add, remove, or change plugins " \ "after the App has started serving." assert plugin, "Plugin must be a valid type! Do not pass in `None` " \ "or `False`" if isinstance(plugin, type): # We got passed in a Class. That's ok, we can handle this! module_name = getattr(plugin, '__module__') class_name = getattr(plugin, '__name__') lower_class = to_snake_case(class_name) try: mod = importlib.import_module(module_name) try: plugin = getattr(mod, lower_class) except AttributeError: plugin = mod # try the module-based resolution next except ImportError: raise if ismodule(plugin): # We got passed in a module. That's ok, we can handle this! try: # look for '.instance' on the module plugin = getattr(plugin, 'instance') assert plugin is not None except (AttributeError, AssertionError): # now look for the same name, # like my_module.my_module on the module. try: plugin_module_name = getattr(plugin, '__name__') assert plugin_module_name and len(plugin_module_name) > 0 plugin_module_name = plugin_module_name.split('.')[-1] plugin = getattr(plugin, plugin_module_name) assert plugin is not None except (AttributeError, AssertionError): raise RuntimeError( "Cannot import this module as a Sanic Plugin.") assert isinstance(plugin, SanicPlugin),\ "Plugin must be derived from SanicPlugin" if name is None: try: name = str(plugin.__class__.__name__) assert name is not None except (AttributeError, AssertionError, ValueError, KeyError): logger.warning( "Cannot determine a name for {}, using UUID." .format(repr(plugin))) name = str(uuid1(None, None)) assert isinstance(name, str), \ "Plugin name must be a python unicode string!" associated_tuple = plugin.AssociatedTuple if name in self._plugin_names: # we're already registered on this SPF reg = plugin.find_plugin_registration(self) assoc = associated_tuple(plugin, reg) raise ValueError( "Plugin {:s} is already registered!".format(name), assoc) if plugin.is_registered_on_framework(self): raise RuntimeError("Plugin already shows it is registered to this " "spf, maybe under a different name?") self._plugin_names.add(name) shared_context = self.shared_context self._contexts[name] = context = SanicContext( self, shared_context, {'shared': shared_context}) _p_context = self._plugins_context _plugin_reg = _p_context.get(name, None) if _plugin_reg is None: _p_context[name] = _plugin_reg = _p_context.create_child_context() _plugin_reg['name'] = name _plugin_reg['context'] = context if skip_reg: dummy_reg = PluginRegistration(spf=self, plugin_name=name, url_prefix=None) context['log'] = partial(self.log, reg=dummy_reg) context['url_for'] = partial(self.url_for, reg=dummy_reg) plugin.registrations.add(dummy_reg) # This indicates the plugin is not registered on the app _plugin_reg['instance'] = None _plugin_reg['reg'] = None return associated_tuple(plugin, dummy_reg) if _plugin_reg.get('instance', False): raise RuntimeError("The plugin we are trying to register already " "has a known instance!") reg = self._register_helper(plugin, context, *args, _spf=self, _plugin_name=name, **kwargs) _plugin_reg['instance'] = plugin _plugin_reg['reg'] = reg return associated_tuple(plugin, reg)