pythonpython-3.xopenapi-generator

Python openapi-python-client runtime error when deserializing


I am attempting to consume the API at https://api.oemserver.com/swagger/index.html

I have run the tool at https://github.com/openapi-generators/openapi-python-client to create an API client

Trying a little test, following the examples in the README file. Execute the get client groups method.

import json
from dmac.device_manager_api_client import AuthenticatedClient
from dmac.device_manager_api_client.models import ClientGroupListModel, ClientGroupModel
from dmac.device_manager_api_client.api.device_group import get_v_1_device_group_get_client_groups
from dmac.device_manager_api_client.types import Response
from pathlib import Path

DEVICE_MANAGER_OPTIONS_FILE = Path(__file__).parents[0].joinpath("device_manager.json")

with open(DEVICE_MANAGER_OPTIONS_FILE, "r") as device_manager_options_file:
    device_manager_options = json.load(device_manager_options_file)

api_host = f"{device_manager_options["scheme"]}://{device_manager_options["host"]}"
client = AuthenticatedClient(base_url=api_host, token=device_manager_options["token"])

with client as client:
    client_groups_response = get_v_1_device_group_get_client_groups.sync(client=client, vendor_id=87)
    if client_groups_response is None:
        print('client_group response is none')
    else:
        if client_groups_response.client_groups is None:
            print('client_groups_response.client_groups is none')
        else:
            for group in client_groups_response.client_groups:
                print(group)

At the point of executing the method, I can see that the data is returned from the web service. Snipped for brevity, client names removed. To Me it looks like a dict[str, list[dict[int, str]]]

{
    "ClientGroups": [
        {
            "Id": 16181,
            "Name": "Client 1"
        },
        {
            "Id": 15461,
            "Name": "Client 2"
        },
        {
            "Id": 18687,
            "Name": "Client 3"
        }
    ]
}

Then it seems to fail processing the response data and casting it

Traceback (most recent call last):
  File "c:\Source\FleetLogix\FleetLogix.Python\device_manager_test.py", line 17, in <module>
    client_groups_response = get_v_1_device_group_get_client_groups.sync(client=client, vendor_id=87)
                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "c:\Source\FleetLogix\FleetLogix.Python\dmac\device_manager_api_client\api\device_group\get_v_1_device_group_get_client_groups.py", line 101, in sync
    return sync_detailed(
           ^^^^^^^^^^^^^^
  File "c:\Source\FleetLogix\FleetLogix.Python\dmac\device_manager_api_client\api\device_group\get_v_1_device_group_get_client_groups.py", line 81, in sync_detailed
    return _build_response(client=client, response=response)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "c:\Source\FleetLogix\FleetLogix.Python\dmac\device_manager_api_client\api\device_group\get_v_1_device_group_get_client_groups.py", line 52, in _build_response
    parsed=_parse_response(client=client, response=response),
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "c:\Source\FleetLogix\FleetLogix.Python\dmac\device_manager_api_client\api\device_group\get_v_1_device_group_get_client_groups.py", line 35, in _parse_response
    response_200 = ClientGroupListModel.from_dict(response.text)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "c:\Source\FleetLogix\FleetLogix.Python\dmac\device_manager_api_client\models\client_group_list_model.py", line 49, in from_dict
    d = dict(src_dict)
        ^^^^^^^^^^^^^^
ValueError: dictionary update sequence element #0 has length 1; 2 is required

Is this a bug in the generated code? Is there someone I can contact specifically for the python api client generator?


Solution

  • The generated methods seem to have a common bug. They include (a variation of) the line

    if response.status_code == 200:
            response_200 = ClientGroupListModel.from_dict(response.text)
    

    This needs to be changed to

    if response.status_code == 200:
            response_200 = ClientGroupListModel.from_dict(response.json())