swagger-api / swagger-codegen

swagger-codegen contains a template-driven engine to generate documentation, API clients and server stubs in different languages by parsing your OpenAPI / Swagger definition.
http://swagger.io
Apache License 2.0
17.02k stars 6.03k forks source link

Python: `obj.to_dict()` methods return wrong structures because they do not use `attribute_map` #8948

Open Ark-kun opened 5 years ago

Ark-kun commented 5 years ago
Description

Generated model code does not make any use of the attribute_map table which holds the mapping between the OpenAPI property names and pythonic property names.

If you have an object with camelCaseProperty, then swagger will generate a model with the camel_case_property field and record the mapping in the attribute_map. Unfortunately, when calling obj.to_dict() this map is not used and the resulting object will be incorrect.

The proper conversion is be performed by the ApiClient.sanitize_for_serialization method which requires first creating the client object. I'm arguing that this conversion should be built-in the obj.to_dict() methods. These methods should never return incorrect objects.

Swagger-codegen version

2.3.1

Swagger declaration file content or url
Command line used for generation

java -jar swagger-codegen-cli.jar generate -l python -i experiment.swagger.json -o $DIR -c config.json

Suggest a fix/enhancement

The attribute_map conversion should be built-in the obj.to_dict() methods.

JesseFinch commented 5 years ago

any upates?

HugoMario commented 5 years ago

going to assign to myself, thanks for remind

JavascriptMick commented 5 years ago

in case you get tired of waiting :)

import six
def to_good_dict(o):
    """Returns the model properties as a dict"""
    result = {}
    o_map = o.attribute_map

    for attr, _ in six.iteritems(o.swagger_types):
        value = getattr(o, attr)
        if isinstance(value, list):
            result[o_map[attr]] = list(map(
                lambda x: to_good_dict(x) if hasattr(x, "to_dict") else x,
                value
            ))
        elif hasattr(value, "to_dict"):
            result[o_map[attr]] = to_good_dict(value)
        elif isinstance(value, dict):
            result[o_map[attr]] = dict(map(
                lambda item: (item[0], to_good_dict(item[1]))
                if hasattr(item[1], "to_dict") else item,
                value.items()
            ))
        else:
            result[o_map[attr]] = value

    return result
JavascriptMick commented 4 years ago

revised in light of additional bug (https://github.com/swagger-api/swagger-codegen/issues/9847) I found @HugoMario would be cool if we could fix this up.

def to_good_dict(o):
    """Returns the model properties as a dict with correct object names"""
    def val_to_dict(val):
        if hasattr(val, "to_dict"):
            return to_good_dict(val)
        elif isinstance(val, list):
            return list(map(
                lambda x: to_good_dict(x) if hasattr(x, "to_dict") else x,
                val
            ))
        else:
            return val

    result = {}
    o_map = o.attribute_map

    for attr, _ in six.iteritems(o.swagger_types):
        value = getattr(o, attr)
        if isinstance(value, list):
            result[o_map[attr]] = list(map(
                lambda x: to_good_dict(x) if hasattr(x, "to_dict") else x,
                value
            ))
        elif hasattr(value, "to_dict"):
            result[o_map[attr]] = to_good_dict(value)
        elif isinstance(value, dict):
            result[o_map[attr]] = dict(map(
                lambda item: (item[0], val_to_dict(item[1])),
                value.items()
            ))
        else:
            result[o_map[attr]] = value

    return result
mloskot commented 4 years ago

@HugoMario Is there any update on this issue? Any hints where the fix should be deployed in the generator to generate the to_dict as suggested by @JavascriptMick in #9847 ?

I'm using the latest version 3.0.19 and the bug is still there.

Change586 commented 1 year ago

I'm using the latest version 3.0.25 and the bug is still there.

cong08 commented 10 months ago

+1

Vhaelan commented 5 months ago

Any update on this bug? It would be great to have this fix merged.