Exclude swagger docs for specific HTTP methods
Asked Answered
S

3

2

I use drf-yasg to generate swagger docs for my Django REST API. I have a couple of endpoints, items/ with GET, POST and DELETE methods; and items/<uuid:itemID> with DELETE method only. However, the generated swagger docs erroneously include also GET and POST for the latter endpoint.

This is a snippet of what I have in urls.py:

urlpatters = [
    url(r'^items/$', views.ItemViewSet.as_view()),
    path('items/<uuid:itemID>', views.ItemViewSet.as_view()),
]

views.py contains something like:

class ItemViewSet(mixins.DestroyModelMixin, GenericAPIView):
    def get(self, request):
            # ...
            return Response(HTTP_200_OK)

    def post(self, request):
            # ...
            return Response(status=status.HTTP_201_CREATED)

    def delete(self, request, itemID):
             # ...
             return Response(status=status.HTTP_204_NO_CONTENT)

    def delete(self, request):
            # ...
            return Response(status=status.HTTP_204_NO_CONTENT)

How can I exclude GET and POST from items/<uuid:itemID> documentation?

I have read through https://github.com/axnsan12/drf-yasg/blob/master/docs/custom_spec.rst and Exclude URLs from Django REST Swagger but haven't found a working solution yet.

Shrink answered 15/10, 2018 at 9:8 Comment(3)
I'm able to create a hacky workaround by specifiying a custom SwaggerAutoSchema class that fine tunes operations in get_operation(). I'll post this as an answer later, unless a better solution comes up.Shrink
Any news on your post ?Philine
@Philine I posted my own workaround.Shrink
I
2

You can exclude and API endpoint from the documentation by setting the swagger_schema = None in your views.py

  class MyView(generics.ListCreateAPIView):
    """MyView class doc."""
    swagger_schema = None

    def get(self, response):
        # Do stuff here

Source: https://github.com/axnsan12/drf-yasg/commit/a211184478e6f0ca348312438c9c29d7b535b0fa

Ilarrold answered 17/5, 2019 at 13:38 Comment(1)
Doesn't this solution exclude both items/ and items/<uuid:itemID>? I only wanted to exclude one of them.Shrink
S
0

My hackish solution:

class SwaggerAutoSchemaMethodExclusion(SwaggerAutoSchema):
    read_op_counter = 0
    create_op_counter = 0       

    def get_operation(self, operation_keys):
        if "create" in in operation_keys:
            SwaggerAutoSchemaMethodExclusion.create_op_counter += 1
            if SwaggerAutoSchemaMethodExclusion.create_op_counter % 2 == 0:
                return None
        elif "read" in operation_keys:
            SwaggerAutoSchemaMethodExclusion.read_op_counter += 1
            if SwaggerAutoSchemaMethodExclusion.read_op_counter % 2 == 0:
                return None

        return super().get_operation(operation_keys)


class ItemViewSet(mixins.DestroyModelMixin, GenericAPIView):
    swagger_schema = SwaggerAutoSchemaMethodExclusion
    // ...
Shrink answered 12/3, 2019 at 6:20 Comment(0)
D
0

If you use a ViewSet (not an APIView), you can use @action decorator https://drf-yasg.readthedocs.io/en/stable/custom_spec.html

In my project

class MyEntityViewSet(ModelViewSet):

@swagger_auto_schema(tags=['your tag here'])
@action(methods=['get'], detail=False)
def list(self, request):
    list obtaining code here

@swagger_auto_schema(tags=['your tag here'])
@action(methods=['post'], detail=True)
def create(self, request):
    creation code here

@swagger_auto_schema(tags=['your tag here'], method='delete')
@action(methods=['delete'], detail=True)
def destroy(self, request, entity_id, **kwargs):
    deletion code here 
#same with update

And then in urls file:

path('my-api/', MyEntityViewSet.as_view({'get': 'list', 'post': 'create'})),
path('my-api/<int:entity_id>/', MyEntityViewSet.as_view({'put': 'update', 'delete': 'destroy'})),
Decembrist answered 24/8, 2021 at 20:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.