Example #1
0
 def base_url(self):
     """
     :return: The base_url for this adapter.  It simply joins
         the provided base_url in the __init__ method and
         joins it with the ``request.url_root``.  If this
         app provided is actually a blueprint, it will
         return join the blueprints url_prefix in between
     :rtype: unicode
     """
     if getattr(self.app, "url_prefix", None):
         return join_url_parts(request.url_root, self.app.url_prefix, self.url_prefix)
     return join_url_parts(request.url_root, self.url_prefix)
Example #2
0
    def register_route(self, endpoint, endpoint_func=None, route=None, methods=None, **options):
        """
        Registers the endpoints on the flask application
        or blueprint.  It does so by using the add_url_rule on
        the blueprint/app.  It wraps the endpoint_func with the
        ``flask_dispatch_wrapper`` which returns an updated function.
        This function appropriately sets the RequestContainer object
        before passing it to the apimethod.

        :param unicode endpoint: The name of the endpoint.  This is typically
            used in flask for reversing urls
        :param method endpoint_func: The actual function that is going to be called.
            This is generally going to be a @apimethod decorated, ResourceBase subclass
            method.
        :param unicode route:  The actual route that is going to be used.
        :param list methods: The http verbs that can be used with this endpoint
        :param dict options: The additional options to pass to the add_url_rule
        """
        valid_flask_options = ('defaults', 'subdomain', 'methods', 'build_only',
                               'endpoint', 'strict_slashes', 'redirect_to',
                               'alias', 'host')
        route = join_url_parts(self.url_prefix, route)

        # Remove invalid flask options.
        options_copy = options.copy()
        for key, value in six.iteritems(options_copy):
            if key not in valid_flask_options:
                options.pop(key, None)
        self.app.add_url_rule(route, endpoint=endpoint,
                              view_func=flask_dispatch_wrapper(self, endpoint_func, self.argument_getter),
                              methods=methods, **options)
Example #3
0
def _generate_endpoint_dict(cls):
    """
    Generates a dictionary of the endpoints on the class
    which are @apimethod decorated.

    :param ResourceMetaClass cls: The ResourceBase subclass that you
        are trying to get the endpoints from.
    :type cls:
    :return:
    :rtype:
    """
    endpoint_dictionary = {}
    for name, method in _get_apimethods(cls):
        _logger.debug('Found the apimethod %s on the class %s', name,
                      cls.__name__)
        all_routes = []
        for route, endpoint, options in method.routes:
            base_url = cls.base_url_sans_pks if options.get(
                'no_pks', False) else cls.base_url
            route = join_url_parts(base_url, route)
            all_routes.append(
                dict(route=route, endpoint_func=method, **options))
        _logger.info('Registering routes: %s as key %s', all_routes, name)
        endpoint_dictionary[name] = all_routes
    return endpoint_dictionary
Example #4
0
    def combine_base_url_with_resource_url(self, resource_url):
        """
        Does exactly what it says it does.  Uses ``join_url_parts``
        with the ``self.base_url`` and ``resource_url`` argument
        together.

        :param unicode resource_url: The part to join with the ``self.base_url``
        :return: The joined url
        :rtype: unicode
        """
        return join_url_parts(self.base_url, resource_url)
Example #5
0
            def base_url_sans_pks(cls):
                """
                A class property that returns the base url
                without the pks.
                This is just the /{namespace}/{resource_name}

                For example if the _namespace = '/api' and
                the _resource_name = 'resource' this would
                return '/api/resource' regardless if there
                are pks or not.

                :return: The base url without the pks
                :rtype: unicode
                """

                pks = cls.pks[:-1] or [] #only use the last primary key element
                parts = ['<{0}>'.format(pk) for pk in pks]
                base_url = join_url_parts(cls.namespace, cls.resource_name).lstrip('/')
                base_url = join_url_parts(base_url, *parts).strip('/')
                return '/{0}/'.format(base_url) if not cls.append_slash else '/{0}/'.format(base_url)
Example #6
0
    def combine_base_url_with_resource_url(self, resource_url):
        """
        Does exactly what it says it does.  Uses ``join_url_parts``
        with the ``self.base_url`` and ``resource_url`` argument
        together.

        :param unicode resource_url: The part to join with the ``self.base_url``
        :return: The joined url
        :rtype: unicode
        """
        return join_url_parts(self.base_url, resource_url)
