openapi-python-client icon indicating copy to clipboard operation
openapi-python-client copied to clipboard

Issue with client generation for FastApi version > 118

Open pintudinesh-1912 opened this issue 2 months ago • 5 comments

Describe the bug Pydantic V1 and V2 models co-existing is creating an issue with backwards compatibility. Please check the latest changes from fast api viz https://github.com/fastapi/fastapi/pull/14168 which create the models as xxxx-Input and xxxx-Output which is breaking the existing code.

pintudinesh-1912 avatar Oct 27 '25 10:10 pintudinesh-1912

Can you give me an example OpenAPI document that shows the issue? And what expected vs actual code is generated?

dbanty avatar Oct 28 '25 00:10 dbanty

I have the same issue. This is a condensed example:

{
    "openapi": "3.1.0",
    "info": {
        "title": "Test",
        "version": "0.0.1"
    },
    "paths": {
        "/endpoint": {
            "post": {
                "tags": [
                    "test"
                ],
                "summary": "Test Endpoint",
                "operationId": "test_endpoint",
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/MySchema-Input"
                            }
                        }
                    },
                    "required": true
                },
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/MySchema-Output"
                                }
                            }
                        }
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "MySchema-Input": {
                "properties": {
                    "id": {
                        "type": "string",
                        "format": "uuid",
                        "title": "Id"
                    },
                    "name": {
                        "type": "string",
                        "title": "Name"
                    }
                },
                "type": "object",
                "required": [
                    "id"
                ],
                "title": "MySchema"
            },
            "MySchema-Output": {
                "properties": {
                    "id": {
                        "type": "string",
                        "format": "uuid",
                        "title": "Id"
                    },
                    "name": {
                        "type": "string",
                        "title": "Name"
                    }
                },
                "type": "object",
                "required": [
                    "id",
                    "name"
                ],
                "title": "MySchema"
            }
        }
    }
}

Yields this output:

python -m openapi_python_client generate --meta=uv --overwrite --path failing.json                                                                                                              chore ✭ ✖ ✱ ◼
Generating /Users/emil/Code/arbo-api-client/test-client
Warning(s) encountered while generating. Client was generated, but some pieces may be missing

WARNING parsing POST /endpoint within test.

Cannot parse response for status code 200 (Could not find reference in parsed models or enums), response will be omitted from generated client

Reference(ref='#/components/schemas/MySchema-Output')

Unable to parse schema /components/schemas/MySchema-Output

Unable to parse this part of your OpenAPI document: : Attempted to generate duplicate models with name "MySchema"

Schema(title='MySchema', multipleOf=None, maximum=None, exclusiveMaximum=None, minimum=None, exclusiveMinimum=None, maxLength=None, minLength=None, pattern=None, maxItems=None, minItems=None, uniqueItems=None, maxProperties=None, minProperties=None, required=['id', 'name'], enum=None, const=None, type=<DataType.OBJECT: 'object'>, allOf=[], oneOf=[], anyOf=[], schema_not=None, items=None, prefixItems=[], properties={'id': Schema(title='Id', multipleOf=None, maximum=None, exclusiveMaximum=None, minimum=None, exclusiveMinimum=None, maxLength=None, minLength=None, pattern=None, maxItems=None, minItems=None, uniqueItems=None, maxProperties=None, minProperties=None, required=None, enum=None, const=None, type=<DataType.STRING: 'string'>, allOf=[], oneOf=[], anyOf=[], schema_not=None, items=None, prefixItems=[], properties=None, additionalProperties=None, description=None, schema_format='uuid', default=None, nullable=False, discriminator=None, readOnly=None, writeOnly=None, xml=None, externalDocs=None, example=None, deprecated=None), 'name': Schema(title='Name', multipleOf=None, maximum=None, exclusiveMaximum=None, minimum=None, exclusiveMinimum=None, maxLength=None, minLength=None, pattern=None, maxItems=None, minItems=None, uniqueItems=None, maxProperties=None, minProperties=None, required=None, enum=None, const=None, type=<DataType.STRING: 'string'>, allOf=[], oneOf=[], anyOf=[], schema_not=None, items=None, prefixItems=[], properties=None, additionalProperties=None, description=None, schema_format=None, default=None, nullable=False, discriminator=None, readOnly=None, writeOnly=None, xml=None, externalDocs=None, example=None, deprecated=None)}, additionalProperties=None, description=None, schema_format=None, default=None, nullable=False, discriminator=None, readOnly=None, writeOnly=None, xml=None, externalDocs=None, example=None, deprecated=None)

The problem is that there are multiple schemas with the same title. There is a flag in FastAPI, separate_input_output_schemas, which is supposed to prevent this, but it doesn't seem to work anymore. It seems it doesn't correctly detect if it needs to split the schemas or not anymore - as far as I can see, our -Input and -Output variants are identical in actual usage under FastAPI 0.120. But then again, it evidently splits the schemas even when I tell it not to, so...

In any case, it would be nice if the api generator worked even in the presence of these split models, maybe there could be a config to take the model name from the schema id instead of the title or something?

One final note is that it doesn't seem to help to specify class_overrides in the config (gives the exact same output), I guess those aren't applied until later or something?

class_overrides:
  MySchema-Output:
    class_name: "MySchemaOutput"
    module_name: my_schema_output
  MySchema-Input:
    class_name: "MySchemaInput"
    module_name: my_schema_input

estyrke avatar Oct 28 '25 12:10 estyrke

Actually, I missed that we had customized our openapi routes. the separate_input_output_schemas=False flag does seem to work if applied properly. 😅

estyrke avatar Oct 28 '25 12:10 estyrke

It does not seem to work for us. Even with separate_input_output_schemas=False. I'm trying to have a minimal reproducible one, but I haven't managed yet (would need to spend more time).

openapi-python-client will still need to fix this, as it seems it's there to last :-/

Mulugruntz avatar Oct 31 '25 14:10 Mulugruntz

Actually, I missed that we had customized our openapi routes. the separate_input_output_schemas=False flag does seem to work if applied properly. 😅

I was having the same issues with FastAPI > 118;

I tried:

With openapi-python-client 0.25.3

  • FastAPI == 0.118.* - worked without this flag
  • FastAPI == 0.121.0 - doesn't work without this flag

With openapi-python-client 0.27.1

  • FastAPI == 0.121.0 - doesn't work without this flag

Hope that helps

rdgsnm avatar Nov 06 '25 15:11 rdgsnm