Skip to content

Invalid python generated when using nested dictionaries #266

Closed
@joshzana

Description

@joshzana

Describe the bug
Using openapi-python-client on a valid FastAPI/pydantic API is generating invalid client library on 0.7.2 when there is a somewhat complex set of nested Dict and Union types.

To Reproduce
Put the following in a main.py

from typing import Any, Dict, List, Union
from fastapi import FastAPI
from pydantic import (
    BaseModel,
    StrictBool,
    StrictInt,
    StrictFloat,
    StrictStr,
)

app = FastAPI()

JSONValue = Union[
    Dict[str, Any], List[Any], StrictBool, StrictFloat, StrictInt, StrictStr, None
]
JSONDict = Dict[str, JSONValue]

class ItemMapResource(BaseModel):
    items: JSONDict

@app.get("/", response_model=ItemMapResource)
def read_item():
    return ItemMapResource(items={})

Run it like this:

 uvicorn main:app --reload --port 4000

Generate a client library like this

openapi-python-client generate --url  http://localhost:4000/openapi.json

Expected behavior
Should generate valid python library

Actual behavior
Generates code with broken indents which fails to execute:

@attr.s(auto_attribs=True)
class ItemMapResourceItems:
    """  """
    additional_properties: Dict[str, Union[ItemMapResourceItemsAdditionalProperty, List[None], bool, float, int, str]] = attr.ib(init=False, factory=dict)


    def to_dict(self) -> Dict[str, Any]:

        field_dict: Dict[str, Any] = {}
        for prop_name, prop in self.additional_properties.items():
            if isinstance(prop, ItemMapResourceItemsAdditionalProperty):
        field_dict[prop_name] = prop.to_dict()

    elif isinstance(prop, List[None]):
        field_dict[prop_name] = []
        for additional_property_item_data in prop:
            additional_property_item =  None

            field_dict[prop_name].append(additional_property_item)




    elif isinstance(prop, bool):
        field_dict[prop_name] = prop
    elif isinstance(prop, float):
        field_dict[prop_name] = prop
    elif isinstance(prop, int):
        field_dict[prop_name] = prop
    else:
        field_dict[prop_name] = prop

        field_dict.update({
        })

        return field_dict

Note the line if isinstance(prop, ItemMapResourceItemsAdditionalProperty): is indented incorrectly.

OpenAPI Spec File

{"openapi":"3.0.2","info":{"title":"FastAPI","version":"0.1.0"},"paths":{"/":{"get":{"summary":"Read Item","operationId":"read_item__get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ItemMapResource"}}}}}}}},"components":{"schemas":{"ItemMapResource":{"title":"ItemMapResource","required":["items"],"type":"object","properties":{"items":{"title":"Items","type":"object","additionalProperties":{"anyOf":[{"type":"object"},{"type":"array","items":{}},{"type":"boolean"},{"type":"number"},{"type":"integer"},{"type":"string"}]}}}}}}}

Desktop (please complete the following information):

  • OS: Ubuntu 20.04
  • Python Version: 3.8.3
  • openapi-python-client version 0.7.2

Additional context
This worked fine with 0.7.0, so I suspect a regression from #252

Metadata

Metadata

Assignees

No one assigned

    Labels

    🐞bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions