Exemplo n.º 1
0
def create_http_method_map(resource, uri_fields, before, after):
    """Maps HTTP methods (e.g., GET, POST) to methods of a resource object.

    Args:
        resource: An object with *responder* methods, following the naming
            convention *on_\**, that correspond to each method the resource
            supports. For example, if a resource supports GET and POST, it
            should define ``on_get(self, req, resp)`` and
            ``on_post(self, req, resp)``.
        uri_fields: A set of field names from the route's URI template
            that a responder must support in order to avoid "method not
            allowed".
        before: An action hook or list of hooks to be called before each
            *on_\** responder defined by the resource.
        after: An action hook or list of hooks to be called after each
            *on_\** responder defined by the resource.

    Returns:
        dict: A mapping of HTTP methods to responders.

    """

    method_map = {}

    for method in HTTP_METHODS:
        try:
            responder = getattr(resource, 'on_' + method.lower())
        except AttributeError:
            # resource does not implement this method
            pass
        else:
            # Usually expect a method, but any callable will do
            if callable(responder):
                responder = _wrap_with_hooks(
                    before, after, responder, resource)
                method_map[method] = responder

    # Attach a resource for unsupported HTTP methods
    allowed_methods = sorted(list(method_map.keys()))

    # NOTE(sebasmagri): We want the OPTIONS and 405 (Not Allowed) methods
    # responders to be wrapped on global hooks
    if 'OPTIONS' not in method_map:
        # OPTIONS itself is intentionally excluded from the Allow header
        responder = responders.create_default_options(
            allowed_methods)
        method_map['OPTIONS'] = _wrap_with_hooks(
            before, after, responder, resource)
        allowed_methods.append('OPTIONS')

    na_responder = responders.create_method_not_allowed(allowed_methods)

    for method in HTTP_METHODS:
        if method not in allowed_methods:
            method_map[method] = _wrap_with_hooks(
                before, after, na_responder, resource)

    return method_map
Exemplo n.º 2
0
def create_http_method_map(resource, uri_fields, before, after):
    """Maps HTTP methods (e.g., 'GET', 'POST') to methods of a resource object.

    Args:
        resource: An object with *responder* methods, following the naming
            convention *on_\**, that correspond to each method the resource
            supports. For example, if a resource supports GET and POST, it
            should define ``on_get(self, req, resp)`` and
            ``on_post(self, req, resp)``.
        uri_fields: A set of field names from the route's URI template
            that a responder must support in order to avoid "method not
            allowed".
        before: An action hook or ``list`` of hooks to be called before each
            *on_\** responder defined by the resource.
        after: An action hook or ``list`` of hooks to be called after each
            *on_\** responder defined by the resource.

    Returns:
        dict: A mapping of HTTP methods to responders.

    """

    method_map = {}

    for method in HTTP_METHODS:
        try:
            responder = getattr(resource, 'on_' + method.lower())
        except AttributeError:
            # resource does not implement this method
            pass
        else:
            # Usually expect a method, but any callable will do
            if callable(responder):
                responder = _wrap_with_hooks(before, after, responder,
                                             resource)
                method_map[method] = responder

    # Attach a resource for unsupported HTTP methods
    allowed_methods = sorted(list(method_map.keys()))

    # NOTE(sebasmagri): We want the OPTIONS and 405 (Not Allowed) methods
    # responders to be wrapped on global hooks
    if 'OPTIONS' not in method_map:
        # OPTIONS itself is intentionally excluded from the Allow header
        responder = responders.create_default_options(allowed_methods)
        method_map['OPTIONS'] = _wrap_with_hooks(before, after, responder,
                                                 resource)
        allowed_methods.append('OPTIONS')

    na_responder = responders.create_method_not_allowed(allowed_methods)

    for method in HTTP_METHODS:
        if method not in allowed_methods:
            method_map[method] = _wrap_with_hooks(before, after, na_responder,
                                                  resource)

    return method_map
Exemplo n.º 3
0
def create_http_method_map(resource, uri_fields, before, after):
    """Maps HTTP methods (such as GET and POST) to methods of resource object

    Args:
        resource: An object with "responder" methods, starting with on_*, that
            correspond to each method the resource supports. For example, if a
            resource supports GET and POST, it should define
            on_get(self, req, resp) and on_post(self,req,resp).
        uri_fields: A set of field names from the route's URI template that
            a responder must support in order to avoid "method not allowed".
        before: An action hook or list of hooks to be called before each
            on_* responder defined by the resource.
        after: An action hook or list of hooks to be called after each on_*
            responder defined by the resource.

    Returns:
        A tuple containing a dict mapping HTTP methods to responders, and
        the method-not-allowed responder.

    """

    method_map = {}

    for method in HTTP_METHODS:
        try:
            responder = getattr(resource, "on_" + method.lower())
        except AttributeError:
            # resource does not implement this method
            pass
        else:
            # Usually expect a method, but any callable will do
            if callable(responder):
                responder = _wrap_with_hooks(before, after, responder, resource)
                method_map[method] = responder

    # Attach a resource for unsupported HTTP methods
    allowed_methods = sorted(list(method_map.keys()))

    # NOTE(sebasmagri): We want the OPTIONS and 405 (Not Allowed) methods
    # responders to be wrapped on global hooks
    if "OPTIONS" not in method_map:
        # OPTIONS itself is intentionally excluded from the Allow header
        responder = responders.create_default_options(allowed_methods)
        method_map["OPTIONS"] = _wrap_with_hooks(before, after, responder, resource)
        allowed_methods.append("OPTIONS")

    na_responder = responders.create_method_not_allowed(allowed_methods)

    for method in HTTP_METHODS:
        if method not in allowed_methods:
            method_map[method] = _wrap_with_hooks(before, after, na_responder, resource)

    return method_map
Exemplo n.º 4
0
    def add_route(self, resource):
        """Associates uri patterns with resource methods.

        A resource is an instance of a class that defines various methods
        to handle http requests.

        Use this class to create applications which serve a standard
        compliant ReSTful API. For example, you may have an API which manage
        monitoring data, there can be multiple implementations of the API
        using different technologies. One can use Mongodb, the other can use
        Cassandra. To make the configuration of the application very easy,
        each implementation provides a class with set of methods decorated
        by class Restify, the application can simply using single entry
        configuration to load different implementations.

        For example::

            class ExampleResource(object):
                @Restify(path='/path1/', method='post')
                def func1(self, req, res):
                    pass

                @Restify(path='/path2/{id}/key/', method='get')
                def func2(self, req, res, id):
                    pass

                def func3(self, req, res, id):
                    pass

        With the above class, the following code will add the class method
        func1, func2 to handle post and get requests respectively, method
        func3 won't be added to the routes.::

            app.add_route(ExampleResource())

        Args:
            resource (instance): Object which represents an HTTP/REST
                "resource". Falcon will pass requests to various decorated
                methods to handle http requests.
        """
        if not resource:
            raise Exception('Not a valid resource')

        path_maps = {}
        for attr in dir(resource):
            method = getattr(resource, attr)
            if callable(method) and hasattr(method, RESOURCE_METHOD_FLAG):
                flag = getattr(method, RESOURCE_METHOD_FLAG)
                map = path_maps.get(flag.path)
                if not map:
                    uri_fields, template = (
                        routing.compile_uri_template(flag.path))
                    map = (template, {})
                    path_maps[flag.path] = map

                new_method = hooks._wrap_with_hooks(
                    self._before, self._after, method, resource)
                map[1][flag.method] = new_method

        for item in path_maps:
            self._routes.insert(0, (path_maps[item][0],
                                    path_maps[item][1],
                                    resource))