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
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
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
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
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
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)
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)
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)
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
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
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
def user_loader(self, func): """ Register a function as user loader. """ self._user_loader = to_coroutine(func) return self._user_loader
def user_loader(self, func): """Register a function as user loader.""" self._user_loader = to_coroutine(func) # noqa return self._user_loader