Exemple #1
0
    def get_resource_args(cls,
                          app,
                          resource,
                          request_method,
                          content_type,
                          resource_method=None,
                          include_defaults=False):
        """Get config args for resource, method, & content type.

        This fetches the args for a resource, method, and content type
        from the app registry. Those args can then be used to construct
        a :class:`Config` instance.

        By default, only args for the specified content type will be
        included.

        .. note:: This is intended primarily for internal use.

        """
        resource_cls = resource.__class__
        resource_method = resource_method or request_method
        resource_method = getattr(resource_cls, resource_method)
        cls_name = fully_qualified_name(resource_cls)
        meth_name = fully_qualified_name(resource_method)
        kwargs = {}
        if include_defaults:
            kwargs.update(app.get(config, (cls_name, '*/*'), default={}))
        kwargs.update(app.get(config, (cls_name, content_type), default={}))
        if include_defaults:
            kwargs.update(app.get(config, (meth_name, '*/*'), default={}))
        kwargs.update(app.get(config, (meth_name, content_type), default={}))
        return kwargs
Exemple #2
0
    def get_resource_args(cls, app, resource, request_method, content_type, resource_method=None,
                          include_defaults=False):
        """Get config args for resource, method, & content type.

        This fetches the args for a resource, method, and content type
        from the app registry. Those args can then be used to construct
        a :class:`Config` instance.

        By default, only args for the specified content type will be
        included.

        .. note:: This is intended primarily for internal use.

        """
        resource_cls = resource.__class__
        resource_method = resource_method or request_method
        resource_method = getattr(resource_cls, resource_method)
        cls_name = fully_qualified_name(resource_cls)
        meth_name = fully_qualified_name(resource_method)
        kwargs = {}
        if include_defaults:
            kwargs.update(app.get(config, (cls_name, '*/*'), default={}))
        kwargs.update(app.get(config, (cls_name, content_type), default={}))
        if include_defaults:
            kwargs.update(app.get(config, (meth_name, '*/*'), default={}))
        kwargs.update(app.get(config, (meth_name, content_type), default={}))
        return kwargs
Exemple #3
0
def register_action(wrapped, action, tag=None, _registry=_ACTION_REGISTRY):
    """Register a deferred decorator action.

    The action will be performed later when :func:`fire_actions` is
    called with the specified ``tag``.

    This is used like so::

        # mymodule.py

        def my_decorator(wrapped):
            def action(some_arg):
                # do something with some_arg
            register_action(wrapped, action, tag='x')
            return wrapped  # <-- IMPORTANT

        @my_decorator
        def my_func():
            # do some stuff

    Later, :func:`fire_actions` can be called to run ``action``::

        fire_actions(mymodule, tags='x', args=('some arg'))

    """
    _registry.setdefault(tag, {})
    fq_name = fully_qualified_name(wrapped)
    actions = _registry[tag].setdefault(fq_name, [])
    actions.append(action)
Exemple #4
0
    def run(self):
        if self.args.reload and not os.environ.get('MONITOR'):
            return self.run_with_monitor()

        print('[{}]'.format(datetime.datetime.now()))
        factory_name = fully_qualified_name(self.args.app_factory)
        print('Creating app from {} factory'.format(factory_name))
        app = self.make_app()

        server = None
        try:
            message = 'Starting server on http://{0.host}:{0.port}/'
            server = make_server(self.args.host, self.args.port, app)
            if self.args.reload:
                message += ' with file monitor'
                reload_interval = self.args.reload_interval
                monitor_thread = MonitorThread(server, reload_interval)
                monitor_thread.start()
            message += '...'
            print(message.format(self.args))
            server.serve_forever()  # Blocks until server.shutdown()
        except KeyboardInterrupt:
            print('\rAborted')
        except:
            traceback.print_exc()
            self.exit('\nCould not start server', 2)
        finally:
            if server is not None:
                server.shutdown()
                server.server_close()
Exemple #5
0
    def run(self):
        reload = self.args.reload

        if reload and not os.environ.get('MONITOR'):
            return self.run_with_monitor()

        print('[{}]'.format(datetime.datetime.now()))
        factory_name = fully_qualified_name(self.args.app_factory)
        print('Creating app from {} factory'.format(factory_name))
        app = self.make_app()

        server = None
        try:
            message = 'Starting server on http://{0.host}:{0.port}/'
            server = make_server(self.args.host, self.args.port, app)
            if reload:
                message += ' with file monitor'
                reload_interval = self.args.reload_interval
                monitor_thread = MonitorThread(server, reload_interval)
                monitor_thread.start()
            message += '...'
            print(message.format(self.args))
            server.serve_forever()  # Blocks until server.shutdown()
        except KeyboardInterrupt:
            print()
        except Exception:
            traceback.print_exc()
            print('\nCould not start server')
            return 2
        finally:
            if server is not None:
                server.shutdown()
                server.server_close()
Exemple #6
0
def register_action(wrapped, action, tag=None, _registry=_ACTION_REGISTRY):
    """Register a deferred decorator action.

    The action will be performed later when :func:`fire_actions` is
    called with the specified ``tag``.

    This is used like so::

        # mymodule.py

        def my_decorator(wrapped):
            def action(some_arg):
                # do something with some_arg
            register_action(wrapped, action, tag='x')
            return wrapped  # <-- IMPORTANT

        @my_decorator
        def my_func():
            # do some stuff

    Later, :func:`fire_actions` can be called to run ``action``::

        fire_actions(mymodule, tags='x', args=('some arg'))

    """
    _registry.setdefault(tag, {})
    fq_name = fully_qualified_name(wrapped)
    actions = _registry[tag].setdefault(fq_name, [])
    actions.append(action)
