koxudaxi/fastapi-code-generator

Encode enums as typing.Literal instead of Enum class

FeherMarcell opened this issue · 0 comments

When only specific values are allowed for a property in OpenAPI, they are listed as an enum, which is translated to an Enum class in the generated Python model. Unfortunately, when the model is converted to a dictionary using the Pydantic built-in model.dict() method, the dict field value is an Enum class instance, not the primitive value (e.g., string). It would work as intended if the enums would be encoded as typing.Literal instead.

OpenAPI:

AccessModel:
  type: object
  properties:
    access:
      type: string
      description: "Only 'readonly' or 'readwrite' is allowed"
      enum:
        - readonly
        - readwrite

Current generated model code:

class Access(Enum):
    readonly = 'readonly'
    readwrite = 'readwrite'

class AccessModel(BaseModel):
    access: Access = Field(
        ...,
        description='Only 'readonly' or 'readwrite' is allowed',
    )

Converting a model instance to a dictionary with access_model.dict() yields {'access': <Access.readonly: 'readonly'>}.

I'm proposing using typing.Literal to encode OpenAPI enums the following way:

from typing import Literal
class AccessModel(BaseModel):
    access: Literal['readonly', 'readwrite'] = Field(
        ...,
        description='Only 'readonly' or 'readwrite' is allowed',
    )

Converting an instance of this yields a dictionary with the correct primitive type: {'access': 'readonly'}