Drf-yasg: Help wanted: File download as Response and versioning

Created on 22 Aug 2018  Â·  4Comments  Â·  Source: axnsan12/drf-yasg

I'm wondering, how to define a filedownload as response with dfr-yasg.
I read the part where "does not handle more complex fields such as FileField, ChoiceField, …" but was wondering if I could manually create a openapi.Response object so that swagger displays the correct response type.

The second thing is most probably a simple thing, if I use NamespaceVersioning in django rest framework, is it possible to tell swagger_auto_schema which Serializer the resquest_body is expecting depending on the version?

I have the same function for version 1 and 2

class DocumentViewSet(NoneViewSet):
    """

    Viewset to interact with the service. 

    download:
        Returns the pdf download.

    """

    def get_objects(self):
        if self.request.version == 'v1':
            return DocumentV1

        if self.request.version == 'v2':
            return DocumentV2

    def get_queryset(self):
        return self.request.get_objects().objects.all()

    def get_serializer_class(self):
        if self.request.version == 'v1':
            return DocumentSerializer

        if self.request.version == 'v2':
            return DocumentSerializer2

        raise NotImplementedError("Can't handle that version")            

    file_response = openapi.Response(
                                     description='Content-Type: application/pdf',

                                     )

    @swagger_auto_schema(
                         method='post', 
                         operation_description="Document download as pdf", 
                         request_body=DocumentSerializer, 
                         produces="application/pdf",
                         responses={
                             201: file_response,
                             400: "Serializer error"
                             }
                         )
    @action(methods=['post'], detail=False)
    def download(self, request):
        ...
        pass

But request_body=DocumentSerializer of course only shows the V1 version in redoc and swagger.
I'd rather like to up or downgrade the model for using the latest version of a function instead of implementing functions for different API versions.

Maybe I'm just missing something obvious here?

Thanks!

question

Most helpful comment

For the file download response, the OpenAPI spec says that you should define a Response with a schema of type file, and set the operation's produces property appropriately.

Versioning is handled transparently by serving up different schema documents for each API version, i.e. you should have /api/v1/swagger.json and /api/v2/swagger.json. request.version will then have the appropriate value and your get_serializer_class will work correctly.

I tried the following but the Response content type is still application/json. I would like to have it as application/octet-stream - thanks

@swagger_auto_schema(
    query_serializer=DocumentQuerySerializer,
    responses={
        '200': openapi.Response('File Attachment', schema=openapi.Schema(type=openapi.TYPE_FILE)),
        '400': 'Bad Request',
        '401': 'Not Authorized',
        '404': 'Not Found'
    },
    produces='application/octet-stream',
    operation_id='Retrieve a Document',
    operation_description='GET server:PORT/documentstore/docs?id=string'
)

All 4 comments

For the file download response, the OpenAPI spec says that you should define a Response with a schema of type file, and set the operation's produces property appropriately.

Versioning is handled transparently by serving up different schema documents for each API version, i.e. you should have /api/v1/swagger.json and /api/v2/swagger.json. request.version will then have the appropriate value and your get_serializer_class will work correctly.

For the file download response, the OpenAPI spec says that you should define a Response with a schema of type file, and set the operation's produces property appropriately.

Versioning is handled transparently by serving up different schema documents for each API version, i.e. you should have /api/v1/swagger.json and /api/v2/swagger.json. request.version will then have the appropriate value and your get_serializer_class will work correctly.

I tried the following but the Response content type is still application/json. I would like to have it as application/octet-stream - thanks

@swagger_auto_schema(
    query_serializer=DocumentQuerySerializer,
    responses={
        '200': openapi.Response('File Attachment', schema=openapi.Schema(type=openapi.TYPE_FILE)),
        '400': 'Bad Request',
        '401': 'Not Authorized',
        '404': 'Not Found'
    },
    produces='application/octet-stream',
    operation_id='Retrieve a Document',
    operation_description='GET server:PORT/documentstore/docs?id=string'
)

Any update on this? I'm having the same issue

Any update on this. Facing same issue.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

nicholasgcoles picture nicholasgcoles  Â·  4Comments

iamhssingh picture iamhssingh  Â·  3Comments

agethecoolguy picture agethecoolguy  Â·  4Comments

therefromhere picture therefromhere  Â·  3Comments

hnykda picture hnykda  Â·  3Comments