Example #1
0
    def __new__(mcs, name, bases, params):
        """Prepare a Handler Class.

        Ensure that the Handler class has a name.
        Ensure that required methods are coroutines.
        Fix the Handler params.
        """
        # Set name
        params['name'] = params.get('name', name.lower())

        # Define new coroutines
        for fname, method in params.items():
            if callable(method) and hasattr(method, '_abcoroutine'):
                mcs._coroutines.add(fname)

        cls = super(HandlerMeta, mcs).__new__(mcs, name, bases, params)

        # Ensure that the class methods are exist and iterable
        if not cls.methods:
            cls.methods = set(method for method in HTTP_METHODS if method.lower() in cls.__dict__)

        elif isinstance(cls.methods, str):
            cls.methods = [cls.methods]

        cls.methods = [method.upper() for method in cls.methods]

        # Ensure that coroutine methods is coroutines
        for name in mcs._coroutines:
            method = getattr(cls, name, None)
            if not method:
                continue
            setattr(cls, name, to_coroutine(method))

        return cls
Example #2
0
 def wrapper(method):
     """Store route params into method."""
     method = to_coroutine(method)
     setattr(method, ROUTE_PARAMS_ATTR, (paths, methods, name))
     if handler and not hasattr(handler, method.__name__):
         setattr(handler, method.__name__, method)
     return method
Example #3
0
 def wrapper(method):
     """Store route params into method."""
     method = to_coroutine(method)
     setattr(method, ROUTE_PARAMS_ATTR, (paths, methods, name))
     if handler and not hasattr(handler, method.__name__):
         setattr(handler, method.__name__, method)
     return method
Example #4
0
    def __new__(mcs, name, bases, params):
        """Prepare a Handler Class.

        Ensure that the Handler class has a name.
        Ensure that required methods are coroutines.
        Fix the Handler params.
        """
        # Set name
        params['name'] = params.get('name', name.lower())

        # Define new coroutines
        for fname, method in params.items():
            if callable(method) and hasattr(method, '_abcoroutine'):
                mcs._coroutines.add(fname)

        cls = super(HandlerMeta, mcs).__new__(mcs, name, bases, params)

        # Ensure that the class methods are exist and iterable
        if not cls.methods:
            cls.methods = set(method for method in HTTP_METHODS
                              if method.lower() in cls.__dict__)

        elif isinstance(cls.methods, str):
            cls.methods = [cls.methods]

        cls.methods = [method.upper() for method in cls.methods]

        # Ensure that coroutine methods is coroutines
        for name in mcs._coroutines:
            method = getattr(cls, name, None)
            if not method:
                continue
            setattr(cls, name, to_coroutine(method))

        return cls
Example #5
0
        def wrapper(view):
            view = to_coroutine(view)

            @asyncio.coroutine
            @functools.wraps(view)
            def handler(request, *args, **kwargs):
                yield from self.check_user(request, func, location, **rkwargs)
                return (yield from view(request, *args, **kwargs))
            return handler
        def decorator(view):
            view = to_coroutine(view)

            @asyncio.coroutine
            @functools.wraps(view)
            def decorated_function(request, *args, **kwargs):
                #: Bypass the cache entirely.
                if callable(unless) and unless() is True:
                    return (yield from view(request, *args, **kwargs))

                try:
                    cache_key = decorated_function.make_cache_key(request, *args, **kwargs)
                    rv = yield from self.conn.get(cache_key)
                except Exception:
                    if self.app.cfg.DEBUG:
                        raise PluginException('Exception possibly due to cache backend.')
                    self.app.logger.exception("Exception possibly due to cache backend.")
                    return (yield from view(request, *args, **kwargs))

                if rv is None:

                    future = asyncio.Future()
                    rv = (yield from view(request, *args, **kwargs))

                    if isinstance(rv, asyncio.futures.Future) or inspect.isgenerator(rv):
                        rv = yield from rv

                    try:
                        yield from self.conn.set(cache_key, jsonpickle.encode(rv), expire=decorated_function.cache_expire)
                    except Exception:
                        if self.app.cfg.DEBUG:
                            raise PluginException('Exception possibly due to cache backend.')
                        self.app.logger.exception("Exception possibly due to cache backend.")
                        return (yield from view(request, *args, **kwargs))
                else:
                    rv = jsonpickle.decode(rv)

                return rv

            def make_cache_key(request, *args, **kwargs):
                if callable(key_prefix):
                    cache_key = key_prefix()
                elif '%s' in key_prefix:
                    cache_key = key_prefix % request.path
                else:
                    cache_key = key_prefix

                return cache_key

            decorated_function.uncached = view
            decorated_function.cache_expire = expire
            decorated_function.make_cache_key = make_cache_key

            return decorated_function
Example #7
0
    def context_processor(self, func):
        """ Decorator for adding a context provider.

        ::
            @app.ps.jinja2.context_processor
            def my_context():
                return {...}
        """
        func = to_coroutine(func)
        self.providers.append(func)
        return func
