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

[Multi-part upload] TypeError: Object of type BytesIO is not JSON serializable

未关闭
#771 3 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

🐞bug
主要语言
Python
星标
2k
派生
293
平均合并
34 分钟
30 天内合并 PR
1

描述

I have a generated client code for FastAPI multi-file upload endpoint which I'm using like this:

file_names = ['fd1.py', 'fd2.py']
files = []
for f in file_names:
    with open(f, 'rb') as fh:
        buf = BytesIO(fh.read())
        files.append(buf)

multipart_data = BodyUploadFeatureDefinitionFeatureDefinitionPost(
    files=[File(payload=files[i], file_name=file_names[i], mime_type='text/x-python') for i in range(len(files))]
    tags=[] # not relevant
)

res = upload_feature_definition_feature_definition_post.sync(
    client=self.client,
    multipart_data=multipart_data
)

I get an error:


Traceback (most recent call last):
  File "/Users/anov/IdeaProjects/svoe/client/featurizer_client/featurizer_client.py", line 77, in <module>
    client.register_feature_definition(
  File "/Users/anov/IdeaProjects/svoe/client/featurizer_client/featurizer_client.py", line 63, in register_feature_definition
    res = upload_feature_definition_feature_definition_post.sync(
  File "/Users/anov/IdeaProjects/svoe/client/fast_api_client/api/default/upload_feature_definition_feature_definition_post.py", line 146, in sync
    return sync_detailed(
  File "/Users/anov/IdeaProjects/svoe/client/fast_api_client/api/default/upload_feature_definition_feature_definition_post.py", line 103, in sync_detailed
    kwargs = _get_kwargs(
  File "/Users/anov/IdeaProjects/svoe/client/fast_api_client/api/default/upload_feature_definition_feature_definition_post.py", line 40, in _get_kwargs
    multipart_multipart_data = multipart_data.to_multipart()
  File "/Users/anov/IdeaProjects/svoe/client/fast_api_client/models/body_upload_feature_definition_feature_definition_post.py", line 67, in to_multipart
    files = (None, json.dumps(_temp_files).encode(), "application/json")
  File "/Users/anov/miniconda3/envs/env_py_3-10/lib/python3.10/json/__init__.py", line 231, in dumps
    return _default_encoder.encode(obj)
  File "/Users/anov/miniconda3/envs/env_py_3-10/lib/python3.10/json/encoder.py", line 199, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/Users/anov/miniconda3/envs/env_py_3-10/lib/python3.10/json/encoder.py", line 257, in iterencode
    return _iterencode(o, 0)
  File "/Users/anov/miniconda3/envs/env_py_3-10/lib/python3.10/site-packages/frozendict/__init__.py", line 32, in default
    return BaseJsonEncoder.default(self, obj)
  File "/Users/anov/miniconda3/envs/env_py_3-10/lib/python3.10/json/encoder.py", line 179, in default
    raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type BytesIO is not JSON serializable

Generated File class:

@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

Looks like generated code tries to call json.dumps() on tuple representation of File, which has BinaryIO field, this causes the exception.

What am I doing wrong?

贡献指南

打开贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

调研方向

先从生成的 body_upload_feature_definition_feature_definition_post.py 模型及其 to_multipart() 方法开始,然后跟踪 upload_feature_definition_feature_definition_post.py 中对 _get_kwargs() 的调用。使用所示的 FileBytesIO 值重现 multipart 请求;当有效的文件 payload 不再在 JSON 序列化期间失败时,即表示完成。

由索引模型根据 Issue 内容生成。

评估

技术栈
fastapi, openapi, python
领域
api, tooling
Issue 类型
缺陷
难度
4/5
预计耗时
3-5 天
活跃度
停滞
描述清晰度
基本清楚
新手友好度
32/100

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。