OpenAPITools / OpenAPITools/openapi-generator
[BUG][PYTHON] Post request arguments not properly sent
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 26.8k
- Forks
- 7.7k
- PR merge metrics
- PR metrics pending
Description
Bug Report Checklist
- Have you provided a full/minimal spec to reproduce the issue?
- Have you validated the input using an OpenAPI validator?
- Have you tested with the latest master to confirm the issue still exists?
- Have you searched for related issues/PRs?
- What's the actual output vs expected output?
- [Optional] Sponsorship to speed up the bug fix or feature request (example)
Description
The issue I have is with a generated client SDK for the Wekan project.
The generated sdk fails to work (partially) for some api endpoints.
If 'content type' of an api endpoints accepts several options, but json included, json will be chosen (by default, as default (see select_header_content_type)).
When no 'schema' is defined for the input parameters, the generated code used _form_params (instead of _body_params, which later is converted to a dict) as the aggregator of the parameters.
Then, in the request function, body is None, and post_params has a list of tuples (actually key:value). The POST flow with json content-type is reached which fully IGNORES the post_params.
openapi-generator version
version 7.21.0
OpenAPI declaration file content or url
https://raw.githubusercontent.com/wekan/wekan/refs/tags/v8.00/public/api/wekan.yml
A specific example is the /api/boards POST request (ie creating boards).
post:
operationId: new_board
summary: Create a board
description: |
This allows to create a board.
The color has to be chosen between `belize`, `nephritis`, `pomegranate`,
`pumpkin`, `wisteria`, `moderatepink`, `strongcyan`,
`limegreen`, `midnight`, `dark`, `relax`, `corteza`:
<img src="https://wekan.github.io/board-colors.png" width="40%" alt="Wekan logo" />
tags:
- Boards
consumes:
- multipart/form-data
- application/json
parameters:
- name: title
in: formData
description: |
the new title of the board
type: string
required: true
- name: owner
in: formData
description: |
"ABCDE12345" <= User ID in Wekan.
(Not username or email)
type: string
required: true
- name: isAdmin
in: formData
description: |
is the owner an admin of the board (default true)
type: boolean
required: false
- name: isActive
in: formData
description: |
is the board active (default true)
type: boolean
required: false
- name: isNoComments
in: formData
description: |
disable comments (default false)
type: boolean
required: false
- name: isCommentOnly
in: formData
description: |
only enable comments (default false)
type: boolean
required: false
- name: isWorker
in: formData
description: |
only move cards, assign himself to card and comment (default false)
type: boolean
required: false
- name: permission
in: formData
description: |
"private" board <== Set to "public" if you
want public Wekan board
type: string
required: false
- name: color
in: formData
description: |
the color of the board
type: string
required: false
produces:
- application/json
security:
- UserSecurity: []
responses:
'200':
description: |-
200 response
schema:
type: object
properties:
_id:
type: string
defaultSwimlaneId:
type: string
Generation Details
Generated a python SDK for that spec via something like this:
openapi-generator-cli generate -i spec.yml -g python -o ~/wekan_sdk/ --skip-validate-spec --package-name wekan --additional-properties generateSourceCodeOnly=false,packageName=wekan
Steps to reproduce
Worth mentioning that the login WORKS because the sdk generated the code to use _body_params.
The expected result is for the new_board call not to throw a 500
# sdk_client is just a `wekan_client.ApiClient` with the proper host and configuration.
import os
import wekan_client
login_api = wekan_client.LoginApi(sdk_client)
login_response = login_api.login(
LoginRequest(
username=os.getenv("API_USERNAME", "test_user"),
password=os.getenv("API_PASSWORD", "test_password"),
)
)
title = f"Test Board {uuid.uuid4().hex[:8]}"
api_instance = wekan_client.BoardsApi(sdk_client)
response = api_instance.new_board(
title,
login_response.id,
is_admin=True,
is_active=True,
permission="public",
color="belize",
)
Suggest a fix
Adding
if not body and post_params:
body = json.dumps(dict(post_params))
Just before https://github.com/OpenAPITools/openapi-generator/blob/e6ef8ee728c8c2b4d22bc869fc81d3cf819575a7/modules/openapi-generator/src/main/resources/python/tornado/rest.mustache#L125
will allow us to support it, WITHOUT breaking anything else.
It will look something like this:
...
if re.search('json', headers['Content-Type'], re.IGNORECASE):
if body:
body = json.dumps(body)
if not body and post_params:
body = json.dumps(dict(post_params))
request.body = body
...
I'm willing to create the PR and follow through
Thanks in advance for the help :)
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with modules/openapi-generator/src/main/resources/python/tornado/rest.mustache near line 125 and trace how body and post_params are handled for JSON requests. Reproduce the /api/boards new_board call from the Wekan specification, then verify that form parameters are included in the JSON request and the call no longer returns a 500.
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
- Clearly specified
- Newbie friendliness
- 74/100