[python-fastapi] type binary multipart fields as UploadFile

Merged
ZS
6mo ago
+131-3

Fixes #20115.

Problem

The python-fastapi server generator typed multipart/form-data fields with format: binary using the client-side bytes union — Union[StrictBytes, StrictStr, Tuple[StrictStr, StrictBytes]] — and bound them via Form(None, ...). FastAPI parses such fields into UploadFile instances at request time, so Pydantic rejected valid uploads with HTTP 422 (Input should be a valid bytes / Input should be a valid string).

Fix

  • PythonFastAPIServerCodegen now overrides x-py-typing for isFormParam && isFile parameters: UploadFile when required, Optional[UploadFile] otherwise. It also injects from fastapi import File, UploadFile into the operation imports when at least one such parameter is present.
  • endpoint_argument_definition.mustache emits File(...) (with ... as the default for required file params, None for optional) instead of Form(None, ...) when the parameter is a binary form file.
  • The abstract base class signature follows automatically via param_type.mustache, which already reads x-py-typing.

Before / after

Before:

file: Annotated[Optional[Union[StrictBytes, StrictStr, Tuple[StrictStr, StrictBytes]]], Field(description="file to upload")] = Form(None, description="file to upload")

After:

file: Optional[UploadFile] = File(None, description="file to upload")

The client-side python generators are untouched — they still use the bytes-union for outbound multipart calls.

Tests / samples

  • Added testBinaryMultipartFieldUsesUploadFile plus a minimal issue_20115.yaml fixture covering both required and optional binary form fields. Asserts UploadFile / Optional[UploadFile] typing, File(...) / File(None, ...) defaults, the from fastapi import File, UploadFile import on both api.py and _base.py, and the absence of the legacy bytes-union.
  • Regenerated samples/server/petstore/python-fastapi/. The only diff is the upload_file endpoint and its imports in pet_api.py and pet_api_base.py.
  • mvn -pl modules/openapi-generator test -Dtest=PythonFastAPIServerCodegenTest — 6/6 pass.

PR checklist

  • Read the contribution guidelines.
  • Pull Request title clearly describes the work in the pull request and Pull Request description provides details about how to validate the work.
  • Run ./mvnw clean package, regenerated samples/server/petstore/python-fastapi/, and committed the changes. (Scoped to the python-fastapi generator; happy to widen the regen if maintainers want it.)
  • File the PR against master.
  • Reference the reported issue (fixes #20115).
  • @mention Python technical committee: @cbornet @tomplus @krjakbrjak @fa0311 @multani — cc @krjakbrjak as the original python-fastapi generator author.

Summary by cubic

Fix binary multipart form parameters in the python-fastapi server generator by typing them as UploadFile and binding with File(...) instead of Form(...). This prevents HTTP 422 errors on valid uploads and matches FastAPI’s request parsing.

  • Bug Fixes
    • For form file params, set x-py-typing to UploadFile or Optional[UploadFile].
    • Use File(...)/File(None, ...) in endpoint signatures; no longer use Form(...) for files.
    • Add from fastapi import File, UploadFile when needed.
    • Add tests for required/optional file fields and update the petstore sample. Client generators are unchanged.