Skip to content

invalid code is generated when mixing lists of type and lists of schema using anyOf #136

Description

@jktr

Hi! I'm trying to generate a client for an API that returns a list of items, and am seeing invalid code being generated.

The returned items are either all strings or all instances of a specific BaseModel ("Foo"), depending on the value of a query parameter. The API is implemented in FastAPI using response_model = list[str] | list[Foo], which results in an openapi spec that uses anyOf for two arrays, one of type string and the other one referencing the Foo schema.

Trying to run openapi-python-generator on this spec generates the following invalid code, which fails at the black step during compilation.

return [Foo],List[str](**item) for item in body]

I'm using openapi-python-generator v2.1.2, installed via uv into a venv.

To reproduce, run openapi-python-generator openapi.json foo --formatter none using the (minimal) openapi.json below and examine the generated foo/services/default_service.py (also below).

`openapi.json`
{
  "openapi": "3.1.0",
  "info": {
    "title": "FastAPI",
    "version": "0.1.0"
  },
  "paths": {
    "/foo": {
      "get": {
        "tags": [],
        "summary": "Foo",
        "description": "Foo",
        "operationId": "foo",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "anyOf": [
                    {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Foo"
                      }
                    },
                    {
                      "type": "array",
                      "items": {
                        "type": "string",
                      }
                    }
                  ],
                  "title": "Foo"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Foo": {
        "properties": {
          "foo": {
            "type": "string",
            "title": "Foo"
          }
        },
        "type": "object",
        "required": [
          "foo"
        ],
        "title": "Foo",
        "description": "Foo"
      }
    }
  }
}
malformed `return` statement at `foo/services/default_service.py`
from typing import *
import httpx


from ..models import *
from ..api_config import APIConfig, HTTPException

def foo(api_config_override : Optional[APIConfig] = None) -> Union[List[Foo],List[str]]:
    api_config = api_config_override if api_config_override else APIConfig()

    base_path = api_config.base_path
    path = f'/foo'
    headers = {
        'Content-Type': 'application/json',
        'Accept': 'application/json',
        'Authorization': f'Bearer { api_config.get_access_token() }',
        
    }
    query_params : Dict[str,Any] = {
        }

    query_params = {key:value for (key,value) in query_params.items() if value is not None}

    with httpx.Client(base_url=base_path, verify=api_config.verify) as client:
        response = client.request(
            'get',
        httpx.URL(path),
        headers=headers,
        params=query_params,
            )

    if response.status_code != 200:
        raise HTTPException(response.status_code, f'foo failed with status code: {response.status_code}')
    else:
                body = None if 200 == 204 else response.json()

    return [Foo],List[str](**item) for item in body]

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions