OpenAPITools / OpenAPITools/openapi-generator
[BUG] [Python-flask] Enum value validation occur 500 error on stub server
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 26.8k
- Forks
- 7.7k
- PR merge metrics
- PR metrics pending
Description
First of all, I want to thank all contributors!
Bug Report Checklist
- Have you provided a full/minimal spec to reproduce the issue?
- Have you validated the input using an OpenAPI validator (example)?
- 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
If a property has an enum setting and is not nullable, API gets 500 error.
requestBody:
content:
application/json:
schema:
type: object
properties:
foo_id:
type: string
enum:
- 'foo'
- 'bar'
openapi-generator version
6.2.0
OpenAPI declaration file content or url
openapi: 3.0.0
info:
description: Appreciate so much contributors
version: 1.0.0
title: Hello OpenAPI
contact:
email: shimizu@thedott.io
tags:
- name: Tag
description: the Tag
paths:
/foobar/{foo_id}:
get:
tags:
- Tag
summary: foo
description: bar
operationId: foobar_get
parameters:
- in: path
name: foo_id
schema:
type: string
enum:
- 'foo'
- 'bar'
required: true
responses:
'200':
description: foobar
/foobar:
post:
tags:
- Tag
summary: foo
description: bar
operationId: foobar_post
requestBody:
content:
application/json:
schema:
type: object
properties:
foo_id:
type: string
enum:
- 'foo'
- 'bar'
responses:
'200':
description: foobar
Generation Details
openapi-generator generate -i swagger-build.yaml -g python-flask
Python 3.8.12
Steps to reproduce
- Make a parameter with an enum and not nullable in RequestBody
- Generate stub server
- Post a correct param to the API
- Got 500 error
Related issues/PRs
Suggest a fix
It worked in my 5.3.1 generator.
I think the problem is in __init__ function in Autogenerated Model class.
In 5.3.1, member variables in the init function were private (like self._foobar) but public (self.foobar) in 6.2.0.
This change causes a problem.
The setter is called forcibly when assigning some variable to a public member like as following sample:
class Foo():
def __init__(self, foo_id=None):
self.foo_id = foo_id ## Setter called (6.2.0)
self._foo_id = foo_id ## Setter doesn't call (5.3.1)
@property
def foo_id(self):
return self._foo_id
@foo.setter
def foo_id(self, foo_id):
print('Setter called')
self._foo_id = foo_id
The detailed problem is in the deserialize_model function that excuted by using `Model.from_dict() function.
def deserialize_model(data, klass):
"""Deserializes list or dict to model.
:param data: dict, list.
:type data: dict | list
:param klass: class literal.
:return: model object.
"""
instance = klass()
if not instance.openapi_types:
return data
for attr, attr_type in six.iteritems(instance.openapi_types):
if data is not None \
and instance.attribute_map[attr] in data \
and isinstance(data, (list, dict)):
value = data[instance.attribute_map[attr]]
setattr(instance, attr, _deserialize(value, attr_type))
return instance
The class is called without any parameters in instance = klass() and will cause a 500.
In this moment, the param is None and raise ValueError.
Invalid value for `foo_id` (None), must be one of ['foo', 'bar']
I understand the problem, ... but I don't know how it should be so I cannot make any PR.
I'm using nullable: true setting for the workaround this time.
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 by generating a python-flask stub from the OpenAPI declaration and reproduce the 500 error with the enum request body. Read the generated model class's init function and the deserialize_model function, focusing on how None is handled before enum validation. Done means a valid request no longer triggers a 500 error while invalid enum values remain validated.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- flask, openapi, python
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100