def scrape_endpoints(self):
        """
        Iterate over the registered API endpoints for this version and generate path specs
        """
        inspector = EndpointEnumerator()
        for path, http_method, func in inspector.get_api_endpoints():
            http_method = http_method.lower()

            if not path.startswith('/api-auth/') and not path.startswith(
                    "/{}/".format(
                        self.version)):  # skip if it doesnt match version
                continue

            method_func = getattr(func.cls, http_method, None)
            if self.has_apispec_wrapper(method_func):
                operation_spec = self.get_operation_spec(path,
                                                         http_method,
                                                         view_cls=func.cls)
                merged_spec = self.merge_specs(
                    operation_spec, self.get_apispec_kwargs(method_func))

                path_spec = {
                    'path': path,
                    'operations': {
                        http_method: merged_spec
                    }
                }
                self.add_path(**path_spec)
    def test_deprecations(self):
        with pytest.warns(PendingDeprecationWarning) as record:

            @api_view(["GET"], exclude_from_schema=True)
            def view(request):
                pass

        assert len(record) == 1
        assert str(record[0].message) == (
            "The `exclude_from_schema` argument to `api_view` is pending "
            "deprecation. Use the `schema` decorator instead, passing `None`.")

        class OldFashionedExcludedView(APIView):
            exclude_from_schema = True

            def get(self, request, *args, **kwargs):
                pass

        patterns = [
            url('^excluded-old-fashioned/$',
                OldFashionedExcludedView.as_view()),
        ]

        inspector = EndpointEnumerator(patterns)
        with pytest.warns(PendingDeprecationWarning) as record:
            inspector.get_api_endpoints()

        assert len(record) == 1
        assert str(record[0].message) == (
            "The `OldFashionedExcludedView.exclude_from_schema` attribute is "
            "pending deprecation. Set `schema = None` instead.")
示例#3
0
    def get_queryset(self):
        """
        get: Return a list of all endpoints.
        """
        endpoint_enumerator = EndpointEnumerator()

        if setting_url_base_path.value:
            url_index = 3
        else:
            url_index = 2

        # Extract the resource names from the API endpoint URLs
        parsed_urls = set()
        for entry in endpoint_enumerator.get_api_endpoints():
            try:
                url = entry[0].split('/')[url_index]
            except IndexError:
                """An unknown or invalid URL"""
            else:
                parsed_urls.add(url)

        endpoints = []
        for url in sorted(parsed_urls):
            if url:
                endpoints.append(Endpoint(label=url))

        return endpoints
    def test_deprecations(self):
        with pytest.warns(PendingDeprecationWarning) as record:
            @api_view(["GET"], exclude_from_schema=True)
            def view(request):
                pass

        assert len(record) == 1
        assert str(record[0].message) == (
            "The `exclude_from_schema` argument to `api_view` is pending "
            "deprecation. Use the `schema` decorator instead, passing `None`."
        )

        class OldFashionedExcludedView(APIView):
            exclude_from_schema = True

            def get(self, request, *args, **kwargs):
                pass

        patterns = [
            url('^excluded-old-fashioned/$', OldFashionedExcludedView.as_view()),
        ]

        inspector = EndpointEnumerator(patterns)
        with pytest.warns(PendingDeprecationWarning) as record:
            inspector.get_api_endpoints()

        assert len(record) == 1
        assert str(record[0].message) == (
            "The `OldFashionedExcludedView.exclude_from_schema` attribute is "
            "pending deprecation. Set `schema = None` instead."
        )
    def test_endpoint_enumerator_excludes_correctly(self):
        """It is responsibility of EndpointEnumerator to exclude views"""
        inspector = EndpointEnumerator(self.patterns)
        endpoints = inspector.get_api_endpoints()

        assert len(endpoints) == 1
        path, method, callback = endpoints[0]
        assert path == '/included-fbv/'
    def test_endpoint_enumerator_excludes_correctly(self):
        """It is responsibility of EndpointEnumerator to exclude views"""
        inspector = EndpointEnumerator(self.patterns)
        endpoints = inspector.get_api_endpoints()

        assert len(endpoints) == 1
        path, method, callback = endpoints[0]
        assert path == '/included-fbv/'
 def scrape_endpoints_for_scopes(self):
     """
     Iterate over the registered API endpoints output all the scopes
     """
     inspector = EndpointEnumerator()
     all_scopes = set()
     for path, http_method, func in inspector.get_api_endpoints():
         all_scopes |= set(
             self.valid_scopes_for_view(func.cls, method=http_method))
     excluded_scopes = set(getattr(settings, 'API_DOCS_EXCLUDED_SCOPES',
                                   []))
     return sorted(list(all_scopes ^ excluded_scopes))
    def test_should_include_endpoint_excludes_correctly(self):
        """This is the specific method that should handle the exclusion"""
        inspector = EndpointEnumerator(self.patterns)

        # Not pretty. Mimics internals of EndpointEnumerator to put should_include_endpoint under test
        pairs = [(inspector.get_path_from_regex(get_regex_pattern(pattern)),
                  pattern.callback) for pattern in self.patterns]

        should_include = [
            inspector.should_include_endpoint(*pair) for pair in pairs
        ]

        expected = [False, False, True]

        assert should_include == expected
    def test_should_include_endpoint_excludes_correctly(self):
        """This is the specific method that should handle the exclusion"""
        inspector = EndpointEnumerator(self.patterns)

        # Not pretty. Mimics internals of EndpointEnumerator to put should_include_endpoint under test
        pairs = [(inspector.get_path_from_regex(get_regex_pattern(pattern)), pattern.callback)
                 for pattern in self.patterns]

        should_include = [
            inspector.should_include_endpoint(*pair) for pair in pairs
        ]

        expected = [False, False, True]

        assert should_include == expected
