OpenAPITools / OpenAPITools/openapi-generator

[BUG] Generated documentation does not match the code (snake_case vs camelCase)

Open
#14,000 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Issue: Bug
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 (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

Generated code uses camelCase variables but generated documentation uses snake case variable

We have an Event model in OpenAPI that contains these fields:

    Event:
      type: object
      x-examples:
        example-1:
          name: watched_trailer
          occuredAt: '2013-07-16T19:20:30+1:00'
          properties: {}
      properties:
        name:
          type: string
        occuredAt:
          type: string
        properties:
          type: object
      required:
        - name
        - occuredAt

Documentation generate this code snipped
Event( name="name_example", occured_at="occured_at_example", properties=dict(), )

but Generated code is the following

Details
from datetime import date, datetime  # noqa: F401
import decimal  # noqa: F401
import functools  # noqa: F401
import io  # noqa: F401
import re  # noqa: F401
import typing  # noqa: F401
import typing_extensions  # noqa: F401
import uuid  # noqa: F401

import frozendict  # noqa: F401

from crm_client import schemas  # noqa: F401


class Event(schemas.DictSchema):
    """NOTE: This class is auto generated by OpenAPI Generator.
    Ref: https://openapi-generator.tech/
    Do not edit the class manually.
    """

    class MetaOapg:
        required = {
            "name",
            "occuredAt",
        }

        class properties:
            name = schemas.StrSchema
            occuredAt = schemas.StrSchema
            properties = schemas.DictSchema
            __annotations__ = {
                "name": name,
                "occuredAt": occuredAt,
                "properties": properties,
            }

    name: MetaOapg.properties.name
    occuredAt: MetaOapg.properties.occuredAt

    @typing.overload
    def __getitem__(
        self, name: typing_extensions.Literal["name"]
    ) -> MetaOapg.properties.name:
        ...

    @typing.overload
    def __getitem__(
        self, name: typing_extensions.Literal["occuredAt"]
    ) -> MetaOapg.properties.occuredAt:
        ...

    @typing.overload
    def __getitem__(
        self, name: typing_extensions.Literal["properties"]
    ) -> MetaOapg.properties.properties:
        ...

    @typing.overload
    def __getitem__(self, name: str) -> schemas.UnsetAnyTypeSchema:
        ...

    def __getitem__(
        self,
        name: typing.Union[
            typing_extensions.Literal[
                "name",
                "occuredAt",
                "properties",
            ],
            str,
        ],
    ):
        # dict_instance[name] accessor
        return super().__getitem__(name)

    @typing.overload
    def get_item_oapg(
        self, name: typing_extensions.Literal["name"]
    ) -> MetaOapg.properties.name:
        ...

    @typing.overload
    def get_item_oapg(
        self, name: typing_extensions.Literal["occuredAt"]
    ) -> MetaOapg.properties.occuredAt:
        ...

    @typing.overload
    def get_item_oapg(
        self, name: typing_extensions.Literal["properties"]
    ) -> typing.Union[MetaOapg.properties.properties, schemas.Unset]:
        ...

    @typing.overload
    def get_item_oapg(
        self, name: str
    ) -> typing.Union[schemas.UnsetAnyTypeSchema, schemas.Unset]:
        ...

    def get_item_oapg(
        self,
        name: typing.Union[
            typing_extensions.Literal[
                "name",
                "occuredAt",
                "properties",
            ],
            str,
        ],
    ):
        return super().get_item_oapg(name)

    def __new__(
        cls,
        *args: typing.Union[
            dict,
            frozendict.frozendict,
        ],
        name: typing.Union[
            MetaOapg.properties.name,
            str,
        ],
        occuredAt: typing.Union[
            MetaOapg.properties.occuredAt,
            str,
        ],
        properties: typing.Union[
            MetaOapg.properties.properties, dict, frozendict.frozendict, schemas.Unset
        ] = schemas.unset,
        _configuration: typing.Optional[schemas.Configuration] = None,
        **kwargs: typing.Union[
            schemas.AnyTypeSchema,
            dict,
            frozendict.frozendict,
            str,
            date,
            datetime,
            uuid.UUID,
            int,
            float,
            decimal.Decimal,
            None,
            list,
            tuple,
            bytes,
        ],
    ) -> "Event":
        return super().__new__(
            cls,
            *args,
            name=name,
            occuredAt=occuredAt,
            properties=properties,
            _configuration=_configuration,
            **kwargs,
        )

This is the case for all models
When I try to init the object like suggested by the documentation, I get the following error

e = Event(occured_at="2020-10-10", name="event")

TypeError: Event.__new__() missing 1 required keyword-only argument: 'occuredAt'

This is also a breaking change compared to previous versions (where the code and documentation was generated using camelCase) so there is a need to transform all snake case calls to camel case with newly generated client

openapi-generator version

6.2.1

OpenAPI declaration file content or url
Generation Details
Steps to reproduce

Declare an OpenAPI model schema with camelCase variable and generated the client

Related issues/PRs
Suggest a fix

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

Reproduce the issue with the Event OpenAPI schema and compare the generated Python model constructor with its generated documentation example. No repository file or test is identified in the report, so locate the Python model and documentation generation paths first. Done means the documented argument names match the generated constructor and the example initializes successfully.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
api, documentation
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.