openapi-generators / openapi-generators/openapi-python-client

Upload file logic seems to be wrong on 3.1 schema

Open
#1,417 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
2k
Forks
293
Avg merge
34m
Merged PRs (30d)
1

Description

Describe the bug
I just upgraded my API, and the schema changed from 3.0 to 3.1. The uploads suddenly broke. It seems that the code generated for the body class now looks like this:

    file: str
 
    ...
    def to_multipart(self) -> types.RequestFiles:
        files: types.RequestFiles = []

        files.append(("file", (None, str(self.file).encode(), "text/plain")))

        for prop_name, prop in self.additional_properties.items():
            files.append((prop_name, (None, str(prop).encode(), "text/plain")))

        return files

While the old looked like this:

    file: File

    python
    def to_multipart(self) -> types.RequestFiles:
        files: types.RequestFiles = []

        files.append(("file", self.file.to_tuple()))

        for prop_name, prop in self.additional_properties.items():
            files.append((prop_name, (None, str(prop).encode(), "text/plain")))

        return files

Where the File object is this:

@define
class File:
    """Contains information for file uploads"""

    payload: BinaryIO
    file_name: str | None = None
    mime_type: str | None = None

    def to_tuple(self) -> FileTypes:
        """Return a tuple representation that httpx will accept for multipart/form-data"""
        return self.file_name, self.payload, self.mime_type

OpenAPI Spec File
A link to an OpenAPI document which produces this issue. Ideally, write a minimal reproduction only containing the problematic pieces.

The API spec for the body (new 3.1):

          "file": {
            "type": "string",
            "contentMediaType": "application/octet-stream",
            "title": "File"
          }

Old (3.0) schema:

          "file": {
            "type": "string",
            "format": "binary",
            "title": "File"
          }

Desktop:

  • OS: [e.g. macOS 10.15.1]: MacOS (M4) 26.3.1
  • Python Version: [e.g. 3.8.0]: 3.11.14
  • openapi-python-client version [e.g. 0.1.0]: 0.28.3

Additional context
I have some code pre-massaging around a different name-related issue and adding this to the pre-processing before this tool is called fixed it, but it's definitely more of a temporary workaround type of thing:

for prop in props.values():
      if prop.get("contentMediaType") == "application/octet-stream":
          prop["format"] = "binary"

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the generated body class from the supplied OpenAPI 3.1 schema and compare it with the 3.0 schema using format: binary. Trace how contentMediaType: application/octet-stream is interpreted during generation; done means the generated field uses File and multipart serialization calls to_tuple() as in the older output.

Written by the indexing model from the issue text.

Assessment

Tech stack
openapi, python
Domain
api, tooling
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.