示例#10
0
def get_paths() -> List[str]:
    """
    Returns a list of endpoint paths.
    """
    return list(
        set(endpoint[0] for endpoint in
            EndpointEnumerator().get_api_endpoints()))  # noqa: C401
示例#11
0
    def get(self, request, format=None):
        """
        get: Return a list of all endpoints.
        """
        endpoint_enumerator = EndpointEnumerator()

        endpoints = []
        for url in sorted(
                set([
                    entry[0].split('/')[2]
                    for entry in endpoint_enumerator.get_api_endpoints()
                ])):
            if url:
                endpoints.append(Endpoint(label=url))

        serializer = EndpointSerializer(endpoints, many=True)
        return Response(serializer.data)
示例#12
0
 def endpoints(self) -> List[str]:  # pylint: disable=no-self-use
     """
     Returns a list of endpoint paths.
     """
     return list({
         endpoint[0]
         for endpoint in EndpointEnumerator().get_api_endpoints()
     })
示例#13
0
 def usable_views(cls):
     api_endpoints = EndpointEnumerator().get_api_endpoints()
     generator = BaseSchemaGenerator()
     views = []
     for endpoint in api_endpoints:
         _, method, view_callback = endpoint
         view = generator.create_view(view_callback, method)
         if cls._usable_viewset(view):
             if view.__class__ not in [v.__class__ for v in views]:
                 views.append(view)
     return views
示例#14
0
def test_head_and_options_methods_are_excluded():
    """
    Regression test for #5528
    https://github.com/encode/django-rest-framework/issues/5528

    Viewset OPTIONS actions were not being correctly excluded

    Initial cases here shown to be working as expected.
    """

    @api_view(['options', 'get'])
    def fbv(request):
        pass

    inspector = EndpointEnumerator()

    path = '/a/path/'
    callback = fbv

    assert inspector.should_include_endpoint(path, callback)
    assert inspector.get_allowed_methods(callback) == ["GET"]

    class AnAPIView(APIView):

        def get(self, request, *args, **kwargs):
            pass

        def options(self, request, *args, **kwargs):
            pass

    callback = AnAPIView.as_view()

    assert inspector.should_include_endpoint(path, callback)
    assert inspector.get_allowed_methods(callback) == ["GET"]

    class AViewSet(ModelViewSet):

        @action(methods=['options', 'get'], detail=True)
        def custom_action(self, request, pk):
            pass

    callback = AViewSet.as_view({
        "options": "custom_action",
        "get": "custom_action"
    })

    assert inspector.should_include_endpoint(path, callback)
    assert inspector.get_allowed_methods(callback) == ["GET"]
示例#15
0
    def get_queryset(self):
        """
        get: Return a list of all endpoints.
        """
        endpoint_enumerator = EndpointEnumerator()

        if setting_url_base_path.value:
            index = 3
        else:
            index = 2

        # Extract the resource names from the API endpoint URLs
        parsed_urls = []
        for entry in endpoint_enumerator.get_api_endpoints():
            parsed_urls.append(entry[0].split('/')[index])

        parsed_urls = sorted(set(parsed_urls))

        endpoints = []
        for url in parsed_urls:
            if url:
                endpoints.append(Endpoint(label=url))

        return endpoints
def test_head_and_options_methods_are_excluded():
    """
    Regression test for #5528
    https://github.com/encode/django-rest-framework/issues/5528

    Viewset OPTIONS actions were not being correctly excluded

    Initial cases here shown to be working as expected.
    """

    @api_view(['options', 'get'])
    def fbv(request):
        pass

    inspector = EndpointEnumerator()

    path = '/a/path/'
    callback = fbv

    assert inspector.should_include_endpoint(path, callback)
    assert inspector.get_allowed_methods(callback) == ["GET"]

    class AnAPIView(APIView):

        def get(self, request, *args, **kwargs):
            pass

        def options(self, request, *args, **kwargs):
            pass

    callback = AnAPIView.as_view()

    assert inspector.should_include_endpoint(path, callback)
    assert inspector.get_allowed_methods(callback) == ["GET"]

    class AViewSet(ModelViewSet):

        @detail_route(methods=['options', 'get'])
        def custom_action(self, request, pk):
            pass

    callback = AViewSet.as_view({
        "options": "custom_action",
        "get": "custom_action"
    })

    assert inspector.should_include_endpoint(path, callback)
    assert inspector.get_allowed_methods(callback) == ["GET"]
示例#17
0
 def get_endpoints_toggle(self):
     for endpoint in EndpointEnumerator().get_api_endpoints():
         endpoint_name = endpoint[0].rsplit("{pk}")[0].rsplit("{uid}")[0]
         if ('{}|{}'.format(endpoint_name, endpoint[1])) not in self._keys:
             self.addnewkey(str('{}|{}'.format(endpoint_name, endpoint[1])),
                            True)