Skip to content

list_directors crashes because of unexpected API response (tried to be parsed as Backend) #110

@pkern

Description

@pkern

Version

12.0.0

What happened

In [89]: director_api = fastly.api.director_api.DirectorApi(api_client)
In [90]: director_api.list_directors('16WArobd6GZiy4u8oCnyMg', 15)
---------------------------------------------------------------------------
ApiTypeError                              Traceback (most recent call last)
File ~/src/debian/fastly/venv/lib/python3.13/site-packages/fastly/model_utils.py:1784, in get_allof_instances(self, model_args, constant_args)
   1783 if constant_args.get('_spec_property_naming'):
-> 1784     allof_instance = allof_class._from_openapi_data(**model_args, **constant_args)
   1785 else:

File ~/src/debian/fastly/venv/lib/python3.13/site-packages/fastly/model_utils.py:45, in convert_js_args_to_python_args.<locals>.wrapped_init(_self, *args, **kwargs)
     44     kwargs = change_keys_js_to_python(kwargs, _self if isinstance(_self, type) else _self.__class__)
---> 45 return fn(_self, *args, **kwargs)

File ~/src/debian/fastly/venv/lib/python3.13/site-packages/fastly/model/director.py:206, in Director._from_openapi_data(cls, *args, **kwargs)
    205         continue
--> 206     setattr(self, var_name, var_value)
    207 return self

File ~/src/debian/fastly/venv/lib/python3.13/site-packages/fastly/model_utils.py:184, in OpenApiModel.__setattr__(self, attr, value)
    183 """set the value of an attribute using dot notation: `instance.attr = val`"""
--> 184 self[attr] = value

File ~/src/debian/fastly/venv/lib/python3.13/site-packages/fastly/model_utils.py:509, in ModelNormal.__setitem__(self, name, value)
    507     return
--> 509 self.set_attribute(name, value)

File ~/src/debian/fastly/venv/lib/python3.13/site-packages/fastly/model_utils.py:156, in OpenApiModel.set_attribute(self, name, value)
    155 if self._check_type:
--> 156     value = validate_and_convert_types(
    157         value, required_types_mixed, path_to_item, self._spec_property_naming,
    158         self._check_type, configuration=self._configuration)
    159 if (name,) in self.allowed_values:

File ~/src/debian/fastly/venv/lib/python3.13/site-packages/fastly/model_utils.py:1619, in validate_and_convert_types(input_value, required_types_mixed, path_to_item, spec_property_naming, _check_type, configuration)
   1618         inner_path.append(index)
-> 1619         input_value[index] = validate_and_convert_types(
   1620             inner_value,
   1621             inner_required_types,
   1622             inner_path,
   1623             spec_property_naming,
   1624             _check_type,
   1625             configuration=configuration
   1626         )
   1627 elif isinstance(input_value, dict):

File ~/src/debian/fastly/venv/lib/python3.13/site-packages/fastly/model_utils.py:1569, in validate_and_convert_types(input_value, required_types_mixed, path_to_item, spec_property_naming, _check_type, configuration)
   1567 if configuration:
   1568     # if input_value is not valid_type try to convert it
-> 1569     converted_instance = attempt_convert_item(
   1570         input_value,
   1571         valid_classes,
   1572         path_to_item,
   1573         configuration,
   1574         spec_property_naming,
   1575         key_type=False,
   1576         must_convert=True,
   1577         check_type=_check_type
   1578     )
   1579     return converted_instance

File ~/src/debian/fastly/venv/lib/python3.13/site-packages/fastly/model_utils.py:1448, in attempt_convert_item(input_value, valid_classes, path_to_item, configuration, spec_property_naming, key_type, must_convert, check_type)
   1447     if configuration is None or not configuration.discard_unknown_keys:
-> 1448         raise get_type_error(input_value, path_to_item, valid_classes,
   1449                              key_type=key_type)
   1450 for valid_class in valid_classes_coercible:

ApiTypeError: Invalid type for variable '0'. Required value type is Backend and passed type was str at ['received_data'][0]['backends'][0]

The above exception was the direct cause of the following exception:

ApiValueError                             Traceback (most recent call last)
Cell In[90], line 1
----> 1 director_api.list_directors('16WArobd6GZiy4u8oCnyMg', 15)

File ~/src/debian/fastly/venv/lib/python3.13/site-packages/fastly/api/director_api.py:779, in DirectorApi.list_directors(self, service_id, version_id, **kwargs)
    775 kwargs['service_id'] = \
    776     service_id
    777 kwargs['version_id'] = \
    778     version_id
--> 779 return self.list_directors_endpoint.call_with_http_info(**kwargs)

File ~/src/debian/fastly/venv/lib/python3.13/site-packages/fastly/api_client.py:872, in Endpoint.call_with_http_info(self, **kwargs)
    867             header_list = self.api_client.select_header_content_type(
    868                 content_type_headers_list, self.settings['http_method'],
    869                 params['body'])
    870             params['header']['Content-Type'] = header_list