Exemple #7
0
    def for_resource(cls, app, resource, request_method, content_type,
                     resource_method=None):
        """Get :class:`Config` for resource, method, & content type.

        This collects all the relevant config set via ``@config`` and
        combines it with the default config. Default config is set when
        ``@config`` args are added via :meth:`add_config_field` and
        :meth:`add_representation_arg`.

        Returns an info structure populated with class level defaults
        for */* plus method level info for ``content_type``.

        If the resource method name differs from the request method
        name, pass ``resource_method`` so the method level config can be
        found.

        Typically, this wouldn't be used directly; usually
        :meth:`Request.resource_config` would be used to get the
        info for the resource associated with the current request.

        """
        resource_cls = resource.__class__
        resource_method = resource_method or request_method
        resource_method = getattr(resource_cls, resource_method)
        cls_name = fully_qualified_name(resource_cls)
        meth_name = fully_qualified_name(resource_method)
        data = [app.get(config, (cls_name, '*/*'))]
        if content_type != '*/*':
            data.append(app.get(config, (cls_name, content_type)))
        data.append(app.get(config, (meth_name, '*/*')))
        if content_type != '*/*':
            data.append(app.get(config, (meth_name, content_type)))
        kwargs = {}
        for d in data:
            if d:
                kwargs.update(d)
        return cls(app, request_method, content_type, **kwargs)
Exemple #8
0
        def action(app):
            # This is here so the app won't start if any of the args
            # passed to @config are invalid. Otherwise, the invalid args
            # wouldn't be detected until a request is made to a resource
            # that was decorated with invalid args. NOTE: We can't check
            # *everything* pre-emptively here, but we do what we can.
            if isinstance(wrapped, type):
                Config(app, 'GET', content_type, **kwargs)
            elif wrapped.__name__ in ALL_HTTP_METHODS:
                Config(app, wrapped.__name__, content_type, **kwargs)

            differentiator = fully_qualified_name(wrapped), content_type
            if app.contains(config, differentiator):
                app.get(config, differentiator).update(kwargs)
            else:
                app.register(config, kwargs, differentiator)
Exemple #9
0
        def action(app):
            # This is here so the app won't start if any of the args
            # passed to @config are invalid. Otherwise, the invalid args
            # wouldn't be detected until a request is made to a resource
            # that was decorated with invalid args. NOTE: We can't check
            # *everything* pre-emptively here, but we do what we can.
            if isinstance(wrapped, type):
                Config(app, 'GET', content_type, **kwargs)
            elif wrapped.__name__ in ALL_HTTP_METHODS:
                Config(app, wrapped.__name__, content_type, **kwargs)

            differentiator = fully_qualified_name(wrapped), content_type
            if app.contains(config, differentiator):
                app.get(config, differentiator).update(kwargs)
            else:
                app.register(config, kwargs, differentiator)
Exemple #10
0
def fire_actions(where,
                 tags=(),
                 args=(),
                 kwargs=None,
                 _registry=_ACTION_REGISTRY):
    """Fire actions previously registered via :func:`register_action`.

    ``where`` is typically a package or module. Only actions registered
    in that package or module will be fired.

    ``where`` can also be some other type of object, such as a class, in
    which case only the actions registered on the class and its methods
    will be fired. Currently, this is considered non-standard usage, but
    it's useful for testing.

    If no ``tags`` are specified, all registered actions under ``where``
    will be fired.

    ``*args`` and ``**kwargs`` will be passed to each action that is
    fired.

    """
    where = load_object(where)
    where_fq_name = fully_qualified_name(where)
    tags = (tags, ) if isinstance(tags, str) else tags
    kwargs = {} if kwargs is None else kwargs

    if hasattr(where, '__path__'):
        # Load all modules in package
        path = where.__path__
        prefix = where.__name__ + '.'
        for (_, name, is_pkg) in pkgutil.walk_packages(path, prefix):
            if name not in sys.modules:
                __import__(name)

    tags = _registry.keys() if not tags else tags

    for tag in tags:
        tag_actions = _registry[tag]
        for fq_name, wrapped_actions in tag_actions.items():
            if fq_name.startswith(where_fq_name):
                for action in wrapped_actions:
                    action(*args, **kwargs)
Exemple #11
0
def fire_actions(where, tags=(), args=(), kwargs=None,
                 _registry=_ACTION_REGISTRY):
    """Fire actions previously registered via :func:`register_action`.

    ``where`` is typically a package or module. Only actions registered
    in that package or module will be fired.

    ``where`` can also be some other type of object, such as a class, in
    which case only the actions registered on the class and its methods
    will be fired. Currently, this is considered non-standard usage, but
    it's useful for testing.

    If no ``tags`` are specified, all registered actions under ``where``
    will be fired.

    ``*args`` and ``**kwargs`` will be passed to each action that is
    fired.

    """
    where = load_object(where)
    where_fq_name = fully_qualified_name(where)
    tags = (tags,) if isinstance(tags, str) else tags
    kwargs = {} if kwargs is None else kwargs

    if hasattr(where, '__path__'):
        # Load all modules in package
        path = where.__path__
        prefix = where.__name__ + '.'
        for (_, name, is_pkg) in pkgutil.walk_packages(path, prefix):
            if name not in sys.modules:
                __import__(name)

    tags = _registry.keys() if not tags else tags

    for tag in tags:
        tag_actions = _registry[tag]
        for fq_name, wrapped_actions in tag_actions.items():
            if fq_name.startswith(where_fq_name):
                for action in wrapped_actions:
                    action(*args, **kwargs)