String Binary File is just expecting BytesIO and not filename and mime-type
I have Java OpenAPI server which provides an upload endpoint (POST) that expect as schema a FileRequest ( schema = @Schema(implementation = FileRequest.class))
The FileRequest looks like:
@Value.Immutable
@JsonDeserialize(builder = com.mydata.request.FileRequest.Builder.class)
public abstract class FileRequest implements FileFields {
@Schema(type = "string", format = "binary", description = "File")
@JsonProperty
public abstract String file();
public static class Builder extends ImmutableFileRequest.Builder {
}
}
Looking at the generated code, the models looks good. This is the relevant part on types.py:
@attr.s(auto_attribs=True)
class File:
""" Contains information for file uploads """
payload: BinaryIO
file_name: Optional[str] = None
mime_type: Optional[str] = None
def to_tuple(self) -> FileJsonType:
""" Return a tuple representation that httpx will accept for multipart/form-data """
return self.file_name, self.payload, self.mime_type
T = TypeVar("T")
However, looking at the upload endpoint request, it doesn't expect the Optional values above:
@classmethod
def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T:
d = src_dict.copy()
_file = d.pop("file", UNSET)
file: Union[Unset, File]
if isinstance(_file, Unset):
file = UNSET
else:
file = File(
payload = BytesIO(_file)
)
Notice that the File expects only the binary data, losing the filename and mimetype.
Expected behavior
I would expect that the generated code would look something like below, which I patched and am using currently:
else:
file = File(
payload = BytesIO(_file['payload']),
file_name=_file['filename']
)
Desktop (please complete the following information):
- OS: Linux, but irrelevant
- openapi-python-client version: 0.11.1
- Python 3.8.10
- openapi: 3.0.1
Hi All, I too have the same requirement of uploading a pdf file via POST and I am running into a issue perhaps because of the above issue.
The relevant part from the OpenAPI.json is:
"requestBody": {
"content": {
"multipart/form-data": {
"schema": {
"required": [
"pdfDocument"
],
"type": "object",
"properties": {
"pdfDocument": {
"type": "string",
"format": "binary"
}
}
}
}
}
}
The relevant and important python code snippet generated via this json file : in types.py:
@define
class File:
"""Contains information for file uploads"""
payload: BinaryIO
file_name: Optional[str] = None
mime_type: Optional[str] = None
def to_tuple(self) -> FileJsonType:
"""Return a tuple representation that httpx will accept for multipart/form-data"""
return self.file_name, self.payload, self.mime_type
in models/post_document_multipart_data.py:
@define
class PostDocumentMultipartData:
"""
Attributes:
pdf_document (File):
"""
pdf_document: File
additional_properties: Dict[str, Any] = field(init=False, factory=dict)
def to_dict(self) -> Dict[str, Any]:
pdf_document = self.pdf_document.to_tuple()
field_dict: Dict[str, Any] = {}
field_dict.update(self.additional_properties)
field_dict.update(
{
"pdfDocument": pdf_document,
}
)
return field_dict
And finally below is my python code that tests the API:
client = AuthenticatedClient(base_url=url, token=token)
payload = open('/path/to/test.pdf', 'rb')
file: File = File(payload=payload)
multipart_data: PostDocumentMultipartData = PostDocumentMultipartData(pdf_document=file)
with client as client:
response = sync_detailed(client=client, multipart_data=multipart_data)
print(response)
But when I run this code, I always receive the error 405 (method not allowed) from the server. I have also tried setting the optional parameters of file_name and mime_type but sadly, same behavior.
NOTE: The server is implemented in Java.
Any suggestion what can be improved/corrected here ?
Regards, GSN