--> 872 return self.api_client.call_api(
    873     self.settings['endpoint_path'], self.settings['http_method'],
    874     params['path'],
    875     self.path_params_allow_reserved_map,
    876     params['query'],
    877     params['header'],
    878     body=params['body'],
    879     post_params=params['form'],
    880     files=params['file'],
    881     response_type=self.settings['response_type'],
    882     auth_settings=self.settings['auth'],
    883     async_req=kwargs['async_req'],
    884     _check_type=kwargs['_check_return_type'],
    885     _return_http_data_only=kwargs['_return_http_data_only'],
    886     _preload_content=kwargs['_preload_content'],
    887     _request_timeout=kwargs['_request_timeout'],
    888     _host=_host,
    889     collection_formats=params['collection_format'])

File ~/src/debian/fastly/venv/lib/python3.13/site-packages/fastly/api_client.py:427, in ApiClient.call_api(self, resource_path, method, path_params, path_params_allow_reserved_map, query_params, header_params, body, post_params, files, response_type, auth_settings, async_req, _return_http_data_only, collection_formats, _preload_content, _request_timeout, _host, _check_type)
    372 """Makes the HTTP request (synchronous) and returns deserialized data.
    373 
    374 To make an async_req request, set the async_req parameter.
   (...)
    424     then the method will return the response directly.
    425 """
    426 if not async_req:
--> 427     return self.__call_api(resource_path, method,
    428                            path_params, path_params_allow_reserved_map, query_params, header_params,
    429                            body, post_params, files,
    430                            response_type, auth_settings,
    431                            _return_http_data_only, collection_formats,
    432                            _preload_content, _request_timeout, _host,
    433                            _check_type)
    435 return self.pool.apply_async(self.__call_api, (resource_path,
    436                                                method, path_params,
    437                                                path_params_allow_reserved_map,
   (...)
    446                                                _request_timeout,
    447                                                _host, _check_type))

File ~/src/debian/fastly/venv/lib/python3.13/site-packages/fastly/api_client.py:236, in ApiClient.__call_api(self, resource_path, method, path_params, path_params_allow_reserved_map, query_params, header_params, body, post_params, files, response_type, auth_settings, _return_http_data_only, collection_formats, _preload_content, _request_timeout, _host, _check_type, _content_type)
    233                 encoding = match.group(1)
    234         response_data.data = response_data.data.decode(encoding)
--> 236     return_data = self.deserialize(
    237         response_data,
    238         response_type,
    239         _check_type
    240     )
    241 else:
    242     return_data = None

File ~/src/debian/fastly/venv/lib/python3.13/site-packages/fastly/api_client.py:341, in ApiClient.deserialize(self, response, response_type, _check_type)
    337     received_data = response.data
    339 # store our data under the key of 'received_data' so users have some
    340 # context if they are deserializing a string and the data type is wrong
--> 341 deserialized_data = validate_and_convert_types(
    342     received_data,
    343     response_type,
    344     ['received_data'],
    345     True,
    346     _check_type,
    347     configuration=self.configuration
    348 )
    349 return deserialized_data

File ~/src/debian/fastly/venv/lib/python3.13/site-packages/fastly/model_utils.py:1619, in validate_and_convert_types(input_value, required_types_mixed, path_to_item, spec_property_naming, _check_type, configuration)
   1617         inner_path = list(path_to_item)
   1618         inner_path.append(index)
-> 1619         input_value[index] = validate_and_convert_types(
   1620             inner_value,
   1621             inner_required_types,
   1622             inner_path,
   1623             spec_property_naming,
   1624             _check_type,
   1625             configuration=configuration
   1626         )
   1627 elif isinstance(input_value, dict):
   1628     if input_value == {}:
   1629         # allow an empty dict

File ~/src/debian/fastly/venv/lib/python3.13/site-packages/fastly/model_utils.py:1569, in validate_and_convert_types(input_value, required_types_mixed, path_to_item, spec_property_naming, _check_type, configuration)
   1566 if not valid_type:
   1567     if configuration:
   1568         # if input_value is not valid_type try to convert it
-> 1569         converted_instance = attempt_convert_item(
   1570             input_value,
   1571             valid_classes,
   1572             path_to_item,
   1573             configuration,
   1574             spec_property_naming,
   1575             key_type=False,
   1576             must_convert=True,
   1577             check_type=_check_type
   1578         )
   1579         return converted_instance
   1580     else:

File ~/src/debian/fastly/venv/lib/python3.13/site-packages/fastly/model_utils.py:1462, in attempt_convert_item(input_value, valid_classes, path_to_item, configuration, spec_property_naming, key_type, must_convert, check_type)
   1460 except (ApiTypeError, ApiValueError, ApiKeyError) as conversion_exc:
   1461     if must_convert:
