OpenAPITools / OpenAPITools/openapi-generator
[BUG][Python] AttributeError while processing response from server
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 26.8k
- Forks
- 7.7k
- PR merge metrics
- PR metrics pending
Description
Bug Report Checklist
- Have you provided a full/minimal spec to reproduce the issue?
- Have you validated the input using an OpenAPI validator (example)?
- What's the version of OpenAPI Generator used?
- Have you search for related issues/PRs?
- What's the actual output vs expected output?
- [Optional] Bounty to sponsor the fix (example)
Description
While generating the TS29573_N32_Handshake.yaml to create python client, the code is incorrectly generated.
The python client after calling post_exchange_capability will raise error in the generated code. This is while processing the response from the server.
Traceback (most recent call last):
File "main.py", line 29, in <module>
api_response = api_instance.post_exchange_capability(sec_negotiate_req_data)
File "./openapi_client/com/h21lab/TS29573_N32_Handshake/model/security_capability_negotiation_api.py", line 61, in post_exchange_capability
return self.post_exchange_capability_with_http_info(sec_negotiate_req_data, **kwargs) # noqa: E501
File "./openapi_client/com/h21lab/TS29573_N32_Handshake/model/security_capability_negotiation_api.py", line 139, in post_exchange_capability_with_http_info
return self.api_client.call_api(
File ".../openapi_client/api_client.py", line 364, in call_api
return self.__call_api(resource_path, method,
File ".../openapi_client/api_client.py", line 208, in __call_api
return_data = self.deserialize(response_data, response_type)
File ".../openapi_client/api_client.py", line 280, in deserialize
return self.__deserialize(data, response_type)
File ".../python2_client/openapi_client/api_client.py", line 308, in __deserialize
klass = getattr(openapi_client.com.h21lab.TS29573_N32_Handshake.handler, klass)
AttributeError: module 'openapi_client.com.h21lab.TS29573_N32_Handshake.handler' has no attribute 'SecNegotiateRspData'
Workaround to fix this, is to modify the generated code in the following way:
./openapi_client/com/h21lab/TS29573_N32_Handshake/model/security_capability_negotiation_api.py:147
# response_type='SecNegotiateRspData', # noqa: E501
response_type='sec_negotiate_rsp_data', # noqa: E501
After the python client is raising another error:
Traceback (most recent call last):
File "main.py", line 29, in <module>
api_response = api_instance.post_exchange_capability(sec_negotiate_req_data)
File "./openapi_client/com/h21lab/TS29573_N32_Handshake/model/security_capability_negotiation_api.py", line 61, in post_exchange_capability
return self.post_exchange_capability_with_http_info(sec_negotiate_req_data, **kwargs) # noqa: E501
File "./openapi_client/com/h21lab/TS29573_N32_Handshake/model/security_capability_negotiation_api.py", line 139, in post_exchange_capability_with_http_info
return self.api_client.call_api(
File ".../openapi_client/api_client.py", line 364, in call_api
return self.__call_api(resource_path, method,
File ".../openapi_client/api_client.py", line 208, in __call_api
return_data = self.deserialize(response_data, response_type)
File ".../openapi_client/api_client.py", line 280, in deserialize
return self.__deserialize(data, response_type)
File ".../openapi_client/api_client.py", line 319, in __deserialize
return self.__deserialize_model(data, klass)
File ".../openapi_client/api_client.py", line 648, in __deserialize_model
if not klass.openapi_types and has_discriminator is False:
AttributeError: module 'openapi_client.com.h21lab.TS29573_N32_Handshake.handler.sec_negotiate_rsp_data' has no attribute 'openapi_types'
Workaround to fix this, is to modify the generated code:
./openapi_client/api_client.py:648
# if not klass.openapi_types and has_discriminator is False:
if not hasattr(klass, 'openapi_types') and has_discriminator is False:
openapi-generator version
5.0.0-SNAPSHOT
OpenAPI declaration file content or url
https://github.com/jdegre/5GC_APIs/blob/master/TS29573_N32_Handshake.yaml
Command line used for generation
Generated by openapi-generator-maven-plugin by using following options:
<plugins>
<plugin>
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<version>5.0.0-SNAPSHOT</version>
<configuration>
<generatorName>python</generatorName>
<output>${project.build.directory}/generated-sources</output>
<configOptions>
</configOptions>
</configuration>
<executions>
<execution>
<id>65</id>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<inputSpec>${project.basedir}/src/main/resources/TS29573_N32_Handshake.yaml</inputSpec>
<modelPackage>com.h21lab.TS29573_N32_Handshake.handler</modelPackage>
<apiPackage>com.h21lab.TS29573_N32_Handshake.model</apiPackage>
<invokerPackage>com.h21lab.TS29573_N32_Handshake.handler</invokerPackage>
</configuration>
</execution>
</executions>
</plugin>
<plugins>
Steps to reproduce
Client code is simple:
main.py
from __future__ import print_function
import sys
# insert at 1, 0 is the script path (or '' in REPL)
sys.path.insert(1, './openapi_client/')
import time
import openapi_client
from openapi_client.rest import ApiException
from pprint import pprint
# Defining the host is optional and defaults to https://example.com/n32c-handshake/v1
# See configuration.py for a list of all supported configuration parameters.
configuration = openapi_client.Configuration(
host = "http://127.0.0.1:8080/n32c-handshake/v1"
)
# Enter a context with an instance of the API client
with openapi_client.ApiClient(configuration) as api_client:
# Create an instance of the API class
api_instance = openapi_client.SecurityCapabilityNegotiationApi(api_client)
sec_negotiate_req_data = openapi_client.SecNegotiateReqData(sender="127.0.0.1", supported_sec_capability_list=["TLS", "string"])
pprint(sec_negotiate_req_data)
try:
# N32-f Context Terminate
api_response = api_instance.post_exchange_capability(sec_negotiate_req_data)
pprint(api_response)
except ApiException as e:
print("Exception when calling SecurityCapabilityNegotiationApi->post_exchange_capability: %s\n" % e)
Server code is generated by python-flask generator and just implementing the following method in security_capability_negotiation_controller.py
import connexion
import six
from openapi_server.com.h21lab.TS29573_N32_Handshake.handler.problem_details import ProblemDetails # noqa: E501
from openapi_server.com.h21lab.TS29573_N32_Handshake.handler.sec_negotiate_req_data import SecNegotiateReqData # noqa: E501
from openapi_server.com.h21lab.TS29573_N32_Handshake.handler.sec_negotiate_rsp_data import SecNegotiateRspData # noqa: E501
from openapi_server import util
def post_exchange_capability(body): # noqa: E501
"""Security Capability Negotiation
# noqa: E501
:param sec_negotiate_req_data: Custom operation for security capability negotiation
:type sec_negotiate_req_data: dict | bytes
:rtype: SecNegotiateRspData
"""
if connexion.request.is_json:
sec_negotiate_req_data = SecNegotiateReqData.from_dict(connexion.request.get_json()) # noqa: E501
return SecNegotiateRspData(sender="127.0.0.1", selected_sec_capability="TLS")
Related issues/PRs
Suggest a fix
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce generation with TS29573_N32_Handshake.yaml and the shown Maven configuration, then inspect the generated security_capability_negotiation_api.py and api_client.py paths where response_type and model deserialization are used. Done means the generated Python client processes post_exchange_capability's response without either AttributeError.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- openapi, python
- Domain
- api, tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100