Example #8
0
    def ctx_provider(self, func):
        """ Decorator for adding a context provider.

        ::
            @jade.ctx_provider
            def my_context():
                return {...}
        """
        func = to_coroutine(func)
        self.providers.append(func)
        return func
Example #9
0
    def context_processor(self, func):
        """ Decorator for adding a context provider.

        ::
            @app.ps.jinja2.context_processor
            def my_context():
                return {...}
        """
        func = to_coroutine(func)
        self.providers.append(func)
        return func
Example #10
0
    def from_view(cls, view, *methods, name=None):
        """ Create a handler class from function or coroutine. """
        view = to_coroutine(view)

        if METH_ANY in methods:
            methods = HTTP_METHODS

        def proxy(self, *args, **kwargs):
            return view(*args, **kwargs)

        params = {m.lower(): proxy for m in methods}
        params['methods'] = methods
        return type(name or view.__name__, (cls, ), params)
Example #11
0
    def from_view(cls, view, *methods, name=None):
        """Create a handler class from function or coroutine."""
        view = to_coroutine(view)

        if METH_ANY in methods:
            methods = HTTP_METHODS

        def proxy(self, *args, **kwargs):
            return view(*args, **kwargs)

        params = {m.lower(): proxy for m in methods}
        params['methods'] = methods
        return type(name or view.__name__, (cls,), params)
Example #12
0
    def from_view(cls, view, *methods, name=None):
        """Create a handler class from function or coroutine."""
        docs = getattr(view, '__doc__', None)
        view = to_coroutine(view)
        methods = methods or ['GET']

        if METH_ANY in methods:
            methods = METH_ALL

        def proxy(self, *args, **kwargs):
            return view(*args, **kwargs)

        params = {m.lower(): proxy for m in methods}
        params['methods'] = methods
        if docs:
            params['__doc__'] = docs

        return type(name or view.__name__, (cls, ), params)
Example #13
0
        def wrapper(view):
            if handler is None:

                handler_ = view
                methods_ = methods or [METH_ANY]

                if isfunction(handler_) or ismethod(handler_):
                    handler_ = Handler.from_view(view, *methods_, name=name)

                handler_.connect(self, *paths, methods=methods_, name=name)

            else:

                view_name = view.__name__
                if not hasattr(handler, view_name):
                    setattr(handler, view_name, to_coroutine(view))
                name_ = name or view_name
                handler.connect(self, *paths, methods=methods, name=name_, view=view_name)

            return view
Example #14
0
        def wrapper(view):
            if handler is None:

                handler_ = view
                methods_ = methods or [METH_ANY]

                if isfunction(handler_) or ismethod(handler_):
                    handler_ = Handler.from_view(view, *methods_, name=name)

                handler_.connect(self, *paths, methods=methods_, name=name)

            else:

                view_name = view.__name__
                if not hasattr(handler, view_name):
                    setattr(handler, view_name, to_coroutine(view))
                name_ = name or view_name
                handler.connect(self, *paths, methods=methods, name=name_, view=view_name)

            return view
Example #15
0
def app(pytestconfig, request):
    """ Provide an example application. """
    from muffin.utils import to_coroutine
    from gunicorn import util

    if pytestconfig.app:
        app = util.import_app(pytestconfig.app)

        loop = asyncio.get_event_loop()
        for plugin in app.ps.values():
            if not hasattr(plugin, 'conftest'):
                continue
            loop.run_until_complete(to_coroutine(plugin.conftest)())

        return app

    logging.warn(
        'Improperly configured. Please set ``muffin_app`` in your pytest config. '
        'Or use ``--muffin-app`` command option.')

    return None
Example #16
0
    def __new__(mcs, name, bases, params):
        """Prepare a Handler Class.

        Ensure that the Handler class has a name.
        Ensure that required methods are coroutines.
        Fix the Handler params.
        """
        # Set name
        params['name'] = params.get('name', name.lower())

        # Define new coroutines
        coroutines = set(m.lower() for m in METH_ALL)
        coroutines |= {
            name
            for cls in bases for name in dir(cls)
            if iscoroutinefunction(getattr(cls, name))
        }

        cls = super().__new__(mcs, name, bases, params)

        # Ensure that the class methods are exist and iterable
        if not cls.methods:
            cls.methods = set(method for method in METH_ALL
                              if method.lower() in cls.__dict__)

        elif isinstance(cls.methods, str):
            cls.methods = [cls.methods]

        cls.methods = [method.upper() for method in cls.methods]

        # Ensure that coroutine methods is coroutines
        for name in coroutines:
            method = getattr(cls, name, None)
            if not method:
                continue
            setattr(cls, name, to_coroutine(method))

        return cls
Example #17
0
 def user_loader(self, func):
     """ Register a function as user loader. """
     self._user_loader = to_coroutine(func)
     return self._user_loader
Example #18
0
 def user_loader(self, func):
     """Register a function as user loader."""
     self._user_loader = to_coroutine(func)  # noqa
     return self._user_loader