Source code for arrested.resource
from flask import Blueprint
__all__ = ['Resource']
[docs]class Resource(Blueprint):
"""Resource extends Flasks existing Blueprint object and provides some utilty methods
that make registering :class:`Endpoint` simpler.
"""
def __init__(
self, name, import_name, api=None, before_all_hooks=None,
after_all_hooks=None, *args, **kwargs):
"""Construct a new Reosurce blueprint. In addition to the normal Blueprint
options, Resource accepts kwargs to set request middleware.
:param api: API instance being the resource is being registered against.
:param before_all_hooks: A list of middleware functions that will be applied
before every request.
:param after_all_hooks: A list of middleware functions that will be applied
after every request.
**Middleware**
Arrested supports applying request middleware at every level of the application
stack. Resource middleware will be applied for every Endpoint registered on
that Resource.
.. code-block:: python
character_resource = Resource(
'characters', __name__,
url_prefix='/characters',
before_all_hooks=[log_request]
)
Arrested request middleware works differently from the way Flask middleware does.
Middleware registered at the Resource and API level are consumed by the
:meth:`arrested.Endpoint.dispatch_request` rather than being fired via the Flask
app instance. This is so we can pass the instance of the endpoint handling the
request to each piece of middleware registered on the API or Resource.
.. code-block:: python
def api_key_required(endpoint):
if request.args.get('api_key', None) is None:
endpoint.return_error(422)
else:
get_client(request.args['api_key'])
character_resource = Resource(
'characters', __name__,
url_prefix='/characters',
before_all_hooks=[api_key_required]
)
Please note, Flask's normal App and Blueprint middleware can still be used
as normal, it just doesn't recieve the instance of the endpoint registered to
handle the request.
"""
self.before_all_hooks = before_all_hooks or []
self.after_all_hooks = after_all_hooks or []
super(Resource, self).__init__(name, import_name, *args, **kwargs)
if api is not None:
self.init_api(api)
[docs] def init_api(self, api):
"""Registered the instance of :class:`.ArrestedAPI` the :class:`.Resource`
is being registered against.
:param api: API instance being the resource is being registered against.
"""
self.api = api
[docs] def add_endpoint(self, endpoint):
"""Register an :class:`.Endpoint` aginst this resource.
:param endpoint: :class:`.Endpoint` API Endpoint class
Usage::
foo_resource = Resource('example', __name__)
class MyEndpoint(Endpoint):
url = '/example'
name = 'myendpoint'
foo_resource.add_endpoint(MyEndpoint)
"""
if self.url_prefix:
url = '{prefix}{url}'.format(prefix=self.url_prefix, url=endpoint.url)
else:
url = endpoint.url
self.add_url_rule(
url,
view_func=endpoint.as_view(endpoint.get_name()),
)