swagger-api / swagger-api/swagger-codegen
[Python] auto generated python-flask server fails to map in-body parameter name
Nobody has claimed this yet.
- Dominant language
- Mustache
- Stars
- 17.8k
- Forks
- 6k
- PR merge metrics
- No merged PRs in 30d
Description
Preface
When using a body parameter, the name is only used for documentation purposes OpenAPI 2.0 specification:
[...] The name of the body parameter has no effect on the parameter itself and is used for documentation purposes only. [...]
According to the Connexion documentatoin it makes a name sanitation for parameter names:
The names of query and form parameters, as well as the name of the body parameter are sanitized by removing characters that are not allowed in Python symbols.
With the following command:
re.sub('^[^a-zA-Z_]+', '', re.sub('[^0-9a-zA-Z_]', '', PARAMETER_NAME))
Description
Swagger converts underscored in-body property name, when generating python-flask server, to the CamelCase, so connexion can not map it.
(The simple swagger.yaml to reproduce the issue is in this Gist)
So the following definition
parameters:
- in: body
name: test_object
description: object that fails to map
schema:
$ref: '#/definitions/TestObject'
Will lead to the following code:
def endpoint_post(testObject = None) -> str:
return 'do some magic! '
As you can see it turns test_object to testObject.
But when mapping the parameters, connexion would expect test_object, since it is a result of
re.sub('^[^a-zA-Z_]+', '', re.sub('[^0-9a-zA-Z_]', '', 'test_object'))
As the result the server accepts the correct request, but fails to map it because of the bad variable name.
Swagger-codegen version
The online version of the swagger editor, and generator (through the editor menu) on https://app.swaggerhub.com
Swagger declaration file content or url
this yaml is a simple reproduction example
Command line used for generation
none - generated via swaggerhub
Steps to reproduce
Tested with Python 3.5.2, Flask 0.12.2 and connexion 1.1.13 on Ubuntu 16.04
- generate online the python-flask server using this yaml
- Edit
default_controller.pyin./controllersto display the output of the request (for the debug purposes) e.g. like this:
def endpoint_post(testObject = None) -> str:
return 'do some magic! ' + str(testObject)
- run it with:
$> python app.py - Get sure the request validation works by sending from another terminal a bad request (
property_sixinstead ofproperty_one) viacurl:
$> curl -X POST -H "Content-Type: application/json" --data '{"property_six":"ONE", "property_two":"TWO", "property_three":"THREE"}' http://127.0.0.1:8080/endpoint
validation works:
{
"detail": "'property_one' is a required property",
"status": 400,
"title": "Bad Request",
"type": "about:blank"
}
- Send now the correct request via
curl:
$> curl -X POST -H "Content-Type: application/json" --data '{"property_one":"ONE", "property_two":"TWO", "property_three":"THREE"}' http://127.0.0.1:8080/endpoint
The request was accepted, but not mapped to testObject – it is None (default value)
"do some magic! None"
- Rename auto generated
testObjectin thedefault_controller.pytotest_objectto get sure, it's a name issue.
def endpoint_post(test_object = None) -> str:
return 'do some magic! ' + str(test_object)
- Send again the correct request via
curl:
$> curl -X POST -H "Content-Type: application/json" --data '{"property_one":"ONE", "property_two":"TWO", "property_three":"THREE"}' http://127.0.0.1:8080/endpoint
et voila: the mapping works like it should:
"do some magic! {'property_one': 'ONE', 'property_two': 'TWO', 'property_three': 'THREE'}"
Related issues/PRs
not seen before
Suggest a fix/enhancement
The problem is caused trhough the name conversion. Maybe when generating this part of the code the name conversion should be similar to
re.sub('^[^a-zA-Z_]+', '', re.sub('[^0-9a-zA-Z_]', '', PARAMETER_NAME))
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
Reproduce the generated Python-Flask server from the linked YAML, then inspect the generated default_controller.py and app.py alongside the parameter-name sanitation behavior described in the issue. The fix is complete when an underscored body parameter such as test_object is mapped correctly without manually renaming the generated controller argument, and the documented curl request returns the request body rather than None.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- flask, python
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 45/100