diff --git a/modules/openapi-generator-maven-plugin/examples/java-client.xml b/modules/openapi-generator-maven-plugin/examples/java-client.xml index b59f96a7945..aceecdeaecb 100644 --- a/modules/openapi-generator-maven-plugin/examples/java-client.xml +++ b/modules/openapi-generator-maven-plugin/examples/java-client.xml @@ -93,13 +93,17 @@ - io.swagger - swagger-annotations - ${swagger-annotations-version} + io.swagger + swagger-annotations + ${swagger-annotations-version} - + + + com.google.code.findbugs + jsr305 + 3.0.2 + @@ -107,6 +111,11 @@ jersey-client ${jersey-version} + + org.glassfish.jersey.inject + jersey-hk2 + ${jersey-version} + org.glassfish.jersey.media jersey-media-multipart @@ -118,77 +127,76 @@ ${jersey-version} - - - com.google.code.findbugs - jsr305 - 3.0.2 - - - com.fasterxml.jackson.jaxrs - jackson-jaxrs-base + com.fasterxml.jackson.core + jackson-core ${jackson-version} - com.fasterxml.jackson.core - jackson-core - ${jackson-version} + com.fasterxml.jackson.core + jackson-annotations + ${jackson-version} - com.fasterxml.jackson.core - jackson-annotations - ${jackson-version} + com.fasterxml.jackson.core + jackson-databind + ${jackson-databind-version} - com.fasterxml.jackson.core - jackson-databind - ${jackson-version} + org.openapitools + jackson-databind-nullable + ${jackson-databind-nullable-version} - com.fasterxml.jackson.jaxrs - jackson-jaxrs-json-provider - ${jackson-version} - - - org.openapitools - jackson-databind-nullable - ${jackson-databind-nullable-version} - - - - - com.fasterxml.jackson.datatype - jackson-datatype-joda - ${jackson-version} + com.fasterxml.jackson.datatype + jackson-datatype-joda + ${jackson-version} - joda-time - joda-time - ${jodatime-version} + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + ${jackson-version} com.github.scribejava scribejava-apis ${scribejava-apis-version} - + + jakarta.annotation + jakarta.annotation-api + ${jakarta-annotation-version} + provided + + + org.glassfish.jersey.connectors + jersey-apache-connector + ${jersey-version} + com.brsanthu migbase64 2.2 + + + junit + junit + ${junit-version} + test + - 1.5.8 - 2.27 - 2.9.10 - 0.2.0 - 2.7 - 1.0.0 - 4.8.1 - 6.9.0 + UTF-8 + 1.6.3 + 2.35 + 2.13.0 + 2.13.0 + 0.2.1 + 1.3.5 + 4.13.2 + 8.3.1 diff --git a/modules/openapi-generator-maven-plugin/examples/multi-module/pom.xml b/modules/openapi-generator-maven-plugin/examples/multi-module/pom.xml index f63c803d62d..c0c25badc1a 100644 --- a/modules/openapi-generator-maven-plugin/examples/multi-module/pom.xml +++ b/modules/openapi-generator-maven-plugin/examples/multi-module/pom.xml @@ -14,9 +14,9 @@ 1.5.8 - 2.27 - 2.9.10 - 0.2.0 + 2.35 + 2.13.0 + 0.2.1 2.7 1.0.0 4.8.1 diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java index 2c530aeaffe..dc67303aa9b 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java @@ -3336,6 +3336,7 @@ public class DefaultCodegen implements CodegenConfig { protected void updatePropertyForString(CodegenProperty property, Schema p) { if (ModelUtils.isByteArraySchema(p)) { + property.setIsString(false); property.isByteArray = true; } else if (ModelUtils.isBinarySchema(p)) { property.isBinary = true; @@ -4277,6 +4278,7 @@ public class DefaultCodegen implements CodegenConfig { } else if (ModelUtils.isUUIDSchema(responseSchema)) { r.isUuid = true; } else if (ModelUtils.isByteArraySchema(responseSchema)) { + r.setIsString(false); r.isByteArray = true; } else if (ModelUtils.isBinarySchema(responseSchema)) { r.isFile = true; // file = binary in OAS3 @@ -6529,6 +6531,7 @@ public class DefaultCodegen implements CodegenConfig { protected void updateRequestBodyForString(CodegenParameter codegenParameter, Schema schema, Set imports, String bodyParameterName) { updateRequestBodyForPrimitiveType(codegenParameter, schema, bodyParameterName, imports); if (ModelUtils.isByteArraySchema(schema)) { + codegenParameter.setIsString(false); codegenParameter.isByteArray = true; } else if (ModelUtils.isBinarySchema(schema)) { codegenParameter.isBinary = true; diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/RustServerCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/RustServerCodegen.java index cc8db68a316..a522c48d60a 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/RustServerCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/RustServerCodegen.java @@ -1686,38 +1686,6 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig { } } - @Override - protected void updateRequestBodyForString(CodegenParameter codegenParameter, Schema schema, Set imports, String bodyParameterName) { - /** - * we have a custom version of this function to set isString to false for isByteArray - */ - updateRequestBodyForPrimitiveType(codegenParameter, schema, bodyParameterName, imports); - if (ModelUtils.isByteArraySchema(schema)) { - codegenParameter.isByteArray = true; - // custom code - codegenParameter.setIsString(false); - } else if (ModelUtils.isBinarySchema(schema)) { - codegenParameter.isBinary = true; - codegenParameter.isFile = true; // file = binary in OAS3 - } else if (ModelUtils.isUUIDSchema(schema)) { - codegenParameter.isUuid = true; - } else if (ModelUtils.isURISchema(schema)) { - codegenParameter.isUri = true; - } else if (ModelUtils.isEmailSchema(schema)) { - codegenParameter.isEmail = true; - } else if (ModelUtils.isDateSchema(schema)) { // date format - codegenParameter.setIsString(false); // for backward compatibility with 2.x - codegenParameter.isDate = true; - } else if (ModelUtils.isDateTimeSchema(schema)) { // date-time format - codegenParameter.setIsString(false); // for backward compatibility with 2.x - codegenParameter.isDateTime = true; - } else if (ModelUtils.isDecimalSchema(schema)) { // type: string, format: number - codegenParameter.isDecimal = true; - codegenParameter.setIsString(false); - } - codegenParameter.pattern = toRegularExpression(schema.getPattern()); - } - @Override protected void updateParameterForString(CodegenParameter codegenParameter, Schema parameterSchema){ /** diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/DefaultCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/DefaultCodegenTest.java index 83917da4eba..f1e0cd6b9b6 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/DefaultCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/DefaultCodegenTest.java @@ -3846,4 +3846,29 @@ public class DefaultCodegenTest { cp = co.queryParams.get(0); assertTrue(cp.getIsAnyType()); } + + @Test + public void testByteArrayTypeInSchemas() { + DefaultCodegen codegen = new DefaultCodegen(); + final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/issue_10725.yaml"); + codegen.setOpenAPI(openAPI); + String path; + CodegenOperation co; + CodegenParameter cp; + + path = "/TxRxByteArray"; + co = codegen.fromOperation(path, "POST", openAPI.getPaths().get(path).getPost(), null); + cp = co.bodyParam; + assertTrue(cp.isByteArray); + assertFalse(cp.getIsString()); + CodegenResponse cr = co.responses.get(0); + assertTrue(cr.isByteArray); + assertFalse(cr.getIsString()); + + String modelName = "ObjectContainingByteArray"; + CodegenModel m = codegen.fromModel(modelName, openAPI.getComponents().getSchemas().get(modelName)); + CodegenProperty pr = m.vars.get(0); + assertTrue(pr.isByteArray); + assertFalse(pr.getIsString()); + } } diff --git a/modules/openapi-generator/src/test/resources/3_0/issue_10725.yaml b/modules/openapi-generator/src/test/resources/3_0/issue_10725.yaml new file mode 100644 index 00000000000..780965111f9 --- /dev/null +++ b/modules/openapi-generator/src/test/resources/3_0/issue_10725.yaml @@ -0,0 +1,46 @@ +openapi: 3.0.1 +info: + title: OpenAPI Petstore + description: "byteArray schema isX type checks" + license: + name: Apache-2.0 + url: https://www.apache.org/licenses/LICENSE-2.0.html + version: 1.0.0 +servers: + - url: http://petstore.swagger.io:80/v2 +tags: [] +paths: + /TxRxByteArray: + post: + requestBody: + required: true + content: + application/json: + schema: + type: string + format: byte + responses: + '200': + description: ComposedObject + content: + application/json: + schema: + type: string + format: byte + /RxRefObjectContainingByteArray: + get: + responses: + '200': + description: ComposedNumber + content: + application/json: + schema: + $ref: '#/components/schemas/ObjectContainingByteArray' +components: + schemas: + ObjectContainingByteArray: + type: object + properties: + byteArray: + type: string + format: byte diff --git a/modules/openapi-generator/src/test/resources/3_0/python/petstore-with-fake-endpoints-models-for-testing-with-http-signature.yaml b/modules/openapi-generator/src/test/resources/3_0/python/petstore-with-fake-endpoints-models-for-testing-with-http-signature.yaml index 7f848086554..ccb4451c6a4 100644 --- a/modules/openapi-generator/src/test/resources/3_0/python/petstore-with-fake-endpoints-models-for-testing-with-http-signature.yaml +++ b/modules/openapi-generator/src/test/resources/3_0/python/petstore-with-fake-endpoints-models-for-testing-with-http-signature.yaml @@ -1348,6 +1348,23 @@ paths: items: type: string nullable: true + /fake/TxRxAnyOfModel: + post: + tags: + - fake + operationId: txRxAnyOfModel + responses: + 200: + description: TxRxAnyOfModel + content: + application/json: + schema: + $ref: '#/components/schemas/GmFruitNoProperties' + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/GmFruitNoProperties' servers: - url: 'http://{server}.swagger.io:{port}/v2' description: petstore server @@ -2243,6 +2260,10 @@ components: type: string required: - className + GmFruitNoProperties: + anyOf: + - $ref: '#/components/schemas/apple' + - $ref: '#/components/schemas/banana' gmFruit: properties: color: diff --git a/pom.xml b/pom.xml index d82d4be0f8f..02914928aec 100644 --- a/pom.xml +++ b/pom.xml @@ -1314,7 +1314,9 @@ samples/client/petstore/java/rest-assured-jackson samples/client/petstore/java/microprofile-rest-client samples/client/petstore/java/apache-httpclient + diff --git a/samples/openapi3/client/petstore/python/.openapi-generator/FILES b/samples/openapi3/client/petstore/python/.openapi-generator/FILES index e4ad25ef9db..4b9b1323443 100644 --- a/samples/openapi3/client/petstore/python/.openapi-generator/FILES +++ b/samples/openapi3/client/petstore/python/.openapi-generator/FILES @@ -49,6 +49,7 @@ docs/FormatTest.md docs/Fruit.md docs/FruitReq.md docs/GmFruit.md +docs/GmFruitNoProperties.md docs/GrandparentAnimal.md docs/HasOnlyReadOnly.md docs/HealthCheckResult.md @@ -161,6 +162,7 @@ petstore_api/model/format_test.py petstore_api/model/fruit.py petstore_api/model/fruit_req.py petstore_api/model/gm_fruit.py +petstore_api/model/gm_fruit_no_properties.py petstore_api/model/grandparent_animal.py petstore_api/model/has_only_read_only.py petstore_api/model/health_check_result.py diff --git a/samples/openapi3/client/petstore/python/README.md b/samples/openapi3/client/petstore/python/README.md index bc3cc959108..f8ceed3eb8e 100644 --- a/samples/openapi3/client/petstore/python/README.md +++ b/samples/openapi3/client/petstore/python/README.md @@ -107,6 +107,7 @@ Class | Method | HTTP request | Description *FakeApi* | [**test_inline_additional_properties**](docs/FakeApi.md#test_inline_additional_properties) | **POST** /fake/inline-additionalProperties | test inline additionalProperties *FakeApi* | [**test_json_form_data**](docs/FakeApi.md#test_json_form_data) | **GET** /fake/jsonFormData | test json serialization of form data *FakeApi* | [**test_query_parameter_collection_format**](docs/FakeApi.md#test_query_parameter_collection_format) | **PUT** /fake/test-query-parameters | +*FakeApi* | [**tx_rx_any_of_model**](docs/FakeApi.md#tx_rx_any_of_model) | **POST** /fake/TxRxAnyOfModel | *FakeApi* | [**upload_download_file**](docs/FakeApi.md#upload_download_file) | **POST** /fake/uploadDownloadFile | uploads a file and downloads a file using application/octet-stream *FakeApi* | [**upload_file**](docs/FakeApi.md#upload_file) | **POST** /fake/uploadFile | uploads a file using multipart/form-data *FakeApi* | [**upload_files**](docs/FakeApi.md#upload_files) | **POST** /fake/uploadFiles | uploads files using multipart/form-data @@ -177,6 +178,7 @@ Class | Method | HTTP request | Description - [Fruit](docs/Fruit.md) - [FruitReq](docs/FruitReq.md) - [GmFruit](docs/GmFruit.md) + - [GmFruitNoProperties](docs/GmFruitNoProperties.md) - [GrandparentAnimal](docs/GrandparentAnimal.md) - [HasOnlyReadOnly](docs/HasOnlyReadOnly.md) - [HealthCheckResult](docs/HealthCheckResult.md) diff --git a/samples/openapi3/client/petstore/python/docs/FakeApi.md b/samples/openapi3/client/petstore/python/docs/FakeApi.md index 6ee1a7c20a7..57114615c44 100644 --- a/samples/openapi3/client/petstore/python/docs/FakeApi.md +++ b/samples/openapi3/client/petstore/python/docs/FakeApi.md @@ -28,6 +28,7 @@ Method | HTTP request | Description [**test_inline_additional_properties**](FakeApi.md#test_inline_additional_properties) | **POST** /fake/inline-additionalProperties | test inline additionalProperties [**test_json_form_data**](FakeApi.md#test_json_form_data) | **GET** /fake/jsonFormData | test json serialization of form data [**test_query_parameter_collection_format**](FakeApi.md#test_query_parameter_collection_format) | **PUT** /fake/test-query-parameters | +[**tx_rx_any_of_model**](FakeApi.md#tx_rx_any_of_model) | **POST** /fake/TxRxAnyOfModel | [**upload_download_file**](FakeApi.md#upload_download_file) | **POST** /fake/uploadDownloadFile | uploads a file and downloads a file using application/octet-stream [**upload_file**](FakeApi.md#upload_file) | **POST** /fake/uploadFile | uploads a file using multipart/form-data [**upload_files**](FakeApi.md#upload_files) | **POST** /fake/uploadFiles | uploads files using multipart/form-data @@ -1789,6 +1790,71 @@ 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) +# **tx_rx_any_of_model** +> GmFruitNoProperties tx_rx_any_of_model() + + + +### Example + + +```python +import time +import petstore_api +from petstore_api.api import fake_api +from petstore_api.model.gm_fruit_no_properties import GmFruitNoProperties +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() as api_client: + # Create an instance of the API class + api_instance = fake_api.FakeApi(api_client) + gm_fruit_no_properties = GmFruitNoProperties(None) # GmFruitNoProperties | (optional) + + # example passing only required values which don't have defaults set + # and optional values + try: + api_response = api_instance.tx_rx_any_of_model(gm_fruit_no_properties=gm_fruit_no_properties) + pprint(api_response) + except petstore_api.ApiException as e: + print("Exception when calling FakeApi->tx_rx_any_of_model: %s\n" % e) +``` + + +### Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **gm_fruit_no_properties** | [**GmFruitNoProperties**](GmFruitNoProperties.md)| | [optional] + +### Return type + +[**GmFruitNoProperties**](GmFruitNoProperties.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json + + +### HTTP response details + +| Status code | Description | Response headers | +|-------------|-------------|------------------| +**200** | TxRxAnyOfModel | - | + +[[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) + # **upload_download_file** > file_type upload_download_file(body) diff --git a/samples/openapi3/client/petstore/python/docs/GmFruitNoProperties.md b/samples/openapi3/client/petstore/python/docs/GmFruitNoProperties.md new file mode 100644 index 00000000000..ca206a83ced --- /dev/null +++ b/samples/openapi3/client/petstore/python/docs/GmFruitNoProperties.md @@ -0,0 +1,14 @@ +# GmFruitNoProperties + + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**origin** | **str** | | [optional] +**cultivar** | **str** | | [optional] +**length_cm** | **float** | | [optional] +**any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/openapi3/client/petstore/python/petstore_api/api/fake_api.py b/samples/openapi3/client/petstore/python/petstore_api/api/fake_api.py index 056c1f33f16..0f93d1cfde1 100644 --- a/samples/openapi3/client/petstore/python/petstore_api/api/fake_api.py +++ b/samples/openapi3/client/petstore/python/petstore_api/api/fake_api.py @@ -29,6 +29,7 @@ from petstore_api.model.client import Client from petstore_api.model.composed_one_of_number_with_validations import ComposedOneOfNumberWithValidations from petstore_api.model.enum_test import EnumTest from petstore_api.model.file_schema_test_class import FileSchemaTestClass +from petstore_api.model.gm_fruit_no_properties import GmFruitNoProperties from petstore_api.model.health_check_result import HealthCheckResult from petstore_api.model.inline_additional_properties_ref_payload import InlineAdditionalPropertiesRefPayload from petstore_api.model.inline_object6 import InlineObject6 @@ -1484,6 +1485,54 @@ class FakeApi(object): }, api_client=api_client ) + self.tx_rx_any_of_model_endpoint = _Endpoint( + settings={ + 'response_type': (GmFruitNoProperties,), + 'auth': [], + 'endpoint_path': '/fake/TxRxAnyOfModel', + 'operation_id': 'tx_rx_any_of_model', + 'http_method': 'POST', + 'servers': None, + }, + params_map={ + 'all': [ + 'gm_fruit_no_properties', + ], + 'required': [], + 'nullable': [ + ], + 'enum': [ + ], + 'validation': [ + ] + }, + root_map={ + 'validations': { + }, + 'allowed_values': { + }, + 'openapi_types': { + 'gm_fruit_no_properties': + (GmFruitNoProperties,), + }, + 'attribute_map': { + }, + 'location_map': { + 'gm_fruit_no_properties': 'body', + }, + 'collection_format_map': { + } + }, + headers_map={ + 'accept': [ + 'application/json' + ], + 'content_type': [ + 'application/json' + ] + }, + api_client=api_client + ) self.upload_download_file_endpoint = _Endpoint( settings={ 'response_type': (file_type,), @@ -3222,6 +3271,67 @@ class FakeApi(object): context return self.test_query_parameter_collection_format_endpoint.call_with_http_info(**kwargs) + def tx_rx_any_of_model( + self, + **kwargs + ): + """tx_rx_any_of_model # noqa: E501 + + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.tx_rx_any_of_model(async_req=True) + >>> result = thread.get() + + + Keyword Args: + gm_fruit_no_properties (GmFruitNoProperties): [optional] + _return_http_data_only (bool): response data without head status + code and headers. Default is True. + _preload_content (bool): if False, the urllib3.HTTPResponse object + will be returned without reading/decoding response data. + Default is True. + _request_timeout (int/float/tuple): 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. + Default is None. + _check_input_type (bool): specifies if type checking + should be done one the data sent to the server. + Default is True. + _check_return_type (bool): specifies if type checking + should be done one the data received from the server. + Default is True. + _host_index (int/None): specifies the index of the server + that we want to use. + Default is read from the configuration. + async_req (bool): execute request asynchronously + + Returns: + GmFruitNoProperties + If the method is called asynchronously, returns the request + thread. + """ + kwargs['async_req'] = kwargs.get( + 'async_req', False + ) + kwargs['_return_http_data_only'] = kwargs.get( + '_return_http_data_only', True + ) + kwargs['_preload_content'] = kwargs.get( + '_preload_content', True + ) + kwargs['_request_timeout'] = kwargs.get( + '_request_timeout', None + ) + kwargs['_check_input_type'] = kwargs.get( + '_check_input_type', True + ) + kwargs['_check_return_type'] = kwargs.get( + '_check_return_type', True + ) + kwargs['_host_index'] = kwargs.get('_host_index') + return self.tx_rx_any_of_model_endpoint.call_with_http_info(**kwargs) + def upload_download_file( self, body, diff --git a/samples/openapi3/client/petstore/python/petstore_api/model/gm_fruit_no_properties.py b/samples/openapi3/client/petstore/python/petstore_api/model/gm_fruit_no_properties.py new file mode 100644 index 00000000000..160b41305b4 --- /dev/null +++ b/samples/openapi3/client/petstore/python/petstore_api/model/gm_fruit_no_properties.py @@ -0,0 +1,333 @@ +""" + OpenAPI Petstore + + This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ # noqa: E501 + + The version of the OpenAPI document: 1.0.0 + Generated by: https://openapi-generator.tech +""" + + +import re # noqa: F401 +import sys # noqa: F401 + +from petstore_api.model_utils import ( # noqa: F401 + ApiTypeError, + ModelComposed, + ModelNormal, + ModelSimple, + cached_property, + change_keys_js_to_python, + convert_js_args_to_python_args, + date, + datetime, + file_type, + none_type, + validate_get_composed_info, +) +from ..model_utils import OpenApiModel +from petstore_api.exceptions import ApiAttributeError + + +def lazy_import(): + from petstore_api.model.apple import Apple + from petstore_api.model.banana import Banana + globals()['Apple'] = Apple + globals()['Banana'] = Banana + + +class GmFruitNoProperties(ModelComposed): + """NOTE: This class is auto generated by OpenAPI Generator. + Ref: https://openapi-generator.tech + + Do not edit the class manually. + + Attributes: + allowed_values (dict): The key is the tuple path to the attribute + and the for var_name this is (var_name,). The value is a dict + with a capitalized key describing the allowed value and an allowed + value. These dicts store the allowed enum values. + attribute_map (dict): The key is attribute name + and the value is json key in definition. + discriminator_value_class_map (dict): A dict to go from the discriminator + variable value to the discriminator class name. + validations (dict): The key is the tuple path to the attribute + and the for var_name this is (var_name,). The value is a dict + that stores validations for max_length, min_length, max_items, + min_items, exclusive_maximum, inclusive_maximum, exclusive_minimum, + inclusive_minimum, and regex. + additional_properties_type (tuple): A tuple of classes accepted + as additional properties values. + """ + + allowed_values = { + } + + validations = { + ('origin',): { + 'regex': { + 'pattern': r'^[A-Z\s]*$', # noqa: E501 + 'flags': (re.IGNORECASE) + }, + }, + ('cultivar',): { + 'regex': { + 'pattern': r'^[a-zA-Z\s]*$', # noqa: E501 + }, + }, + } + + @cached_property + def additional_properties_type(): + """ + This must be a method because a model may have properties that are + of type self, this must run after the class is loaded + """ + lazy_import() + return (bool, date, datetime, dict, float, int, list, str, none_type,) # noqa: E501 + + _nullable = False + + @cached_property + def openapi_types(): + """ + This must be a method because a model may have properties that are + of type self, this must run after the class is loaded + + Returns + openapi_types (dict): The key is attribute name + and the value is attribute type. + """ + lazy_import() + return { + 'origin': (str,), # noqa: E501 + 'cultivar': (str,), # noqa: E501 + 'length_cm': (float,), # noqa: E501 + } + + @cached_property + def discriminator(): + return None + + + attribute_map = { + 'origin': 'origin', # noqa: E501 + 'cultivar': 'cultivar', # noqa: E501 + 'length_cm': 'lengthCm', # noqa: E501 + } + + read_only_vars = { + } + + @classmethod + @convert_js_args_to_python_args + def _from_openapi_data(cls, *args, **kwargs): # noqa: E501 + """GmFruitNoProperties - a model defined in OpenAPI + + Keyword Args: + _check_type (bool): if True, values for parameters in openapi_types + will be type checked and a TypeError will be + raised if the wrong type is input. + Defaults to True + _path_to_item (tuple/list): This is a list of keys or values to + drill down to the model in received_data + when deserializing a response + _spec_property_naming (bool): True if the variable names in the input data + are serialized names, as specified in the OpenAPI document. + False if the variable names in the input data + are pythonic names, e.g. snake case (default) + _configuration (Configuration): the instance to use when + deserializing a file_type parameter. + If passed, type conversion is attempted + If omitted no type conversion is done. + _visited_composed_classes (tuple): This stores a tuple of + classes that we have traveled through so that + if we see that class again we will not use its + discriminator again. + When traveling through a discriminator, the + composed schema that is + is traveled through is added to this set. + For example if Animal has a discriminator + petType and we pass in "Dog", and the class Dog + allOf includes Animal, we move through Animal + once using the discriminator, and pick Dog. + Then in Dog, we will make an instance of the + Animal class but this time we won't travel + through its discriminator because we passed in + _visited_composed_classes = (Animal,) + origin (str): [optional] # noqa: E501 + cultivar (str): [optional] # noqa: E501 + length_cm (float): [optional] # noqa: E501 + """ + + _check_type = kwargs.pop('_check_type', True) + _spec_property_naming = kwargs.pop('_spec_property_naming', False) + _path_to_item = kwargs.pop('_path_to_item', ()) + _configuration = kwargs.pop('_configuration', None) + _visited_composed_classes = kwargs.pop('_visited_composed_classes', ()) + + self = super(OpenApiModel, cls).__new__(cls) + + if args: + raise ApiTypeError( + "Invalid positional arguments=%s passed to %s. Remove those invalid positional arguments." % ( + args, + self.__class__.__name__, + ), + path_to_item=_path_to_item, + valid_classes=(self.__class__,), + ) + + self._data_store = {} + self._check_type = _check_type + self._spec_property_naming = _spec_property_naming + self._path_to_item = _path_to_item + self._configuration = _configuration + self._visited_composed_classes = _visited_composed_classes + (self.__class__,) + + constant_args = { + '_check_type': _check_type, + '_path_to_item': _path_to_item, + '_spec_property_naming': _spec_property_naming, + '_configuration': _configuration, + '_visited_composed_classes': self._visited_composed_classes, + } + composed_info = validate_get_composed_info( + constant_args, kwargs, self) + self._composed_instances = composed_info[0] + self._var_name_to_model_instances = composed_info[1] + self._additional_properties_model_instances = composed_info[2] + discarded_args = composed_info[3] + + for var_name, var_value in kwargs.items(): + if var_name in discarded_args and \ + self._configuration is not None and \ + self._configuration.discard_unknown_keys and \ + self._additional_properties_model_instances: + # discard variable. + continue + setattr(self, var_name, var_value) + + return self + + required_properties = set([ + '_data_store', + '_check_type', + '_spec_property_naming', + '_path_to_item', + '_configuration', + '_visited_composed_classes', + '_composed_instances', + '_var_name_to_model_instances', + '_additional_properties_model_instances', + ]) + + @convert_js_args_to_python_args + def __init__(self, *args, **kwargs): # noqa: E501 + """GmFruitNoProperties - a model defined in OpenAPI + + Keyword Args: + _check_type (bool): if True, values for parameters in openapi_types + will be type checked and a TypeError will be + raised if the wrong type is input. + Defaults to True + _path_to_item (tuple/list): This is a list of keys or values to + drill down to the model in received_data + when deserializing a response + _spec_property_naming (bool): True if the variable names in the input data + are serialized names, as specified in the OpenAPI document. + False if the variable names in the input data + are pythonic names, e.g. snake case (default) + _configuration (Configuration): the instance to use when + deserializing a file_type parameter. + If passed, type conversion is attempted + If omitted no type conversion is done. + _visited_composed_classes (tuple): This stores a tuple of + classes that we have traveled through so that + if we see that class again we will not use its + discriminator again. + When traveling through a discriminator, the + composed schema that is + is traveled through is added to this set. + For example if Animal has a discriminator + petType and we pass in "Dog", and the class Dog + allOf includes Animal, we move through Animal + once using the discriminator, and pick Dog. + Then in Dog, we will make an instance of the + Animal class but this time we won't travel + through its discriminator because we passed in + _visited_composed_classes = (Animal,) + origin (str): [optional] # noqa: E501 + cultivar (str): [optional] # noqa: E501 + length_cm (float): [optional] # noqa: E501 + """ + + _check_type = kwargs.pop('_check_type', True) + _spec_property_naming = kwargs.pop('_spec_property_naming', False) + _path_to_item = kwargs.pop('_path_to_item', ()) + _configuration = kwargs.pop('_configuration', None) + _visited_composed_classes = kwargs.pop('_visited_composed_classes', ()) + + if args: + raise ApiTypeError( + "Invalid positional arguments=%s passed to %s. Remove those invalid positional arguments." % ( + args, + self.__class__.__name__, + ), + path_to_item=_path_to_item, + valid_classes=(self.__class__,), + ) + + self._data_store = {} + self._check_type = _check_type + self._spec_property_naming = _spec_property_naming + self._path_to_item = _path_to_item + self._configuration = _configuration + self._visited_composed_classes = _visited_composed_classes + (self.__class__,) + + constant_args = { + '_check_type': _check_type, + '_path_to_item': _path_to_item, + '_spec_property_naming': _spec_property_naming, + '_configuration': _configuration, + '_visited_composed_classes': self._visited_composed_classes, + } + composed_info = validate_get_composed_info( + constant_args, kwargs, self) + self._composed_instances = composed_info[0] + self._var_name_to_model_instances = composed_info[1] + self._additional_properties_model_instances = composed_info[2] + discarded_args = composed_info[3] + + for var_name, var_value in kwargs.items(): + if var_name in discarded_args and \ + self._configuration is not None and \ + self._configuration.discard_unknown_keys and \ + self._additional_properties_model_instances: + # discard variable. + continue + setattr(self, var_name, var_value) + if var_name in self.read_only_vars: + raise ApiAttributeError(f"`{var_name}` is a read-only attribute. Use `from_openapi_data` to instantiate " + f"class with read only attributes.") + + @cached_property + def _composed_schemas(): + # we need this here to make our import statements work + # we must store _composed_schemas in here so the code is only run + # when we invoke this method. If we kept this at the class + # level we would get an error because the class level + # code would be run when this module is imported, and these composed + # classes don't exist yet because their module has not finished + # loading + lazy_import() + return { + 'anyOf': [ + Apple, + Banana, + ], + 'allOf': [ + ], + 'oneOf': [ + ], + } diff --git a/samples/openapi3/client/petstore/python/petstore_api/models/__init__.py b/samples/openapi3/client/petstore/python/petstore_api/models/__init__.py index b1bc33c5188..5e9f7f3bfaa 100644 --- a/samples/openapi3/client/petstore/python/petstore_api/models/__init__.py +++ b/samples/openapi3/client/petstore/python/petstore_api/models/__init__.py @@ -52,6 +52,7 @@ from petstore_api.model.format_test import FormatTest from petstore_api.model.fruit import Fruit from petstore_api.model.fruit_req import FruitReq from petstore_api.model.gm_fruit import GmFruit +from petstore_api.model.gm_fruit_no_properties import GmFruitNoProperties from petstore_api.model.grandparent_animal import GrandparentAnimal from petstore_api.model.has_only_read_only import HasOnlyReadOnly from petstore_api.model.health_check_result import HealthCheckResult diff --git a/samples/openapi3/client/petstore/python/test/test_gm_fruit_no_properties.py b/samples/openapi3/client/petstore/python/test/test_gm_fruit_no_properties.py new file mode 100644 index 00000000000..6307028c07c --- /dev/null +++ b/samples/openapi3/client/petstore/python/test/test_gm_fruit_no_properties.py @@ -0,0 +1,39 @@ +""" + OpenAPI Petstore + + This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ # noqa: E501 + + The version of the OpenAPI document: 1.0.0 + Generated by: https://openapi-generator.tech +""" + + +import sys +import unittest + +import petstore_api +from petstore_api.model.apple import Apple +from petstore_api.model.banana import Banana +globals()['Apple'] = Apple +globals()['Banana'] = Banana +from petstore_api.model.gm_fruit_no_properties import GmFruitNoProperties + + +class TestGmFruitNoProperties(unittest.TestCase): + """GmFruitNoProperties unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def testGmFruitNoProperties(self): + """Test GmFruitNoProperties""" + # FIXME: construct object with mandatory attributes with example values + # model = GmFruitNoProperties() # noqa: E501 + pass + + +if __name__ == '__main__': + unittest.main() diff --git a/samples/openapi3/client/petstore/python/tests_manual/test_fake_api.py b/samples/openapi3/client/petstore/python/tests_manual/test_fake_api.py index 232faa46e6e..33812b1b3f5 100644 --- a/samples/openapi3/client/petstore/python/tests_manual/test_fake_api.py +++ b/samples/openapi3/client/petstore/python/tests_manual/test_fake_api.py @@ -714,5 +714,34 @@ class TestFakeApi(unittest.TestCase): assert isinstance(response, InlineObject6) assert model_to_dict(response) == expected_json_body + def test_post_tx_rx_any_of_payload(self): + """Test case for postInlineAdditionlPropertiesPayload + """ + from petstore_api.model.gm_fruit_no_properties import GmFruitNoProperties + endpoint = self.api.tx_rx_any_of_model_endpoint + assert endpoint.openapi_types['gm_fruit_no_properties'] == (GmFruitNoProperties,) + assert endpoint.settings['response_type'] == (GmFruitNoProperties,) + + # serialization + deserialization works + from petstore_api.rest import RESTClientObject, RESTResponse + with patch.object(RESTClientObject, 'request') as mock_method: + expected_json_body = { + 'cultivar': 'Alice', + 'origin': 'Kazakhstan', + 'lengthCm': 7, + } + fruit = GmFruitNoProperties(**expected_json_body) + mock_method.return_value = self.mock_response(expected_json_body) + + response = self.api.tx_rx_any_of_model(gm_fruit_no_properties=fruit) + self.assert_request_called_with( + mock_method, + 'http://petstore.swagger.io:80/v2/fake/TxRxAnyOfModel', + body=expected_json_body + ) + + assert isinstance(response, GmFruitNoProperties) + assert model_to_dict(response) == expected_json_body + if __name__ == '__main__': unittest.main()