-> 1462         raise conversion_exc
   1463     # if we have conversion errors when must_convert == False
   1464     # we ignore the exception and move on to the next class
   1465     continue

File ~/src/debian/fastly/venv/lib/python3.13/site-packages/fastly/model_utils.py:1453, in attempt_convert_item(input_value, valid_classes, path_to_item, configuration, spec_property_naming, key_type, must_convert, check_type)
   1451 try:
   1452     if issubclass(valid_class, OpenApiModel):
-> 1453         return deserialize_model(input_value, valid_class,
   1454                                  path_to_item, check_type,
   1455                                  configuration, spec_property_naming)
   1456     elif valid_class == file_type:
   1457         return deserialize_file(input_value, configuration)

File ~/src/debian/fastly/venv/lib/python3.13/site-packages/fastly/model_utils.py:1373, in deserialize_model(model_data, model_class, path_to_item, check_type, configuration, spec_property_naming)
   1371 if isinstance(model_data, dict):
   1372     kw_args.update(model_data)
-> 1373     return model_class._new_from_openapi_data(**kw_args)
   1374 elif isinstance(model_data, PRIMITIVE_TYPES):
   1375     return model_class._new_from_openapi_data(model_data, **kw_args)

File ~/src/debian/fastly/venv/lib/python3.13/site-packages/fastly/model_utils.py:45, in convert_js_args_to_python_args.<locals>.wrapped_init(_self, *args, **kwargs)
     43 if spec_property_naming:
     44     kwargs = change_keys_js_to_python(kwargs, _self if isinstance(_self, type) else _self.__class__)
---> 45 return fn(_self, *args, **kwargs)

File ~/src/debian/fastly/venv/lib/python3.13/site-packages/fastly/model_utils.py:369, in OpenApiModel._new_from_openapi_data(cls, *args, **kwargs)
    348 visited_composed_classes = kwargs.get('_visited_composed_classes', ())
    349 if (
    350     cls.discriminator is None or
    351     cls in visited_composed_classes
   (...)
    366     # through Animal's discriminator because we passed in
    367     # _visited_composed_classes = (Animal,)
--> 369     return cls._from_openapi_data(*args, **kwargs)
    371 # Get the name and value of the discriminator property.
    372 # The discriminator name is obtained from the discriminator meta-data
    373 # and the discriminator value is obtained from the input data.
    374 discr_propertyname_py = list(cls.discriminator.keys())[0]

File ~/src/debian/fastly/venv/lib/python3.13/site-packages/fastly/model_utils.py:45, in convert_js_args_to_python_args.<locals>.wrapped_init(_self, *args, **kwargs)
     43 if spec_property_naming:
     44     kwargs = change_keys_js_to_python(kwargs, _self if isinstance(_self, type) else _self.__class__)
---> 45 return fn(_self, *args, **kwargs)

File ~/src/debian/fastly/venv/lib/python3.13/site-packages/fastly/model/director_response.py:230, in DirectorResponse._from_openapi_data(cls, *args, **kwargs)
    221 self._visited_composed_classes = _visited_composed_classes + (self.__class__,)
    223 constant_args = {
    224     '_check_type': _check_type,
    225     '_path_to_item': _path_to_item,
   (...)
    228     '_visited_composed_classes': self._visited_composed_classes,
    229 }
--> 230 composed_info = validate_get_composed_info(
    231     constant_args, kwargs, self)
    232 self._composed_instances = composed_info[0]
    233 self._var_name_to_model_instances = composed_info[1]

File ~/src/debian/fastly/venv/lib/python3.13/site-packages/fastly/model_utils.py:1992, in validate_get_composed_info(constant_args, model_args, self)
   1990 # create composed_instances
   1991 composed_instances = []
-> 1992 allof_instances = get_allof_instances(self, model_args, constant_args)
   1993 composed_instances.extend(allof_instances)
   1994 oneof_instance = get_oneof_instance(self.__class__, model_args, constant_args)

File ~/src/debian/fastly/venv/lib/python3.13/site-packages/fastly/model_utils.py:1789, in get_allof_instances(self, model_args, constant_args)
   1787         composed_instances.append(allof_instance)
   1788     except Exception as ex:
-> 1789         raise ApiValueError(
   1790             "Invalid inputs given to generate an instance of '%s'. The "
   1791             "input data was invalid for the allOf schema '%s' in the composed "
   1792             "schema '%s'. Error=%s" % (
   1793                 allof_class.__name__,
   1794                 allof_class.__name__,
   1795                 self.__class__.__name__,
   1796                 str(ex)
   1797             )
   1798         ) from ex
   1799 return composed_instances

ApiValueError: Invalid inputs given to generate an instance of 'Director'. The input data was invalid for the allOf schema 'Director' in the composed schema 'DirectorResponse'. Error=Invalid type for variable '0'. Required value type is Backend and passed type was str at ['received_data'][0]['backends'][0]

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions