Yelp / bravado-core

Other
109 stars 98 forks source link

collectionFormat array list of lists #382

Open abyssusj opened 3 years ago

abyssusj commented 3 years ago

Fails to marshal lists of list arrays.

{"description":"connected solar system pairs",
    "in":"query",
    "items": {
        "collectionFormat":"pipes",
        "items": {
            "format":"int32",
            "type":"integer"
        },
        "maxItems":2,
        "minItems":2,
        "type":"array",
        "uniqueItems":true},
        "maxItems":100,
        "name":"connections",
        "type":"array",
        "uniqueItems":true
    }
connections = [[30000142,30002801], [30002801,30002661]]

API response

error="failed to coerce value '[30000142' into type integer (format: int32)

Note presence of "[30000142" in integer.

Expected request

/?connections=30000142%7C30002801,30002801%7C30002661

marshal_collection_format() appears to fail marshalling the list of lists at https://github.com/Yelp/bravado-core/blob/382db874b7b838dcfd169b0ce490d6a447ad6ff2/bravado_core/param.py#L356


Monkeypatched with the following

def mymarshal_collection_format(swagger_spec, param_spec, value):
    """For an array, apply the collection format and return the result.

    :type swagger_spec: :class:`bravado_core.spec.Spec`
    :param param_spec: spec of the parameter with 'type': 'array'
    :param value: array value of the parameter
    :return: transformed value as a string
    """
    result = []
    collection_format = swagger_spec.deref(param_spec).get('items').get('collectionFormat', 'csv')
    if collection_format == 'multi':
        # http client lib should handle this
        return value

    sep = param.COLLECTION_FORMATS[collection_format]

    if any(isinstance(i, list) for i in value):
        """ if list of lists, apply marshaling to each item in list"""
        for i in value:
            result.append( sep.join(str(element) for element in i) )

    else:
        result = sep.join(str(element) for element in value)
    return result