def create_temporary_request_context(self, request): request_hash = id(request) shared_context = self.shared_context shared_requests_dict = shared_context.get('request', False) if not shared_requests_dict: new_ctx = SanicContext(self, None, {'id': 'shared request contexts'}) shared_context['request'] = shared_requests_dict = new_ctx shared_request_ctx = shared_requests_dict.get(request_hash, None) if shared_request_ctx: # Somehow, we've already created a temporary context for this request. return shared_request_ctx shared_requests_dict[request_hash] = shared_request_ctx = SanicContext( self, None, {'request': request, 'id': "shared request context for request {}".format(id(request))} ) for name, _p in self._plugins_context.items(): if not (isinstance(_p, SanicContext) and 'instance' in _p and isinstance(_p['instance'], SanicPlugin)): continue if not ('context' in _p and isinstance(_p['context'], SanicContext)): continue _p_context = _p['context'] if 'request' not in _p_context: _p_context['request'] = p_request = SanicContext(self, None, {'id': 'private request contexts'}) else: p_request = _p_context.request p_request[request_hash] = SanicContext( self, None, {'request': request, 'id': "private request context for {} on request {}".format(name, id(request))}, ) return shared_request_ctx
def test_context_get_private_from_slots(realm): context = SanicContext(realm, None) context.set("t1", "hello world") d = context.__getattr__('_dict') d2 = getattr(context, '_dict') assert isinstance(d, dict) assert "t1" in d assert d == d2
def test_context_update(realm): context = SanicContext(realm, None) child_context = context.create_child_context() context['t1'] = "hello world" child_context['t2'] = "hello2" assert child_context['t1'] == "hello world" child_context.update({'t1': "test1", 't2': "test2"}) assert context['t1'] == "test1" assert child_context['t2'] == "test2"
def test_context_replace(realm): context = SanicContext(realm, None) child_context = context.create_child_context() context['t1'] = "hello world" assert child_context['t1'] == "hello world" child_context['t1'] = "goodbye world" assert context['t1'] != "goodbye world" del (child_context['t1']) child_context.replace('t1', 'goodbye world') assert context['t1'] == "goodbye world"
def test_context_pickle(realm): context = SanicContext(realm, None) child_context = context.create_child_context() child_context['t1'] = "hello world" p_bytes = pickle.dumps(child_context) un_p = pickle.loads(p_bytes) # the sanic_plugin_toolkit and the parent context are not the same as before, because # their state got pickled and unpicked too assert un_p._stk_realm != realm assert un_p._parent_hd != context assert un_p['t1'] == "hello world"
def test_context_items_keys_values(realm): context = SanicContext(realm, None) context["t1"] = "hello world" context["t2"] = "hello 2" items = context.items() assert len(items) == 2 keys = context.keys() assert len(keys) == 2 assert "t1" in list(keys) vals = context.values() assert len(vals) == 2 assert "hello world" in list(vals)
def _recreate(cls, app): self = super(SanicPluginRealm, cls).__new__(cls) self._running = False self._app = app self._loop = None self._plugin_names = set() # these deques get replaced with frozen tuples at runtime self._pre_request_middleware = deque() self._post_request_middleware = deque() self._pre_response_middleware = deque() self._post_response_middleware = deque() self._cleanup_middleware = deque() self._contexts = SanicContext(self, None) self._contexts['shared'] = SanicContext(self, None, {'app': app}) self._contexts['_plugins'] = SanicContext(self, None, {'sanic_plugin_toolkit': self}) return self
def test_recursive_dict(realm): context = SanicContext(realm, None) context['t1'] = "hello world" c2 = context.create_child_context() c2['t2'] = "hello 2" c3 = c2.create_child_context() c3['t3'] = "hello 3" context._parent_hd = c3 # This is dodgy, why would anyone do this? exceptions = [] try: _ = c2['t4'] except RuntimeError as e: assert len(e.args) > 0 assert "recursive" in str(e.args[0]).lower() exceptions.append(e) finally: assert len(exceptions) == 1
def test_context_set_contains_get(realm): context = SanicContext(realm, None) context.set("t1", "hello world") assert "t1" in context assert context.get("t1") == "hello world" exceptions = [] try: context.set("__weakref__", set()) except ValueError as e: exceptions.append(e) finally: assert len(exceptions) > 0
def test_context_del(realm): context = SanicContext(realm, None) context.set(1, "1") context.set(2, "2") context.set(3, "3") context.set(4, "4") del context[1] one = context.get(1, None) assert one is None exceptions = [] try: #TODO: How do you even delete a slice? del context[2:4] except Exception as e: exceptions.append(e) finally: assert len(exceptions) > 0
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 Realm 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_in_realm(self): raise RuntimeError( "Plugin already shows it is registered to this " "sanic_plugin_toolkit, 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(realm=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, _realm=self, _plugin_name=name, **kwargs) _plugin_reg['instance'] = plugin _plugin_reg['reg'] = reg return associated_tuple(plugin, reg)
def test_context_str(realm): context = SanicContext(realm, None) context['t1'] = "hello world" s1 = str(context) assert s1 == "SanicContext({'t1': 'hello world'})"