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

Generation for multiple content types for a single endpoint fails when content types expect identical models

Đang mở
#1,276 1 bình luận 1 reaction 0 người được giao Xem trên GitHub

Chưa có ai nhận issue này.

Ngôn ngữ chính
Python
Star
2k
Fork
293
Merge trung bình
34 phút
Pull request đã merge (30 ngày)
1

Mô tả

Describe the bug
Support for multiple content types for a single endpoint was added in #453 / #822. However, the implemented fix generates non-functional code if the content types expect the same model. For instance, take this Api Spec snippet:

paths./api/dns/add/...
requestBody:
  content:
    application/json:
      schema:
        $ref: '#/components/schemas/DnsCreate'
    application/x-www-form-urlencoded:
      schema:
        $ref: '#/components/schemas/DnsCreate'
    multipart/form-data:
      schema:
        $ref: '#/components/schemas/DnsCreate'
  required: true

...
components.schemas...:

DnsCreate:
  type: object
  properties:
    name:
      type: string
    dns_type:
      oneOf:
      - $ref: '#/components/schemas/DnsTypeEnum'
      - $ref: '#/components/schemas/BlankEnum'
    content:
      type: string
    ttl:
      type: integer
      maximum: 2147483647
      minimum: -2147483648
      nullable: true
  required:
  - content
  - dns_type
  - name

All 3 content types expect the same content type: DnsCreate. However, this generates this Python code:

def _get_kwargs(
    *,
    body: Union[
        DnsCreate,
        DnsCreate,
        DnsCreate,
    ],
) -> dict[str, Any]:
    headers: dict[str, Any] = {}

    _kwargs: dict[str, Any] = {
        "method": "post",
        "url": "/api/dns/add/",
    }

    if isinstance(body, DnsCreate):
        _kwargs["json"] = body.to_dict()

        headers["Content-Type"] = "application/json"
    if isinstance(body, DnsCreate):
        _kwargs["data"] = body.to_dict()

        headers["Content-Type"] = "application/x-www-form-urlencoded"
    if isinstance(body, DnsCreate):
        _kwargs["files"] = body.to_multipart()

        headers["Content-Type"] = "multipart/form-data"

    _kwargs["headers"] = headers
    return _kwargs

This results in all requests made to this endpoint being treated as multipart form data, and it is impossible to make a JSON or form-urlencoded request.

Desktop (please complete the following information):

  • Python Version: 3.12.3
  • openapi-python-client version: 0.25.0

Additional context
While it may seem odd to support 3 different content types for the same endpoint, this specification has the advantage of making Django Rest Framework's interactive API support form uploads (instead of requiring you to manually edit JSON). While I'm sure this is a more niche problem, I think we can all agree that this is problematic code generation. While I haven't contributed to this repo, perhaps supporting an additional content type parameter is the solution (rather than relying on isinstance calls).

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Hướng nghiên cứu

Bắt đầu bằng cách tái hiện việc sinh mã với đoạn OpenAPI trong issue và kiểm tra hàm endpoint _get_kwargs đã được sinh. Theo dõi cách các model giống hệt nhau được liên kết với từng loại nội dung của request; hoàn tất khi các request JSON, form-urlencoded và multipart vẫn có thể được chọn thay vì bị branch cuối cùng ghi đè.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Đánh giá

Công nghệ
openapi, python
Lĩnh vực
api, tooling
Loại issue
Lỗi
Độ khó
4/5
Thời gian dự kiến
3-5 ngày
Mức độ hoạt động
Đình trệ
Độ rõ ràng
Khá rõ ràng
Mức phù hợp với người mới
45/100

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.