예제 #1
0
 def create_temporary_request_context(self, request):
     request_hash = id(request)
     new_ctx = ContextDict(self, None, {'id': 'shared request contexts'})
     shared_context = self.shared_context
     shared_request = shared_context.get('request', False)
     if not shared_request:
         shared_context['request'] = shared_request = new_ctx
     shared_request[request_hash] =\
         ContextDict(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, ContextDict) and 'instance' in _p
                 and isinstance(_p['instance'], SanicPlugin)):
             continue
         if not ('context' in _p
                 and isinstance(_p['context'], ContextDict)):
             continue
         _p_context = _p['context']
         if 'request' not in _p_context:
             _p_context['request'] = p_request = ContextDict(
                 self, None, {'id': 'private request contexts'})
         else:
             p_request = _p_context.request
         p_request[request_hash] =\
             ContextDict(self, None, {'request': request,
                 'id': "private request context for {} on request {}"
                       .format(name, id(request))})
def test_context_get_private_from_slots(spf):
    context = ContextDict(spf, 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(spf):
    context = ContextDict(spf, 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(spf):
    context = ContextDict(spf, 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(spf):
    context = ContextDict(spf, 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 spf and the parent context are not the same as before, because
    # their state got pickled and unpicked too
    assert un_p._spf != spf
    assert un_p._parent_context != context
    assert un_p['t1'] == "hello world"
def test_context_items_keys_values(spf):
    context = ContextDict(spf, 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)
예제 #7
0
 def _recreate(cls, app):
     self = super(SanicPluginsFramework, 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._contexts = ContextDict(self, None)
     self._contexts['shared'] = ContextDict(self, None, {'app': app})
     self._contexts['_plugins'] = ContextDict(self, None, {'spf': self})
     return self
def test_recursive_dict(spf):
    context = ContextDict(spf, 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_context = 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
예제 #9
0
 def __new__(cls, app, *args, **kwargs):
     assert app, "SPF must be given a valid Sanic App to work with."
     assert isinstance(app, Sanic) or isinstance(app, Blueprint),\
         "SPF only works with Sanic Apps or Blueprints. " \
         "Please pass in an app instance to the SPF constructor."
     # An app _must_ only have one spf instance associated with it.
     # If there is already one registered on the app, return that one.
     try:
         instance = app.config[APP_CONFIG_KEY]
         assert isinstance(instance, cls),\
             "This app is already registered to a different type of " \
             "Sanic Plugins Framework!"
         return instance
     except AttributeError:  # app must then be a blueprint
         try:
             instance = getattr(app, APP_CONFIG_KEY)
             assert isinstance(instance, cls),\
                 "This Blueprint is already registered to a different " \
                 "type of Sanic Plugins Framework!"
             return instance
         except AttributeError:
             pass
     except KeyError:
         pass
     self = super(SanicPluginsFramework, cls).__new__(cls)
     self._running = False
     self._app = app
     self._logger = logging.getLogger(__name__)
     self._plugin_names = set()
     # these PQs get replaced with frozen tuples at runtime
     self._pre_request_middleware = PriorityQueue()
     self._post_request_middleware = PriorityQueue()
     self._pre_response_middleware = PriorityQueue()
     self._post_response_middleware = PriorityQueue()
     self._contexts = ContextDict(self, None)
     self._contexts['shared'] = ContextDict(self, None, {'app': app})
     self._contexts['_plugins'] = ContextDict(self, None, {'spf': self})
     if isinstance(app, Blueprint):
         self._patch_blueprint(app)
     else:
         self._patch_app(app)
     return self
예제 #10
0
 def create_temporary_request_context(self, request):
     request_hash = id(request)
     new_ctx = ContextDict(self, None, {})
     shared_context = self.shared_context
     shared_request = shared_context.get('request', False)
     if not shared_request:
         shared_context['request'] = shared_request = new_ctx
     shared_request[request_hash] =\
         ContextDict(self, None, {'request': request})
     for name, _p in self._plugins_context.items():
         if isinstance(_p, ContextDict) and 'instance' in _p \
                 and isinstance(_p['instance'], SanicPlugin):
             if 'context' in _p and isinstance(_p['context'], ContextDict):
                 _p_context = _p['context']
                 p_request = _p_context.get('request', False)
                 if not p_request:
                     _p_context['request'] = p_request = ContextDict(
                         self, None, {})
                 p_request[request_hash] =\
                     ContextDict(self, None, {'request': request})
예제 #11
0
def test_context_set_contains_get(spf):
    context = ContextDict(spf, 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
예제 #12
0
def test_context_del(spf):
    context = ContextDict(spf, 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
예제 #13
0
def test_context_repr(spf):
    context = ContextDict(spf, None)
    context['t1'] = "hello world"
    s1 = repr(context)
    assert s1 == "ContextDict({'t1': 'hello world'})"
예제 #14
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 = mod.getattr(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):
                self._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.")
        self._plugin_names.add(name)
        shared_context = self.shared_context
        self._contexts[name] = context = ContextDict(
            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)