-
-
Notifications
You must be signed in to change notification settings - Fork 7.3k
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
The python-fastapi generator generates invalid model code when the model's OpenAPI schema specifies additionalProperties:
It lets the generated model class extend the type of the value of additionalProperties.
Also, it generates an additional_properties dict field to hold the additional properties but the generated to_dict method that would map it to the correct transfer representation is not honoured by pydantic v2 (which supports storing additional properties within the model object's __dict__ when model_config.extra=allow is specified).
For instance currently the generator generates the following model code when given a type ExampleObject that specifies a static name property as well as additionalProperties: {"type": "string"}:
example_object.py
from __future__ import annotations
import pprint
import re # noqa: F401
import json
from pydantic import ConfigDict, StrictStr
from typing import Any, ClassVar, Dict, List
from example.gen.models.str import str
try:
from typing import Self
except ImportError:
from typing_extensions import Self
class ExampleObject(str):
name: StrictStr
additional_properties: Dict[str, Any] = {}
__properties: ClassVar[List[str]] = ["name"]
model_config = {
"populate_by_name": True,
"validate_assignment": True,
"protected_namespaces": (),
}
def to_str(self) -> str:
...
def to_json(self) -> str:
...
@classmethod
def from_json(cls, json_str: str) -> Self:
...
def to_dict(self) -> Dict[str, Any]:
...
@classmethod
def from_dict(cls, obj: Dict) -> Self:
...Please note:
- It lets the model class inherit from
str(specified byadditionalPropertiesschema) and import the non-existing packageexample.gen.models.str. - It generated an
additional_propertiesdict in addition to the__dict__that already holds all model fields dynamically under the hood - the latter should be leveraged and is sufficient.
Expectation
Instead, I'd expect the following:
- It should not inherit the value type specified within the
additionalPropertiesschema. - It should not generate an additional
additional_propertiesdict but leverage the built-in__dict__which is anyway how pydantic v2 supports additional properties.
openapi-generator version
131fd51 # v7.7.0+patch
OpenAPI declaration file content or url
openapi.yaml with additionalProperties schema
openapi: "3.0.1"
info:
title: Example API
description: Example API to test additionalProperties support
version: 1.0.0
servers:
- url: /
tags:
- name: example
paths:
/example:
get:
operationId: example
summary: Example operation
description: An operation that returns an object with dynamic properties
tags:
- example
responses:
'200':
description: Example object
content:
application/json:
schema:
$ref: '#/components/schemas/ExampleObject'
components:
schemas:
ExampleObject:
type: object
properties:
name:
type: string
additionalProperties:
type: string
required:
- nameGeneration Details
Generate a python server from the previously listed openapi.yaml file using the python-fastapi generator:
openapi-generator generate -i ./openapi.yaml -g python-fastapi -o ./generated --package-name=example.generated -p sourceFolder= -p fastapiImplementationPackage=example.controller
Steps to reproduce
java -jar ./modules/openapi-generator-cli/target/openapi-generator-cli.jar generate -i ./openapi.yaml -g python-fastapi -o ./generated --package-name=example.generated -p sourceFolder= -p fastapiImplementationPackage=example.controller