OpenAPITools / OpenAPITools/openapi-generator

[BUG] [Python-flask] Enum value validation occur 500 error on stub server

Open
#13,837 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Issue: Bug Server: Python
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
  1. Make a parameter with an enum and not nullable in RequestBody
  2. Generate stub server
  3. Post a correct param to the API
  4. 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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.