Skip to content

Invalid python generated when using nested dictionaries #266

Closed

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

Activity

  1. dbanty commented on Dec 15, 2020

    @dbanty
    Collaborator

    Thanks for reporting the bug, we'll have to make sure we add an end to end test case with nesting like this so we don't miss it in the future 😅. I should have a chance to fix this at the end of the week, but CC @packyg in case you get a moment to check this out before I do.

  2. added this to the 0.7.3 milestone on Dec 15, 2020
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

    🐞bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions