Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for different content type responses (e.g. application/octet-stream) #1073

Open
LevonW-IIS opened this issue Feb 6, 2024 · 2 comments

Comments

@LevonW-IIS
Copy link

I have been creating a ninja API for my web app and have found the process very smooth, and have been enjoying the open API auto documentation, which I rely on in my front-end. I have encountered one problem in dealing with a file download endpoint.

The response should be easily specifiable under the openapi specs as

content:
  application/octet-stream:
    schema:
      type: string
      format: binary

however I've found no easy way to implement this within django-ninja.

I've had a look through the code and I think I've found where a change could be made

if model not in [None, NOT_SET]:
    # ::TODO:: test this: by_alias == True
    schema = self._create_schema_from_model(
        model, by_alias=operation.by_alias
    )[0]
    details[status]["content"] = {
        self.api.renderer.media_type: {"schema": schema}
    }

if the schema had an __ninja_override_media_type__ attribute, this could be used to provide a custom media type for a response.

If you want me to have a stab at writing a PR for this let me know

@LevonW-IIS LevonW-IIS changed the title Add support for a built in file schema Add support for different content type responses (e.g. application/octet-stream) Feb 6, 2024
@vitalik
Copy link
Owner

vitalik commented Feb 6, 2024

Hi @LevonW-IIS

currently you can do it like this:

BIN_RESPONSE = {
    "responses": {
        200: {
            "description": "OK",
            "content": {"application/octet-stream": {"schema": {"type": "string", "format": "binary"}}},
        }
    }
}


@api.get("/hello", openapi_extra=BIN_RESPONSE)
def hello(request):
    return HttpResponse(b'hello', content_type='application/octet-stream')

but yeah - I guess some nicer/less-wordy solution would be nice...

like maybe this should give the same result:

@api.get("/hello", response=bytes)
def hello(request):
    return b'hello'

but maybe it's not super obvious.. not sure yet - still thinking

@LevonW-IIS
Copy link
Author

Thanks for the speedy reply. Didn't manage to spot this in the docs.

Some extension of response= would be nice. There's a fair few file types where "schema": {"type": "string", "format": "binary"} would remain the same but you might want to change up the content type, e.g. application/pdf, application/zip, application/vnd.*.

Would be quite nice to use something like:

@api.get("/hello", response=BytesResponse("application/pdf"))
def hello(request):
    file_content: bytes = get_file_content()
    return file_content

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants