[python] Fix data type (#16291)

* fix data type in python client codegen

* add model mapping feature
This commit is contained in:
William Cheng 2023-08-10 23:05:35 +08:00 committed by GitHub
parent 7a7309edb8
commit fd12bb3508
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 462 additions and 24 deletions

View File

@ -649,24 +649,60 @@ public abstract class AbstractPythonCodegen extends DefaultCodegen implements Co
this.packageVersion = packageVersion;
}
@Override
public String getTypeDeclaration(Schema p) {
p = ModelUtils.unaliasSchema(openAPI, p);
if (ModelUtils.isArraySchema(p)) {
ArraySchema ap = (ArraySchema) p;
Schema inner = ap.getItems();
return getSchemaType(p) + "[" + getTypeDeclaration(inner) + "]";
} else if (ModelUtils.isMapSchema(p)) {
Schema inner = ModelUtils.getAdditionalProperties(p);
return getSchemaType(p) + "[str, " + getTypeDeclaration(inner) + "]";
}
String openAPIType = getSchemaType(p);
if (typeMapping.containsKey(openAPIType)) {
return typeMapping.get(openAPIType);
}
if (languageSpecificPrimitives.contains(openAPIType)) {
return openAPIType;
}
return toModelName(openAPIType);
}
@Override
public String getSchemaType(Schema p) {
String openAPIType = super.getSchemaType(p);
String type = null;
String type;
if (openAPIType == null) {
LOGGER.error("OpenAPI Type for {} is null. Default to UNKNOWN_OPENAPI_TYPE instead.", p.getName());
openAPIType = "UNKNOWN_OPENAPI_TYPE";
}
if (typeMapping.containsKey(openAPIType)) {
type = typeMapping.get(openAPIType);
if (languageSpecificPrimitives.contains(type)) {
if (type != null) {
return type;
}
} else {
type = toModelName(openAPIType);
type = openAPIType;
}
return type;
}
return toModelName(type);
}
@Override
public String toModelName(String name) {
// obtain the name from modelNameMapping directly if provided
if (modelNameMapping.containsKey(name)) {
return modelNameMapping.get(name);
}
// check if schema-mapping has a different model for this class, so we can use it
// instead of the auto-generated one.
if (schemaMapping.containsKey(name)) {
@ -1935,4 +1971,4 @@ public abstract class AbstractPythonCodegen extends DefaultCodegen implements Co
public String toEnumDefaultValue(String value, String datatype) {
return value;
}
}
}

View File

@ -373,20 +373,6 @@ public class PythonClientCodegen extends AbstractPythonCodegen implements Codege
return modelImport;
}
@Override
public String getTypeDeclaration(Schema p) {
if (ModelUtils.isArraySchema(p)) {
ArraySchema ap = (ArraySchema) p;
Schema inner = ap.getItems();
return getSchemaType(p) + "[" + getTypeDeclaration(inner) + "]";
} else if (ModelUtils.isMapSchema(p)) {
Schema inner = ModelUtils.getAdditionalProperties(p);
return getSchemaType(p) + "[str, " + getTypeDeclaration(inner) + "]";
}
return super.getTypeDeclaration(p);
}
@Override
public CodegenType getTag() {
return CodegenType.CLIENT;

View File

@ -1265,9 +1265,24 @@ paths:
description: enum reference
schema:
$ref: '#/components/schemas/EnumClass'
responses:
"200":
description: Get successful
/fake/return_list_of_object:
get:
tags:
- fake
summary: test returning list of objects
operationId: fake_return_list_of_objects
responses:
200:
description: OK
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/ListOfObjects"
servers:
- url: 'http://{server}.swagger.io:{port}/v2'
description: petstore server
@ -2292,3 +2307,8 @@ components:
type: string
additionalProperties:
description: This is what the additional property is
ListOfObjects:
type: array
title: ListOfObjects
items:
$ref: "#/components/schemas/Tag"

View File

@ -96,6 +96,7 @@ Class | Method | HTTP request | Description
*FakeApi* | [**fake_outer_number_serialize**](docs/FakeApi.md#fake_outer_number_serialize) | **POST** /fake/outer/number |
*FakeApi* | [**fake_outer_string_serialize**](docs/FakeApi.md#fake_outer_string_serialize) | **POST** /fake/outer/string |
*FakeApi* | [**fake_property_enum_integer_serialize**](docs/FakeApi.md#fake_property_enum_integer_serialize) | **POST** /fake/property/enum-int |
*FakeApi* | [**fake_return_list_of_objects**](docs/FakeApi.md#fake_return_list_of_objects) | **GET** /fake/return_list_of_object | test returning list of objects
*FakeApi* | [**test_body_with_binary**](docs/FakeApi.md#test_body_with_binary) | **PUT** /fake/body-with-binary |
*FakeApi* | [**test_body_with_file_schema**](docs/FakeApi.md#test_body_with_file_schema) | **PUT** /fake/body-with-file-schema |
*FakeApi* | [**test_body_with_query_params**](docs/FakeApi.md#test_body_with_query_params) | **PUT** /fake/body-with-query-params |

View File

@ -13,6 +13,7 @@ Method | HTTP request | Description
[**fake_outer_number_serialize**](FakeApi.md#fake_outer_number_serialize) | **POST** /fake/outer/number |
[**fake_outer_string_serialize**](FakeApi.md#fake_outer_string_serialize) | **POST** /fake/outer/string |
[**fake_property_enum_integer_serialize**](FakeApi.md#fake_property_enum_integer_serialize) | **POST** /fake/property/enum-int |
[**fake_return_list_of_objects**](FakeApi.md#fake_return_list_of_objects) | **GET** /fake/return_list_of_object | test returning list of objects
[**test_body_with_binary**](FakeApi.md#test_body_with_binary) | **PUT** /fake/body-with-binary |
[**test_body_with_file_schema**](FakeApi.md#test_body_with_file_schema) | **PUT** /fake/body-with-file-schema |
[**test_body_with_query_params**](FakeApi.md#test_body_with_query_params) | **PUT** /fake/body-with-query-params |
@ -146,7 +147,7 @@ No authorization required
### HTTP response details
| Status code | Description | Response headers |
|-------------|-------------|------------------|
**200** | OK | - |
**200** | Get successful | - |
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
@ -672,6 +673,67 @@ No authorization required
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
# **fake_return_list_of_objects**
> List[List[Tag]] fake_return_list_of_objects()
test returning list of objects
### Example
```python
import time
import os
import petstore_api
from petstore_api.models.tag import Tag
from petstore_api.rest import ApiException
from pprint import pprint
# Defining the host is optional and defaults to http://petstore.swagger.io:80/v2
# See configuration.py for a list of all supported configuration parameters.
configuration = petstore_api.Configuration(
host = "http://petstore.swagger.io:80/v2"
)
# Enter a context with an instance of the API client
async with petstore_api.ApiClient(configuration) as api_client:
# Create an instance of the API class
api_instance = petstore_api.FakeApi(api_client)
try:
# test returning list of objects
api_response = await api_instance.fake_return_list_of_objects()
print("The response of FakeApi->fake_return_list_of_objects:\n")
pprint(api_response)
except Exception as e:
print("Exception when calling FakeApi->fake_return_list_of_objects: %s\n" % e)
```
### Parameters
This endpoint does not need any parameter.
### Return type
**List[List[Tag]]**
### Authorization
No authorization required
### HTTP request headers
- **Content-Type**: Not defined
- **Accept**: application/json
### HTTP response details
| Status code | Description | Response headers |
|-------------|-------------|------------------|
**200** | OK | - |
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
# **test_body_with_binary**
> test_body_with_binary(body)

View File

@ -24,7 +24,7 @@ from datetime import date, datetime
from pydantic import Field, StrictBool, StrictBytes, StrictInt, StrictStr, conbytes, confloat, conint, conlist, constr, validator
from typing import Any, Dict, Optional, Union
from typing import Any, Dict, List, Optional, Union
from petstore_api.models.client import Client
from petstore_api.models.enum_class import EnumClass
@ -33,6 +33,7 @@ from petstore_api.models.health_check_result import HealthCheckResult
from petstore_api.models.outer_composite import OuterComposite
from petstore_api.models.outer_object_with_enum_property import OuterObjectWithEnumProperty
from petstore_api.models.pet import Pet
from petstore_api.models.tag import Tag
from petstore_api.models.user import User
from petstore_api.api_client import ApiClient
@ -1427,6 +1428,145 @@ class FakeApi(object):
collection_formats=_collection_formats,
_request_auth=_params.get('_request_auth'))
@overload
async def fake_return_list_of_objects(self, **kwargs) -> List[List[Tag]]: # noqa: E501
...
@overload
def fake_return_list_of_objects(self, async_req: Optional[bool]=True, **kwargs) -> List[List[Tag]]: # noqa: E501
...
@validate_arguments
def fake_return_list_of_objects(self, async_req: Optional[bool]=None, **kwargs) -> Union[List[List[Tag]], Awaitable[List[List[Tag]]]]: # noqa: E501
"""test returning list of objects # noqa: E501
This method makes a synchronous HTTP request by default. To make an
asynchronous HTTP request, please pass async_req=True
>>> thread = api.fake_return_list_of_objects(async_req=True)
>>> result = thread.get()
:param async_req: Whether to execute the request asynchronously.
:type async_req: bool, optional
:param _request_timeout: timeout setting for this request. If one
number provided, it will be total request
timeout. It can also be a pair (tuple) of
(connection, read) timeouts.
:return: Returns the result object.
If the method is called asynchronously,
returns the request thread.
:rtype: List[List[Tag]]
"""
kwargs['_return_http_data_only'] = True
if '_preload_content' in kwargs:
raise ValueError("Error! Please call the fake_return_list_of_objects_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data")
if async_req is not None:
kwargs['async_req'] = async_req
return self.fake_return_list_of_objects_with_http_info(**kwargs) # noqa: E501
@validate_arguments
def fake_return_list_of_objects_with_http_info(self, **kwargs) -> ApiResponse: # noqa: E501
"""test returning list of objects # noqa: E501
This method makes a synchronous HTTP request by default. To make an
asynchronous HTTP request, please pass async_req=True
>>> thread = api.fake_return_list_of_objects_with_http_info(async_req=True)
>>> result = thread.get()
:param async_req: Whether to execute the request asynchronously.
:type async_req: bool, optional
:param _preload_content: if False, the ApiResponse.data will
be set to none and raw_data will store the
HTTP response body without reading/decoding.
Default is True.
:type _preload_content: bool, optional
:param _return_http_data_only: response data instead of ApiResponse
object with status code, headers, etc
:type _return_http_data_only: bool, optional
:param _request_timeout: timeout setting for this request. If one
number provided, it will be total request
timeout. It can also be a pair (tuple) of
(connection, read) timeouts.
:param _request_auth: set to override the auth_settings for an a single
request; this effectively ignores the authentication
in the spec for a single request.
:type _request_auth: dict, optional
:type _content_type: string, optional: force content-type for the request
:return: Returns the result object.
If the method is called asynchronously,
returns the request thread.
:rtype: tuple(List[List[Tag]], status_code(int), headers(HTTPHeaderDict))
"""
_params = locals()
_all_params = [
]
_all_params.extend(
[
'async_req',
'_return_http_data_only',
'_preload_content',
'_request_timeout',
'_request_auth',
'_content_type',
'_headers'
]
)
# validate the arguments
for _key, _val in _params['kwargs'].items():
if _key not in _all_params:
raise ApiTypeError(
"Got an unexpected keyword argument '%s'"
" to method fake_return_list_of_objects" % _key
)
_params[_key] = _val
del _params['kwargs']
_collection_formats = {}
# process the path parameters
_path_params = {}
# process the query parameters
_query_params = []
# process the header parameters
_header_params = dict(_params.get('_headers', {}))
# process the form parameters
_form_params = []
_files = {}
# process the body parameter
_body_params = None
# set the HTTP header `Accept`
_header_params['Accept'] = self.api_client.select_header_accept(
['application/json']) # noqa: E501
# authentication setting
_auth_settings = [] # noqa: E501
_response_types_map = {
'200': "List[List[Tag]]",
}
return self.api_client.call_api(
'/fake/return_list_of_object', 'GET',
_path_params,
_query_params,
_header_params,
body=_body_params,
post_params=_form_params,
files=_files,
response_types_map=_response_types_map,
auth_settings=_auth_settings,
async_req=_params.get('async_req'),
_return_http_data_only=_params.get('_return_http_data_only'), # noqa: E501
_preload_content=_params.get('_preload_content', True),
_request_timeout=_params.get('_request_timeout'),
collection_formats=_collection_formats,
_request_auth=_params.get('_request_auth'))
@overload
async def test_body_with_binary(self, body : Annotated[Optional[Union[StrictBytes, StrictStr]], Field(..., description="image to upload")], **kwargs) -> None: # noqa: E501
...

View File

@ -96,6 +96,7 @@ Class | Method | HTTP request | Description
*FakeApi* | [**fake_outer_number_serialize**](docs/FakeApi.md#fake_outer_number_serialize) | **POST** /fake/outer/number |
*FakeApi* | [**fake_outer_string_serialize**](docs/FakeApi.md#fake_outer_string_serialize) | **POST** /fake/outer/string |
*FakeApi* | [**fake_property_enum_integer_serialize**](docs/FakeApi.md#fake_property_enum_integer_serialize) | **POST** /fake/property/enum-int |
*FakeApi* | [**fake_return_list_of_objects**](docs/FakeApi.md#fake_return_list_of_objects) | **GET** /fake/return_list_of_object | test returning list of objects
*FakeApi* | [**test_body_with_binary**](docs/FakeApi.md#test_body_with_binary) | **PUT** /fake/body-with-binary |
*FakeApi* | [**test_body_with_file_schema**](docs/FakeApi.md#test_body_with_file_schema) | **PUT** /fake/body-with-file-schema |
*FakeApi* | [**test_body_with_query_params**](docs/FakeApi.md#test_body_with_query_params) | **PUT** /fake/body-with-query-params |

View File

@ -13,6 +13,7 @@ Method | HTTP request | Description
[**fake_outer_number_serialize**](FakeApi.md#fake_outer_number_serialize) | **POST** /fake/outer/number |
[**fake_outer_string_serialize**](FakeApi.md#fake_outer_string_serialize) | **POST** /fake/outer/string |
[**fake_property_enum_integer_serialize**](FakeApi.md#fake_property_enum_integer_serialize) | **POST** /fake/property/enum-int |
[**fake_return_list_of_objects**](FakeApi.md#fake_return_list_of_objects) | **GET** /fake/return_list_of_object | test returning list of objects
[**test_body_with_binary**](FakeApi.md#test_body_with_binary) | **PUT** /fake/body-with-binary |
[**test_body_with_file_schema**](FakeApi.md#test_body_with_file_schema) | **PUT** /fake/body-with-file-schema |
[**test_body_with_query_params**](FakeApi.md#test_body_with_query_params) | **PUT** /fake/body-with-query-params |
@ -146,7 +147,7 @@ No authorization required
### HTTP response details
| Status code | Description | Response headers |
|-------------|-------------|------------------|
**200** | OK | - |
**200** | Get successful | - |
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
@ -672,6 +673,67 @@ No authorization required
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
# **fake_return_list_of_objects**
> List[List[Tag]] fake_return_list_of_objects()
test returning list of objects
### Example
```python
import time
import os
import petstore_api
from petstore_api.models.tag import Tag
from petstore_api.rest import ApiException
from pprint import pprint
# Defining the host is optional and defaults to http://petstore.swagger.io:80/v2
# See configuration.py for a list of all supported configuration parameters.
configuration = petstore_api.Configuration(
host = "http://petstore.swagger.io:80/v2"
)
# Enter a context with an instance of the API client
with petstore_api.ApiClient(configuration) as api_client:
# Create an instance of the API class
api_instance = petstore_api.FakeApi(api_client)
try:
# test returning list of objects
api_response = api_instance.fake_return_list_of_objects()
print("The response of FakeApi->fake_return_list_of_objects:\n")
pprint(api_response)
except Exception as e:
print("Exception when calling FakeApi->fake_return_list_of_objects: %s\n" % e)
```
### Parameters
This endpoint does not need any parameter.
### Return type
**List[List[Tag]]**
### Authorization
No authorization required
### HTTP request headers
- **Content-Type**: Not defined
- **Accept**: application/json
### HTTP response details
| Status code | Description | Response headers |
|-------------|-------------|------------------|
**200** | OK | - |
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
# **test_body_with_binary**
> test_body_with_binary(body)

View File

@ -23,7 +23,7 @@ from datetime import date, datetime
from pydantic import Field, StrictBool, StrictBytes, StrictFloat, StrictInt, StrictStr, conbytes, confloat, conint, conlist, constr, validator
from typing import Any, Dict, Optional, Union
from typing import Any, Dict, List, Optional, Union
from petstore_api.models.client import Client
from petstore_api.models.enum_class import EnumClass
@ -32,6 +32,7 @@ from petstore_api.models.health_check_result import HealthCheckResult
from petstore_api.models.outer_composite import OuterComposite
from petstore_api.models.outer_object_with_enum_property import OuterObjectWithEnumProperty
from petstore_api.models.pet import Pet
from petstore_api.models.tag import Tag
from petstore_api.models.user import User
from petstore_api.api_client import ApiClient
@ -1336,6 +1337,135 @@ class FakeApi(object):
collection_formats=_collection_formats,
_request_auth=_params.get('_request_auth'))
@validate_arguments
def fake_return_list_of_objects(self, **kwargs) -> List[List[Tag]]: # noqa: E501
"""test returning list of objects # noqa: E501
This method makes a synchronous HTTP request by default. To make an
asynchronous HTTP request, please pass async_req=True
>>> thread = api.fake_return_list_of_objects(async_req=True)
>>> result = thread.get()
:param async_req: Whether to execute the request asynchronously.
:type async_req: bool, optional
:param _request_timeout: timeout setting for this request. If one
number provided, it will be total request
timeout. It can also be a pair (tuple) of
(connection, read) timeouts.
:return: Returns the result object.
If the method is called asynchronously,
returns the request thread.
:rtype: List[List[Tag]]
"""
kwargs['_return_http_data_only'] = True
if '_preload_content' in kwargs:
raise ValueError("Error! Please call the fake_return_list_of_objects_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data")
return self.fake_return_list_of_objects_with_http_info(**kwargs) # noqa: E501
@validate_arguments
def fake_return_list_of_objects_with_http_info(self, **kwargs) -> ApiResponse: # noqa: E501
"""test returning list of objects # noqa: E501
This method makes a synchronous HTTP request by default. To make an
asynchronous HTTP request, please pass async_req=True
>>> thread = api.fake_return_list_of_objects_with_http_info(async_req=True)
>>> result = thread.get()
:param async_req: Whether to execute the request asynchronously.
:type async_req: bool, optional
:param _preload_content: if False, the ApiResponse.data will
be set to none and raw_data will store the
HTTP response body without reading/decoding.
Default is True.
:type _preload_content: bool, optional
:param _return_http_data_only: response data instead of ApiResponse
object with status code, headers, etc
:type _return_http_data_only: bool, optional
:param _request_timeout: timeout setting for this request. If one
number provided, it will be total request
timeout. It can also be a pair (tuple) of
(connection, read) timeouts.
:param _request_auth: set to override the auth_settings for an a single
request; this effectively ignores the authentication
in the spec for a single request.
:type _request_auth: dict, optional
:type _content_type: string, optional: force content-type for the request
:return: Returns the result object.
If the method is called asynchronously,
returns the request thread.
:rtype: tuple(List[List[Tag]], status_code(int), headers(HTTPHeaderDict))
"""
_params = locals()
_all_params = [
]
_all_params.extend(
[
'async_req',
'_return_http_data_only',
'_preload_content',
'_request_timeout',
'_request_auth',
'_content_type',
'_headers'
]
)
# validate the arguments
for _key, _val in _params['kwargs'].items():
if _key not in _all_params:
raise ApiTypeError(
"Got an unexpected keyword argument '%s'"
" to method fake_return_list_of_objects" % _key
)
_params[_key] = _val
del _params['kwargs']
_collection_formats = {}
# process the path parameters
_path_params = {}
# process the query parameters
_query_params = []
# process the header parameters
_header_params = dict(_params.get('_headers', {}))
# process the form parameters
_form_params = []
_files = {}
# process the body parameter
_body_params = None
# set the HTTP header `Accept`
_header_params['Accept'] = self.api_client.select_header_accept(
['application/json']) # noqa: E501
# authentication setting
_auth_settings = [] # noqa: E501
_response_types_map = {
'200': "List[List[Tag]]",
}
return self.api_client.call_api(
'/fake/return_list_of_object', 'GET',
_path_params,
_query_params,
_header_params,
body=_body_params,
post_params=_form_params,
files=_files,
response_types_map=_response_types_map,
auth_settings=_auth_settings,
async_req=_params.get('async_req'),
_return_http_data_only=_params.get('_return_http_data_only'), # noqa: E501
_preload_content=_params.get('_preload_content', True),
_request_timeout=_params.get('_request_timeout'),
collection_formats=_collection_formats,
_request_auth=_params.get('_request_auth'))
@validate_arguments
def test_body_with_binary(self, body : Annotated[Optional[Union[StrictBytes, StrictStr]], Field(..., description="image to upload")], **kwargs) -> None: # noqa: E501
"""test_body_with_binary # noqa: E501