question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[QUESTION] Can the OpenAPI Schema autogenerated from an UploadFile be customised?

See original GitHub issue

First check

  • [✔️] I used the GitHub search to find a similar issue and didn’t find it.
  • [✔️] I searched the FastAPI documentation, with the integrated search.
  • [✔️] I already searched in Google “How to X in FastAPI” and didn’t find any information.

Description

Is it possible to customise the documentation generated by fastapi when I define an UploadFile object to a POST method?

Additional context

Say for example I had a method like this where a file can be uploaded:

@router.post("/entity/new",)
async def upload_new_entity(file: UploadFile = File(...):
    return {"filename": file.filename}

This seems to generate an entry in the schemas section of the docs with the pattern of Body<func_name><path><method>

So my example above will have a Schema entry with the name: Body_upload_new_entity_entity_new_post

The docs for UploadFile don’t mention anything about OpenAPI docs.

Is it possible to specify a name for this UploadFile instead? And ideally also customise the details within the schema?

Thanks

Issue Analytics

  • State:open
  • Created 3 years ago
  • Reactions:7
  • Comments:12 (2 by maintainers)

github_iconTop GitHub Comments

5reactions
synchronizingcommented, Mar 26, 2021

After some investigation this is possible, but it requires some monkey patching. Using the example given here, the solution looks like so:

from fastapi import FastAPI, File, UploadFile
from typing import Callable

app = FastAPI()

@app.post("/files/")
async def create_file(file: bytes = File(...)):
    return {"file_size": len(file)}

@app.post("/uploadfile/")
async def create_upload_file(file: UploadFile = File(...)):
    return {"filename": file.filename}

def update_schema_name(app: FastAPI, function: Callable, name: str) -> None:
    """
    Updates the Pydantic schema name for a FastAPI function that takes
    in a fastapi.UploadFile = File(...) or bytes = File(...).

    This is a known issue that was reported on FastAPI#1442 in which
    the schema for file upload routes were auto-generated with no
    customization options. This renames the auto-generated schema to
    something more useful and clear.

    Args:
        app: The FastAPI application to modify.
        function: The function object to modify.
        name: The new name of the schema.
    """
    for route in app.routes:
        if route.endpoint is function:
            route.body_field.type_.__name__ = name
            break

update_schema_name(app, create_file, "CreateFileSchema")
update_schema_name(app, create_upload_file, "CreateUploadSchema")

Screen Shot 2021-03-02 at 12 52 04 AM

4reactions
adriangbcommented, Apr 15, 2021

Here is a solution to move the schema from the Schemas to the path itself in OpenAPI without touching the routing or anything:

from fastapi import FastAPI, File, UploadFile
from fastapi.openapi.utils import get_openapi


app = FastAPI()


@app.post("/uploadfile/")
async def create_upload_file(file1: UploadFile = File(...), file2: UploadFile = File(...)):
    pass


def custom_openapi():
    if app.openapi_schema:
        return app.openapi_schema
    openapi_schema = get_openapi(
        title="Custom title",
        version="2.5.0",
        description="This is a very custom OpenAPI schema",
        routes=app.routes,
    )
    # Move autogenerated Body_ schemas, see https://github.com/tiangolo/fastapi/issues/1442
    for path in openapi_schema["paths"].values():
        for method_data in path.values():
            if "requestBody" in method_data:
                for content_type, content in method_data["requestBody"]["content"].items():
                    if content_type == "multipart/form-data":
                        schema_name = content["schema"]["$ref"].lstrip("#/components/schemas/")
                        schema_data = openapi_schema["components"]["schemas"].pop(schema_name)
                        content["schema"] = schema_data
    app.openapi_schema = openapi_schema
    return app.openapi_schema

app.openapi = custom_openapi

In this case, my main goal was to just not list this as a Schema in swagger. But presumably something similar could be done to rename the models (although I don’t think it’s very helpful to have them in the Schemas section, especially since they’re unique to each endpoint/method).

Since modifying/extending the OpenAPI schema is documented in the FastAPI docs and the OpenAPI schema spec itself is very well documented, I think this is a decent solution, though I’d be curious to get input from others on how reliable (or not) this might be since I feel there might be sharp edges.

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to create an OpenAPI schema for an UploadFile in ...
This is a known issue that was reported on FastAPI#1442 in which the schema for file upload routes were auto-generated with no customization...
Read more >
How to Generate an OpenAPI Spec From Code - BlazeMeter
You can download the autogenerated OpenAPI definition from your local web server, do your edits and then upload it to its final destination,...
Read more >
An adventure in OpenAPI V3 code generation | Mux blog
OpenAPI is a way of describing your APIs in a YAML (or JSON) file. You model the data structures exposed and accepted by...
Read more >
ReadMe: OpenAPI and Swagger for API Documentation
When you write your OpenAPI or Swagger docs, you can choose from either of two formats: JSON or YAML. Both will use the...
Read more >
Extending OpenAPI - FastAPI - tiangolo
You can use the property .openapi_schema as a "cache", to store your generated schema. That way, your application won't have to generate the...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found