openapi-generator icon indicating copy to clipboard operation
openapi-generator copied to clipboard

[BUG] [PYTHON] Generated Python code fails to deserialize dictionary objects

Open damzog opened this issue 10 months ago • 3 comments

Description

Generated Python code fails to deserialize dictionary objects

openapi-generator version

7.5.0

OpenAPI declaration file content or url

see this repo for complete example and explanation.

Generation Details

Problem is probably caused by the code to deserialize a dict:

    @classmethod
    def from_dict(cls, obj: Dict) -> Self:
        """Create an instance of User from a dict"""
        if obj is None:
            return None

        # Why don't we just let handle pydantic the deserialization? The generated code completely ignores the relations 
        # attribute.
        # 
        # This code works for me
        #  _obj = cls.model_validate(obj)
        # return _obj
        # 
        # The generated code below does not
        if not isinstance(obj, dict):
            return cls.model_validate(obj)

        _obj = cls.model_validate({
            "name": obj.get("name"),
            "address": Address.from_dict(obj.get("address")) if obj.get("address") is not None else None,
        })
        return _obj
Steps to reproduce

Checkout this repo pip install -r requirements.txt uvicorn main:app --reload python client.py

Related issues/PRs
Suggest a fix

damzog avatar Apr 22 '24 15:04 damzog

so if you remove/comment out the following:

        if not isinstance(obj, dict):
            return cls.model_validate(obj)

the code works as expected?

wing328 avatar Apr 24 '24 10:04 wing328

@wing328 no. In my case all obj passed to this class are instance of dict so this code is anyway noop. It does work if you omit the "not" meaning if you simply return return cls.model_validate(obj) . In that case pydantic will deserialize (one might to also need to assign the result to _obj)

damzog avatar Apr 24 '24 11:04 damzog

And as you can see

  _obj = cls.model_validate({
            "name": obj.get("name"),
            "address": Address.from_dict(obj.get("address")) if obj.get("address") is not None else None,
        })

filters out all entries from a dict that are not name, address which I do not understand why (sorry code snippet is not completely up to date. I removed address and added age in the example repo but it does not make a difference.)

damzog avatar Apr 24 '24 11:04 damzog