Example #7
0
    def base_url(cls):
        """
        Gets the base_url for the resource
        This is prepended to all routes indicated
        by an apimethod decorator.

        :return: The base_url for the resource(s)
        :rtype: unicode
        """
        pks = cls.pks or []
        parts = ['<{0}>'.format(pk) for pk in pks]
        base_url = join_url_parts(cls.base_url_sans_pks, *parts).strip('/')
        return '/{0}'.format(base_url) if not cls.append_slash else '/{0}/'.format(base_url)
Example #8
0
    def base_url(cls):
        """
        Gets the base_url for the resource
        This is prepended to all routes indicated
        by an apimethod decorator.

        :return: The base_url for the resource(s)
        :rtype: unicode
        """
        pks = cls.pks or []
        parts = ['<{0}>'.format(pk) for pk in pks]
        base_url = join_url_parts(cls.base_url_sans_pks, *parts).lstrip('/')
        return '/{0}'.format(
            base_url) if not cls.append_slash else '/{0}/'.format(base_url)
Example #9
0
            def base_url_sans_pks(cls):
                """
                A class property that returns the base url
                without the pks.
                This is just the /{namespace}/{resource_name}

                For example if the _namespace = '/api' and
                the _resource_name = 'resource' this would
                return '/api/resource' regardless if there
                are pks or not.

                :return: The base url without the pks
                :rtype: unicode
                """

                pks = cls.pks[:-1] or [
                ]  #only use the last primary key element
                parts = ['<{0}>'.format(pk) for pk in pks]
                base_url = join_url_parts(cls.namespace,
                                          cls.resource_name).lstrip('/')
                base_url = join_url_parts(base_url, *parts).strip('/')
                return '/{0}/'.format(
                    base_url) if not cls.append_slash else '/{0}/'.format(
                        base_url)
Example #10
0
    def base_url_sans_pks(cls):
        """
        A class property that returns the base url
        without the pks.
        This is just the /{namespace}/{resource_name}

        For example if the _namespace = '/api' and
        the _resource_name = 'resource' this would
        return '/api/resource' regardless if there
        are pks or not.

        :return: The base url without the pks
        :rtype: unicode
        """
        base_url = join_url_parts(cls.namespace, cls.resource_name).lstrip('/')
        return '/{0}'.format(base_url) if not cls.append_slash else '/{0}/'.format(base_url)
Example #11
0
    def _construct_id(resource):
        """
        Constructs a JSON API compatible id.
        May not work particularly well for composite ids since
        apparently JSON API hates them.  It will simply
        join the pks with a `"/"` in the appropriate order.

        :param ResourceBase resource: The resource whose
            id needs to be constructed.
        :return: The id in a format `<pk1>/<pk2>`
        :rtype: unicode
        """
        pks = resource.pks
        id_parts = [resource.item_pks[pk] for pk in pks]
        id_ = join_url_parts(*id_parts)
        return id_
Example #12
0
    def base_url_sans_pks(cls):
        """
        A class property that eturns the base url
        without the pks.
        This is just the /{namespace}/{resource_name}

        For example if the _namespace = '/api' and
        the _resource_name = 'resource' this would
        return '/api/resource' regardless if there
        are pks or not.

        :return: The base url without the pks
        :rtype: unicode
        """
        base_url = join_url_parts(cls.namespace, cls.resource_name).lstrip('/')
        return '/{0}'.format(
            base_url) if not cls.append_slash else '/{0}/'.format(base_url)
Example #13
0
    def url(self):
        """
        Lazily constructs the url for this specific resource using the specific
        pks as specified in the pks tuple.

        :return: The url for this resource
        :rtype: unicode
        """
        if not self._url:
            base_url = self.base_url_sans_pks if self.no_pks else self.base_url
            base_url = join_url_parts(base_url, self.route_extension)
            url = create_url(base_url, **self.item_pks).strip('/')
            url = '/{0}'.format(url) if not self.append_slash else '/{0}/'.format(url)
            query_string = self.query_string
            if query_string:
                url = '{0}?{1}'.format(url, query_string)
            self._url = url
        return self._url
Example #14
0
    def url(self):
        """
        Lazily constructs the url for this specific resource using the specific
        pks as specified in the pks tuple.

        :return: The url for this resource
        :rtype: unicode
        """
        if not self._url:
            base_url = self.base_url_sans_pks if self.no_pks else self.base_url
            base_url = join_url_parts(base_url, self.route_extension)
            url = create_url(base_url, **self.item_pks).strip('/')
            url = '/{0}'.format(
                url) if not self.append_slash else '/{0}/'.format(url)
            query_string = self.query_string
            if query_string:
                url = '{0}?{1}'.format(url, query_string)
            self._url = url
        return self._url
Example #15
0
    def _construct_id(resource):
        """
        Constructs a JSON API compatible id.
        May not work particularly well for composite ids since
        apparently JSON API hates them.  It will simply
        join the pks with a `"/"` in the appropriate order.
        Additionally, for resources with no_pks=True, it
        will return an empty string.

        :param ResourceBase resource: The resource whose
            id needs to be constructed.
        :return: The id in a format `<pk1>/<pk2>`
        :rtype: unicode
        """
        if resource.no_pks:
            return ""
        pks = resource.pks
        id_parts = [resource.item_pks[pk] for pk in pks]
        id_ = join_url_parts(*id_parts)
        return id_
 def register_route(self, endpoint, endpoint_func=None, route=None, methods=None, **options):
     """
     Adds a route to the url_map which is used when getting
     the url_patterns property which are then added to the django
     app.
     :param unicode endpoint: The name of this endpoint
     :param function endpoint_func: the function that should be called when
         this endpoint is hit.
     :param unicode route: The url that corresponds to this endpoint.
         Each unique url generates a MethodRouter which then dispatches
         them to the appopriate endpoints for the http verbs
     :param list methods: The http verbs that correspond to this endpoint
     :param dict options: Additional options.  Not used at this time
     """
     route = join_url_parts(self.base_url, route)
     route = self._convert_url_to_regex(route)
     if route not in self.url_map:
         self.url_map[route] = self.method_route_class(route, self, self.error_handler)
     method_router = self.url_map[route]
     method_router.add_route(endpoint_func=endpoint_func, endpoint=endpoint,
                             methods=methods, **options)
Example #17
0
def _generate_endpoint_dict(cls):
    """
    Generates a dictionary of the endpoints on the class
    which are @apimethod decorated.

    :param ResourceMetaClass cls: The ResourceBase subclass that you
        are trying to get the endpoints from.
    :type cls:
    :return:
    :rtype:
    """
    endpoint_dictionary = {}
    for name, method in _get_apimethods(cls):
        _logger.debug('Found the apimethod %s on the class %s', name, cls.__name__)
        all_routes = []
        for route, endpoint, options in method.routes:
            base_url = cls.base_url_sans_pks if options.get('no_pks', False) else cls.base_url #TODO: Add trailing slash here if no_pks??
            route = join_url_parts(base_url, route)
            all_routes.append(dict(route=route, endpoint_func=method, **options))
        _logger.info('Registering routes: %s as key %s', all_routes, name)
        endpoint_dictionary[name] = all_routes
    return endpoint_dictionary
Example #18
0
    def test_join_url_parts(self):
        url = join_url_parts()
        self.assertIsInstance(url, six.text_type)
        self.assertEqual('', url)

        url = join_url_parts('/something', '/another', '/thing')
        self.assertEqual(url, '/something/another/thing')

        url = join_url_parts('something/', '/another/', '/thing')
        self.assertEqual(url, 'something/another/thing')

        url = join_url_parts('something//', '/another')
        self.assertEqual(url, 'something/another')

        url = join_url_parts('/', '/another')
        self.assertEqual('/another', url)

        url = join_url_parts('/', '/')
        self.assertEqual('/', url)
Example #19
0
    def test_join_url_parts(self):
        url = join_url_parts()
        self.assertIsInstance(url, six.text_type)
        self.assertEqual('', url)

        url = join_url_parts('/something', '/another', '/thing')
        self.assertEqual(url, '/something/another/thing')

        url = join_url_parts('something/', '/another/', '/thing')
        self.assertEqual(url, 'something/another/thing')

        url = join_url_parts('something//', '/another')
        self.assertEqual(url, 'something/another')

        url = join_url_parts('/', '/another')
        self.assertEqual('/another', url)

        url = join_url_parts('/', '/')
        self.assertEqual('/', url)
 def test_join_url_parts_ints(self):
     """joining parts when a single int.  Ensuring that it is unicode"""
     resp = join_url_parts(1)
     self.assertEqual(resp, '1')
Example #21
0
 def test_join_url_parts_ints(self):
     """joining parts when a single int.  Ensuring that it is unicode"""
     resp = join_url_parts(1)
     self.assertEqual(resp, '1')