From 89f7c853f8a70b6e68bc838a926df42abbcae613 Mon Sep 17 00:00:00 2001 From: Justin Black Date: Mon, 23 Sep 2019 10:49:10 -0700 Subject: [PATCH 01/13] Changes python-experimental types to classes, adds additionalalproperties handling Adds model_utils update, updates model.mustache Updates api.mustache and uses model_to_dict in model_normal.mustache Updates requirements.mustache for PythonClientExperimental Passes through check_type when deserializing models Converts types from strings to classes in PythonClientExperimentalCodegen.java and PythonTest.java Creates PythonClientExperimentalTest.java Updates toInstantiationType to use ModelUtils.xxx Corrects docstring descriptions of response_type Updates python-experimental typing, partially fixes deserialization tests Adds fixes for some of the deserialization tests Fixes deserialization tests Switches model teplates to use allVars so allof props will be included Fixes tests.test_enum_arrays Fixes test_to_str Adds additional_properties_type, fixes teast_todict in test_map_test.py Correctly check the type of _request_timeout values Fixes test_upload_file test Turns off coercion when instantiating model types with client data Updates file handling to input and output an open file object Fixes linting errors Adds fixes for python2 tests, linting fixes Adds additionalproperties to docs + tests Regenerates python-experimatal client --- .../openapitools/codegen/DefaultCodegen.java | 2 +- .../languages/PythonClientCodegen.java | 2 +- .../PythonClientExperimentalCodegen.java | 153 ++- .../python/python-experimental/api.mustache | 114 ++- .../python-experimental/api_client.mustache | 320 ++---- .../python/python-experimental/model.mustache | 21 +- .../python-experimental/model_doc.mustache | 18 +- .../model_templates/classvar_allowed.mustache | 6 +- .../classvar_openapi_validations.mustache | 43 +- .../docstring_openapi_validations.mustache | 4 +- .../methods_init_properties.mustache | 170 +-- .../model_templates/model_normal.mustache | 56 +- .../model_templates/model_simple.mustache | 16 +- .../python-experimental/model_utils.mustache | 735 ++++++++++++- .../python-experimental/requirements.mustache | 6 + .../python/python-experimental/setup.mustache | 45 + .../resources/python/requirements.mustache | 1 + .../python/PythonClientExperimentalTest.java | 297 ++++++ .../codegen/python/PythonTest.java | 2 +- .../docs/AdditionalPropertiesAnyType.md | 1 + .../docs/AdditionalPropertiesArray.md | 1 + .../docs/AdditionalPropertiesBoolean.md | 1 + .../docs/AdditionalPropertiesClass.md | 22 +- .../docs/AdditionalPropertiesInteger.md | 1 + .../docs/AdditionalPropertiesNumber.md | 1 + .../docs/AdditionalPropertiesObject.md | 1 + .../docs/AdditionalPropertiesString.md | 1 + .../docs/ArrayOfArrayOfNumberOnly.md | 2 +- .../docs/ArrayOfNumberOnly.md | 2 +- .../python-experimental/docs/ArrayTest.md | 6 +- .../python-experimental/docs/EnumArrays.md | 2 +- .../python-experimental/docs/FakeApi.md | 20 +- .../docs/FileSchemaTestClass.md | 2 +- .../python-experimental/docs/FormatTest.md | 2 +- .../python-experimental/docs/MapTest.md | 6 +- ...dPropertiesAndAdditionalPropertiesClass.md | 2 +- .../petstore/python-experimental/docs/Pet.md | 4 +- .../python-experimental/docs/PetApi.md | 24 +- .../python-experimental/docs/StoreApi.md | 4 +- .../docs/StringBooleanMap.md | 1 + .../docs/TypeHolderDefault.md | 2 +- .../docs/TypeHolderExample.md | 2 +- .../python-experimental/docs/UserApi.md | 8 +- .../python-experimental/docs/XmlItem.md | 18 +- .../petstore_api/api/another_fake_api.py | 112 +- .../petstore_api/api/fake_api.py | 634 ++++++++++-- .../api/fake_classname_tags_123_api.py | 112 +- .../petstore_api/api/pet_api.py | 395 +++++-- .../petstore_api/api/store_api.py | 209 +++- .../petstore_api/api/user_api.py | 337 +++++- .../petstore_api/api_client.py | 320 ++---- .../petstore_api/model_utils.py | 735 ++++++++++++- .../models/additional_properties_any_type.py | 188 +++- .../models/additional_properties_array.py | 188 +++- .../models/additional_properties_boolean.py | 188 +++- .../models/additional_properties_class.py | 462 ++++----- .../models/additional_properties_integer.py | 188 +++- .../models/additional_properties_number.py | 188 +++- .../models/additional_properties_object.py | 188 +++- .../models/additional_properties_string.py | 188 +++- .../petstore_api/models/animal.py | 234 +++-- .../petstore_api/models/api_response.py | 242 +++-- .../models/array_of_array_of_number_only.py | 188 +++- .../models/array_of_number_only.py | 188 +++- .../petstore_api/models/array_test.py | 243 +++-- .../petstore_api/models/capitalization.py | 322 +++--- .../petstore_api/models/cat.py | 224 +++- .../petstore_api/models/cat_all_of.py | 188 +++- .../petstore_api/models/category.py | 217 ++-- .../petstore_api/models/class_model.py | 188 +++- .../petstore_api/models/client.py | 188 +++- .../petstore_api/models/dog.py | 224 +++- .../petstore_api/models/dog_all_of.py | 188 +++- .../petstore_api/models/enum_arrays.py | 230 +++-- .../petstore_api/models/enum_class.py | 174 +++- .../petstore_api/models/enum_test.py | 330 +++--- .../petstore_api/models/file.py | 188 +++- .../models/file_schema_test_class.py | 215 ++-- .../petstore_api/models/format_test.py | 566 +++++----- .../petstore_api/models/has_only_read_only.py | 214 ++-- .../petstore_api/models/list.py | 188 +++- .../petstore_api/models/map_test.py | 277 +++-- ...perties_and_additional_properties_class.py | 243 +++-- .../petstore_api/models/model200_response.py | 214 ++-- .../petstore_api/models/model_return.py | 188 +++- .../petstore_api/models/name.py | 271 +++-- .../petstore_api/models/number_only.py | 188 +++- .../petstore_api/models/order.py | 330 +++--- .../petstore_api/models/outer_composite.py | 243 +++-- .../petstore_api/models/outer_enum.py | 174 +++- .../petstore_api/models/outer_number.py | 172 +++- .../petstore_api/models/pet.py | 335 +++--- .../petstore_api/models/read_only_first.py | 214 ++-- .../petstore_api/models/special_model_name.py | 188 +++- .../petstore_api/models/string_boolean_map.py | 162 ++- .../petstore_api/models/tag.py | 214 ++-- .../models/type_holder_default.py | 357 ++++--- .../models/type_holder_example.py | 325 +++--- .../petstore_api/models/user.py | 378 +++---- .../petstore_api/models/xml_item.py | 966 +++++++----------- .../python-experimental/requirements.txt | 1 + .../petstore/python-experimental/setup.py | 2 + .../test/test_additional_properties_array.py | 20 +- .../test_additional_properties_boolean.py | 14 +- .../test_additional_properties_integer.py | 14 +- .../test/test_additional_properties_number.py | 13 +- .../test/test_additional_properties_object.py | 20 +- .../test/test_additional_properties_string.py | 14 +- .../python-experimental/test/test_fake_api.py | 8 +- .../test/test_format_test.py | 3 +- .../tests/test_api_client.py | 6 + .../tests/test_deserialization.py | 149 ++- .../tests/test_enum_arrays.py | 82 +- .../tests/test_map_test.py | 32 +- .../python-experimental/tests/test_pet_api.py | 27 +- .../tests/test_pet_model.py | 2 +- 116 files changed, 12021 insertions(+), 5543 deletions(-) create mode 100644 modules/openapi-generator/src/main/resources/python/python-experimental/requirements.mustache create mode 100644 modules/openapi-generator/src/main/resources/python/python-experimental/setup.mustache create mode 100644 modules/openapi-generator/src/test/java/org/openapitools/codegen/python/PythonClientExperimentalTest.java 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 ab3ef8b418e3..7ac1b1c3fa08 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 @@ -3617,7 +3617,7 @@ public void addOperationToGroup(String tag, String resourcePath, Operation opera co.baseName = tag; } - private void addParentContainer(CodegenModel model, String name, Schema schema) { + protected void addParentContainer(CodegenModel model, String name, Schema schema) { final CodegenProperty property = fromProperty(name, schema); addImport(model, property.complexType); model.parent = toInstantiationType(schema); diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PythonClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PythonClientCodegen.java index 16ec0bd3c03a..5438395949af 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PythonClientCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PythonClientCodegen.java @@ -190,7 +190,7 @@ public void processOpts() { if (additionalProperties.containsKey(CodegenConstants.PACKAGE_VERSION)) { setPackageVersion((String) additionalProperties.get(CodegenConstants.PACKAGE_VERSION)); - } + } Boolean generateSourceCodeOnly = false; if (additionalProperties.containsKey(CodegenConstants.SOURCECODEONLY_GENERATION)) { diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PythonClientExperimentalCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PythonClientExperimentalCodegen.java index 71dd5d61133e..30effec0cd1b 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PythonClientExperimentalCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PythonClientExperimentalCodegen.java @@ -50,6 +50,9 @@ public class PythonClientExperimentalCodegen extends PythonClientCodegen { public PythonClientExperimentalCodegen() { super(); + // this may set datatype right for additional properties + instantiationTypes.put("map", "dict"); + apiTemplateFiles.remove("api.mustache"); apiTemplateFiles.put("python-experimental/api.mustache", ".py"); @@ -76,6 +79,18 @@ public void processOpts() { supportingFiles.add(new SupportingFile("python-experimental/model_utils.mustache", packagePath(), "model_utils.py")); + Boolean generateSourceCodeOnly = false; + if (additionalProperties.containsKey(CodegenConstants.SOURCECODEONLY_GENERATION)) { + generateSourceCodeOnly = Boolean.valueOf(additionalProperties.get(CodegenConstants.SOURCECODEONLY_GENERATION).toString()); + } + + if (!generateSourceCodeOnly) { + supportingFiles.remove(new SupportingFile("setup.mustache", "", "setup.py")); + supportingFiles.add(new SupportingFile("python-experimental/setup.mustache", "", "setup.py")); + supportingFiles.remove(new SupportingFile("requirements.mustache", "", "requirements.txt")); + supportingFiles.add(new SupportingFile("python-experimental/requirements.mustache", "", "requirements.txt")); + } + // default this to true so the python ModelSimple models will be generated ModelUtils.setGenerateAliasAsModel(true); LOGGER.info(CodegenConstants.GENERATE_ALIAS_AS_MODEL + " is hard coded to true in this generator. Alias models will only be generated if they contain validations or enums"); @@ -196,10 +211,16 @@ public String toDefaultValue(Schema p) { } } - @Override - public void postProcessModelProperty(CodegenModel model, CodegenProperty property) { - // add regex information to property - postProcessPattern(property.pattern, property.vendorExtensions); + public void addModelImport(Map objs, CodegenModel cm, String otherModelName) { + // adds the absolute path to otherModelName as an import in CodegenModel cm + HashMap referencedModel = (HashMap) objs.get(otherModelName); + ArrayList myModel = (ArrayList) referencedModel.get("models"); + HashMap modelData = (HashMap) myModel.get(0); + String importPath = (String) modelData.get("importPath"); + // only add importPath to parameters if it isn't in importPaths + if (!cm.imports.contains(importPath)) { + cm.imports.add(importPath); + } } // override with any special post-processing for all models @@ -213,6 +234,41 @@ public Map postProcessAllModels(Map objs) { List> models = (List>) inner.get("models"); for (Map mo : models) { CodegenModel cm = (CodegenModel) mo.get("model"); + + // fix the imports that each model has, change them to absolute + // imports + // clear out imports so we will only include full path imports + cm.imports.clear(); + CodegenDiscriminator discriminator = cm.discriminator; + if (discriminator != null) { + Set mappedModels = discriminator.getMappedModels(); + for (CodegenDiscriminator.MappedModel mappedModel : mappedModels) { + String otherModelName = mappedModel.getModelName(); + addModelImport(objs, cm, otherModelName); + } + } + ArrayList> listOfLists= new ArrayList>(); + listOfLists.add(cm.allVars); + listOfLists.add(cm.requiredVars); + listOfLists.add(cm.optionalVars); + listOfLists.add(cm.vars); + for (List varList : listOfLists) { + for (CodegenProperty cp : varList) { + String otherModelName = null; + if (cp.complexType != null) { + otherModelName = cp.complexType; + } + if (cp.mostInnerItems != null) { + if (cp.mostInnerItems.complexType != null) { + otherModelName = cp.mostInnerItems.complexType; + } + } + if (otherModelName != null) { + addModelImport(objs, cm, otherModelName); + } + } + } + Schema modelSchema = ModelUtils.getSchema(this.openAPI, cm.name); CodegenProperty modelProperty = fromProperty("value", modelSchema); if (cm.isEnum || cm.isAlias) { @@ -491,11 +547,6 @@ public String toEnumValue(String value, String datatype) { } } - @Override - public void postProcessParameter(CodegenParameter parameter) { - postProcessPattern(parameter.pattern, parameter.vendorExtensions); - } - /** * Convert OAS Model object to Codegen Model object * @@ -559,11 +610,7 @@ public CodegenModel fromModel(String name, Schema schema) { } } - // return all models which don't need their properties connected to non-object models - if (propertyToModelName.isEmpty()) { - return result; - } - + // set regex values, before it was only done on model.vars // fix all property references to non-object models, make those properties non-primitive and // set their dataType and complexType to the model name, so documentation will refer to the correct model ArrayList> listOfLists = new ArrayList>(); @@ -575,6 +622,9 @@ public CodegenModel fromModel(String name, Schema schema) { listOfLists.add(result.readWriteVars); for (List cpList : listOfLists) { for (CodegenProperty cp : cpList) { + // set regex values, before it was only done on model.vars + postProcessModelProperty(result, cp); + // fix references to non-object models if (!propertyToModelName.containsKey(cp.name)) { continue; } @@ -589,4 +639,79 @@ public CodegenModel fromModel(String name, Schema schema) { return result; } + /** + * Output the type declaration of the property + * + * @param schema property schema + * @return a string presentation of the property type + */ + public String getSimpleTypeDeclaration(Schema schema) { + String oasType = getSchemaType(schema); + if (typeMapping.containsKey(oasType)) { + return typeMapping.get(oasType); + } + return oasType; + } + + public String getTypeString(Schema p, String prefix, String suffix) { + // this is used to set dataType, which defines a python tuple of classes + String fullSuffix = suffix; + if (")".equals(suffix)) { + fullSuffix = "," + suffix; + } + if (ModelUtils.isNullable(p)) { + fullSuffix = ", none_type" + suffix; + } + if (ModelUtils.isFreeFormObject(p) && ModelUtils.getAdditionalProperties(p) == null) { + return prefix + "bool, date, datetime, dict, float, int, list, str" + fullSuffix; + } + if (ModelUtils.isMapSchema(p)) { + Schema inner = ModelUtils.getAdditionalProperties(p); + return prefix + "{str: " + getTypeString(inner, "(", ")") + "}" + fullSuffix; + } else if (ModelUtils.isArraySchema(p)) { + ArraySchema ap = (ArraySchema) p; + Schema inner = ap.getItems(); + return prefix + "[" + getTypeString(inner, "", "") + "]" + fullSuffix; + } + String baseType = getSimpleTypeDeclaration(p); + if (ModelUtils.isFileSchema(p)) { + baseType = "file_type"; + } + return prefix + baseType + fullSuffix; + } + + /** + * Output the type declaration of a given name + * + * @param p property schema + * @return a string presentation of the type + */ + @Override + public String getTypeDeclaration(Schema p) { + // this is used to set dataType, which defines a python tuple of classes + // in Python we will wrap this in () to make it a tuple but here we + // will omit the parens so the generated documentaion will not include + // them + return getTypeString(p, "", ""); + } + + @Override + public String toInstantiationType(Schema property) { + if (ModelUtils.isArraySchema(property) || ModelUtils.isMapSchema(property) || property.getAdditionalProperties() != null) { + return getSchemaType(property); + } + return super.toInstantiationType(property); + } + + @Override + protected void addAdditionPropertiesToCodeGenModel(CodegenModel codegenModel, Schema schema) { + Schema addProps = ModelUtils.getAdditionalProperties(schema); + if (addProps != null && addProps.get$ref() == null) { + // if AdditionalProperties exists and is an inline definition, get its datatype and store it in m.parent + String typeString = getTypeDeclaration(addProps); + codegenModel.additionalPropertiesType = typeString; + } else { + addParentContainer(codegenModel, codegenModel.name, schema); + } + } } diff --git a/modules/openapi-generator/src/main/resources/python/python-experimental/api.mustache b/modules/openapi-generator/src/main/resources/python/python-experimental/api.mustache index dd650b37d7f2..98f8be8f0eab 100644 --- a/modules/openapi-generator/src/main/resources/python/python-experimental/api.mustache +++ b/modules/openapi-generator/src/main/resources/python/python-experimental/api.mustache @@ -14,10 +14,20 @@ from {{packageName}}.exceptions import ( ApiTypeError, ApiValueError ) -from {{packageName}}.model_utils import ( +from {{packageName}}.model_utils import ( # noqa: F401 check_allowed_values, - check_validations + check_validations, + date, + datetime, + file_type, + int, + none_type, + str, + validate_and_convert_types ) +{{#imports}} +{{{import}}} +{{/imports}} {{#operations}} @@ -51,24 +61,51 @@ class {{classname}}(object): >>> result = thread.get() :param async_req bool: execute request asynchronously + Default is False. {{#allParams}} :param {{dataType}} {{paramName}}:{{#description}} {{{description}}}{{/description}}{{#required}} (required){{/required}}{{#optional}}(optional){{/optional}} {{/allParams}} :param _return_http_data_only: response data without head status - code and headers + code and headers. Default is True. :param _preload_content: if False, the urllib3.HTTPResponse object will be returned without reading/decoding response data. Default is True. :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. + Default is None. + :param _check_input_type: boolean specifying if type checking + should be done one the data sent to the server. + Default is True. + :param _check_return_type: boolean specifying if type checking + should be done one the data received from the server. + Default is True. + :param _host_index: integer specifying the index of the server + that we want to use. + Default is 0. :return: {{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}None{{/returnType}} 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', 0) {{#requiredParams}} kwargs['{{paramName}}'] = {{paramName}} {{/requiredParams}} @@ -76,7 +113,7 @@ class {{classname}}(object): self.{{operationId}} = Endpoint( settings={ - 'response_type': {{#returnType}}'{{returnType}}'{{/returnType}}{{^returnType}}None{{/returnType}}, + 'response_type': {{#returnType}}({{{returnType}}},){{/returnType}}{{^returnType}}None{{/returnType}}, {{#authMethods}} {{#-first}} 'auth': [ @@ -178,7 +215,7 @@ class {{classname}}(object): }, 'openapi_types': { {{#allParams}} - '{{paramName}}': '{{dataType}}', + '{{paramName}}': ({{{dataType}}},), {{/allParams}} }, 'attribute_map': { @@ -237,7 +274,7 @@ class Endpoint(object): Args: settings (dict): see below key value pairs - 'response_type' (str): response type + 'response_type' (tuple/None): response type 'auth' (list): a list of auth type keys 'endpoint_path' (str): the endpoint path 'operation_id' (str): endpoint string identifier @@ -273,11 +310,24 @@ class Endpoint(object): '_host_index', '_preload_content', '_request_timeout', - '_return_http_data_only' + '_return_http_data_only', + '_check_input_type', + '_check_return_type' ]) + self.params_map['nullable'].extend(['_request_timeout']) self.validations = root_map['validations'] self.allowed_values = root_map['allowed_values'] self.openapi_types = root_map['openapi_types'] + extra_types = { + 'async_req': (bool,), + '_host_index': (int,), + '_preload_content': (bool,), + '_request_timeout': (none_type, int, (int,), [int]), + '_return_http_data_only': (bool,), + '_check_input_type': (bool,), + '_check_return_type': (bool,) + } + self.openapi_types.update(extra_types) self.attribute_map = root_map['attribute_map'] self.location_map = root_map['location_map'] self.collection_format_map = root_map['collection_format_map'] @@ -291,8 +341,7 @@ class Endpoint(object): check_allowed_values( self.allowed_values, (param,), - kwargs[param], - self.validations + kwargs[param] ) for param in self.params_map['validation']: @@ -303,6 +352,20 @@ class Endpoint(object): kwargs[param] ) + if kwargs['_check_input_type'] is False: + return + + for key, value in six.iteritems(kwargs): + fixed_val = validate_and_convert_types( + value, + self.openapi_types[key], + [key], + False, + kwargs['_check_input_type'], + configuration=self.api_client.configuration + ) + kwargs[key] = fixed_val + def __gather_params(self, kwargs): params = { 'body': None, @@ -322,8 +385,9 @@ class Endpoint(object): continue base_name = self.attribute_map[param_name] if (param_location == 'form' and - self.openapi_types[param_name] == 'file'): + self.openapi_types[param_name] == (file_type,)): param_location = 'file' + params[param_location][param_name] = param_value elif param_location in {'form', 'query'}: param_value_full = (base_name, param_value) params[param_location].append(param_value_full) @@ -348,20 +412,15 @@ class Endpoint(object): def call_with_http_info(self, **kwargs): - if kwargs.get('_host_index') and self.settings['servers']: - _host_index = kwargs.get('_host_index') - try: - _host = self.settings['servers'][_host_index] - except IndexError: + try: + _host = self.settings['servers'][kwargs['_host_index']] + except IndexError: + if self.settings['servers']: raise ApiValueError( "Invalid host index. Must be 0 <= index < %s" % len(self.settings['servers']) ) - else: - try: - _host = self.settings['servers'][0] - except IndexError: - _host = None + _host = None for key, value in six.iteritems(kwargs): if key not in self.params_map['all']: @@ -370,7 +429,11 @@ class Endpoint(object): " to method `%s`" % (key, self.settings['operation_id']) ) - if key not in self.params_map['nullable'] and value is None: + # only throw this nullable ApiValueError if _check_input_type + # is False, if _check_input_type==True we catch this case + # in self.__validate_inputs + if (key not in self.params_map['nullable'] and value is None + and kwargs['_check_input_type'] is False): raise ApiValueError( "Value may not be None for non-nullable parameter `%s`" " when calling `%s`" % @@ -409,9 +472,10 @@ class Endpoint(object): files=params['file'], response_type=self.settings['response_type'], auth_settings=self.settings['auth'], - async_req=kwargs.get('async_req'), - _return_http_data_only=kwargs.get('_return_http_data_only'), - _preload_content=kwargs.get('_preload_content', True), - _request_timeout=kwargs.get('_request_timeout'), + async_req=kwargs['async_req'], + _check_type=kwargs['_check_return_type'], + _return_http_data_only=kwargs['_return_http_data_only'], + _preload_content=kwargs['_preload_content'], + _request_timeout=kwargs['_request_timeout'], _host=_host, collection_formats=params['collection_format']) diff --git a/modules/openapi-generator/src/main/resources/python/python-experimental/api_client.mustache b/modules/openapi-generator/src/main/resources/python/python-experimental/api_client.mustache index 0f02b445dfba..179ce3c37210 100644 --- a/modules/openapi-generator/src/main/resources/python/python-experimental/api_client.mustache +++ b/modules/openapi-generator/src/main/resources/python/python-experimental/api_client.mustache @@ -2,14 +2,10 @@ {{>partial_header}} from __future__ import absolute_import -import datetime -import inspect import json import mimetypes from multiprocessing.pool import ThreadPool import os -import re -import tempfile # python 2 and python 3 compatibility library import six @@ -18,14 +14,20 @@ from six.moves.urllib.parse import quote import tornado.gen {{/tornado}} -import {{modelPackage}} from {{packageName}} import rest from {{packageName}}.configuration import Configuration +from {{packageName}}.exceptions import ApiValueError from {{packageName}}.model_utils import ( ModelNormal, - ModelSimple + ModelSimple, + date, + datetime, + deserialize_file, + file_type, + model_to_dict, + str, + validate_and_convert_types ) -from {{packageName}}.exceptions import ApiValueError class ApiClient(object): @@ -50,17 +52,11 @@ class ApiClient(object): to the API. More threads means more concurrent API requests. """ - PRIMITIVE_TYPES = (float, bool, bytes, six.text_type) + six.integer_types - NATIVE_TYPES_MAPPING = { - 'int': int, - 'long': int if six.PY3 else long, # noqa: F821 - 'float': float, - 'str': str, - 'bool': bool, - 'date': datetime.date, - 'datetime': datetime.datetime, - 'object': object, - } + # six.binary_type python2=str, python3=bytes + # six.text_type python2=unicode, python3=str + PRIMITIVE_TYPES = ( + (float, bool, six.binary_type, six.text_type) + six.integer_types + ) _pool = None def __init__(self, configuration=None, header_name=None, header_value=None, @@ -113,7 +109,8 @@ class ApiClient(object): query_params=None, header_params=None, body=None, post_params=None, files=None, response_type=None, auth_settings=None, _return_http_data_only=None, collection_formats=None, - _preload_content=True, _request_timeout=None, _host=None): + _preload_content=True, _request_timeout=None, _host=None, + _check_type=None): config = self.configuration @@ -180,7 +177,11 @@ class ApiClient(object): if _preload_content: # deserialize response data if response_type: - return_data = self.deserialize(response_data, response_type) + return_data = self.deserialize( + response_data, + response_type, + _check_type + ) else: return_data = None @@ -223,93 +224,73 @@ class ApiClient(object): elif isinstance(obj, tuple): return tuple(self.sanitize_for_serialization(sub_obj) for sub_obj in obj) - elif isinstance(obj, (datetime.datetime, datetime.date)): + elif isinstance(obj, (datetime, date)): return obj.isoformat() if isinstance(obj, dict): obj_dict = obj elif isinstance(obj, ModelNormal): - # Convert model obj to dict except - # attributes `openapi_types`, `attribute_map` - # and attributes which value is not None. + # Convert model obj to dict # Convert attribute name to json key in - # model definition for request. - obj_dict = {obj.attribute_map[attr]: getattr(obj, attr) - for attr, _ in six.iteritems(obj.openapi_types) - if getattr(obj, attr) is not None} + # model definition for request + obj_dict = model_to_dict(obj, serialize=True) elif isinstance(obj, ModelSimple): return self.sanitize_for_serialization(obj.value) return {key: self.sanitize_for_serialization(val) for key, val in six.iteritems(obj_dict)} - def deserialize(self, response, response_type): + def deserialize(self, response, response_type, _check_type): """Deserializes response into an object. :param response: RESTResponse object to be deserialized. - :param response_type: class literal for - deserialized object, or string of class name. + :param response_type: For the response, a tuple containing: + valid classes + a list containing valid classes (for list schemas) + a dict containing a tuple of valid classes as the value + Example values: + (str,) + (Pet,) + (float, none_type) + ([int, none_type],) + ({str: (bool, str, int, float, date, datetime, str, none_type)},) + :param _check_type: boolean, whether to check the types of the data + received from the server :return: deserialized object. """ # handle file downloading # save response body into a tmp file and return the instance - if response_type == "file": - return self.__deserialize_file(response) + if response_type == (file_type,): + content_disposition = response.getheader("Content-Disposition") + return deserialize_file(response.data, self.configuration, + content_disposition=content_disposition) # fetch data from response object try: - data = json.loads(response.data) + received_data = json.loads(response.data) except ValueError: - data = response.data - - return self.__deserialize(data, response_type) - - def __deserialize(self, data, klass): - """Deserializes dict, list, str into an object. - - :param data: dict, list or str. - :param klass: class literal, or string of class name. - - :return: object. - """ - if data is None: - return None - - if type(klass) == str: - if klass.startswith('list['): - sub_kls = re.match(r'list\[(.*)\]', klass).group(1) - return [self.__deserialize(sub_data, sub_kls) - for sub_data in data] - - if klass.startswith('dict('): - sub_kls = re.match(r'dict\(([^,]*), (.*)\)', klass).group(2) - return {k: self.__deserialize(v, sub_kls) - for k, v in six.iteritems(data)} - - # convert str to class - if klass in self.NATIVE_TYPES_MAPPING: - klass = self.NATIVE_TYPES_MAPPING[klass] - else: - klass = getattr({{modelPackage}}, klass) - - if klass in self.PRIMITIVE_TYPES: - return self.__deserialize_primitive(data, klass) - elif klass == object: - return self.__deserialize_object(data) - elif klass == datetime.date: - return self.__deserialize_date(data) - elif klass == datetime.datetime: - return self.__deserialize_datatime(data) - else: - return self.__deserialize_model(data, klass) + received_data = response.data + + # store our data under the key of 'received_data' so users have some + # context if they are deserializing a string and the data type is wrong + deserialized_data = validate_and_convert_types( + received_data, + response_type, + ['received_data'], + True, + _check_type, + configuration=self.configuration + ) + return deserialized_data def call_api(self, resource_path, method, path_params=None, query_params=None, header_params=None, body=None, post_params=None, files=None, response_type=None, auth_settings=None, async_req=None, _return_http_data_only=None, collection_formats=None, - _preload_content=True, _request_timeout=None, _host=None): + _preload_content=True, _request_timeout=None, _host=None, + _check_type=None): """Makes the HTTP request (synchronous) and returns deserialized data. To make an async_req request, set the async_req parameter. @@ -324,7 +305,16 @@ class ApiClient(object): :param post_params dict: Request post form parameters, for `application/x-www-form-urlencoded`, `multipart/form-data`. :param auth_settings list: Auth Settings names for the request. - :param response: Response data type. + :param response_type: For the response, a tuple containing: + valid classes + a list containing valid classes (for list schemas) + a dict containing a tuple of valid classes as the value + Example values: + (str,) + (Pet,) + (float, none_type) + ([int, none_type],) + ({str: (bool, str, int, float, date, datetime, str, none_type)},) :param files dict: key -> filename, value -> filepath, for `multipart/form-data`. :param async_req bool: execute request asynchronously @@ -339,6 +329,8 @@ class ApiClient(object): number provided, it will be total request timeout. It can also be a pair (tuple) of (connection, read) timeouts. + :param _check_type: boolean describing if the data back from the server + should have its type checked. :return: If async_req parameter is True, the request will be called asynchronously. @@ -352,7 +344,8 @@ class ApiClient(object): body, post_params, files, response_type, auth_settings, _return_http_data_only, collection_formats, - _preload_content, _request_timeout, _host) + _preload_content, _request_timeout, _host, + _check_type) else: thread = self.pool.apply_async(self.__call_api, (resource_path, method, path_params, query_params, @@ -363,7 +356,7 @@ class ApiClient(object): collection_formats, _preload_content, _request_timeout, - _host)) + _host, _check_type)) return thread def request(self, method, url, query_params=None, headers=None, @@ -460,24 +453,29 @@ class ApiClient(object): def files_parameters(self, files=None): """Builds form parameters. - :param files: File parameters. - :return: Form parameters with files. + :param files: None or a dict with key=param_name and value=file_object + :return: List of tuples of form parameters with file data """ - params = [] + if files is None: + return [] - if files: - for k, v in six.iteritems(files): - if not v: - continue - file_names = v if type(v) is list else [v] - for n in file_names: - with open(n, 'rb') as f: - filename = os.path.basename(f.name) - filedata = f.read() - mimetype = (mimetypes.guess_type(filename)[0] or - 'application/octet-stream') - params.append( - tuple([k, tuple([filename, filedata, mimetype])])) + params = [] + for param_name, file_instance in six.iteritems(files): + if file_instance is None: + # if the file field is nullable, skip None values + continue + if file_instance.closed is True: + raise ApiValueError( + "Cannot read a closed file. The passed in file_type for " + "%s must be open." % param_name + ) + filename = os.path.basename(file_instance.name) + filedata = file_instance.read() + mimetype = (mimetypes.guess_type(filename)[0] or + 'application/octet-stream') + params.append( + tuple([param_name, tuple([filename, filedata, mimetype])])) + file_instance.close() return params @@ -538,133 +536,3 @@ class ApiClient(object): raise ApiValueError( 'Authentication token must be in `query` or `header`' ) - - def __deserialize_file(self, response): - """Deserializes body to file - - Saves response body into a file in a temporary folder, - using the filename from the `Content-Disposition` header if provided. - - :param response: RESTResponse. - :return: file path. - """ - fd, path = tempfile.mkstemp(dir=self.configuration.temp_folder_path) - os.close(fd) - os.remove(path) - - content_disposition = response.getheader("Content-Disposition") - if content_disposition: - filename = re.search(r'filename=[\'"]?([^\'"\s]+)[\'"]?', - content_disposition).group(1) - path = os.path.join(os.path.dirname(path), filename) - - with open(path, "wb") as f: - f.write(response.data) - - return path - - def __deserialize_primitive(self, data, klass): - """Deserializes string to primitive type. - - :param data: str. - :param klass: class literal. - - :return: int, long, float, str, bool. - """ - try: - return klass(data) - except UnicodeEncodeError: - return six.text_type(data) - except TypeError: - return data - except ValueError as exc: - raise ApiValueError(str(exc)) - - def __deserialize_object(self, value): - """Return an original value. - - :return: object. - """ - return value - - def __deserialize_date(self, string): - """Deserializes string to date. - - :param string: str. - :return: date. - """ - try: - from dateutil.parser import parse - return parse(string).date() - except ImportError: - return string - except ValueError: - raise rest.ApiException( - status=0, - reason="Failed to parse `{0}` as date object".format(string) - ) - - def __deserialize_datatime(self, string): - """Deserializes string to datetime. - - The string should be in iso8601 datetime format. - - :param string: str. - :return: datetime. - """ - try: - from dateutil.parser import parse - return parse(string) - except ImportError: - return string - except ValueError: - raise rest.ApiException( - status=0, - reason=( - "Failed to parse `{0}` as datetime object" - .format(string) - ) - ) - - def __deserialize_model(self, data, klass): - """Deserializes list or dict to model. - - :param data: dict, list. - :param klass: class literal, ModelSimple or ModelNormal - :return: model object. - """ - - if issubclass(klass, ModelSimple): - value = self.__deserialize(data, klass.openapi_types['value']) - return klass(value) - - # code to handle ModelNormal - used_data = data - if not isinstance(data, (list, dict)): - used_data = [data] - keyword_args = {} - positional_args = [] - if klass.openapi_types is not None: - for attr, attr_type in six.iteritems(klass.openapi_types): - if (data is not None and - klass.attribute_map[attr] in used_data): - value = used_data[klass.attribute_map[attr]] - keyword_args[attr] = self.__deserialize(value, attr_type) - end_index = None - argspec = inspect.getargspec(getattr(klass, '__init__')) - if argspec.defaults: - end_index = -len(argspec.defaults) - required_positional_args = argspec.args[1:end_index] - for index, req_positional_arg in enumerate(required_positional_args): - if keyword_args and req_positional_arg in keyword_args: - positional_args.append(keyword_args[req_positional_arg]) - del keyword_args[req_positional_arg] - elif (not keyword_args and index < len(used_data) and - isinstance(used_data, list)): - positional_args.append(used_data[index]) - instance = klass(*positional_args, **keyword_args) - if hasattr(instance, 'get_real_child_model'): - klass_name = instance.get_real_child_model(data) - if klass_name: - instance = self.__deserialize(data, klass_name) - return instance diff --git a/modules/openapi-generator/src/main/resources/python/python-experimental/model.mustache b/modules/openapi-generator/src/main/resources/python/python-experimental/model.mustache index 082f4bddc432..2513d6b3f867 100644 --- a/modules/openapi-generator/src/main/resources/python/python-experimental/model.mustache +++ b/modules/openapi-generator/src/main/resources/python/python-experimental/model.mustache @@ -7,14 +7,29 @@ import re # noqa: F401 import six # noqa: F401 -from {{packageName}}.exceptions import ApiValueError # noqa: F401 +from {{packageName}}.exceptions import ( # noqa: F401 + ApiKeyError, + ApiTypeError, + ApiValueError, +) from {{packageName}}.model_utils import ( # noqa: F401 ModelNormal, ModelSimple, check_allowed_values, - check_validations + check_validations, + date, + datetime, + file_type, + get_simple_class, + int, + model_to_dict, + none_type, + str, + type_error_message, + validate_and_convert_types ) - +{{#models}}{{#model}}{{#imports}}{{.}} +{{/imports}}{{/model}}{{/models}} {{#models}} {{#model}} diff --git a/modules/openapi-generator/src/main/resources/python/python-experimental/model_doc.mustache b/modules/openapi-generator/src/main/resources/python/python-experimental/model_doc.mustache index 16592869b741..70b233998505 100644 --- a/modules/openapi-generator/src/main/resources/python/python-experimental/model_doc.mustache +++ b/modules/openapi-generator/src/main/resources/python/python-experimental/model_doc.mustache @@ -3,10 +3,22 @@ ## Properties Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -{{#requiredVars}}{{^defaultValue}}**{{name}}** | {{#isPrimitiveType}}**{{dataType}}**{{/isPrimitiveType}}{{^isPrimitiveType}}[**{{dataType}}**]({{complexType}}.md){{/isPrimitiveType}} | {{description}} | {{#isReadOnly}}[readonly] {{/isReadOnly}} -{{/defaultValue}}{{/requiredVars}}{{#requiredVars}}{{#defaultValue}}**{{name}}** | {{#isPrimitiveType}}**{{dataType}}**{{/isPrimitiveType}}{{^isPrimitiveType}}[**{{dataType}}**]({{complexType}}.md){{/isPrimitiveType}} | {{description}} | {{^required}}[optional] {{/required}}{{#isReadOnly}}[readonly] {{/isReadOnly}}{{#defaultValue}}defaults to {{{.}}}{{/defaultValue}} -{{/defaultValue}}{{/requiredVars}}{{#optionalVars}}**{{name}}** | {{#isPrimitiveType}}**{{dataType}}**{{/isPrimitiveType}}{{^isPrimitiveType}}[**{{dataType}}**]({{complexType}}.md){{/isPrimitiveType}} | {{description}} | [optional] {{#isReadOnly}}[readonly] {{/isReadOnly}}{{#defaultValue}} if omitted the server will use the default value of {{{.}}}{{/defaultValue}} +{{#requiredVars}} +{{^defaultValue}} +**{{name}}** | {{#isPrimitiveType}}**{{dataType}}**{{/isPrimitiveType}}{{^isPrimitiveType}}[**{{dataType}}**]({{complexType}}.md){{/isPrimitiveType}} | {{description}} | {{#isReadOnly}}[readonly] {{/isReadOnly}} +{{/defaultValue}} +{{/requiredVars}} +{{#requiredVars}} +{{#defaultValue}} +**{{name}}** | {{#isPrimitiveType}}**{{dataType}}**{{/isPrimitiveType}}{{^isPrimitiveType}}[**{{dataType}}**]({{complexType}}.md){{/isPrimitiveType}} | {{description}} | {{^required}}[optional] {{/required}}{{#isReadOnly}}[readonly] {{/isReadOnly}}{{#defaultValue}}defaults to {{{.}}}{{/defaultValue}} +{{/defaultValue}} +{{/requiredVars}} +{{#optionalVars}} +**{{name}}** | {{#isPrimitiveType}}**{{dataType}}**{{/isPrimitiveType}}{{^isPrimitiveType}}[**{{dataType}}**]({{complexType}}.md){{/isPrimitiveType}} | {{description}} | [optional] {{#isReadOnly}}[readonly] {{/isReadOnly}}{{#defaultValue}} if omitted the server will use the default value of {{{.}}}{{/defaultValue}} {{/optionalVars}} +{{#additionalPropertiesType}} +**any string name** | **{{additionalPropertiesType}}** | any string name can be used but the value must be the correct type | [optional] +{{/additionalPropertiesType}} [[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/modules/openapi-generator/src/main/resources/python/python-experimental/model_templates/classvar_allowed.mustache b/modules/openapi-generator/src/main/resources/python/python-experimental/model_templates/classvar_allowed.mustache index 6ed39521f66e..2414be114a35 100644 --- a/modules/openapi-generator/src/main/resources/python/python-experimental/model_templates/classvar_allowed.mustache +++ b/modules/openapi-generator/src/main/resources/python/python-experimental/model_templates/classvar_allowed.mustache @@ -1,5 +1,5 @@ allowed_values = { -{{#vars}} +{{#allVars}} {{#isEnum}} ('{{name}}',): { {{#isNullable}} @@ -7,10 +7,10 @@ {{/isNullable}} {{#allowableValues}} {{#enumVars}} - '{{name}}': {{{value}}}{{^-last}},{{/-last}} + '{{name}}': {{{value}}}, {{/enumVars}} {{/allowableValues}} }, {{/isEnum}} -{{/vars}} +{{/allVars}} } \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/python/python-experimental/model_templates/classvar_openapi_validations.mustache b/modules/openapi-generator/src/main/resources/python/python-experimental/model_templates/classvar_openapi_validations.mustache index 7e89f83ef261..1cc7b5855072 100644 --- a/modules/openapi-generator/src/main/resources/python/python-experimental/model_templates/classvar_openapi_validations.mustache +++ b/modules/openapi-generator/src/main/resources/python/python-experimental/model_templates/classvar_openapi_validations.mustache @@ -1,25 +1,42 @@ openapi_types = { -{{#vars}} - '{{name}}': '{{{dataType}}}'{{#hasMore}},{{/hasMore}} -{{/vars}} +{{#allVars}} + '{{name}}': ({{{dataType}}},), # noqa: E501 +{{/allVars}} } validations = { -{{#vars}} +{{#allVars}} {{#hasValidation}} ('{{name}}',): { {{#maxLength}} - 'max_length': {{maxLength}},{{/maxLength}}{{#minLength}} - 'min_length': {{minLength}},{{/minLength}}{{#maxItems}} - 'max_items': {{maxItems}},{{/maxItems}}{{#minItems}} - 'min_items': {{minItems}},{{/minItems}}{{#maximum}} - {{#exclusiveMaximum}}'exclusive_maximum'{{/exclusiveMaximum}}'inclusive_maximum'{{^exclusiveMaximum}}{{/exclusiveMaximum}}: {{maximum}},{{/maximum}}{{#minimum}} - {{#exclusiveMinimum}}'exclusive_minimum'{{/exclusiveMinimum}}'inclusive_minimum'{{^exclusiveMinimum}}{{/exclusiveMinimum}}: {{minimum}},{{/minimum}}{{#pattern}} + 'max_length': {{maxLength}}, +{{/maxLength}} +{{#minLength}} + 'min_length': {{minLength}}, +{{/minLength}} +{{#maxItems}} + 'max_items': {{maxItems}}, +{{/maxItems}} +{{#minItems}} + 'min_items': {{minItems}}, +{{/minItems}} +{{#maximum}} + {{#exclusiveMaximum}}'exclusive_maximum'{{/exclusiveMaximum}}'inclusive_maximum'{{^exclusiveMaximum}}{{/exclusiveMaximum}}: {{maximum}}, +{{/maximum}} +{{#minimum}} + {{#exclusiveMinimum}}'exclusive_minimum'{{/exclusiveMinimum}}'inclusive_minimum'{{^exclusiveMinimum}}{{/exclusiveMinimum}}: {{minimum}}, +{{/minimum}} +{{#pattern}} 'regex': { 'pattern': r'{{{vendorExtensions.x-regex}}}', # noqa: E501{{#vendorExtensions.x-modifiers}} {{#-first}}'flags': (re.{{.}}{{/-first}}{{^-first}} re.{{.}}{{/-first}}{{^-last}} | {{/-last}}{{#-last}}){{/-last}}{{/vendorExtensions.x-modifiers}} - },{{/pattern}} + }, +{{/pattern}} }, {{/hasValidation}} -{{/vars}} - } \ No newline at end of file +{{/allVars}} + } + + additional_properties_type = {{#additionalPropertiesType}}({{{additionalPropertiesType}}},) # noqa: E501{{/additionalPropertiesType}}{{^additionalPropertiesType}}None{{/additionalPropertiesType}} + + discriminator = {{#discriminator}}'{{{discriminatorName}}}'{{/discriminator}}{{^discriminator}}None{{/discriminator}} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/python/python-experimental/model_templates/docstring_openapi_validations.mustache b/modules/openapi-generator/src/main/resources/python/python-experimental/model_templates/docstring_openapi_validations.mustache index 46dc1afefc49..03eec953f378 100644 --- a/modules/openapi-generator/src/main/resources/python/python-experimental/model_templates/docstring_openapi_validations.mustache +++ b/modules/openapi-generator/src/main/resources/python/python-experimental/model_templates/docstring_openapi_validations.mustache @@ -4,4 +4,6 @@ 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. \ No newline at end of file + inclusive_minimum, and regex. + additional_properties_type (tuple): A tuple of classes accepted + as additional properties values. \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/python/python-experimental/model_templates/methods_init_properties.mustache b/modules/openapi-generator/src/main/resources/python/python-experimental/model_templates/methods_init_properties.mustache index 447aa22cacd0..dab632efab04 100644 --- a/modules/openapi-generator/src/main/resources/python/python-experimental/model_templates/methods_init_properties.mustache +++ b/modules/openapi-generator/src/main/resources/python/python-experimental/model_templates/methods_init_properties.mustache @@ -1,76 +1,126 @@ - def __init__(self{{#vars}}, {{name}}={{#defaultValue}}{{{defaultValue}}}{{/defaultValue}}{{^defaultValue}}None{{/defaultValue}}{{/vars}}): # noqa: E501 - """{{classname}} - a model defined in OpenAPI""" # noqa: E501 -{{#vars}}{{#-first}} -{{/-first}} - self._{{name}} = None -{{/vars}} - self.discriminator = {{#discriminator}}'{{{discriminatorName}}}'{{/discriminator}}{{^discriminator}}None{{/discriminator}} -{{#vars}}{{#-first}} -{{/-first}} -{{#required}} - self.{{name}} = {{name}} -{{/required}} -{{^required}} -{{#isNullable}} - self.{{name}} = {{name}} -{{/isNullable}} -{{^isNullable}} - if {{name}} is not None: - self.{{name}} = ( - {{name}} + def __init__(self{{#requiredVars}}{{^defaultValue}}, {{name}}{{/defaultValue}}{{/requiredVars}}{{#requiredVars}}{{#defaultValue}}, {{name}}={{{defaultValue}}}{{/defaultValue}}{{/requiredVars}}, _check_type=True, _from_server=False, _path_to_item=(), _configuration=None, **kwargs): # noqa: E501 + """{{classname}} - a model defined in OpenAPI + +{{#requiredVars}}{{^hasMore}} Args:{{/hasMore}}{{/requiredVars}}{{#requiredVars}}{{^defaultValue}} + {{name}} ({{{dataType}}}):{{#description}} {{description}}{{/description}}{{/defaultValue}}{{/requiredVars}}{{#requiredVars}}{{^hasMore}} +{{/hasMore}}{{/requiredVars}} + Keyword Args:{{#requiredVars}}{{#defaultValue}} + {{name}} ({{{dataType}}}):{{#description}} {{description}}.{{/description}} defaults to {{{defaultValue}}}, must be one of [{{{defaultValue}}}] # noqa: E501{{/defaultValue}}{{/requiredVars}} + _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 + _from_server (bool): True if the data is from the server + False if the data is from the client (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.{{#optionalVars}} + {{name}} ({{{dataType}}}):{{#description}} {{description}}.{{/description}} [optional]{{#defaultValue}} if omitted the server will use the default value of {{{defaultValue}}}{{/defaultValue}} # noqa: E501{{/optionalVars}} + """ + self._data_store = {} + self._check_type = _check_type + self._from_server = _from_server + self._path_to_item = _path_to_item + self._configuration = _configuration + +{{#requiredVars}} + self.__set_item('{{name}}', {{name}}) +{{/requiredVars}} + for var_name, var_value in six.iteritems(kwargs): + self.__set_item(var_name, var_value) + + def __set_item(self, name, value): + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + + if name in self.openapi_types: + required_types_mixed = self.openapi_types[name] + elif self.additional_properties_type is None: + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + path_to_item + ) + elif self.additional_properties_type is not None: + required_types_mixed = self.additional_properties_type + + if get_simple_class(name) != str: + error_msg = type_error_message( + var_name=name, + var_value=name, + valid_classes=(str,), + key_type=True + ) + raise ApiTypeError( + error_msg, + path_to_item=path_to_item, + valid_classes=(str,), + key_type=True + ) + + if self._check_type: + value = validate_and_convert_types( + value, required_types_mixed, path_to_item, self._from_server, + self._check_type, configuration=self._configuration) + if (name,) in self.allowed_values: + check_allowed_values( + self.allowed_values, + (name,), + value + ) + if (name,) in self.validations: + check_validations( + self.validations, + (name,), + value ) -{{/isNullable}} -{{/required}} -{{/vars}} -{{#vars}} + self._data_store[name] = value + + def __get_item(self, name): + if name in self._data_store: + return self._data_store[name] + + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + [name] + ) + + def __setitem__(self, name, value): + """this allows us to set values with instance[field_name] = val""" + self.__set_item(name, value) + + def __getitem__(self, name): + """this allows us to get a value with val = instance[field_name]""" + return self.__get_item(name) +{{#allVars}} @property def {{name}}(self): """Gets the {{name}} of this {{classname}}. # noqa: E501 - {{#description}} {{{description}}} # noqa: E501 {{/description}} - :return: The {{name}} of this {{classname}}. # noqa: E501 - :rtype: {{dataType}} + Returns: + ({{{dataType}}}): The {{name}} of this {{classname}}. # noqa: E501 """ - return self._{{name}} + return self.__get_item('{{name}}') @{{name}}.setter - def {{name}}(self, {{name}}): # noqa: E501 - """Sets the {{name}} of this {{classname}}. - + def {{name}}(self, value): + """Sets the {{name}} of this {{classname}}. # noqa: E501 {{#description}} {{{description}}} # noqa: E501 {{/description}} - - :param {{name}}: The {{name}} of this {{classname}}. # noqa: E501 - :type: {{dataType}} """ -{{^isNullable}} -{{#required}} - if {{name}} is None: - raise ApiValueError("Invalid value for `{{name}}`, must not be `None`") # noqa: E501 -{{/required}} -{{/isNullable}} -{{#isEnum}} - check_allowed_values( - self.allowed_values, - ('{{name}}',), - {{name}}, - self.validations - ) -{{/isEnum}} -{{#hasValidation}} - check_validations( - self.validations, - ('{{name}}',), - {{name}} - ) -{{/hasValidation}} - - self._{{name}} = ( - {{name}} - ) -{{/vars}} \ No newline at end of file + return self.__set_item('{{name}}', value) +{{/allVars}} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/python/python-experimental/model_templates/model_normal.mustache b/modules/openapi-generator/src/main/resources/python/python-experimental/model_templates/model_normal.mustache index bd1eaddcb40b..c4e707e036e0 100644 --- a/modules/openapi-generator/src/main/resources/python/python-experimental/model_templates/model_normal.mustache +++ b/modules/openapi-generator/src/main/resources/python/python-experimental/model_templates/model_normal.mustache @@ -16,14 +16,14 @@ class {{classname}}(ModelNormal): {{> python-experimental/model_templates/classvar_allowed }} attribute_map = { -{{#vars}} +{{#allVars}} '{{name}}': '{{baseName}}'{{#hasMore}},{{/hasMore}} # noqa: E501 -{{/vars}} +{{/allVars}} } {{#discriminator}} discriminator_value_class_map = { - {{#children}}'{{^vendorExtensions.x-discriminator-value}}{{name}}{{/vendorExtensions.x-discriminator-value}}{{#vendorExtensions.x-discriminator-value}}{{{vendorExtensions.x-discriminator-value}}}{{/vendorExtensions.x-discriminator-value}}': '{{{classname}}}'{{^-last}}, + {{#children}}'{{^vendorExtensions.x-discriminator-value}}{{name}}{{/vendorExtensions.x-discriminator-value}}{{#vendorExtensions.x-discriminator-value}}{{{vendorExtensions.x-discriminator-value}}}{{/vendorExtensions.x-discriminator-value}}': {{{classname}}}{{^-last}}, {{/-last}}{{/children}} } {{/discriminator}} @@ -32,36 +32,19 @@ class {{classname}}(ModelNormal): {{> python-experimental/model_templates/methods_init_properties }} {{#discriminator}} - def get_real_child_model(self, data): - """Returns the real base class specified by the discriminator""" - discriminator_key = self.attribute_map[self.discriminator] + @classmethod + def get_real_child_model(cls, data): + """Returns the real base class specified by the discriminator + We assume that data has javascript keys + """ + discriminator_key = cls.attribute_map[cls.discriminator] discriminator_value = data[discriminator_key] - return self.discriminator_value_class_map.get(discriminator_value) + return cls.discriminator_value_class_map.get(discriminator_value) {{/discriminator}} def to_dict(self): """Returns the model properties as a dict""" - result = {} - - for attr, _ in six.iteritems(self.openapi_types): - value = getattr(self, attr) - if isinstance(value, list): - result[attr] = list(map( - lambda x: x.to_dict() if hasattr(x, "to_dict") else x, - value - )) - elif hasattr(value, "to_dict"): - result[attr] = value.to_dict() - elif isinstance(value, dict): - result[attr] = dict(map( - lambda item: (item[0], item[1].to_dict()) - if hasattr(item[1], "to_dict") else item, - value.items() - )) - else: - result[attr] = value - - return result + return model_to_dict(self, serialize=False) def to_str(self): """Returns the string representation of the model""" @@ -76,7 +59,22 @@ class {{classname}}(ModelNormal): if not isinstance(other, {{classname}}): return False - return self.__dict__ == other.__dict__ + if not set(self._data_store.keys()) == set(other._data_store.keys()): + return False + for _var_name, this_val in six.iteritems(self._data_store): + that_val = other._data_store[_var_name] + types = set() + types.add(this_val.__class__) + types.add(that_val.__class__) + vals_equal = this_val == that_val + if (not six.PY3 and + len(types) == 2 and unicode in types): # noqa: F821 + vals_equal = ( + this_val.encode('utf-8') == that_val.encode('utf-8') + ) + if not vals_equal: + return False + return True def __ne__(self, other): """Returns true if both objects are not equal""" diff --git a/modules/openapi-generator/src/main/resources/python/python-experimental/model_templates/model_simple.mustache b/modules/openapi-generator/src/main/resources/python/python-experimental/model_templates/model_simple.mustache index 94ad6336f9c8..b5939d926c2f 100644 --- a/modules/openapi-generator/src/main/resources/python/python-experimental/model_templates/model_simple.mustache +++ b/modules/openapi-generator/src/main/resources/python/python-experimental/model_templates/model_simple.mustache @@ -16,7 +16,7 @@ class {{classname}}(ModelSimple): {{> python-experimental/model_templates/methods_init_properties }} def to_str(self): """Returns the string representation of the model""" - return str(self._value) + return str(self.value) def __repr__(self): """For `print` and `pprint`""" @@ -27,7 +27,19 @@ class {{classname}}(ModelSimple): if not isinstance(other, {{classname}}): return False - return self.__dict__ == other.__dict__ + this_val = self._data_store['value'] + that_val = other._data_store['value'] + types = set() + types.add(this_val.__class__) + types.add(that_val.__class__) + vals_equal = this_val == that_val + if not six.PY3 and len(types) == 2 and unicode in types: # noqa: F821 + vals_equal = ( + this_val.encode('utf-8') == that_val.encode('utf-8') + ) + if not vals_equal: + return False + return True def __ne__(self, other): """Returns true if both objects are not equal""" diff --git a/modules/openapi-generator/src/main/resources/python/python-experimental/model_utils.mustache b/modules/openapi-generator/src/main/resources/python/python-experimental/model_utils.mustache index c251879b1045..101b5466c31b 100644 --- a/modules/openapi-generator/src/main/resources/python/python-experimental/model_utils.mustache +++ b/modules/openapi-generator/src/main/resources/python/python-experimental/model_utils.mustache @@ -1,13 +1,162 @@ # coding: utf-8 {{>partial_header}} + +import copy +from datetime import date, datetime # noqa: F401 +import inspect +import os import re +import tempfile + +from dateutil.parser import parse +import six + +from {{packageName}}.exceptions import ( + ApiKeyError, + ApiTypeError, + ApiValueError, +) + +none_type = type(None) +if six.PY3: + import io + file_type = io.IOBase + # these are needed for when other modules import str and int from here + str = str + int = int +else: + file_type = file # noqa: F821 + str_py2 = str + unicode_py2 = unicode # noqa: F821 + long_py2 = long # noqa: F821 + int_py2 = int + # this requires that the future library is installed + from builtins import int, str + + +class OpenApiModel(object): + """The base class for all OpenAPIModels""" + + +class ModelSimple(OpenApiModel): + """the parent class of models whose type != object in their + swagger/openapi""" -from {{packageName}}.exceptions import ApiValueError +class ModelNormal(OpenApiModel): + """the parent class of models whose type == object in their + swagger/openapi""" -def check_allowed_values(allowed_values, input_variable_path, input_values, - validations): + +COERCION_INDEX_BY_TYPE = { + ModelNormal: 0, + ModelSimple: 1, + none_type: 2, + list: 3, + dict: 4, + float: 5, + int: 6, + bool: 7, + datetime: 8, + date: 9, + str: 10, + file_type: 11, +} + +# these are used to limit what type conversions we try to do +# when we have a valid type already and we want to try converting +# to another type +UPCONVERSION_TYPE_PAIRS = ( + (str, datetime), + (str, date), + (list, ModelNormal), + (dict, ModelNormal), + (str, ModelSimple), + (int, ModelSimple), + (float, ModelSimple), + (list, ModelSimple), +) + +COERCIBLE_TYPE_PAIRS = { + False: ( # client instantiation of a model with client data + # (dict, ModelNormal), + # (list, ModelNormal), + # (str, ModelSimple), + # (int, ModelSimple), + # (float, ModelSimple), + # (list, ModelSimple), + # (str, int), + # (str, float), + # (str, datetime), + # (str, date), + # (int, str), + # (float, str), + ), + True: ( # server -> client data + (dict, ModelNormal), + (list, ModelNormal), + (str, ModelSimple), + (int, ModelSimple), + (float, ModelSimple), + (list, ModelSimple), + # (str, int), + # (str, float), + (str, datetime), + (str, date), + # (int, str), + # (float, str), + (str, file_type) + ), +} + + +def get_simple_class(input_value): + """Returns an input_value's simple class that we will use for type checking + Python2: + float and int will return int, where int is the python3 int backport + str and unicode will return str, where str is the python3 str backport + Note: float and int ARE both instances of int backport + Note: str_py2 and unicode_py2 are NOT both instances of str backport + + Args: + input_value (class/class_instance): the item for which we will return + the simple class + """ + if isinstance(input_value, type): + # input_value is a class + return input_value + elif isinstance(input_value, tuple): + return tuple + elif isinstance(input_value, list): + return list + elif isinstance(input_value, dict): + return dict + elif isinstance(input_value, none_type): + return none_type + elif isinstance(input_value, file_type): + return file_type + elif isinstance(input_value, bool): + # this must be higher than the int check because + # isinstance(True, int) == True + return bool + elif isinstance(input_value, int): + # for python2 input_value==long_instance -> return int + # where int is the python3 int backport + return int + elif isinstance(input_value, datetime): + # this must be higher than the date check because + # isinstance(datetime_instance, date) == True + return datetime + elif isinstance(input_value, date): + return date + elif (six.PY2 and isinstance(input_value, (str_py2, unicode_py2, str)) or + isinstance(input_value, str)): + return str + return type(input_value) + + +def check_allowed_values(allowed_values, input_variable_path, input_values): """Raises an exception if the input_values are not allowed Args: @@ -15,14 +164,9 @@ def check_allowed_values(allowed_values, input_variable_path, input_values, input_variable_path (tuple): the path to the input variable input_values (list/str/int/float/date/datetime): the values that we are checking to see if they are in allowed_values - validations (dict): the validations dict """ - min_collection_length = ( - validations.get(input_variable_path, {}).get('min_length') or - validations.get(input_variable_path, {}).get('min_items', 0)) these_allowed_values = list(allowed_values[input_variable_path].values()) if (isinstance(input_values, list) - and len(input_values) > min_collection_length and not set(input_values).issubset( set(these_allowed_values))): invalid_values = ", ".join( @@ -36,7 +180,6 @@ def check_allowed_values(allowed_values, input_variable_path, input_values, ) ) elif (isinstance(input_values, dict) - and len(input_values) > min_collection_length and not set( input_values.keys()).issubset(set(these_allowed_values))): invalid_values = ", ".join( @@ -111,8 +254,21 @@ def check_validations(validations, input_variable_path, input_values): ) ) + items = ('exclusive_maximum', 'inclusive_maximum', 'exclusive_minimum', + 'inclusive_minimum') + if (any(item in current_validations for item in items)): + if isinstance(input_values, list): + max_val = max(input_values) + min_val = min(input_values) + elif isinstance(input_values, dict): + max_val = max(input_values.values()) + min_val = min(input_values.values()) + else: + max_val = input_values + min_val = input_values + if ('exclusive_maximum' in current_validations and - input_values >= current_validations['exclusive_maximum']): + max_val >= current_validations['exclusive_maximum']): raise ApiValueError( "Invalid value for `%s`, must be a value less than `%s`" % ( input_variable_path[0], @@ -121,7 +277,7 @@ def check_validations(validations, input_variable_path, input_values): ) if ('inclusive_maximum' in current_validations and - input_values > current_validations['inclusive_maximum']): + max_val > current_validations['inclusive_maximum']): raise ApiValueError( "Invalid value for `%s`, must be a value less than or equal to " "`%s`" % ( @@ -131,7 +287,7 @@ def check_validations(validations, input_variable_path, input_values): ) if ('exclusive_minimum' in current_validations and - input_values <= current_validations['exclusive_minimum']): + min_val <= current_validations['exclusive_minimum']): raise ApiValueError( "Invalid value for `%s`, must be a value greater than `%s`" % ( @@ -141,7 +297,7 @@ def check_validations(validations, input_variable_path, input_values): ) if ('inclusive_minimum' in current_validations and - input_values < current_validations['inclusive_minimum']): + min_val < current_validations['inclusive_minimum']): raise ApiValueError( "Invalid value for `%s`, must be a value greater than or equal " "to `%s`" % ( @@ -163,13 +319,550 @@ def check_validations(validations, input_variable_path, input_values): ) -class ModelSimple(object): - # the parent class of models whose type != object in their swagger/openapi - # spec - pass +def order_response_types(required_types): + """Returns the required types sorted in coercion order + + Args: + required_types (list/tuple): collection of classes or instance of + list or dict with classs information inside it + + Returns: + (list): coercion order sorted collection of classes or instance + of list or dict with classs information inside it + """ + + def index_getter(class_or_instance): + if isinstance(class_or_instance, list): + return COERCION_INDEX_BY_TYPE[list] + elif isinstance(class_or_instance, dict): + return COERCION_INDEX_BY_TYPE[dict] + elif (inspect.isclass(class_or_instance) + and issubclass(class_or_instance, ModelNormal)): + return COERCION_INDEX_BY_TYPE[ModelNormal] + elif (inspect.isclass(class_or_instance) + and issubclass(class_or_instance, ModelSimple)): + return COERCION_INDEX_BY_TYPE[ModelSimple] + return COERCION_INDEX_BY_TYPE[class_or_instance] + + sorted_types = sorted( + required_types, + key=lambda class_or_instance: index_getter(class_or_instance) + ) + return sorted_types + + +def remove_uncoercible(required_types_classes, current_item, from_server, + must_convert=True): + """Only keeps the type conversions that are possible + + Args: + required_types_classes (tuple): tuple of classes that are required + these should be ordered by COERCION_INDEX_BY_TYPE + from_server (bool): a boolean of whether the data is from the server + if false, the data is from the client + current_item (any): the current item to be converted + + Keyword Args: + must_convert (bool): if True the item to convert is of the wrong + type and we want a big list of coercibles + if False, we want a limited list of coercibles + + Returns: + (list): the remaining coercible required types, classes only + """ + current_type_simple = get_simple_class(current_item) + + results_classes = [] + for required_type_class in required_types_classes: + # convert our models to OpenApiModel + required_type_class_simplified = required_type_class + if isinstance(required_type_class_simplified, type): + if issubclass(required_type_class_simplified, ModelNormal): + required_type_class_simplified = ModelNormal + elif issubclass(required_type_class_simplified, ModelSimple): + required_type_class_simplified = ModelSimple + + if required_type_class_simplified == current_type_simple: + # don't consider converting to one's own class + continue + + class_pair = (current_type_simple, required_type_class_simplified) + if must_convert and class_pair in COERCIBLE_TYPE_PAIRS[from_server]: + results_classes.append(required_type_class) + elif class_pair in UPCONVERSION_TYPE_PAIRS: + results_classes.append(required_type_class) + return results_classes + + +def get_required_type_classes(required_types_mixed): + """Converts the tuple required_types into a tuple and a dict described + below + + Args: + required_types_mixed (tuple/list): will contain either classes or + instance of list or dict + + Returns: + (valid_classes, dict_valid_class_to_child_types_mixed): + valid_classes (tuple): the valid classes that the current item + should be + dict_valid_class_to_child_types_mixed (doct): + valid_class (class): this is the key + child_types_mixed (list/dict/tuple): describes the valid child + types + """ + valid_classes = [] + child_req_types_by_current_type = {} + for required_type in required_types_mixed: + if isinstance(required_type, list): + valid_classes.append(list) + child_req_types_by_current_type[list] = required_type + elif isinstance(required_type, tuple): + valid_classes.append(tuple) + child_req_types_by_current_type[tuple] = required_type + elif isinstance(required_type, dict): + valid_classes.append(dict) + child_req_types_by_current_type[dict] = required_type[str] + else: + valid_classes.append(required_type) + return tuple(valid_classes), child_req_types_by_current_type + + +def change_keys_js_to_python(input_dict, model_class): + """ + Converts from javascript_key keys in the input_dict to python_keys in + the output dict using the mapping in model_class + """ + + output_dict = {} + reversed_attr_map = {value: key for key, value in + six.iteritems(model_class.attribute_map)} + for javascript_key, value in six.iteritems(input_dict): + python_key = reversed_attr_map.get(javascript_key) + if python_key is None: + # if the key is unknown, it is in error or it is an + # additionalProperties variable + python_key = javascript_key + output_dict[python_key] = value + return output_dict + + +def get_type_error(var_value, path_to_item, valid_classes, key_type=False): + error_msg = type_error_message( + var_name=path_to_item[-1], + var_value=var_value, + valid_classes=valid_classes, + key_type=key_type + ) + return ApiTypeError( + error_msg, + path_to_item=path_to_item, + valid_classes=valid_classes, + key_type=key_type + ) + + +def deserialize_primitive(data, klass, path_to_item): + """Deserializes string to primitive type. + + :param data: str/int/float + :param klass: str/class the class to convert to + + :return: int, float, str, bool, date, datetime + """ + additional_message = "" + try: + if klass in {datetime, date}: + additional_message = ( + "If you need your parameter to have a fallback " + "string value, please set its type as `type: {}` in your " + "spec. That allows the value to be any type. " + ) + if klass == datetime: + if len(data) < 8: + raise ValueError("This is not a datetime") + # The string should be in iso8601 datetime format. + parsed_datetime = parse(data) + date_only = ( + parsed_datetime.hour == 0 and + parsed_datetime.minute == 0 and + parsed_datetime.second == 0 and + parsed_datetime.tzinfo is None and + 8 <= len(data) <= 10 + ) + if date_only: + raise ValueError("This is a date, not a datetime") + return parsed_datetime + elif klass == date: + if len(data) < 8: + raise ValueError("This is not a date") + return parse(data).date() + else: + converted_value = klass(data) + if isinstance(data, str) and klass == float: + if str(converted_value) != data: + # '7' -> 7.0 -> '7.0' != '7' + raise ValueError('This is not a float') + return converted_value + except (OverflowError, ValueError): + # parse can raise OverflowError + raise ApiValueError( + "{0}Failed to parse {1} as {2}".format( + additional_message, repr(data), get_py3_class_name(klass) + ), + path_to_item=path_to_item + ) + + +def deserialize_model(model_data, model_class, path_to_item, check_type, + configuration, from_server): + """Deserializes model_data to model instance. + + Args: + model_data (list/dict): data to instantiate the model + model_class (OpenApiModel): the model class + path_to_item (list): path to the model in the received data + check_type (bool): whether to check the data tupe for the values in + the model + configuration (Configuration): the instance to use to convert files + from_server (bool): True if the data is from the server + False if the data is from the client + + Returns: + model instance + + Raise: + ApiTypeError + ApiValueError + ApiKeyError + """ + fixed_model_data = copy.deepcopy(model_data) + + if isinstance(fixed_model_data, dict): + fixed_model_data = change_keys_js_to_python(fixed_model_data, + model_class) + + kw_args = dict(_check_type=check_type, + _path_to_item=path_to_item, + _configuration=configuration, + _from_server=from_server) + + if hasattr(model_class, 'get_real_child_model'): + # discriminator case + discriminator_class = model_class.get_real_child_model(model_data) + if discriminator_class: + if isinstance(model_data, list): + instance = discriminator_class(*model_data, **kw_args) + elif isinstance(model_data, dict): + fixed_model_data = change_keys_js_to_python( + fixed_model_data, + discriminator_class + ) + kw_args.update(fixed_model_data) + instance = discriminator_class(**kw_args) + else: + # all other cases + if isinstance(model_data, list): + instance = model_class(*model_data, **kw_args) + if isinstance(model_data, dict): + fixed_model_data = change_keys_js_to_python(fixed_model_data, + model_class) + kw_args.update(fixed_model_data) + instance = model_class(**kw_args) + else: + instance = model_class(model_data, **kw_args) + + return instance + + +def deserialize_file(response_data, configuration, content_disposition=None): + """Deserializes body to file + + Saves response body into a file in a temporary folder, + using the filename from the `Content-Disposition` header if provided. + + Args: + param response_data (str): the file data to write + configuration (Configuration): the instance to use to convert files + + Keyword Args: + content_disposition (str): the value of the Content-Disposition + header + + Returns: + (file_type): the deserialized file which is open + The user is responsible for closing and reading the file + """ + fd, path = tempfile.mkstemp(dir=configuration.temp_folder_path) + os.close(fd) + os.remove(path) + + if content_disposition: + filename = re.search(r'filename=[\'"]?([^\'"\s]+)[\'"]?', + content_disposition).group(1) + path = os.path.join(os.path.dirname(path), filename) + + with open(path, "wb") as f: + if six.PY3 and isinstance(response_data, str): + # in python3 change str to bytes so we can write it + response_data = response_data.encode('utf-8') + f.write(response_data) + + f = open(path, "rb") + return f + + +def attempt_convert_item(input_value, valid_classes, path_to_item, + configuration, from_server, key_type=False, + must_convert=False, check_type=True): + """ + Args: + input_value (any): the data to convert + valid_classes (any): the classes that are valid + path_to_item (list): the path to the item to convert + configuration (Configuration): the instance to use to convert files + from_server (bool): True if data is from the server, False is data is + from the client + key_type (bool): if True we need to convert a key type (not supported) + must_convert (bool): if True we must convert + check_type (bool): if True we check the type or the returned data in + ModelNormal and ModelSimple instances + + Returns: + instance (any) the fixed item + + Raises: + ApiTypeError + ApiValueError + ApiKeyError + """ + valid_classes_ordered = order_response_types(valid_classes) + valid_classes_coercible = remove_uncoercible( + valid_classes_ordered, input_value, from_server) + if not valid_classes_coercible or key_type: + # we do not handle keytype errors, json will take care + # of this for us + raise get_type_error(input_value, path_to_item, valid_classes, + key_type=key_type) + for valid_class in valid_classes_coercible: + try: + if issubclass(valid_class, OpenApiModel): + return deserialize_model(input_value, valid_class, + path_to_item, check_type, + configuration, from_server) + elif valid_class == file_type: + return deserialize_file(input_value, configuration) + return deserialize_primitive(input_value, valid_class, + path_to_item) + except (ApiTypeError, ApiValueError, ApiKeyError) as conversion_exc: + if must_convert: + raise conversion_exc + # if we have conversion errors when must_convert == False + # we ignore the exception and move on to the next class + continue + # we were unable to convert, must_convert == False + return input_value + + +def validate_and_convert_types(input_value, required_types_mixed, path_to_item, + from_server, _check_type, configuration=None): + """Raises a TypeError is there is a problem, otherwise returns value + + Args: + input_value (any): the data to validate/convert + required_types_mixed (list/dict/tuple): A list of + valid classes, or a list tuples of valid classes, or a dict where + the value is a tuple of value classes + path_to_item: (list) the path to the data being validated + this stores a list of keys or indices to get to the data being + validated + from_server (bool): True if data is from the server + False if data is from the client + _check_type: (boolean) if true, type will be checked and conversion + will be attempted. + configuration: (Configuration): the configuration class to use + when converting file_type items. + If passed, conversion will be attempted when possible + If not passed, no conversions will be attempted and + exceptions will be raised + + Returns: + the correctly typed value + + Raises: + ApiTypeError + """ + results = get_required_type_classes(required_types_mixed) + valid_classes, child_req_types_by_current_type = results + + input_class_simple = get_simple_class(input_value) + valid_type = input_class_simple in set(valid_classes) + if not valid_type: + if configuration: + # if input_value is not valid_type try to convert it + converted_instance = attempt_convert_item( + input_value, + valid_classes, + path_to_item, + configuration, + from_server, + key_type=False, + must_convert=True + ) + return converted_instance + else: + raise get_type_error(input_value, path_to_item, valid_classes, + key_type=False) + + # input_value's type is in valid_classes + if len(valid_classes) > 1 and configuration: + # there are valid classes which are not the current class + valid_classes_coercible = remove_uncoercible( + valid_classes, input_value, from_server, must_convert=False) + if valid_classes_coercible: + converted_instance = attempt_convert_item( + input_value, + valid_classes_coercible, + path_to_item, + configuration, + from_server, + key_type=False, + must_convert=False + ) + return converted_instance + + if child_req_types_by_current_type == {}: + # all types are of the required types and there are no more inner + # variables left to look at + return input_value + inner_required_types = child_req_types_by_current_type.get( + type(input_value) + ) + if inner_required_types is None: + # for this type, there are not more inner variables left to look at + return input_value + if isinstance(input_value, list): + if input_value == []: + # allow an empty list + return input_value + for index, inner_value in enumerate(input_value): + inner_path = list(path_to_item) + inner_path.append(index) + input_value[index] = validate_and_convert_types( + inner_value, + inner_required_types, + inner_path, + from_server, + _check_type, + configuration=configuration + ) + elif isinstance(input_value, dict): + if input_value == {}: + # allow an empty dict + return input_value + for inner_key, inner_val in six.iteritems(input_value): + inner_path = list(path_to_item) + inner_path.append(inner_key) + if get_simple_class(inner_key) != str: + raise get_type_error(inner_key, inner_path, valid_classes, + key_type=True) + input_value[inner_key] = validate_and_convert_types( + inner_val, + inner_required_types, + inner_path, + from_server, + _check_type, + configuration=configuration + ) + return input_value + + +def model_to_dict(model_instance, serialize=True): + """Returns the model properties as a dict + + Args: + model_instance (one of your model instances): the model instance that + will be converted to a dict. + + Keyword Args: + serialize (bool): if True, the keys in the dict will be values from + attribute_map + """ + result = {} + + for attr, value in six.iteritems(model_instance._data_store): + if serialize: + # we use get here because additional property key names do not + # exist in attribute_map + attr = model_instance.attribute_map.get(attr, attr) + if isinstance(value, list): + result[attr] = list(map( + lambda x: model_to_dict(x, serialize=serialize) + if hasattr(x, '_data_store') else x, value + )) + elif isinstance(value, dict): + result[attr] = dict(map( + lambda item: (item[0], + model_to_dict(item[1], serialize=serialize)) + if hasattr(item[1], '_data_store') else item, + value.items() + )) + elif hasattr(value, '_data_store'): + result[attr] = model_to_dict(value, serialize=serialize) + else: + result[attr] = value + + return result + + +def type_error_message(var_value=None, var_name=None, valid_classes=None, + key_type=None): + """ + Keyword Args: + var_value (any): the variable which has the type_error + var_name (str): the name of the variable which has the typ error + valid_classes (tuple): the accepted classes for current_item's + value + key_type (bool): False if our value is a value in a dict + True if it is a key in a dict + False if our item is an item in a list + """ + key_or_value = 'value' + if key_type: + key_or_value = 'key' + valid_classes_phrase = get_valid_classes_phrase(valid_classes) + msg = ( + "Invalid type for variable '{0}'. Required {1} type {2} and " + "passed type was {3}".format( + var_name, + key_or_value, + valid_classes_phrase, + type(var_value).__name__, + ) + ) + return msg + + +def get_valid_classes_phrase(input_classes): + """Returns a string phrase describing what types are allowed + Note: Adds the extra valid classes in python2 + """ + all_classes = list(input_classes) + if six.PY2 and str in input_classes: + all_classes.extend([str_py2, unicode_py2]) + if six.PY2 and int in input_classes: + all_classes.extend([int_py2, long_py2]) + all_classes = sorted(all_classes, key=lambda cls: cls.__name__) + all_class_names = [cls.__name__ for cls in all_classes] + if len(all_class_names) == 1: + return 'is {0}'.format(all_class_names[0]) + return "is one of [{0}]".format(", ".join(all_class_names)) -class ModelNormal(object): - # the parent class of models whose type == object in their swagger/openapi - # spec - pass +def get_py3_class_name(input_class): + if six.PY2: + if input_class == str: + return 'str' + elif input_class == int: + return 'int' + return input_class.__name__ diff --git a/modules/openapi-generator/src/main/resources/python/python-experimental/requirements.mustache b/modules/openapi-generator/src/main/resources/python/python-experimental/requirements.mustache new file mode 100644 index 000000000000..eb358efd5bd3 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/python/python-experimental/requirements.mustache @@ -0,0 +1,6 @@ +certifi >= 14.05.14 +future; python_version<="2.7" +six >= 1.10 +python_dateutil >= 2.5.3 +setuptools >= 21.0.0 +urllib3 >= 1.15.1 diff --git a/modules/openapi-generator/src/main/resources/python/python-experimental/setup.mustache b/modules/openapi-generator/src/main/resources/python/python-experimental/setup.mustache new file mode 100644 index 000000000000..80006ded1608 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/python/python-experimental/setup.mustache @@ -0,0 +1,45 @@ +# coding: utf-8 + +{{>partial_header}} + +from setuptools import setup, find_packages # noqa: H301 + +NAME = "{{{projectName}}}" +VERSION = "{{packageVersion}}" +{{#apiInfo}} +{{#apis}} +{{^hasMore}} +# To install the library, run the following +# +# python setup.py install +# +# prerequisite: setuptools +# http://pypi.python.org/pypi/setuptools + +REQUIRES = ["urllib3 >= 1.15", "six >= 1.10", "certifi", "python-dateutil"] +{{#asyncio}} +REQUIRES.append("aiohttp >= 3.0.0") +{{/asyncio}} +{{#tornado}} +REQUIRES.append("tornado>=4.2,<5") +{{/tornado}} +EXTRAS = {':python_version <= "2.7"': ['future']} + +setup( + name=NAME, + version=VERSION, + description="{{appName}}", + author_email="{{infoEmail}}", + url="{{packageUrl}}", + keywords=["OpenAPI", "OpenAPI-Generator", "{{{appName}}}"], + install_requires=REQUIRES, + extras_require=EXTRAS, + packages=find_packages(exclude=["test", "tests"]), + include_package_data=True, + long_description="""\ + {{appDescription}} # noqa: E501 + """ +) +{{/hasMore}} +{{/apis}} +{{/apiInfo}} diff --git a/modules/openapi-generator/src/main/resources/python/requirements.mustache b/modules/openapi-generator/src/main/resources/python/requirements.mustache index bafdc07532f5..eb358efd5bd3 100644 --- a/modules/openapi-generator/src/main/resources/python/requirements.mustache +++ b/modules/openapi-generator/src/main/resources/python/requirements.mustache @@ -1,4 +1,5 @@ certifi >= 14.05.14 +future; python_version<="2.7" six >= 1.10 python_dateutil >= 2.5.3 setuptools >= 21.0.0 diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/python/PythonClientExperimentalTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/python/PythonClientExperimentalTest.java new file mode 100644 index 000000000000..6ddfe891d2f7 --- /dev/null +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/python/PythonClientExperimentalTest.java @@ -0,0 +1,297 @@ +/* + * Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech) + * Copyright 2018 SmartBear Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.openapitools.codegen.python; + +import com.google.common.collect.Sets; +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.Operation; +import io.swagger.v3.oas.models.media.*; +import io.swagger.v3.parser.util.SchemaTypeUtil; +import org.openapitools.codegen.*; +import org.openapitools.codegen.languages.PythonClientExperimentalCodegen; +import org.testng.Assert; +import org.testng.annotations.Test; + +@SuppressWarnings("static-method") +public class PythonClientExperimentalTest { + + @Test(description = "convert a python model with dots") + public void modelTest() { + final OpenAPI openAPI= TestUtils.parseSpec("src/test/resources/2_0/v1beta3.json"); + final DefaultCodegen codegen = new PythonClientExperimentalCodegen(); + codegen.setOpenAPI(openAPI); + + codegen.setOpenAPI(openAPI); + final CodegenModel simpleName = codegen.fromModel("v1beta3.Binding", openAPI.getComponents().getSchemas().get("v1beta3.Binding")); + Assert.assertEquals(simpleName.name, "v1beta3.Binding"); + Assert.assertEquals(simpleName.classname, "V1beta3Binding"); + Assert.assertEquals(simpleName.classVarName, "v1beta3_binding"); + + codegen.setOpenAPI(openAPI); + final CodegenModel compoundName = codegen.fromModel("v1beta3.ComponentStatus", openAPI.getComponents().getSchemas().get("v1beta3.ComponentStatus")); + Assert.assertEquals(compoundName.name, "v1beta3.ComponentStatus"); + Assert.assertEquals(compoundName.classname, "V1beta3ComponentStatus"); + Assert.assertEquals(compoundName.classVarName, "v1beta3_component_status"); + + final String path = "/api/v1beta3/namespaces/{namespaces}/bindings"; + final Operation operation = openAPI.getPaths().get(path).getPost(); + final CodegenOperation codegenOperation = codegen.fromOperation(path, "get", operation, null); + Assert.assertEquals(codegenOperation.returnType, "V1beta3Binding"); + Assert.assertEquals(codegenOperation.returnBaseType, "V1beta3Binding"); + } + + @Test(description = "convert a simple java model") + public void simpleModelTest() { + final Schema schema = new Schema() + .description("a sample model") + .addProperties("id", new IntegerSchema().format(SchemaTypeUtil.INTEGER64_FORMAT)) + .addProperties("name", new StringSchema()) + .addProperties("createdAt", new DateTimeSchema()) + .addRequiredItem("id") + .addRequiredItem("name"); + final DefaultCodegen codegen = new PythonClientExperimentalCodegen(); + OpenAPI openAPI = TestUtils.createOpenAPIWithOneSchema("sample", schema); + codegen.setOpenAPI(openAPI); + final CodegenModel cm = codegen.fromModel("sample", schema); + + Assert.assertEquals(cm.name, "sample"); + Assert.assertEquals(cm.classname, "Sample"); + Assert.assertEquals(cm.description, "a sample model"); + Assert.assertEquals(cm.vars.size(), 3); + + final CodegenProperty property1 = cm.vars.get(0); + Assert.assertEquals(property1.baseName, "id"); + Assert.assertEquals(property1.dataType, "int"); + Assert.assertEquals(property1.name, "id"); + Assert.assertNull(property1.defaultValue); + Assert.assertEquals(property1.baseType, "int"); + Assert.assertTrue(property1.hasMore); + Assert.assertTrue(property1.required); + Assert.assertTrue(property1.isPrimitiveType); + + final CodegenProperty property2 = cm.vars.get(1); + Assert.assertEquals(property2.baseName, "name"); + Assert.assertEquals(property2.dataType, "str"); + Assert.assertEquals(property2.name, "name"); + Assert.assertNull(property2.defaultValue); + Assert.assertEquals(property2.baseType, "str"); + Assert.assertTrue(property2.hasMore); + Assert.assertTrue(property2.required); + Assert.assertTrue(property2.isPrimitiveType); + + final CodegenProperty property3 = cm.vars.get(2); + Assert.assertEquals(property3.baseName, "createdAt"); + Assert.assertEquals(property3.dataType, "datetime"); + Assert.assertEquals(property3.name, "created_at"); + Assert.assertNull(property3.defaultValue); + Assert.assertEquals(property3.baseType, "datetime"); + Assert.assertFalse(property3.hasMore); + Assert.assertFalse(property3.required); + } + + @Test(description = "convert a model with list property") + public void listPropertyTest() { + final Schema model = new Schema() + .description("a sample model") + .addProperties("id", new IntegerSchema().format(SchemaTypeUtil.INTEGER64_FORMAT)) + .addProperties("urls", new ArraySchema() + .items(new StringSchema())) + .addRequiredItem("id"); + final DefaultCodegen codegen = new PythonClientExperimentalCodegen(); + OpenAPI openAPI = TestUtils.createOpenAPIWithOneSchema("sample", model); + codegen.setOpenAPI(openAPI); + final CodegenModel cm = codegen.fromModel("sample", model); + + Assert.assertEquals(cm.name, "sample"); + Assert.assertEquals(cm.classname, "Sample"); + Assert.assertEquals(cm.description, "a sample model"); + Assert.assertEquals(cm.vars.size(), 2); + + final CodegenProperty property1 = cm.vars.get(0); + Assert.assertEquals(property1.baseName, "id"); + Assert.assertEquals(property1.dataType, "int"); + Assert.assertEquals(property1.name, "id"); + Assert.assertNull(property1.defaultValue); + Assert.assertEquals(property1.baseType, "int"); + Assert.assertTrue(property1.hasMore); + Assert.assertTrue(property1.required); + Assert.assertTrue(property1.isPrimitiveType); + + final CodegenProperty property2 = cm.vars.get(1); + Assert.assertEquals(property2.baseName, "urls"); + Assert.assertEquals(property2.dataType, "[str]"); + Assert.assertEquals(property2.name, "urls"); + Assert.assertNull(property2.defaultValue); + Assert.assertEquals(property2.baseType, "list"); + Assert.assertFalse(property2.hasMore); + Assert.assertEquals(property2.containerType, "array"); + Assert.assertFalse(property2.required); + Assert.assertTrue(property2.isPrimitiveType); + Assert.assertTrue(property2.isContainer); + } + + @Test(description = "convert a model with a map property") + public void mapPropertyTest() { + final Schema model = new Schema() + .description("a sample model") + .addProperties("translations", new MapSchema() + .additionalProperties(new StringSchema())) + .addRequiredItem("id"); + final DefaultCodegen codegen = new PythonClientExperimentalCodegen(); + OpenAPI openAPI = TestUtils.createOpenAPIWithOneSchema("sample", model); + codegen.setOpenAPI(openAPI); + final CodegenModel cm = codegen.fromModel("sample", model); + + Assert.assertEquals(cm.name, "sample"); + Assert.assertEquals(cm.classname, "Sample"); + Assert.assertEquals(cm.description, "a sample model"); + Assert.assertEquals(cm.vars.size(), 1); + + final CodegenProperty property1 = cm.vars.get(0); + Assert.assertEquals(property1.baseName, "translations"); + Assert.assertEquals(property1.dataType, "{str: (str,)}"); + Assert.assertEquals(property1.name, "translations"); + Assert.assertEquals(property1.baseType, "dict"); + Assert.assertEquals(property1.containerType, "map"); + Assert.assertFalse(property1.required); + Assert.assertTrue(property1.isContainer); + Assert.assertTrue(property1.isPrimitiveType); + } + + @Test(description = "convert a model with complex property") + public void complexPropertyTest() { + final Schema model = new Schema() + .description("a sample model") + .addProperties("children", new Schema().$ref("#/definitions/Children")); + final DefaultCodegen codegen = new PythonClientExperimentalCodegen(); + OpenAPI openAPI = TestUtils.createOpenAPIWithOneSchema("sample", model); + codegen.setOpenAPI(openAPI); + final CodegenModel cm = codegen.fromModel("sample", model); + + Assert.assertEquals(cm.name, "sample"); + Assert.assertEquals(cm.classname, "Sample"); + Assert.assertEquals(cm.description, "a sample model"); + Assert.assertEquals(cm.vars.size(), 1); + + final CodegenProperty property1 = cm.vars.get(0); + Assert.assertEquals(property1.baseName, "children"); + Assert.assertEquals(property1.dataType, "Children"); + Assert.assertEquals(property1.name, "children"); + Assert.assertEquals(property1.baseType, "Children"); + Assert.assertFalse(property1.required); + Assert.assertFalse(property1.isContainer); + } + + @Test(description = "convert a model with complex list property") + public void complexListPropertyTest() { + final Schema model = new Schema() + .description("a sample model") + .addProperties("children", new ArraySchema() + .items(new Schema().$ref("#/definitions/Children"))); + final DefaultCodegen codegen = new PythonClientExperimentalCodegen(); + OpenAPI openAPI = TestUtils.createOpenAPIWithOneSchema("sample", model); + codegen.setOpenAPI(openAPI); + final CodegenModel cm = codegen.fromModel("sample", model); + + Assert.assertEquals(cm.name, "sample"); + Assert.assertEquals(cm.classname, "Sample"); + Assert.assertEquals(cm.description, "a sample model"); + Assert.assertEquals(cm.vars.size(), 1); + + final CodegenProperty property1 = cm.vars.get(0); + Assert.assertEquals(property1.baseName, "children"); + Assert.assertEquals(property1.complexType, "Children"); + Assert.assertEquals(property1.dataType, "[Children]"); + Assert.assertEquals(property1.name, "children"); + Assert.assertEquals(property1.baseType, "list"); + Assert.assertEquals(property1.containerType, "array"); + Assert.assertFalse(property1.required); + Assert.assertTrue(property1.isContainer); + } + + @Test(description = "convert a model with complex map property") + public void complexMapPropertyTest() { + final Schema model = new Schema() + .description("a sample model") + .addProperties("children", new MapSchema() + .additionalProperties(new Schema().$ref("#/definitions/Children"))); + final DefaultCodegen codegen = new PythonClientExperimentalCodegen(); + OpenAPI openAPI = TestUtils.createOpenAPIWithOneSchema("sample", model); + codegen.setOpenAPI(openAPI); + final CodegenModel cm = codegen.fromModel("sample", model); + + Assert.assertEquals(cm.name, "sample"); + Assert.assertEquals(cm.classname, "Sample"); + Assert.assertEquals(cm.description, "a sample model"); + Assert.assertEquals(cm.vars.size(), 1); + Assert.assertEquals(Sets.intersection(cm.imports, Sets.newHashSet("Children")).size(), 1); + + final CodegenProperty property1 = cm.vars.get(0); + Assert.assertEquals(property1.baseName, "children"); + Assert.assertEquals(property1.complexType, "Children"); + Assert.assertEquals(property1.dataType, "{str: (Children,)}"); + Assert.assertEquals(property1.name, "children"); + Assert.assertEquals(property1.baseType, "dict"); + Assert.assertEquals(property1.containerType, "map"); + Assert.assertFalse(property1.required); + Assert.assertTrue(property1.isContainer); + } + + + // should not start with 'null'. need help from the community to investigate further + @Test(description = "convert an array model") + public void arrayModelTest() { + final Schema model = new ArraySchema() + //.description() + .items(new Schema().$ref("#/definitions/Children")) + .description("an array model"); + final DefaultCodegen codegen = new PythonClientExperimentalCodegen(); + OpenAPI openAPI = TestUtils.createOpenAPIWithOneSchema("sample", model); + codegen.setOpenAPI(openAPI); + final CodegenModel cm = codegen.fromModel("sample", model); + + Assert.assertEquals(cm.name, "sample"); + Assert.assertEquals(cm.classname, "Sample"); + Assert.assertEquals(cm.description, "an array model"); + Assert.assertEquals(cm.vars.size(), 0); + Assert.assertEquals(cm.parent, "list"); + Assert.assertEquals(cm.imports.size(), 1); + Assert.assertEquals(Sets.intersection(cm.imports, Sets.newHashSet("Children")).size(), 1); + } + + // should not start with 'null'. need help from the community to investigate further + @Test(description = "convert a map model") + public void mapModelTest() { + final Schema model = new Schema() + .description("a map model") + .additionalProperties(new Schema().$ref("#/definitions/Children")); + final DefaultCodegen codegen = new PythonClientExperimentalCodegen(); + OpenAPI openAPI = TestUtils.createOpenAPIWithOneSchema("sample", model); + codegen.setOpenAPI(openAPI); + final CodegenModel cm = codegen.fromModel("sample", model); + + Assert.assertEquals(cm.name, "sample"); + Assert.assertEquals(cm.classname, "Sample"); + Assert.assertEquals(cm.description, "a map model"); + Assert.assertEquals(cm.vars.size(), 0); + Assert.assertEquals(cm.parent, "dict"); + Assert.assertEquals(cm.imports.size(), 1); + Assert.assertEquals(Sets.intersection(cm.imports, Sets.newHashSet("Children")).size(), 1); + } + +} diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/python/PythonTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/python/PythonTest.java index 7a2a37f4132d..5d606847a284 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/python/PythonTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/python/PythonTest.java @@ -294,4 +294,4 @@ public void mapModelTest() { Assert.assertEquals(Sets.intersection(cm.imports, Sets.newHashSet("Children")).size(), 1); } -} +} \ No newline at end of file diff --git a/samples/client/petstore/python-experimental/docs/AdditionalPropertiesAnyType.md b/samples/client/petstore/python-experimental/docs/AdditionalPropertiesAnyType.md index 9843d35ab906..754b2f3ada4c 100644 --- a/samples/client/petstore/python-experimental/docs/AdditionalPropertiesAnyType.md +++ b/samples/client/petstore/python-experimental/docs/AdditionalPropertiesAnyType.md @@ -4,6 +4,7 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **name** | **str** | | [optional] +**any string name** | **bool, date, datetime, dict, float, int, list, str** | 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/client/petstore/python-experimental/docs/AdditionalPropertiesArray.md b/samples/client/petstore/python-experimental/docs/AdditionalPropertiesArray.md index cfe09d91c726..61ac566c14d2 100644 --- a/samples/client/petstore/python-experimental/docs/AdditionalPropertiesArray.md +++ b/samples/client/petstore/python-experimental/docs/AdditionalPropertiesArray.md @@ -4,6 +4,7 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **name** | **str** | | [optional] +**any string name** | **[bool, date, datetime, dict, float, int, list, str]** | 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/client/petstore/python-experimental/docs/AdditionalPropertiesBoolean.md b/samples/client/petstore/python-experimental/docs/AdditionalPropertiesBoolean.md index 74f009554a7f..f2567f064cfd 100644 --- a/samples/client/petstore/python-experimental/docs/AdditionalPropertiesBoolean.md +++ b/samples/client/petstore/python-experimental/docs/AdditionalPropertiesBoolean.md @@ -4,6 +4,7 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **name** | **str** | | [optional] +**any string name** | **bool** | 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/client/petstore/python-experimental/docs/AdditionalPropertiesClass.md b/samples/client/petstore/python-experimental/docs/AdditionalPropertiesClass.md index f1f9b29a608f..1a379bff6f0a 100644 --- a/samples/client/petstore/python-experimental/docs/AdditionalPropertiesClass.md +++ b/samples/client/petstore/python-experimental/docs/AdditionalPropertiesClass.md @@ -3,17 +3,17 @@ ## Properties Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**map_string** | **dict(str, str)** | | [optional] -**map_number** | **dict(str, float)** | | [optional] -**map_integer** | **dict(str, int)** | | [optional] -**map_boolean** | **dict(str, bool)** | | [optional] -**map_array_integer** | **dict(str, list[int])** | | [optional] -**map_array_anytype** | **dict(str, list[object])** | | [optional] -**map_map_string** | **dict(str, dict(str, str))** | | [optional] -**map_map_anytype** | **dict(str, dict(str, object))** | | [optional] -**anytype_1** | [**object**](.md) | | [optional] -**anytype_2** | [**object**](.md) | | [optional] -**anytype_3** | [**object**](.md) | | [optional] +**map_string** | **{str: (str,)}** | | [optional] +**map_number** | **{str: (float,)}** | | [optional] +**map_integer** | **{str: (int,)}** | | [optional] +**map_boolean** | **{str: (bool,)}** | | [optional] +**map_array_integer** | **{str: ([int],)}** | | [optional] +**map_array_anytype** | **{str: ([bool, date, datetime, dict, float, int, list, str],)}** | | [optional] +**map_map_string** | **{str: ({str: (str,)},)}** | | [optional] +**map_map_anytype** | **{str: ({str: (bool, date, datetime, dict, float, int, list, str,)},)}** | | [optional] +**anytype_1** | [**bool, date, datetime, dict, float, int, list, str**](.md) | | [optional] +**anytype_2** | [**bool, date, datetime, dict, float, int, list, str**](.md) | | [optional] +**anytype_3** | [**bool, date, datetime, dict, float, int, list, str**](.md) | | [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/client/petstore/python-experimental/docs/AdditionalPropertiesInteger.md b/samples/client/petstore/python-experimental/docs/AdditionalPropertiesInteger.md index a3e58fd1b0bd..fe0ba709c8ef 100644 --- a/samples/client/petstore/python-experimental/docs/AdditionalPropertiesInteger.md +++ b/samples/client/petstore/python-experimental/docs/AdditionalPropertiesInteger.md @@ -4,6 +4,7 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **name** | **str** | | [optional] +**any string name** | **int** | 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/client/petstore/python-experimental/docs/AdditionalPropertiesNumber.md b/samples/client/petstore/python-experimental/docs/AdditionalPropertiesNumber.md index 37eafe1ff031..bec81854b950 100644 --- a/samples/client/petstore/python-experimental/docs/AdditionalPropertiesNumber.md +++ b/samples/client/petstore/python-experimental/docs/AdditionalPropertiesNumber.md @@ -4,6 +4,7 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **name** | **str** | | [optional] +**any string name** | **float** | 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/client/petstore/python-experimental/docs/AdditionalPropertiesObject.md b/samples/client/petstore/python-experimental/docs/AdditionalPropertiesObject.md index 7f4d6713c758..3fcf2c9299df 100644 --- a/samples/client/petstore/python-experimental/docs/AdditionalPropertiesObject.md +++ b/samples/client/petstore/python-experimental/docs/AdditionalPropertiesObject.md @@ -4,6 +4,7 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **name** | **str** | | [optional] +**any string name** | **{str: (bool, date, datetime, dict, float, int, list, str,)}** | 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/client/petstore/python-experimental/docs/AdditionalPropertiesString.md b/samples/client/petstore/python-experimental/docs/AdditionalPropertiesString.md index 9317cfeee80b..bbe0b1cbbbb9 100644 --- a/samples/client/petstore/python-experimental/docs/AdditionalPropertiesString.md +++ b/samples/client/petstore/python-experimental/docs/AdditionalPropertiesString.md @@ -4,6 +4,7 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **name** | **str** | | [optional] +**any string name** | **str** | 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/client/petstore/python-experimental/docs/ArrayOfArrayOfNumberOnly.md b/samples/client/petstore/python-experimental/docs/ArrayOfArrayOfNumberOnly.md index aa3988ab1679..1a68df0090bb 100644 --- a/samples/client/petstore/python-experimental/docs/ArrayOfArrayOfNumberOnly.md +++ b/samples/client/petstore/python-experimental/docs/ArrayOfArrayOfNumberOnly.md @@ -3,7 +3,7 @@ ## Properties Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**array_array_number** | **list[list[float]]** | | [optional] +**array_array_number** | **[[float]]** | | [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/client/petstore/python-experimental/docs/ArrayOfNumberOnly.md b/samples/client/petstore/python-experimental/docs/ArrayOfNumberOnly.md index 2c3de967aec6..b8a760f56dc2 100644 --- a/samples/client/petstore/python-experimental/docs/ArrayOfNumberOnly.md +++ b/samples/client/petstore/python-experimental/docs/ArrayOfNumberOnly.md @@ -3,7 +3,7 @@ ## Properties Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**array_number** | **list[float]** | | [optional] +**array_number** | **[float]** | | [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/client/petstore/python-experimental/docs/ArrayTest.md b/samples/client/petstore/python-experimental/docs/ArrayTest.md index 6ab0d1378065..c677e324ad47 100644 --- a/samples/client/petstore/python-experimental/docs/ArrayTest.md +++ b/samples/client/petstore/python-experimental/docs/ArrayTest.md @@ -3,9 +3,9 @@ ## Properties Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**array_of_string** | **list[str]** | | [optional] -**array_array_of_integer** | **list[list[int]]** | | [optional] -**array_array_of_model** | **list[list[ReadOnlyFirst]]** | | [optional] +**array_of_string** | **[str]** | | [optional] +**array_array_of_integer** | **[[int]]** | | [optional] +**array_array_of_model** | **[[ReadOnlyFirst]]** | | [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/client/petstore/python-experimental/docs/EnumArrays.md b/samples/client/petstore/python-experimental/docs/EnumArrays.md index e15a5f1fd049..e0b5582e9d5b 100644 --- a/samples/client/petstore/python-experimental/docs/EnumArrays.md +++ b/samples/client/petstore/python-experimental/docs/EnumArrays.md @@ -4,7 +4,7 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **just_symbol** | **str** | | [optional] -**array_enum** | **list[str]** | | [optional] +**array_enum** | **[str]** | | [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/client/petstore/python-experimental/docs/FakeApi.md b/samples/client/petstore/python-experimental/docs/FakeApi.md index 94280a712344..368f9ec306eb 100644 --- a/samples/client/petstore/python-experimental/docs/FakeApi.md +++ b/samples/client/petstore/python-experimental/docs/FakeApi.md @@ -591,7 +591,7 @@ int32 = 56 # int | None (optional) int64 = 56 # int | None (optional) float = 3.4 # float | None (optional) string = 'string_example' # str | None (optional) -binary = '/path/to/file' # file | None (optional) +binary = '/path/to/file' # file_type | None (optional) date = '2013-10-20' # date | None (optional) date_time = '2013-10-20T19:20:30+01:00' # datetime | None (optional) password = 'password_example' # str | None (optional) @@ -617,7 +617,7 @@ Name | Type | Description | Notes **int64** | **int**| None | [optional] **float** | **float**| None | [optional] **string** | **str**| None | [optional] - **binary** | **file**| None | [optional] + **binary** | **file_type**| None | [optional] **date** | **date**| None | [optional] **date_time** | **datetime**| None | [optional] **password** | **str**| None | [optional] @@ -662,13 +662,13 @@ from pprint import pprint # Create an instance of the API class api_instance = petstore_api.FakeApi() -enum_header_string_array = ['enum_header_string_array_example'] # list[str] | Header parameter enum test (string array) (optional) +enum_header_string_array = ['enum_header_string_array_example'] # [str] | Header parameter enum test (string array) (optional) enum_header_string = '-efg' # str | Header parameter enum test (string) (optional) (default to '-efg') -enum_query_string_array = ['enum_query_string_array_example'] # list[str] | Query parameter enum test (string array) (optional) +enum_query_string_array = ['enum_query_string_array_example'] # [str] | Query parameter enum test (string array) (optional) enum_query_string = '-efg' # str | Query parameter enum test (string) (optional) (default to '-efg') enum_query_integer = 56 # int | Query parameter enum test (double) (optional) enum_query_double = 3.4 # float | Query parameter enum test (double) (optional) -enum_form_string_array = '$' # list[str] | Form parameter enum test (string array) (optional) (default to '$') +enum_form_string_array = '$' # [str] | Form parameter enum test (string array) (optional) (default to '$') enum_form_string = '-efg' # str | Form parameter enum test (string) (optional) (default to '-efg') try: @@ -682,13 +682,13 @@ except ApiException as e: Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **enum_header_string_array** | [**list[str]**](str.md)| Header parameter enum test (string array) | [optional] + **enum_header_string_array** | [**[str]**](str.md)| Header parameter enum test (string array) | [optional] **enum_header_string** | **str**| Header parameter enum test (string) | [optional] if omitted the server will use the default value of '-efg' - **enum_query_string_array** | [**list[str]**](str.md)| Query parameter enum test (string array) | [optional] + **enum_query_string_array** | [**[str]**](str.md)| Query parameter enum test (string array) | [optional] **enum_query_string** | **str**| Query parameter enum test (string) | [optional] if omitted the server will use the default value of '-efg' **enum_query_integer** | **int**| Query parameter enum test (double) | [optional] **enum_query_double** | **float**| Query parameter enum test (double) | [optional] - **enum_form_string_array** | [**list[str]**](str.md)| Form parameter enum test (string array) | [optional] if omitted the server will use the default value of '$' + **enum_form_string_array** | [**[str]**](str.md)| Form parameter enum test (string array) | [optional] if omitted the server will use the default value of '$' **enum_form_string** | **str**| Form parameter enum test (string) | [optional] if omitted the server will use the default value of '-efg' ### Return type @@ -791,7 +791,7 @@ from pprint import pprint # Create an instance of the API class api_instance = petstore_api.FakeApi() -param = {'key': 'param_example'} # dict(str, str) | request body +param = {'key': 'param_example'} # {str: (str,)} | request body try: # test inline additionalProperties @@ -804,7 +804,7 @@ except ApiException as e: Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **param** | [**dict(str, str)**](str.md)| request body | + **param** | [**{str: (str,)}**](str.md)| request body | ### Return type diff --git a/samples/client/petstore/python-experimental/docs/FileSchemaTestClass.md b/samples/client/petstore/python-experimental/docs/FileSchemaTestClass.md index dc3722289887..d0a8bbaaba95 100644 --- a/samples/client/petstore/python-experimental/docs/FileSchemaTestClass.md +++ b/samples/client/petstore/python-experimental/docs/FileSchemaTestClass.md @@ -4,7 +4,7 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **file** | [**File**](File.md) | | [optional] -**files** | [**list[File]**](File.md) | | [optional] +**files** | [**[File]**](File.md) | | [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/client/petstore/python-experimental/docs/FormatTest.md b/samples/client/petstore/python-experimental/docs/FormatTest.md index 1bf152e6828b..083b0bd4c98a 100644 --- a/samples/client/petstore/python-experimental/docs/FormatTest.md +++ b/samples/client/petstore/python-experimental/docs/FormatTest.md @@ -13,7 +13,7 @@ Name | Type | Description | Notes **float** | **float** | | [optional] **double** | **float** | | [optional] **string** | **str** | | [optional] -**binary** | **file** | | [optional] +**binary** | **file_type** | | [optional] **date_time** | **datetime** | | [optional] **uuid** | **str** | | [optional] diff --git a/samples/client/petstore/python-experimental/docs/MapTest.md b/samples/client/petstore/python-experimental/docs/MapTest.md index ee6036eb2f42..ad561b7220bf 100644 --- a/samples/client/petstore/python-experimental/docs/MapTest.md +++ b/samples/client/petstore/python-experimental/docs/MapTest.md @@ -3,9 +3,9 @@ ## Properties Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**map_map_of_string** | **dict(str, dict(str, str))** | | [optional] -**map_of_enum_string** | **dict(str, str)** | | [optional] -**direct_map** | **dict(str, bool)** | | [optional] +**map_map_of_string** | **{str: ({str: (str,)},)}** | | [optional] +**map_of_enum_string** | **{str: (str,)}** | | [optional] +**direct_map** | **{str: (bool,)}** | | [optional] **indirect_map** | [**StringBooleanMap**](StringBooleanMap.md) | | [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/client/petstore/python-experimental/docs/MixedPropertiesAndAdditionalPropertiesClass.md b/samples/client/petstore/python-experimental/docs/MixedPropertiesAndAdditionalPropertiesClass.md index b9808d5275e5..1484c0638d83 100644 --- a/samples/client/petstore/python-experimental/docs/MixedPropertiesAndAdditionalPropertiesClass.md +++ b/samples/client/petstore/python-experimental/docs/MixedPropertiesAndAdditionalPropertiesClass.md @@ -5,7 +5,7 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **uuid** | **str** | | [optional] **date_time** | **datetime** | | [optional] -**map** | [**dict(str, Animal)**](Animal.md) | | [optional] +**map** | [**{str: (Animal,)}**](Animal.md) | | [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/client/petstore/python-experimental/docs/Pet.md b/samples/client/petstore/python-experimental/docs/Pet.md index 15185316feae..ce09d401c899 100644 --- a/samples/client/petstore/python-experimental/docs/Pet.md +++ b/samples/client/petstore/python-experimental/docs/Pet.md @@ -4,10 +4,10 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **name** | **str** | | -**photo_urls** | **list[str]** | | +**photo_urls** | **[str]** | | **id** | **int** | | [optional] **category** | [**Category**](Category.md) | | [optional] -**tags** | [**list[Tag]**](Tag.md) | | [optional] +**tags** | [**[Tag]**](Tag.md) | | [optional] **status** | **str** | pet status in the store | [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/client/petstore/python-experimental/docs/PetApi.md b/samples/client/petstore/python-experimental/docs/PetApi.md index cda559d0c62b..048a0af56ffc 100644 --- a/samples/client/petstore/python-experimental/docs/PetApi.md +++ b/samples/client/petstore/python-experimental/docs/PetApi.md @@ -134,7 +134,7 @@ void (empty response body) [[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) # **find_pets_by_status** -> list[Pet] find_pets_by_status(status) +> [Pet] find_pets_by_status(status) Finds Pets by status @@ -157,7 +157,7 @@ configuration.access_token = 'YOUR_ACCESS_TOKEN' configuration.host = "http://petstore.swagger.io:80/v2" # Create an instance of the API class api_instance = petstore_api.PetApi(petstore_api.ApiClient(configuration)) -status = ['status_example'] # list[str] | Status values that need to be considered for filter +status = ['status_example'] # [str] | Status values that need to be considered for filter try: # Finds Pets by status @@ -171,11 +171,11 @@ except ApiException as e: Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **status** | [**list[str]**](str.md)| Status values that need to be considered for filter | + **status** | [**[str]**](str.md)| Status values that need to be considered for filter | ### Return type -[**list[Pet]**](Pet.md) +[**[Pet]**](Pet.md) ### Authorization @@ -195,7 +195,7 @@ Name | Type | Description | Notes [[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) # **find_pets_by_tags** -> list[Pet] find_pets_by_tags(tags) +> [Pet] find_pets_by_tags(tags) Finds Pets by tags @@ -218,7 +218,7 @@ configuration.access_token = 'YOUR_ACCESS_TOKEN' configuration.host = "http://petstore.swagger.io:80/v2" # Create an instance of the API class api_instance = petstore_api.PetApi(petstore_api.ApiClient(configuration)) -tags = ['tags_example'] # list[str] | Tags to filter by +tags = ['tags_example'] # [str] | Tags to filter by try: # Finds Pets by tags @@ -232,11 +232,11 @@ except ApiException as e: Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **tags** | [**list[str]**](str.md)| Tags to filter by | + **tags** | [**[str]**](str.md)| Tags to filter by | ### Return type -[**list[Pet]**](Pet.md) +[**[Pet]**](Pet.md) ### Authorization @@ -464,7 +464,7 @@ configuration.host = "http://petstore.swagger.io:80/v2" api_instance = petstore_api.PetApi(petstore_api.ApiClient(configuration)) pet_id = 56 # int | ID of pet to update additional_metadata = 'additional_metadata_example' # str | Additional data to pass to server (optional) -file = '/path/to/file' # file | file to upload (optional) +file = '/path/to/file' # file_type | file to upload (optional) try: # uploads an image @@ -480,7 +480,7 @@ Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **pet_id** | **int**| ID of pet to update | **additional_metadata** | **str**| Additional data to pass to server | [optional] - **file** | **file**| file to upload | [optional] + **file** | **file_type**| file to upload | [optional] ### Return type @@ -525,7 +525,7 @@ configuration.host = "http://petstore.swagger.io:80/v2" # Create an instance of the API class api_instance = petstore_api.PetApi(petstore_api.ApiClient(configuration)) pet_id = 56 # int | ID of pet to update -required_file = '/path/to/file' # file | file to upload +required_file = '/path/to/file' # file_type | file to upload additional_metadata = 'additional_metadata_example' # str | Additional data to pass to server (optional) try: @@ -541,7 +541,7 @@ except ApiException as e: Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **pet_id** | **int**| ID of pet to update | - **required_file** | **file**| file to upload | + **required_file** | **file_type**| file to upload | **additional_metadata** | **str**| Additional data to pass to server | [optional] ### Return type diff --git a/samples/client/petstore/python-experimental/docs/StoreApi.md b/samples/client/petstore/python-experimental/docs/StoreApi.md index 8c49f3262224..bc010729c4e9 100644 --- a/samples/client/petstore/python-experimental/docs/StoreApi.md +++ b/samples/client/petstore/python-experimental/docs/StoreApi.md @@ -65,7 +65,7 @@ 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) # **get_inventory** -> dict(str, int) get_inventory() +> {str: (int,)} get_inventory() Returns pet inventories by status @@ -104,7 +104,7 @@ This endpoint does not need any parameter. ### Return type -**dict(str, int)** +**{str: (int,)}** ### Authorization diff --git a/samples/client/petstore/python-experimental/docs/StringBooleanMap.md b/samples/client/petstore/python-experimental/docs/StringBooleanMap.md index 7abf11ec68b1..2fbf3b3767d0 100644 --- a/samples/client/petstore/python-experimental/docs/StringBooleanMap.md +++ b/samples/client/petstore/python-experimental/docs/StringBooleanMap.md @@ -3,6 +3,7 @@ ## Properties Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- +**any string name** | **bool** | 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/client/petstore/python-experimental/docs/TypeHolderDefault.md b/samples/client/petstore/python-experimental/docs/TypeHolderDefault.md index 7ec864de09df..aa409ec65272 100644 --- a/samples/client/petstore/python-experimental/docs/TypeHolderDefault.md +++ b/samples/client/petstore/python-experimental/docs/TypeHolderDefault.md @@ -3,7 +3,7 @@ ## Properties Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**array_item** | **list[int]** | | +**array_item** | **[int]** | | **string_item** | **str** | | defaults to 'what' **number_item** | **float** | | defaults to 1.234 **integer_item** | **int** | | defaults to -2 diff --git a/samples/client/petstore/python-experimental/docs/TypeHolderExample.md b/samples/client/petstore/python-experimental/docs/TypeHolderExample.md index 71f302f8d9ff..3f38a46c5803 100644 --- a/samples/client/petstore/python-experimental/docs/TypeHolderExample.md +++ b/samples/client/petstore/python-experimental/docs/TypeHolderExample.md @@ -4,7 +4,7 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **bool_item** | **bool** | | -**array_item** | **list[int]** | | +**array_item** | **[int]** | | **string_item** | **str** | | defaults to 'what' **number_item** | **float** | | defaults to 1.234 **integer_item** | **int** | | defaults to -2 diff --git a/samples/client/petstore/python-experimental/docs/UserApi.md b/samples/client/petstore/python-experimental/docs/UserApi.md index b4df7a368037..d8d8b59a7d86 100644 --- a/samples/client/petstore/python-experimental/docs/UserApi.md +++ b/samples/client/petstore/python-experimental/docs/UserApi.md @@ -83,7 +83,7 @@ from pprint import pprint # Create an instance of the API class api_instance = petstore_api.UserApi() -body = [petstore_api.User()] # list[User] | List of user object +body = [petstore_api.User()] # [User] | List of user object try: # Creates list of users with given input array @@ -96,7 +96,7 @@ except ApiException as e: Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **body** | [**list[User]**](User.md)| List of user object | + **body** | [**[User]**](User.md)| List of user object | ### Return type @@ -134,7 +134,7 @@ from pprint import pprint # Create an instance of the API class api_instance = petstore_api.UserApi() -body = [petstore_api.User()] # list[User] | List of user object +body = [petstore_api.User()] # [User] | List of user object try: # Creates list of users with given input array @@ -147,7 +147,7 @@ except ApiException as e: Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **body** | [**list[User]**](User.md)| List of user object | + **body** | [**[User]**](User.md)| List of user object | ### Return type diff --git a/samples/client/petstore/python-experimental/docs/XmlItem.md b/samples/client/petstore/python-experimental/docs/XmlItem.md index 3dd09833fe52..d30ca4362293 100644 --- a/samples/client/petstore/python-experimental/docs/XmlItem.md +++ b/samples/client/petstore/python-experimental/docs/XmlItem.md @@ -7,31 +7,31 @@ Name | Type | Description | Notes **attribute_number** | **float** | | [optional] **attribute_integer** | **int** | | [optional] **attribute_boolean** | **bool** | | [optional] -**wrapped_array** | **list[int]** | | [optional] +**wrapped_array** | **[int]** | | [optional] **name_string** | **str** | | [optional] **name_number** | **float** | | [optional] **name_integer** | **int** | | [optional] **name_boolean** | **bool** | | [optional] -**name_array** | **list[int]** | | [optional] -**name_wrapped_array** | **list[int]** | | [optional] +**name_array** | **[int]** | | [optional] +**name_wrapped_array** | **[int]** | | [optional] **prefix_string** | **str** | | [optional] **prefix_number** | **float** | | [optional] **prefix_integer** | **int** | | [optional] **prefix_boolean** | **bool** | | [optional] -**prefix_array** | **list[int]** | | [optional] -**prefix_wrapped_array** | **list[int]** | | [optional] +**prefix_array** | **[int]** | | [optional] +**prefix_wrapped_array** | **[int]** | | [optional] **namespace_string** | **str** | | [optional] **namespace_number** | **float** | | [optional] **namespace_integer** | **int** | | [optional] **namespace_boolean** | **bool** | | [optional] -**namespace_array** | **list[int]** | | [optional] -**namespace_wrapped_array** | **list[int]** | | [optional] +**namespace_array** | **[int]** | | [optional] +**namespace_wrapped_array** | **[int]** | | [optional] **prefix_ns_string** | **str** | | [optional] **prefix_ns_number** | **float** | | [optional] **prefix_ns_integer** | **int** | | [optional] **prefix_ns_boolean** | **bool** | | [optional] -**prefix_ns_array** | **list[int]** | | [optional] -**prefix_ns_wrapped_array** | **list[int]** | | [optional] +**prefix_ns_array** | **[int]** | | [optional] +**prefix_ns_wrapped_array** | **[int]** | | [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/client/petstore/python-experimental/petstore_api/api/another_fake_api.py b/samples/client/petstore/python-experimental/petstore_api/api/another_fake_api.py index 1c429821437f..2ba53120ee8a 100644 --- a/samples/client/petstore/python-experimental/petstore_api/api/another_fake_api.py +++ b/samples/client/petstore/python-experimental/petstore_api/api/another_fake_api.py @@ -22,10 +22,18 @@ ApiTypeError, ApiValueError ) -from petstore_api.model_utils import ( +from petstore_api.model_utils import ( # noqa: F401 check_allowed_values, - check_validations + check_validations, + date, + datetime, + file_type, + int, + none_type, + str, + validate_and_convert_types ) +from petstore_api.models.client import Client class AnotherFakeApi(object): @@ -50,28 +58,55 @@ def __call_123_test_special_tags(self, body, **kwargs): # noqa: E501 >>> result = thread.get() :param async_req bool: execute request asynchronously + Default is False. :param Client body: client model (required) :param _return_http_data_only: response data without head status - code and headers + code and headers. Default is True. :param _preload_content: if False, the urllib3.HTTPResponse object will be returned without reading/decoding response data. Default is True. :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. + Default is None. + :param _check_input_type: boolean specifying if type checking + should be done one the data sent to the server. + Default is True. + :param _check_return_type: boolean specifying if type checking + should be done one the data received from the server. + Default is True. + :param _host_index: integer specifying the index of the server + that we want to use. + Default is 0. :return: Client 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', 0) kwargs['body'] = body return self.call_with_http_info(**kwargs) self.call_123_test_special_tags = Endpoint( settings={ - 'response_type': 'Client', + 'response_type': (Client,), 'auth': [], 'endpoint_path': '/another-fake/dummy', 'operation_id': 'call_123_test_special_tags', @@ -98,7 +133,7 @@ def __call_123_test_special_tags(self, body, **kwargs): # noqa: E501 'allowed_values': { }, 'openapi_types': { - 'body': 'Client', + 'body': (Client,), }, 'attribute_map': { }, @@ -128,7 +163,7 @@ def __init__(self, settings=None, params_map=None, root_map=None, Args: settings (dict): see below key value pairs - 'response_type' (str): response type + 'response_type' (tuple/None): response type 'auth' (list): a list of auth type keys 'endpoint_path' (str): the endpoint path 'operation_id' (str): endpoint string identifier @@ -164,11 +199,24 @@ def __init__(self, settings=None, params_map=None, root_map=None, '_host_index', '_preload_content', '_request_timeout', - '_return_http_data_only' + '_return_http_data_only', + '_check_input_type', + '_check_return_type' ]) + self.params_map['nullable'].extend(['_request_timeout']) self.validations = root_map['validations'] self.allowed_values = root_map['allowed_values'] self.openapi_types = root_map['openapi_types'] + extra_types = { + 'async_req': (bool,), + '_host_index': (int,), + '_preload_content': (bool,), + '_request_timeout': (none_type, int, (int,), [int]), + '_return_http_data_only': (bool,), + '_check_input_type': (bool,), + '_check_return_type': (bool,) + } + self.openapi_types.update(extra_types) self.attribute_map = root_map['attribute_map'] self.location_map = root_map['location_map'] self.collection_format_map = root_map['collection_format_map'] @@ -182,8 +230,7 @@ def __validate_inputs(self, kwargs): check_allowed_values( self.allowed_values, (param,), - kwargs[param], - self.validations + kwargs[param] ) for param in self.params_map['validation']: @@ -194,6 +241,20 @@ def __validate_inputs(self, kwargs): kwargs[param] ) + if kwargs['_check_input_type'] is False: + return + + for key, value in six.iteritems(kwargs): + fixed_val = validate_and_convert_types( + value, + self.openapi_types[key], + [key], + False, + kwargs['_check_input_type'], + configuration=self.api_client.configuration + ) + kwargs[key] = fixed_val + def __gather_params(self, kwargs): params = { 'body': None, @@ -213,8 +274,9 @@ def __gather_params(self, kwargs): continue base_name = self.attribute_map[param_name] if (param_location == 'form' and - self.openapi_types[param_name] == 'file'): + self.openapi_types[param_name] == (file_type,)): param_location = 'file' + params[param_location][param_name] = param_value elif param_location in {'form', 'query'}: param_value_full = (base_name, param_value) params[param_location].append(param_value_full) @@ -239,20 +301,15 @@ def __call__(self, *args, **kwargs): def call_with_http_info(self, **kwargs): - if kwargs.get('_host_index') and self.settings['servers']: - _host_index = kwargs.get('_host_index') - try: - _host = self.settings['servers'][_host_index] - except IndexError: + try: + _host = self.settings['servers'][kwargs['_host_index']] + except IndexError: + if self.settings['servers']: raise ApiValueError( "Invalid host index. Must be 0 <= index < %s" % len(self.settings['servers']) ) - else: - try: - _host = self.settings['servers'][0] - except IndexError: - _host = None + _host = None for key, value in six.iteritems(kwargs): if key not in self.params_map['all']: @@ -261,7 +318,11 @@ def call_with_http_info(self, **kwargs): " to method `%s`" % (key, self.settings['operation_id']) ) - if key not in self.params_map['nullable'] and value is None: + # only throw this nullable ApiValueError if _check_input_type + # is False, if _check_input_type==True we catch this case + # in self.__validate_inputs + if (key not in self.params_map['nullable'] and value is None + and kwargs['_check_input_type'] is False): raise ApiValueError( "Value may not be None for non-nullable parameter `%s`" " when calling `%s`" % @@ -300,9 +361,10 @@ def call_with_http_info(self, **kwargs): files=params['file'], response_type=self.settings['response_type'], auth_settings=self.settings['auth'], - async_req=kwargs.get('async_req'), - _return_http_data_only=kwargs.get('_return_http_data_only'), - _preload_content=kwargs.get('_preload_content', True), - _request_timeout=kwargs.get('_request_timeout'), + async_req=kwargs['async_req'], + _check_type=kwargs['_check_return_type'], + _return_http_data_only=kwargs['_return_http_data_only'], + _preload_content=kwargs['_preload_content'], + _request_timeout=kwargs['_request_timeout'], _host=_host, collection_formats=params['collection_format']) diff --git a/samples/client/petstore/python-experimental/petstore_api/api/fake_api.py b/samples/client/petstore/python-experimental/petstore_api/api/fake_api.py index 4b41defbc5a8..cb839e5817b5 100644 --- a/samples/client/petstore/python-experimental/petstore_api/api/fake_api.py +++ b/samples/client/petstore/python-experimental/petstore_api/api/fake_api.py @@ -22,10 +22,24 @@ ApiTypeError, ApiValueError ) -from petstore_api.model_utils import ( +from petstore_api.model_utils import ( # noqa: F401 check_allowed_values, - check_validations + check_validations, + date, + datetime, + file_type, + int, + none_type, + str, + validate_and_convert_types ) +from petstore_api.models.client import Client +from petstore_api.models.file_schema_test_class import FileSchemaTestClass +from petstore_api.models.outer_composite import OuterComposite +from petstore_api.models.outer_enum import OuterEnum +from petstore_api.models.outer_number import OuterNumber +from petstore_api.models.user import User +from petstore_api.models.xml_item import XmlItem class FakeApi(object): @@ -50,22 +64,49 @@ def __create_xml_item(self, xml_item, **kwargs): # noqa: E501 >>> result = thread.get() :param async_req bool: execute request asynchronously + Default is False. :param XmlItem xml_item: XmlItem Body (required) :param _return_http_data_only: response data without head status - code and headers + code and headers. Default is True. :param _preload_content: if False, the urllib3.HTTPResponse object will be returned without reading/decoding response data. Default is True. :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. + Default is None. + :param _check_input_type: boolean specifying if type checking + should be done one the data sent to the server. + Default is True. + :param _check_return_type: boolean specifying if type checking + should be done one the data received from the server. + Default is True. + :param _host_index: integer specifying the index of the server + that we want to use. + Default is 0. :return: None 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', 0) kwargs['xml_item'] = xml_item return self.call_with_http_info(**kwargs) @@ -98,7 +139,7 @@ def __create_xml_item(self, xml_item, **kwargs): # noqa: E501 'allowed_values': { }, 'openapi_types': { - 'xml_item': 'XmlItem', + 'xml_item': (XmlItem,), }, 'attribute_map': { }, @@ -133,27 +174,54 @@ def __fake_outer_boolean_serialize(self, **kwargs): # noqa: E501 >>> result = thread.get() :param async_req bool: execute request asynchronously + Default is False. :param bool body: Input boolean as post body :param _return_http_data_only: response data without head status - code and headers + code and headers. Default is True. :param _preload_content: if False, the urllib3.HTTPResponse object will be returned without reading/decoding response data. Default is True. :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. + Default is None. + :param _check_input_type: boolean specifying if type checking + should be done one the data sent to the server. + Default is True. + :param _check_return_type: boolean specifying if type checking + should be done one the data received from the server. + Default is True. + :param _host_index: integer specifying the index of the server + that we want to use. + Default is 0. :return: bool 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', 0) return self.call_with_http_info(**kwargs) self.fake_outer_boolean_serialize = Endpoint( settings={ - 'response_type': 'bool', + 'response_type': (bool,), 'auth': [], 'endpoint_path': '/fake/outer/boolean', 'operation_id': 'fake_outer_boolean_serialize', @@ -178,7 +246,7 @@ def __fake_outer_boolean_serialize(self, **kwargs): # noqa: E501 'allowed_values': { }, 'openapi_types': { - 'body': 'bool', + 'body': (bool,), }, 'attribute_map': { }, @@ -208,27 +276,54 @@ def __fake_outer_composite_serialize(self, **kwargs): # noqa: E501 >>> result = thread.get() :param async_req bool: execute request asynchronously + Default is False. :param OuterComposite body: Input composite as post body :param _return_http_data_only: response data without head status - code and headers + code and headers. Default is True. :param _preload_content: if False, the urllib3.HTTPResponse object will be returned without reading/decoding response data. Default is True. :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. + Default is None. + :param _check_input_type: boolean specifying if type checking + should be done one the data sent to the server. + Default is True. + :param _check_return_type: boolean specifying if type checking + should be done one the data received from the server. + Default is True. + :param _host_index: integer specifying the index of the server + that we want to use. + Default is 0. :return: OuterComposite 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', 0) return self.call_with_http_info(**kwargs) self.fake_outer_composite_serialize = Endpoint( settings={ - 'response_type': 'OuterComposite', + 'response_type': (OuterComposite,), 'auth': [], 'endpoint_path': '/fake/outer/composite', 'operation_id': 'fake_outer_composite_serialize', @@ -253,7 +348,7 @@ def __fake_outer_composite_serialize(self, **kwargs): # noqa: E501 'allowed_values': { }, 'openapi_types': { - 'body': 'OuterComposite', + 'body': (OuterComposite,), }, 'attribute_map': { }, @@ -283,27 +378,54 @@ def __fake_outer_enum_serialize(self, **kwargs): # noqa: E501 >>> result = thread.get() :param async_req bool: execute request asynchronously + Default is False. :param OuterEnum body: Input enum as post body :param _return_http_data_only: response data without head status - code and headers + code and headers. Default is True. :param _preload_content: if False, the urllib3.HTTPResponse object will be returned without reading/decoding response data. Default is True. :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. + Default is None. + :param _check_input_type: boolean specifying if type checking + should be done one the data sent to the server. + Default is True. + :param _check_return_type: boolean specifying if type checking + should be done one the data received from the server. + Default is True. + :param _host_index: integer specifying the index of the server + that we want to use. + Default is 0. :return: OuterEnum 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', 0) return self.call_with_http_info(**kwargs) self.fake_outer_enum_serialize = Endpoint( settings={ - 'response_type': 'OuterEnum', + 'response_type': (OuterEnum,), 'auth': [], 'endpoint_path': '/fake/outer/enum', 'operation_id': 'fake_outer_enum_serialize', @@ -328,7 +450,7 @@ def __fake_outer_enum_serialize(self, **kwargs): # noqa: E501 'allowed_values': { }, 'openapi_types': { - 'body': 'OuterEnum', + 'body': (OuterEnum,), }, 'attribute_map': { }, @@ -358,27 +480,54 @@ def __fake_outer_number_serialize(self, **kwargs): # noqa: E501 >>> result = thread.get() :param async_req bool: execute request asynchronously + Default is False. :param OuterNumber body: Input number as post body :param _return_http_data_only: response data without head status - code and headers + code and headers. Default is True. :param _preload_content: if False, the urllib3.HTTPResponse object will be returned without reading/decoding response data. Default is True. :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. + Default is None. + :param _check_input_type: boolean specifying if type checking + should be done one the data sent to the server. + Default is True. + :param _check_return_type: boolean specifying if type checking + should be done one the data received from the server. + Default is True. + :param _host_index: integer specifying the index of the server + that we want to use. + Default is 0. :return: OuterNumber 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', 0) return self.call_with_http_info(**kwargs) self.fake_outer_number_serialize = Endpoint( settings={ - 'response_type': 'OuterNumber', + 'response_type': (OuterNumber,), 'auth': [], 'endpoint_path': '/fake/outer/number', 'operation_id': 'fake_outer_number_serialize', @@ -403,7 +552,7 @@ def __fake_outer_number_serialize(self, **kwargs): # noqa: E501 'allowed_values': { }, 'openapi_types': { - 'body': 'OuterNumber', + 'body': (OuterNumber,), }, 'attribute_map': { }, @@ -433,27 +582,54 @@ def __fake_outer_string_serialize(self, **kwargs): # noqa: E501 >>> result = thread.get() :param async_req bool: execute request asynchronously + Default is False. :param str body: Input string as post body :param _return_http_data_only: response data without head status - code and headers + code and headers. Default is True. :param _preload_content: if False, the urllib3.HTTPResponse object will be returned without reading/decoding response data. Default is True. :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. + Default is None. + :param _check_input_type: boolean specifying if type checking + should be done one the data sent to the server. + Default is True. + :param _check_return_type: boolean specifying if type checking + should be done one the data received from the server. + Default is True. + :param _host_index: integer specifying the index of the server + that we want to use. + Default is 0. :return: str 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', 0) return self.call_with_http_info(**kwargs) self.fake_outer_string_serialize = Endpoint( settings={ - 'response_type': 'str', + 'response_type': (str,), 'auth': [], 'endpoint_path': '/fake/outer/string', 'operation_id': 'fake_outer_string_serialize', @@ -478,7 +654,7 @@ def __fake_outer_string_serialize(self, **kwargs): # noqa: E501 'allowed_values': { }, 'openapi_types': { - 'body': 'str', + 'body': (str,), }, 'attribute_map': { }, @@ -508,22 +684,49 @@ def __test_body_with_file_schema(self, body, **kwargs): # noqa: E501 >>> result = thread.get() :param async_req bool: execute request asynchronously + Default is False. :param FileSchemaTestClass body: (required) :param _return_http_data_only: response data without head status - code and headers + code and headers. Default is True. :param _preload_content: if False, the urllib3.HTTPResponse object will be returned without reading/decoding response data. Default is True. :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. + Default is None. + :param _check_input_type: boolean specifying if type checking + should be done one the data sent to the server. + Default is True. + :param _check_return_type: boolean specifying if type checking + should be done one the data received from the server. + Default is True. + :param _host_index: integer specifying the index of the server + that we want to use. + Default is 0. :return: None 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', 0) kwargs['body'] = body return self.call_with_http_info(**kwargs) @@ -556,7 +759,7 @@ def __test_body_with_file_schema(self, body, **kwargs): # noqa: E501 'allowed_values': { }, 'openapi_types': { - 'body': 'FileSchemaTestClass', + 'body': (FileSchemaTestClass,), }, 'attribute_map': { }, @@ -585,23 +788,50 @@ def __test_body_with_query_params(self, query, body, **kwargs): # noqa: E501 >>> result = thread.get() :param async_req bool: execute request asynchronously + Default is False. :param str query: (required) :param User body: (required) :param _return_http_data_only: response data without head status - code and headers + code and headers. Default is True. :param _preload_content: if False, the urllib3.HTTPResponse object will be returned without reading/decoding response data. Default is True. :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. + Default is None. + :param _check_input_type: boolean specifying if type checking + should be done one the data sent to the server. + Default is True. + :param _check_return_type: boolean specifying if type checking + should be done one the data received from the server. + Default is True. + :param _host_index: integer specifying the index of the server + that we want to use. + Default is 0. :return: None 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', 0) kwargs['query'] = query kwargs['body'] = body return self.call_with_http_info(**kwargs) @@ -637,8 +867,8 @@ def __test_body_with_query_params(self, query, body, **kwargs): # noqa: E501 'allowed_values': { }, 'openapi_types': { - 'query': 'str', - 'body': 'User', + 'query': (str,), + 'body': (User,), }, 'attribute_map': { 'query': 'query', @@ -670,28 +900,55 @@ def __test_client_model(self, body, **kwargs): # noqa: E501 >>> result = thread.get() :param async_req bool: execute request asynchronously + Default is False. :param Client body: client model (required) :param _return_http_data_only: response data without head status - code and headers + code and headers. Default is True. :param _preload_content: if False, the urllib3.HTTPResponse object will be returned without reading/decoding response data. Default is True. :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. + Default is None. + :param _check_input_type: boolean specifying if type checking + should be done one the data sent to the server. + Default is True. + :param _check_return_type: boolean specifying if type checking + should be done one the data received from the server. + Default is True. + :param _host_index: integer specifying the index of the server + that we want to use. + Default is 0. :return: Client 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', 0) kwargs['body'] = body return self.call_with_http_info(**kwargs) self.test_client_model = Endpoint( settings={ - 'response_type': 'Client', + 'response_type': (Client,), 'auth': [], 'endpoint_path': '/fake', 'operation_id': 'test_client_model', @@ -718,7 +975,7 @@ def __test_client_model(self, body, **kwargs): # noqa: E501 'allowed_values': { }, 'openapi_types': { - 'body': 'Client', + 'body': (Client,), }, 'attribute_map': { }, @@ -750,26 +1007,53 @@ def __test_endpoint_enums_length_one(self, query_integer, query_string, path_str >>> result = thread.get() :param async_req bool: execute request asynchronously + Default is False. :param int query_integer: (required) :param str query_string: (required) :param str path_string: (required) :param int path_integer: (required) :param float header_number: (required) :param _return_http_data_only: response data without head status - code and headers + code and headers. Default is True. :param _preload_content: if False, the urllib3.HTTPResponse object will be returned without reading/decoding response data. Default is True. :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. + Default is None. + :param _check_input_type: boolean specifying if type checking + should be done one the data sent to the server. + Default is True. + :param _check_return_type: boolean specifying if type checking + should be done one the data received from the server. + Default is True. + :param _host_index: integer specifying the index of the server + that we want to use. + Default is 0. :return: None 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', 0) kwargs['query_integer'] = query_integer kwargs['query_string'] = query_string kwargs['path_string'] = path_string @@ -839,11 +1123,11 @@ def __test_endpoint_enums_length_one(self, query_integer, query_string, path_str }, }, 'openapi_types': { - 'query_integer': 'int', - 'query_string': 'str', - 'path_string': 'str', - 'path_integer': 'int', - 'header_number': 'float', + 'query_integer': (int,), + 'query_string': (str,), + 'path_string': (str,), + 'path_integer': (int,), + 'header_number': (float,), }, 'attribute_map': { 'query_integer': 'query_integer', @@ -880,6 +1164,7 @@ def __test_endpoint_parameters(self, number, double, pattern_without_delimiter, >>> result = thread.get() :param async_req bool: execute request asynchronously + Default is False. :param float number: None (required) :param float double: None (required) :param str pattern_without_delimiter: None (required) @@ -889,26 +1174,52 @@ def __test_endpoint_parameters(self, number, double, pattern_without_delimiter, :param int int64: None :param float float: None :param str string: None - :param file binary: None + :param file_type binary: None :param date date: None :param datetime date_time: None :param str password: None :param str param_callback: None :param _return_http_data_only: response data without head status - code and headers + code and headers. Default is True. :param _preload_content: if False, the urllib3.HTTPResponse object will be returned without reading/decoding response data. Default is True. :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. + Default is None. + :param _check_input_type: boolean specifying if type checking + should be done one the data sent to the server. + Default is True. + :param _check_return_type: boolean specifying if type checking + should be done one the data received from the server. + Default is True. + :param _host_index: integer specifying the index of the server + that we want to use. + Default is 0. :return: None 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', 0) kwargs['number'] = number kwargs['double'] = double kwargs['pattern_without_delimiter'] = pattern_without_delimiter @@ -1011,20 +1322,20 @@ def __test_endpoint_parameters(self, number, double, pattern_without_delimiter, 'allowed_values': { }, 'openapi_types': { - 'number': 'float', - 'double': 'float', - 'pattern_without_delimiter': 'str', - 'byte': 'str', - 'integer': 'int', - 'int32': 'int', - 'int64': 'int', - 'float': 'float', - 'string': 'str', - 'binary': 'file', - 'date': 'date', - 'date_time': 'datetime', - 'password': 'str', - 'param_callback': 'str', + 'number': (float,), + 'double': (float,), + 'pattern_without_delimiter': (str,), + 'byte': (str,), + 'integer': (int,), + 'int32': (int,), + 'int64': (int,), + 'float': (float,), + 'string': (str,), + 'binary': (file_type,), + 'date': (date,), + 'date_time': (datetime,), + 'password': (str,), + 'param_callback': (str,), }, 'attribute_map': { 'number': 'number', @@ -1081,29 +1392,56 @@ def __test_enum_parameters(self, **kwargs): # noqa: E501 >>> result = thread.get() :param async_req bool: execute request asynchronously - :param list[str] enum_header_string_array: Header parameter enum test (string array) + Default is False. + :param [str] enum_header_string_array: Header parameter enum test (string array) :param str enum_header_string: Header parameter enum test (string) - :param list[str] enum_query_string_array: Query parameter enum test (string array) + :param [str] enum_query_string_array: Query parameter enum test (string array) :param str enum_query_string: Query parameter enum test (string) :param int enum_query_integer: Query parameter enum test (double) :param float enum_query_double: Query parameter enum test (double) - :param list[str] enum_form_string_array: Form parameter enum test (string array) + :param [str] enum_form_string_array: Form parameter enum test (string array) :param str enum_form_string: Form parameter enum test (string) :param _return_http_data_only: response data without head status - code and headers + code and headers. Default is True. :param _preload_content: if False, the urllib3.HTTPResponse object will be returned without reading/decoding response data. Default is True. :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. + Default is None. + :param _check_input_type: boolean specifying if type checking + should be done one the data sent to the server. + Default is True. + :param _check_return_type: boolean specifying if type checking + should be done one the data received from the server. + Default is True. + :param _host_index: integer specifying the index of the server + that we want to use. + Default is 0. :return: None 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', 0) return self.call_with_http_info(**kwargs) self.test_enum_parameters = Endpoint( @@ -1191,14 +1529,14 @@ def __test_enum_parameters(self, **kwargs): # noqa: E501 }, }, 'openapi_types': { - 'enum_header_string_array': 'list[str]', - 'enum_header_string': 'str', - 'enum_query_string_array': 'list[str]', - 'enum_query_string': 'str', - 'enum_query_integer': 'int', - 'enum_query_double': 'float', - 'enum_form_string_array': 'list[str]', - 'enum_form_string': 'str', + 'enum_header_string_array': ([str],), + 'enum_header_string': (str,), + 'enum_query_string_array': ([str],), + 'enum_query_string': (str,), + 'enum_query_integer': (int,), + 'enum_query_double': (float,), + 'enum_form_string_array': ([str],), + 'enum_form_string': (str,), }, 'attribute_map': { 'enum_header_string_array': 'enum_header_string_array', @@ -1246,6 +1584,7 @@ def __test_group_parameters(self, required_string_group, required_boolean_group, >>> result = thread.get() :param async_req bool: execute request asynchronously + Default is False. :param int required_string_group: Required String in group parameters (required) :param bool required_boolean_group: Required Boolean in group parameters (required) :param int required_int64_group: Required Integer in group parameters (required) @@ -1253,20 +1592,46 @@ def __test_group_parameters(self, required_string_group, required_boolean_group, :param bool boolean_group: Boolean in group parameters :param int int64_group: Integer in group parameters :param _return_http_data_only: response data without head status - code and headers + code and headers. Default is True. :param _preload_content: if False, the urllib3.HTTPResponse object will be returned without reading/decoding response data. Default is True. :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. + Default is None. + :param _check_input_type: boolean specifying if type checking + should be done one the data sent to the server. + Default is True. + :param _check_return_type: boolean specifying if type checking + should be done one the data received from the server. + Default is True. + :param _host_index: integer specifying the index of the server + that we want to use. + Default is 0. :return: None 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', 0) kwargs['required_string_group'] = required_string_group kwargs['required_boolean_group'] = required_boolean_group kwargs['required_int64_group'] = required_int64_group @@ -1308,12 +1673,12 @@ def __test_group_parameters(self, required_string_group, required_boolean_group, 'allowed_values': { }, 'openapi_types': { - 'required_string_group': 'int', - 'required_boolean_group': 'bool', - 'required_int64_group': 'int', - 'string_group': 'int', - 'boolean_group': 'bool', - 'int64_group': 'int', + 'required_string_group': (int,), + 'required_boolean_group': (bool,), + 'required_int64_group': (int,), + 'string_group': (int,), + 'boolean_group': (bool,), + 'int64_group': (int,), }, 'attribute_map': { 'required_string_group': 'required_string_group', @@ -1351,22 +1716,49 @@ def __test_inline_additional_properties(self, param, **kwargs): # noqa: E501 >>> result = thread.get() :param async_req bool: execute request asynchronously - :param dict(str, str) param: request body (required) + Default is False. + :param {str: (str,)} param: request body (required) :param _return_http_data_only: response data without head status - code and headers + code and headers. Default is True. :param _preload_content: if False, the urllib3.HTTPResponse object will be returned without reading/decoding response data. Default is True. :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. + Default is None. + :param _check_input_type: boolean specifying if type checking + should be done one the data sent to the server. + Default is True. + :param _check_return_type: boolean specifying if type checking + should be done one the data received from the server. + Default is True. + :param _host_index: integer specifying the index of the server + that we want to use. + Default is 0. :return: None 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', 0) kwargs['param'] = param return self.call_with_http_info(**kwargs) @@ -1399,7 +1791,7 @@ def __test_inline_additional_properties(self, param, **kwargs): # noqa: E501 'allowed_values': { }, 'openapi_types': { - 'param': 'dict(str, str)', + 'param': ({str: (str,)},), }, 'attribute_map': { }, @@ -1428,23 +1820,50 @@ def __test_json_form_data(self, param, param2, **kwargs): # noqa: E501 >>> result = thread.get() :param async_req bool: execute request asynchronously + Default is False. :param str param: field1 (required) :param str param2: field2 (required) :param _return_http_data_only: response data without head status - code and headers + code and headers. Default is True. :param _preload_content: if False, the urllib3.HTTPResponse object will be returned without reading/decoding response data. Default is True. :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. + Default is None. + :param _check_input_type: boolean specifying if type checking + should be done one the data sent to the server. + Default is True. + :param _check_return_type: boolean specifying if type checking + should be done one the data received from the server. + Default is True. + :param _host_index: integer specifying the index of the server + that we want to use. + Default is 0. :return: None 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', 0) kwargs['param'] = param kwargs['param2'] = param2 return self.call_with_http_info(**kwargs) @@ -1480,8 +1899,8 @@ def __test_json_form_data(self, param, param2, **kwargs): # noqa: E501 'allowed_values': { }, 'openapi_types': { - 'param': 'str', - 'param2': 'str', + 'param': (str,), + 'param2': (str,), }, 'attribute_map': { 'param': 'param', @@ -1512,7 +1931,7 @@ def __init__(self, settings=None, params_map=None, root_map=None, Args: settings (dict): see below key value pairs - 'response_type' (str): response type + 'response_type' (tuple/None): response type 'auth' (list): a list of auth type keys 'endpoint_path' (str): the endpoint path 'operation_id' (str): endpoint string identifier @@ -1548,11 +1967,24 @@ def __init__(self, settings=None, params_map=None, root_map=None, '_host_index', '_preload_content', '_request_timeout', - '_return_http_data_only' + '_return_http_data_only', + '_check_input_type', + '_check_return_type' ]) + self.params_map['nullable'].extend(['_request_timeout']) self.validations = root_map['validations'] self.allowed_values = root_map['allowed_values'] self.openapi_types = root_map['openapi_types'] + extra_types = { + 'async_req': (bool,), + '_host_index': (int,), + '_preload_content': (bool,), + '_request_timeout': (none_type, int, (int,), [int]), + '_return_http_data_only': (bool,), + '_check_input_type': (bool,), + '_check_return_type': (bool,) + } + self.openapi_types.update(extra_types) self.attribute_map = root_map['attribute_map'] self.location_map = root_map['location_map'] self.collection_format_map = root_map['collection_format_map'] @@ -1566,8 +1998,7 @@ def __validate_inputs(self, kwargs): check_allowed_values( self.allowed_values, (param,), - kwargs[param], - self.validations + kwargs[param] ) for param in self.params_map['validation']: @@ -1578,6 +2009,20 @@ def __validate_inputs(self, kwargs): kwargs[param] ) + if kwargs['_check_input_type'] is False: + return + + for key, value in six.iteritems(kwargs): + fixed_val = validate_and_convert_types( + value, + self.openapi_types[key], + [key], + False, + kwargs['_check_input_type'], + configuration=self.api_client.configuration + ) + kwargs[key] = fixed_val + def __gather_params(self, kwargs): params = { 'body': None, @@ -1597,8 +2042,9 @@ def __gather_params(self, kwargs): continue base_name = self.attribute_map[param_name] if (param_location == 'form' and - self.openapi_types[param_name] == 'file'): + self.openapi_types[param_name] == (file_type,)): param_location = 'file' + params[param_location][param_name] = param_value elif param_location in {'form', 'query'}: param_value_full = (base_name, param_value) params[param_location].append(param_value_full) @@ -1623,20 +2069,15 @@ def __call__(self, *args, **kwargs): def call_with_http_info(self, **kwargs): - if kwargs.get('_host_index') and self.settings['servers']: - _host_index = kwargs.get('_host_index') - try: - _host = self.settings['servers'][_host_index] - except IndexError: + try: + _host = self.settings['servers'][kwargs['_host_index']] + except IndexError: + if self.settings['servers']: raise ApiValueError( "Invalid host index. Must be 0 <= index < %s" % len(self.settings['servers']) ) - else: - try: - _host = self.settings['servers'][0] - except IndexError: - _host = None + _host = None for key, value in six.iteritems(kwargs): if key not in self.params_map['all']: @@ -1645,7 +2086,11 @@ def call_with_http_info(self, **kwargs): " to method `%s`" % (key, self.settings['operation_id']) ) - if key not in self.params_map['nullable'] and value is None: + # only throw this nullable ApiValueError if _check_input_type + # is False, if _check_input_type==True we catch this case + # in self.__validate_inputs + if (key not in self.params_map['nullable'] and value is None + and kwargs['_check_input_type'] is False): raise ApiValueError( "Value may not be None for non-nullable parameter `%s`" " when calling `%s`" % @@ -1684,9 +2129,10 @@ def call_with_http_info(self, **kwargs): files=params['file'], response_type=self.settings['response_type'], auth_settings=self.settings['auth'], - async_req=kwargs.get('async_req'), - _return_http_data_only=kwargs.get('_return_http_data_only'), - _preload_content=kwargs.get('_preload_content', True), - _request_timeout=kwargs.get('_request_timeout'), + async_req=kwargs['async_req'], + _check_type=kwargs['_check_return_type'], + _return_http_data_only=kwargs['_return_http_data_only'], + _preload_content=kwargs['_preload_content'], + _request_timeout=kwargs['_request_timeout'], _host=_host, collection_formats=params['collection_format']) diff --git a/samples/client/petstore/python-experimental/petstore_api/api/fake_classname_tags_123_api.py b/samples/client/petstore/python-experimental/petstore_api/api/fake_classname_tags_123_api.py index 6811a990bbcc..8bb447b34edc 100644 --- a/samples/client/petstore/python-experimental/petstore_api/api/fake_classname_tags_123_api.py +++ b/samples/client/petstore/python-experimental/petstore_api/api/fake_classname_tags_123_api.py @@ -22,10 +22,18 @@ ApiTypeError, ApiValueError ) -from petstore_api.model_utils import ( +from petstore_api.model_utils import ( # noqa: F401 check_allowed_values, - check_validations + check_validations, + date, + datetime, + file_type, + int, + none_type, + str, + validate_and_convert_types ) +from petstore_api.models.client import Client class FakeClassnameTags123Api(object): @@ -50,28 +58,55 @@ def __test_classname(self, body, **kwargs): # noqa: E501 >>> result = thread.get() :param async_req bool: execute request asynchronously + Default is False. :param Client body: client model (required) :param _return_http_data_only: response data without head status - code and headers + code and headers. Default is True. :param _preload_content: if False, the urllib3.HTTPResponse object will be returned without reading/decoding response data. Default is True. :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. + Default is None. + :param _check_input_type: boolean specifying if type checking + should be done one the data sent to the server. + Default is True. + :param _check_return_type: boolean specifying if type checking + should be done one the data received from the server. + Default is True. + :param _host_index: integer specifying the index of the server + that we want to use. + Default is 0. :return: Client 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', 0) kwargs['body'] = body return self.call_with_http_info(**kwargs) self.test_classname = Endpoint( settings={ - 'response_type': 'Client', + 'response_type': (Client,), 'auth': [ 'api_key_query' ], @@ -100,7 +135,7 @@ def __test_classname(self, body, **kwargs): # noqa: E501 'allowed_values': { }, 'openapi_types': { - 'body': 'Client', + 'body': (Client,), }, 'attribute_map': { }, @@ -130,7 +165,7 @@ def __init__(self, settings=None, params_map=None, root_map=None, Args: settings (dict): see below key value pairs - 'response_type' (str): response type + 'response_type' (tuple/None): response type 'auth' (list): a list of auth type keys 'endpoint_path' (str): the endpoint path 'operation_id' (str): endpoint string identifier @@ -166,11 +201,24 @@ def __init__(self, settings=None, params_map=None, root_map=None, '_host_index', '_preload_content', '_request_timeout', - '_return_http_data_only' + '_return_http_data_only', + '_check_input_type', + '_check_return_type' ]) + self.params_map['nullable'].extend(['_request_timeout']) self.validations = root_map['validations'] self.allowed_values = root_map['allowed_values'] self.openapi_types = root_map['openapi_types'] + extra_types = { + 'async_req': (bool,), + '_host_index': (int,), + '_preload_content': (bool,), + '_request_timeout': (none_type, int, (int,), [int]), + '_return_http_data_only': (bool,), + '_check_input_type': (bool,), + '_check_return_type': (bool,) + } + self.openapi_types.update(extra_types) self.attribute_map = root_map['attribute_map'] self.location_map = root_map['location_map'] self.collection_format_map = root_map['collection_format_map'] @@ -184,8 +232,7 @@ def __validate_inputs(self, kwargs): check_allowed_values( self.allowed_values, (param,), - kwargs[param], - self.validations + kwargs[param] ) for param in self.params_map['validation']: @@ -196,6 +243,20 @@ def __validate_inputs(self, kwargs): kwargs[param] ) + if kwargs['_check_input_type'] is False: + return + + for key, value in six.iteritems(kwargs): + fixed_val = validate_and_convert_types( + value, + self.openapi_types[key], + [key], + False, + kwargs['_check_input_type'], + configuration=self.api_client.configuration + ) + kwargs[key] = fixed_val + def __gather_params(self, kwargs): params = { 'body': None, @@ -215,8 +276,9 @@ def __gather_params(self, kwargs): continue base_name = self.attribute_map[param_name] if (param_location == 'form' and - self.openapi_types[param_name] == 'file'): + self.openapi_types[param_name] == (file_type,)): param_location = 'file' + params[param_location][param_name] = param_value elif param_location in {'form', 'query'}: param_value_full = (base_name, param_value) params[param_location].append(param_value_full) @@ -241,20 +303,15 @@ def __call__(self, *args, **kwargs): def call_with_http_info(self, **kwargs): - if kwargs.get('_host_index') and self.settings['servers']: - _host_index = kwargs.get('_host_index') - try: - _host = self.settings['servers'][_host_index] - except IndexError: + try: + _host = self.settings['servers'][kwargs['_host_index']] + except IndexError: + if self.settings['servers']: raise ApiValueError( "Invalid host index. Must be 0 <= index < %s" % len(self.settings['servers']) ) - else: - try: - _host = self.settings['servers'][0] - except IndexError: - _host = None + _host = None for key, value in six.iteritems(kwargs): if key not in self.params_map['all']: @@ -263,7 +320,11 @@ def call_with_http_info(self, **kwargs): " to method `%s`" % (key, self.settings['operation_id']) ) - if key not in self.params_map['nullable'] and value is None: + # only throw this nullable ApiValueError if _check_input_type + # is False, if _check_input_type==True we catch this case + # in self.__validate_inputs + if (key not in self.params_map['nullable'] and value is None + and kwargs['_check_input_type'] is False): raise ApiValueError( "Value may not be None for non-nullable parameter `%s`" " when calling `%s`" % @@ -302,9 +363,10 @@ def call_with_http_info(self, **kwargs): files=params['file'], response_type=self.settings['response_type'], auth_settings=self.settings['auth'], - async_req=kwargs.get('async_req'), - _return_http_data_only=kwargs.get('_return_http_data_only'), - _preload_content=kwargs.get('_preload_content', True), - _request_timeout=kwargs.get('_request_timeout'), + async_req=kwargs['async_req'], + _check_type=kwargs['_check_return_type'], + _return_http_data_only=kwargs['_return_http_data_only'], + _preload_content=kwargs['_preload_content'], + _request_timeout=kwargs['_request_timeout'], _host=_host, collection_formats=params['collection_format']) diff --git a/samples/client/petstore/python-experimental/petstore_api/api/pet_api.py b/samples/client/petstore/python-experimental/petstore_api/api/pet_api.py index 29bbead6c35a..41a0a329ea9a 100644 --- a/samples/client/petstore/python-experimental/petstore_api/api/pet_api.py +++ b/samples/client/petstore/python-experimental/petstore_api/api/pet_api.py @@ -22,10 +22,19 @@ ApiTypeError, ApiValueError ) -from petstore_api.model_utils import ( +from petstore_api.model_utils import ( # noqa: F401 check_allowed_values, - check_validations + check_validations, + date, + datetime, + file_type, + int, + none_type, + str, + validate_and_convert_types ) +from petstore_api.models.api_response import ApiResponse +from petstore_api.models.pet import Pet class PetApi(object): @@ -49,22 +58,49 @@ def __add_pet(self, body, **kwargs): # noqa: E501 >>> result = thread.get() :param async_req bool: execute request asynchronously + Default is False. :param Pet body: Pet object that needs to be added to the store (required) :param _return_http_data_only: response data without head status - code and headers + code and headers. Default is True. :param _preload_content: if False, the urllib3.HTTPResponse object will be returned without reading/decoding response data. Default is True. :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. + Default is None. + :param _check_input_type: boolean specifying if type checking + should be done one the data sent to the server. + Default is True. + :param _check_return_type: boolean specifying if type checking + should be done one the data received from the server. + Default is True. + :param _host_index: integer specifying the index of the server + that we want to use. + Default is 0. :return: None 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', 0) kwargs['body'] = body return self.call_with_http_info(**kwargs) @@ -99,7 +135,7 @@ def __add_pet(self, body, **kwargs): # noqa: E501 'allowed_values': { }, 'openapi_types': { - 'body': 'Pet', + 'body': (Pet,), }, 'attribute_map': { }, @@ -129,23 +165,50 @@ def __delete_pet(self, pet_id, **kwargs): # noqa: E501 >>> result = thread.get() :param async_req bool: execute request asynchronously + Default is False. :param int pet_id: Pet id to delete (required) :param str api_key: :param _return_http_data_only: response data without head status - code and headers + code and headers. Default is True. :param _preload_content: if False, the urllib3.HTTPResponse object will be returned without reading/decoding response data. Default is True. :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. + Default is None. + :param _check_input_type: boolean specifying if type checking + should be done one the data sent to the server. + Default is True. + :param _check_return_type: boolean specifying if type checking + should be done one the data received from the server. + Default is True. + :param _host_index: integer specifying the index of the server + that we want to use. + Default is 0. :return: None 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', 0) kwargs['pet_id'] = pet_id return self.call_with_http_info(**kwargs) @@ -181,8 +244,8 @@ def __delete_pet(self, pet_id, **kwargs): # noqa: E501 'allowed_values': { }, 'openapi_types': { - 'pet_id': 'int', - 'api_key': 'str', + 'pet_id': (int,), + 'api_key': (str,), }, 'attribute_map': { 'pet_id': 'petId', @@ -213,28 +276,55 @@ def __find_pets_by_status(self, status, **kwargs): # noqa: E501 >>> result = thread.get() :param async_req bool: execute request asynchronously - :param list[str] status: Status values that need to be considered for filter (required) + Default is False. + :param [str] status: Status values that need to be considered for filter (required) :param _return_http_data_only: response data without head status - code and headers + code and headers. Default is True. :param _preload_content: if False, the urllib3.HTTPResponse object will be returned without reading/decoding response data. Default is True. :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: list[Pet] + Default is None. + :param _check_input_type: boolean specifying if type checking + should be done one the data sent to the server. + Default is True. + :param _check_return_type: boolean specifying if type checking + should be done one the data received from the server. + Default is True. + :param _host_index: integer specifying the index of the server + that we want to use. + Default is 0. + :return: [Pet] 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', 0) kwargs['status'] = status return self.call_with_http_info(**kwargs) self.find_pets_by_status = Endpoint( settings={ - 'response_type': 'list[Pet]', + 'response_type': ([Pet],), 'auth': [ 'petstore_auth' ], @@ -270,7 +360,7 @@ def __find_pets_by_status(self, status, **kwargs): # noqa: E501 }, }, 'openapi_types': { - 'status': 'list[str]', + 'status': ([str],), }, 'attribute_map': { 'status': 'status', @@ -303,28 +393,55 @@ def __find_pets_by_tags(self, tags, **kwargs): # noqa: E501 >>> result = thread.get() :param async_req bool: execute request asynchronously - :param list[str] tags: Tags to filter by (required) + Default is False. + :param [str] tags: Tags to filter by (required) :param _return_http_data_only: response data without head status - code and headers + code and headers. Default is True. :param _preload_content: if False, the urllib3.HTTPResponse object will be returned without reading/decoding response data. Default is True. :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: list[Pet] + Default is None. + :param _check_input_type: boolean specifying if type checking + should be done one the data sent to the server. + Default is True. + :param _check_return_type: boolean specifying if type checking + should be done one the data received from the server. + Default is True. + :param _host_index: integer specifying the index of the server + that we want to use. + Default is 0. + :return: [Pet] 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', 0) kwargs['tags'] = tags return self.call_with_http_info(**kwargs) self.find_pets_by_tags = Endpoint( settings={ - 'response_type': 'list[Pet]', + 'response_type': ([Pet],), 'auth': [ 'petstore_auth' ], @@ -353,7 +470,7 @@ def __find_pets_by_tags(self, tags, **kwargs): # noqa: E501 'allowed_values': { }, 'openapi_types': { - 'tags': 'list[str]', + 'tags': ([str],), }, 'attribute_map': { 'tags': 'tags', @@ -386,28 +503,55 @@ def __get_pet_by_id(self, pet_id, **kwargs): # noqa: E501 >>> result = thread.get() :param async_req bool: execute request asynchronously + Default is False. :param int pet_id: ID of pet to return (required) :param _return_http_data_only: response data without head status - code and headers + code and headers. Default is True. :param _preload_content: if False, the urllib3.HTTPResponse object will be returned without reading/decoding response data. Default is True. :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. + Default is None. + :param _check_input_type: boolean specifying if type checking + should be done one the data sent to the server. + Default is True. + :param _check_return_type: boolean specifying if type checking + should be done one the data received from the server. + Default is True. + :param _host_index: integer specifying the index of the server + that we want to use. + Default is 0. :return: Pet 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', 0) kwargs['pet_id'] = pet_id return self.call_with_http_info(**kwargs) self.get_pet_by_id = Endpoint( settings={ - 'response_type': 'Pet', + 'response_type': (Pet,), 'auth': [ 'api_key' ], @@ -436,7 +580,7 @@ def __get_pet_by_id(self, pet_id, **kwargs): # noqa: E501 'allowed_values': { }, 'openapi_types': { - 'pet_id': 'int', + 'pet_id': (int,), }, 'attribute_map': { 'pet_id': 'petId', @@ -467,22 +611,49 @@ def __update_pet(self, body, **kwargs): # noqa: E501 >>> result = thread.get() :param async_req bool: execute request asynchronously + Default is False. :param Pet body: Pet object that needs to be added to the store (required) :param _return_http_data_only: response data without head status - code and headers + code and headers. Default is True. :param _preload_content: if False, the urllib3.HTTPResponse object will be returned without reading/decoding response data. Default is True. :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. + Default is None. + :param _check_input_type: boolean specifying if type checking + should be done one the data sent to the server. + Default is True. + :param _check_return_type: boolean specifying if type checking + should be done one the data received from the server. + Default is True. + :param _host_index: integer specifying the index of the server + that we want to use. + Default is 0. :return: None 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', 0) kwargs['body'] = body return self.call_with_http_info(**kwargs) @@ -517,7 +688,7 @@ def __update_pet(self, body, **kwargs): # noqa: E501 'allowed_values': { }, 'openapi_types': { - 'body': 'Pet', + 'body': (Pet,), }, 'attribute_map': { }, @@ -547,24 +718,51 @@ def __update_pet_with_form(self, pet_id, **kwargs): # noqa: E501 >>> result = thread.get() :param async_req bool: execute request asynchronously + Default is False. :param int pet_id: ID of pet that needs to be updated (required) :param str name: Updated name of the pet :param str status: Updated status of the pet :param _return_http_data_only: response data without head status - code and headers + code and headers. Default is True. :param _preload_content: if False, the urllib3.HTTPResponse object will be returned without reading/decoding response data. Default is True. :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. + Default is None. + :param _check_input_type: boolean specifying if type checking + should be done one the data sent to the server. + Default is True. + :param _check_return_type: boolean specifying if type checking + should be done one the data received from the server. + Default is True. + :param _host_index: integer specifying the index of the server + that we want to use. + Default is 0. :return: None 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', 0) kwargs['pet_id'] = pet_id return self.call_with_http_info(**kwargs) @@ -601,9 +799,9 @@ def __update_pet_with_form(self, pet_id, **kwargs): # noqa: E501 'allowed_values': { }, 'openapi_types': { - 'pet_id': 'int', - 'name': 'str', - 'status': 'str', + 'pet_id': (int,), + 'name': (str,), + 'status': (str,), }, 'attribute_map': { 'pet_id': 'petId', @@ -637,30 +835,57 @@ def __upload_file(self, pet_id, **kwargs): # noqa: E501 >>> result = thread.get() :param async_req bool: execute request asynchronously + Default is False. :param int pet_id: ID of pet to update (required) :param str additional_metadata: Additional data to pass to server - :param file file: file to upload + :param file_type file: file to upload :param _return_http_data_only: response data without head status - code and headers + code and headers. Default is True. :param _preload_content: if False, the urllib3.HTTPResponse object will be returned without reading/decoding response data. Default is True. :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. + Default is None. + :param _check_input_type: boolean specifying if type checking + should be done one the data sent to the server. + Default is True. + :param _check_return_type: boolean specifying if type checking + should be done one the data received from the server. + Default is True. + :param _host_index: integer specifying the index of the server + that we want to use. + Default is 0. :return: ApiResponse 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', 0) kwargs['pet_id'] = pet_id return self.call_with_http_info(**kwargs) self.upload_file = Endpoint( settings={ - 'response_type': 'ApiResponse', + 'response_type': (ApiResponse,), 'auth': [ 'petstore_auth' ], @@ -691,9 +916,9 @@ def __upload_file(self, pet_id, **kwargs): # noqa: E501 'allowed_values': { }, 'openapi_types': { - 'pet_id': 'int', - 'additional_metadata': 'str', - 'file': 'file', + 'pet_id': (int,), + 'additional_metadata': (str,), + 'file': (file_type,), }, 'attribute_map': { 'pet_id': 'petId', @@ -729,31 +954,58 @@ def __upload_file_with_required_file(self, pet_id, required_file, **kwargs): # >>> result = thread.get() :param async_req bool: execute request asynchronously + Default is False. :param int pet_id: ID of pet to update (required) - :param file required_file: file to upload (required) + :param file_type required_file: file to upload (required) :param str additional_metadata: Additional data to pass to server :param _return_http_data_only: response data without head status - code and headers + code and headers. Default is True. :param _preload_content: if False, the urllib3.HTTPResponse object will be returned without reading/decoding response data. Default is True. :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. + Default is None. + :param _check_input_type: boolean specifying if type checking + should be done one the data sent to the server. + Default is True. + :param _check_return_type: boolean specifying if type checking + should be done one the data received from the server. + Default is True. + :param _host_index: integer specifying the index of the server + that we want to use. + Default is 0. :return: ApiResponse 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', 0) kwargs['pet_id'] = pet_id kwargs['required_file'] = required_file return self.call_with_http_info(**kwargs) self.upload_file_with_required_file = Endpoint( settings={ - 'response_type': 'ApiResponse', + 'response_type': (ApiResponse,), 'auth': [ 'petstore_auth' ], @@ -785,9 +1037,9 @@ def __upload_file_with_required_file(self, pet_id, required_file, **kwargs): # 'allowed_values': { }, 'openapi_types': { - 'pet_id': 'int', - 'required_file': 'file', - 'additional_metadata': 'str', + 'pet_id': (int,), + 'required_file': (file_type,), + 'additional_metadata': (str,), }, 'attribute_map': { 'pet_id': 'petId', @@ -822,7 +1074,7 @@ def __init__(self, settings=None, params_map=None, root_map=None, Args: settings (dict): see below key value pairs - 'response_type' (str): response type + 'response_type' (tuple/None): response type 'auth' (list): a list of auth type keys 'endpoint_path' (str): the endpoint path 'operation_id' (str): endpoint string identifier @@ -858,11 +1110,24 @@ def __init__(self, settings=None, params_map=None, root_map=None, '_host_index', '_preload_content', '_request_timeout', - '_return_http_data_only' + '_return_http_data_only', + '_check_input_type', + '_check_return_type' ]) + self.params_map['nullable'].extend(['_request_timeout']) self.validations = root_map['validations'] self.allowed_values = root_map['allowed_values'] self.openapi_types = root_map['openapi_types'] + extra_types = { + 'async_req': (bool,), + '_host_index': (int,), + '_preload_content': (bool,), + '_request_timeout': (none_type, int, (int,), [int]), + '_return_http_data_only': (bool,), + '_check_input_type': (bool,), + '_check_return_type': (bool,) + } + self.openapi_types.update(extra_types) self.attribute_map = root_map['attribute_map'] self.location_map = root_map['location_map'] self.collection_format_map = root_map['collection_format_map'] @@ -876,8 +1141,7 @@ def __validate_inputs(self, kwargs): check_allowed_values( self.allowed_values, (param,), - kwargs[param], - self.validations + kwargs[param] ) for param in self.params_map['validation']: @@ -888,6 +1152,20 @@ def __validate_inputs(self, kwargs): kwargs[param] ) + if kwargs['_check_input_type'] is False: + return + + for key, value in six.iteritems(kwargs): + fixed_val = validate_and_convert_types( + value, + self.openapi_types[key], + [key], + False, + kwargs['_check_input_type'], + configuration=self.api_client.configuration + ) + kwargs[key] = fixed_val + def __gather_params(self, kwargs): params = { 'body': None, @@ -907,8 +1185,9 @@ def __gather_params(self, kwargs): continue base_name = self.attribute_map[param_name] if (param_location == 'form' and - self.openapi_types[param_name] == 'file'): + self.openapi_types[param_name] == (file_type,)): param_location = 'file' + params[param_location][param_name] = param_value elif param_location in {'form', 'query'}: param_value_full = (base_name, param_value) params[param_location].append(param_value_full) @@ -933,20 +1212,15 @@ def __call__(self, *args, **kwargs): def call_with_http_info(self, **kwargs): - if kwargs.get('_host_index') and self.settings['servers']: - _host_index = kwargs.get('_host_index') - try: - _host = self.settings['servers'][_host_index] - except IndexError: + try: + _host = self.settings['servers'][kwargs['_host_index']] + except IndexError: + if self.settings['servers']: raise ApiValueError( "Invalid host index. Must be 0 <= index < %s" % len(self.settings['servers']) ) - else: - try: - _host = self.settings['servers'][0] - except IndexError: - _host = None + _host = None for key, value in six.iteritems(kwargs): if key not in self.params_map['all']: @@ -955,7 +1229,11 @@ def call_with_http_info(self, **kwargs): " to method `%s`" % (key, self.settings['operation_id']) ) - if key not in self.params_map['nullable'] and value is None: + # only throw this nullable ApiValueError if _check_input_type + # is False, if _check_input_type==True we catch this case + # in self.__validate_inputs + if (key not in self.params_map['nullable'] and value is None + and kwargs['_check_input_type'] is False): raise ApiValueError( "Value may not be None for non-nullable parameter `%s`" " when calling `%s`" % @@ -994,9 +1272,10 @@ def call_with_http_info(self, **kwargs): files=params['file'], response_type=self.settings['response_type'], auth_settings=self.settings['auth'], - async_req=kwargs.get('async_req'), - _return_http_data_only=kwargs.get('_return_http_data_only'), - _preload_content=kwargs.get('_preload_content', True), - _request_timeout=kwargs.get('_request_timeout'), + async_req=kwargs['async_req'], + _check_type=kwargs['_check_return_type'], + _return_http_data_only=kwargs['_return_http_data_only'], + _preload_content=kwargs['_preload_content'], + _request_timeout=kwargs['_request_timeout'], _host=_host, collection_formats=params['collection_format']) diff --git a/samples/client/petstore/python-experimental/petstore_api/api/store_api.py b/samples/client/petstore/python-experimental/petstore_api/api/store_api.py index db3f4d2561df..18cc23735e1c 100644 --- a/samples/client/petstore/python-experimental/petstore_api/api/store_api.py +++ b/samples/client/petstore/python-experimental/petstore_api/api/store_api.py @@ -22,10 +22,18 @@ ApiTypeError, ApiValueError ) -from petstore_api.model_utils import ( +from petstore_api.model_utils import ( # noqa: F401 check_allowed_values, - check_validations + check_validations, + date, + datetime, + file_type, + int, + none_type, + str, + validate_and_convert_types ) +from petstore_api.models.order import Order class StoreApi(object): @@ -50,22 +58,49 @@ def __delete_order(self, order_id, **kwargs): # noqa: E501 >>> result = thread.get() :param async_req bool: execute request asynchronously + Default is False. :param str order_id: ID of the order that needs to be deleted (required) :param _return_http_data_only: response data without head status - code and headers + code and headers. Default is True. :param _preload_content: if False, the urllib3.HTTPResponse object will be returned without reading/decoding response data. Default is True. :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. + Default is None. + :param _check_input_type: boolean specifying if type checking + should be done one the data sent to the server. + Default is True. + :param _check_return_type: boolean specifying if type checking + should be done one the data received from the server. + Default is True. + :param _host_index: integer specifying the index of the server + that we want to use. + Default is 0. :return: None 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', 0) kwargs['order_id'] = order_id return self.call_with_http_info(**kwargs) @@ -98,7 +133,7 @@ def __delete_order(self, order_id, **kwargs): # noqa: E501 'allowed_values': { }, 'openapi_types': { - 'order_id': 'str', + 'order_id': (str,), }, 'attribute_map': { 'order_id': 'order_id', @@ -127,26 +162,53 @@ def __get_inventory(self, **kwargs): # noqa: E501 >>> result = thread.get() :param async_req bool: execute request asynchronously + Default is False. :param _return_http_data_only: response data without head status - code and headers + code and headers. Default is True. :param _preload_content: if False, the urllib3.HTTPResponse object will be returned without reading/decoding response data. Default is True. :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: dict(str, int) + Default is None. + :param _check_input_type: boolean specifying if type checking + should be done one the data sent to the server. + Default is True. + :param _check_return_type: boolean specifying if type checking + should be done one the data received from the server. + Default is True. + :param _host_index: integer specifying the index of the server + that we want to use. + Default is 0. + :return: {str: (int,)} 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', 0) return self.call_with_http_info(**kwargs) self.get_inventory = Endpoint( settings={ - 'response_type': 'dict(str, int)', + 'response_type': ({str: (int,)},), 'auth': [ 'api_key' ], @@ -200,28 +262,55 @@ def __get_order_by_id(self, order_id, **kwargs): # noqa: E501 >>> result = thread.get() :param async_req bool: execute request asynchronously + Default is False. :param int order_id: ID of pet that needs to be fetched (required) :param _return_http_data_only: response data without head status - code and headers + code and headers. Default is True. :param _preload_content: if False, the urllib3.HTTPResponse object will be returned without reading/decoding response data. Default is True. :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. + Default is None. + :param _check_input_type: boolean specifying if type checking + should be done one the data sent to the server. + Default is True. + :param _check_return_type: boolean specifying if type checking + should be done one the data received from the server. + Default is True. + :param _host_index: integer specifying the index of the server + that we want to use. + Default is 0. :return: Order 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', 0) kwargs['order_id'] = order_id return self.call_with_http_info(**kwargs) self.get_order_by_id = Endpoint( settings={ - 'response_type': 'Order', + 'response_type': (Order,), 'auth': [], 'endpoint_path': '/store/order/{order_id}', 'operation_id': 'get_order_by_id', @@ -254,7 +343,7 @@ def __get_order_by_id(self, order_id, **kwargs): # noqa: E501 'allowed_values': { }, 'openapi_types': { - 'order_id': 'int', + 'order_id': (int,), }, 'attribute_map': { 'order_id': 'order_id', @@ -285,28 +374,55 @@ def __place_order(self, body, **kwargs): # noqa: E501 >>> result = thread.get() :param async_req bool: execute request asynchronously + Default is False. :param Order body: order placed for purchasing the pet (required) :param _return_http_data_only: response data without head status - code and headers + code and headers. Default is True. :param _preload_content: if False, the urllib3.HTTPResponse object will be returned without reading/decoding response data. Default is True. :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. + Default is None. + :param _check_input_type: boolean specifying if type checking + should be done one the data sent to the server. + Default is True. + :param _check_return_type: boolean specifying if type checking + should be done one the data received from the server. + Default is True. + :param _host_index: integer specifying the index of the server + that we want to use. + Default is 0. :return: Order 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', 0) kwargs['body'] = body return self.call_with_http_info(**kwargs) self.place_order = Endpoint( settings={ - 'response_type': 'Order', + 'response_type': (Order,), 'auth': [], 'endpoint_path': '/store/order', 'operation_id': 'place_order', @@ -333,7 +449,7 @@ def __place_order(self, body, **kwargs): # noqa: E501 'allowed_values': { }, 'openapi_types': { - 'body': 'Order', + 'body': (Order,), }, 'attribute_map': { }, @@ -362,7 +478,7 @@ def __init__(self, settings=None, params_map=None, root_map=None, Args: settings (dict): see below key value pairs - 'response_type' (str): response type + 'response_type' (tuple/None): response type 'auth' (list): a list of auth type keys 'endpoint_path' (str): the endpoint path 'operation_id' (str): endpoint string identifier @@ -398,11 +514,24 @@ def __init__(self, settings=None, params_map=None, root_map=None, '_host_index', '_preload_content', '_request_timeout', - '_return_http_data_only' + '_return_http_data_only', + '_check_input_type', + '_check_return_type' ]) + self.params_map['nullable'].extend(['_request_timeout']) self.validations = root_map['validations'] self.allowed_values = root_map['allowed_values'] self.openapi_types = root_map['openapi_types'] + extra_types = { + 'async_req': (bool,), + '_host_index': (int,), + '_preload_content': (bool,), + '_request_timeout': (none_type, int, (int,), [int]), + '_return_http_data_only': (bool,), + '_check_input_type': (bool,), + '_check_return_type': (bool,) + } + self.openapi_types.update(extra_types) self.attribute_map = root_map['attribute_map'] self.location_map = root_map['location_map'] self.collection_format_map = root_map['collection_format_map'] @@ -416,8 +545,7 @@ def __validate_inputs(self, kwargs): check_allowed_values( self.allowed_values, (param,), - kwargs[param], - self.validations + kwargs[param] ) for param in self.params_map['validation']: @@ -428,6 +556,20 @@ def __validate_inputs(self, kwargs): kwargs[param] ) + if kwargs['_check_input_type'] is False: + return + + for key, value in six.iteritems(kwargs): + fixed_val = validate_and_convert_types( + value, + self.openapi_types[key], + [key], + False, + kwargs['_check_input_type'], + configuration=self.api_client.configuration + ) + kwargs[key] = fixed_val + def __gather_params(self, kwargs): params = { 'body': None, @@ -447,8 +589,9 @@ def __gather_params(self, kwargs): continue base_name = self.attribute_map[param_name] if (param_location == 'form' and - self.openapi_types[param_name] == 'file'): + self.openapi_types[param_name] == (file_type,)): param_location = 'file' + params[param_location][param_name] = param_value elif param_location in {'form', 'query'}: param_value_full = (base_name, param_value) params[param_location].append(param_value_full) @@ -473,20 +616,15 @@ def __call__(self, *args, **kwargs): def call_with_http_info(self, **kwargs): - if kwargs.get('_host_index') and self.settings['servers']: - _host_index = kwargs.get('_host_index') - try: - _host = self.settings['servers'][_host_index] - except IndexError: + try: + _host = self.settings['servers'][kwargs['_host_index']] + except IndexError: + if self.settings['servers']: raise ApiValueError( "Invalid host index. Must be 0 <= index < %s" % len(self.settings['servers']) ) - else: - try: - _host = self.settings['servers'][0] - except IndexError: - _host = None + _host = None for key, value in six.iteritems(kwargs): if key not in self.params_map['all']: @@ -495,7 +633,11 @@ def call_with_http_info(self, **kwargs): " to method `%s`" % (key, self.settings['operation_id']) ) - if key not in self.params_map['nullable'] and value is None: + # only throw this nullable ApiValueError if _check_input_type + # is False, if _check_input_type==True we catch this case + # in self.__validate_inputs + if (key not in self.params_map['nullable'] and value is None + and kwargs['_check_input_type'] is False): raise ApiValueError( "Value may not be None for non-nullable parameter `%s`" " when calling `%s`" % @@ -534,9 +676,10 @@ def call_with_http_info(self, **kwargs): files=params['file'], response_type=self.settings['response_type'], auth_settings=self.settings['auth'], - async_req=kwargs.get('async_req'), - _return_http_data_only=kwargs.get('_return_http_data_only'), - _preload_content=kwargs.get('_preload_content', True), - _request_timeout=kwargs.get('_request_timeout'), + async_req=kwargs['async_req'], + _check_type=kwargs['_check_return_type'], + _return_http_data_only=kwargs['_return_http_data_only'], + _preload_content=kwargs['_preload_content'], + _request_timeout=kwargs['_request_timeout'], _host=_host, collection_formats=params['collection_format']) diff --git a/samples/client/petstore/python-experimental/petstore_api/api/user_api.py b/samples/client/petstore/python-experimental/petstore_api/api/user_api.py index 7a3fb67c1268..8826867d5f0e 100644 --- a/samples/client/petstore/python-experimental/petstore_api/api/user_api.py +++ b/samples/client/petstore/python-experimental/petstore_api/api/user_api.py @@ -22,10 +22,18 @@ ApiTypeError, ApiValueError ) -from petstore_api.model_utils import ( +from petstore_api.model_utils import ( # noqa: F401 check_allowed_values, - check_validations + check_validations, + date, + datetime, + file_type, + int, + none_type, + str, + validate_and_convert_types ) +from petstore_api.models.user import User class UserApi(object): @@ -50,22 +58,49 @@ def __create_user(self, body, **kwargs): # noqa: E501 >>> result = thread.get() :param async_req bool: execute request asynchronously + Default is False. :param User body: Created user object (required) :param _return_http_data_only: response data without head status - code and headers + code and headers. Default is True. :param _preload_content: if False, the urllib3.HTTPResponse object will be returned without reading/decoding response data. Default is True. :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. + Default is None. + :param _check_input_type: boolean specifying if type checking + should be done one the data sent to the server. + Default is True. + :param _check_return_type: boolean specifying if type checking + should be done one the data received from the server. + Default is True. + :param _host_index: integer specifying the index of the server + that we want to use. + Default is 0. :return: None 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', 0) kwargs['body'] = body return self.call_with_http_info(**kwargs) @@ -98,7 +133,7 @@ def __create_user(self, body, **kwargs): # noqa: E501 'allowed_values': { }, 'openapi_types': { - 'body': 'User', + 'body': (User,), }, 'attribute_map': { }, @@ -125,22 +160,49 @@ def __create_users_with_array_input(self, body, **kwargs): # noqa: E501 >>> result = thread.get() :param async_req bool: execute request asynchronously - :param list[User] body: List of user object (required) + Default is False. + :param [User] body: List of user object (required) :param _return_http_data_only: response data without head status - code and headers + code and headers. Default is True. :param _preload_content: if False, the urllib3.HTTPResponse object will be returned without reading/decoding response data. Default is True. :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. + Default is None. + :param _check_input_type: boolean specifying if type checking + should be done one the data sent to the server. + Default is True. + :param _check_return_type: boolean specifying if type checking + should be done one the data received from the server. + Default is True. + :param _host_index: integer specifying the index of the server + that we want to use. + Default is 0. :return: None 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', 0) kwargs['body'] = body return self.call_with_http_info(**kwargs) @@ -173,7 +235,7 @@ def __create_users_with_array_input(self, body, **kwargs): # noqa: E501 'allowed_values': { }, 'openapi_types': { - 'body': 'list[User]', + 'body': ([User],), }, 'attribute_map': { }, @@ -200,22 +262,49 @@ def __create_users_with_list_input(self, body, **kwargs): # noqa: E501 >>> result = thread.get() :param async_req bool: execute request asynchronously - :param list[User] body: List of user object (required) + Default is False. + :param [User] body: List of user object (required) :param _return_http_data_only: response data without head status - code and headers + code and headers. Default is True. :param _preload_content: if False, the urllib3.HTTPResponse object will be returned without reading/decoding response data. Default is True. :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. + Default is None. + :param _check_input_type: boolean specifying if type checking + should be done one the data sent to the server. + Default is True. + :param _check_return_type: boolean specifying if type checking + should be done one the data received from the server. + Default is True. + :param _host_index: integer specifying the index of the server + that we want to use. + Default is 0. :return: None 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', 0) kwargs['body'] = body return self.call_with_http_info(**kwargs) @@ -248,7 +337,7 @@ def __create_users_with_list_input(self, body, **kwargs): # noqa: E501 'allowed_values': { }, 'openapi_types': { - 'body': 'list[User]', + 'body': ([User],), }, 'attribute_map': { }, @@ -276,22 +365,49 @@ def __delete_user(self, username, **kwargs): # noqa: E501 >>> result = thread.get() :param async_req bool: execute request asynchronously + Default is False. :param str username: The name that needs to be deleted (required) :param _return_http_data_only: response data without head status - code and headers + code and headers. Default is True. :param _preload_content: if False, the urllib3.HTTPResponse object will be returned without reading/decoding response data. Default is True. :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. + Default is None. + :param _check_input_type: boolean specifying if type checking + should be done one the data sent to the server. + Default is True. + :param _check_return_type: boolean specifying if type checking + should be done one the data received from the server. + Default is True. + :param _host_index: integer specifying the index of the server + that we want to use. + Default is 0. :return: None 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', 0) kwargs['username'] = username return self.call_with_http_info(**kwargs) @@ -324,7 +440,7 @@ def __delete_user(self, username, **kwargs): # noqa: E501 'allowed_values': { }, 'openapi_types': { - 'username': 'str', + 'username': (str,), }, 'attribute_map': { 'username': 'username', @@ -352,28 +468,55 @@ def __get_user_by_name(self, username, **kwargs): # noqa: E501 >>> result = thread.get() :param async_req bool: execute request asynchronously + Default is False. :param str username: The name that needs to be fetched. Use user1 for testing. (required) :param _return_http_data_only: response data without head status - code and headers + code and headers. Default is True. :param _preload_content: if False, the urllib3.HTTPResponse object will be returned without reading/decoding response data. Default is True. :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. + Default is None. + :param _check_input_type: boolean specifying if type checking + should be done one the data sent to the server. + Default is True. + :param _check_return_type: boolean specifying if type checking + should be done one the data received from the server. + Default is True. + :param _host_index: integer specifying the index of the server + that we want to use. + Default is 0. :return: User 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', 0) kwargs['username'] = username return self.call_with_http_info(**kwargs) self.get_user_by_name = Endpoint( settings={ - 'response_type': 'User', + 'response_type': (User,), 'auth': [], 'endpoint_path': '/user/{username}', 'operation_id': 'get_user_by_name', @@ -400,7 +543,7 @@ def __get_user_by_name(self, username, **kwargs): # noqa: E501 'allowed_values': { }, 'openapi_types': { - 'username': 'str', + 'username': (str,), }, 'attribute_map': { 'username': 'username', @@ -431,30 +574,57 @@ def __login_user(self, username, password, **kwargs): # noqa: E501 >>> result = thread.get() :param async_req bool: execute request asynchronously + Default is False. :param str username: The user name for login (required) :param str password: The password for login in clear text (required) :param _return_http_data_only: response data without head status - code and headers + code and headers. Default is True. :param _preload_content: if False, the urllib3.HTTPResponse object will be returned without reading/decoding response data. Default is True. :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. + Default is None. + :param _check_input_type: boolean specifying if type checking + should be done one the data sent to the server. + Default is True. + :param _check_return_type: boolean specifying if type checking + should be done one the data received from the server. + Default is True. + :param _host_index: integer specifying the index of the server + that we want to use. + Default is 0. :return: str 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', 0) kwargs['username'] = username kwargs['password'] = password return self.call_with_http_info(**kwargs) self.login_user = Endpoint( settings={ - 'response_type': 'str', + 'response_type': (str,), 'auth': [], 'endpoint_path': '/user/login', 'operation_id': 'login_user', @@ -483,8 +653,8 @@ def __login_user(self, username, password, **kwargs): # noqa: E501 'allowed_values': { }, 'openapi_types': { - 'username': 'str', - 'password': 'str', + 'username': (str,), + 'password': (str,), }, 'attribute_map': { 'username': 'username', @@ -517,21 +687,48 @@ def __logout_user(self, **kwargs): # noqa: E501 >>> result = thread.get() :param async_req bool: execute request asynchronously + Default is False. :param _return_http_data_only: response data without head status - code and headers + code and headers. Default is True. :param _preload_content: if False, the urllib3.HTTPResponse object will be returned without reading/decoding response data. Default is True. :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. + Default is None. + :param _check_input_type: boolean specifying if type checking + should be done one the data sent to the server. + Default is True. + :param _check_return_type: boolean specifying if type checking + should be done one the data received from the server. + Default is True. + :param _host_index: integer specifying the index of the server + that we want to use. + Default is 0. :return: None 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', 0) return self.call_with_http_info(**kwargs) self.logout_user = Endpoint( @@ -586,23 +783,50 @@ def __update_user(self, username, body, **kwargs): # noqa: E501 >>> result = thread.get() :param async_req bool: execute request asynchronously + Default is False. :param str username: name that need to be deleted (required) :param User body: Updated user object (required) :param _return_http_data_only: response data without head status - code and headers + code and headers. Default is True. :param _preload_content: if False, the urllib3.HTTPResponse object will be returned without reading/decoding response data. Default is True. :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. + Default is None. + :param _check_input_type: boolean specifying if type checking + should be done one the data sent to the server. + Default is True. + :param _check_return_type: boolean specifying if type checking + should be done one the data received from the server. + Default is True. + :param _host_index: integer specifying the index of the server + that we want to use. + Default is 0. :return: None 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', 0) kwargs['username'] = username kwargs['body'] = body return self.call_with_http_info(**kwargs) @@ -638,8 +862,8 @@ def __update_user(self, username, body, **kwargs): # noqa: E501 'allowed_values': { }, 'openapi_types': { - 'username': 'str', - 'body': 'User', + 'username': (str,), + 'body': (User,), }, 'attribute_map': { 'username': 'username', @@ -667,7 +891,7 @@ def __init__(self, settings=None, params_map=None, root_map=None, Args: settings (dict): see below key value pairs - 'response_type' (str): response type + 'response_type' (tuple/None): response type 'auth' (list): a list of auth type keys 'endpoint_path' (str): the endpoint path 'operation_id' (str): endpoint string identifier @@ -703,11 +927,24 @@ def __init__(self, settings=None, params_map=None, root_map=None, '_host_index', '_preload_content', '_request_timeout', - '_return_http_data_only' + '_return_http_data_only', + '_check_input_type', + '_check_return_type' ]) + self.params_map['nullable'].extend(['_request_timeout']) self.validations = root_map['validations'] self.allowed_values = root_map['allowed_values'] self.openapi_types = root_map['openapi_types'] + extra_types = { + 'async_req': (bool,), + '_host_index': (int,), + '_preload_content': (bool,), + '_request_timeout': (none_type, int, (int,), [int]), + '_return_http_data_only': (bool,), + '_check_input_type': (bool,), + '_check_return_type': (bool,) + } + self.openapi_types.update(extra_types) self.attribute_map = root_map['attribute_map'] self.location_map = root_map['location_map'] self.collection_format_map = root_map['collection_format_map'] @@ -721,8 +958,7 @@ def __validate_inputs(self, kwargs): check_allowed_values( self.allowed_values, (param,), - kwargs[param], - self.validations + kwargs[param] ) for param in self.params_map['validation']: @@ -733,6 +969,20 @@ def __validate_inputs(self, kwargs): kwargs[param] ) + if kwargs['_check_input_type'] is False: + return + + for key, value in six.iteritems(kwargs): + fixed_val = validate_and_convert_types( + value, + self.openapi_types[key], + [key], + False, + kwargs['_check_input_type'], + configuration=self.api_client.configuration + ) + kwargs[key] = fixed_val + def __gather_params(self, kwargs): params = { 'body': None, @@ -752,8 +1002,9 @@ def __gather_params(self, kwargs): continue base_name = self.attribute_map[param_name] if (param_location == 'form' and - self.openapi_types[param_name] == 'file'): + self.openapi_types[param_name] == (file_type,)): param_location = 'file' + params[param_location][param_name] = param_value elif param_location in {'form', 'query'}: param_value_full = (base_name, param_value) params[param_location].append(param_value_full) @@ -778,20 +1029,15 @@ def __call__(self, *args, **kwargs): def call_with_http_info(self, **kwargs): - if kwargs.get('_host_index') and self.settings['servers']: - _host_index = kwargs.get('_host_index') - try: - _host = self.settings['servers'][_host_index] - except IndexError: + try: + _host = self.settings['servers'][kwargs['_host_index']] + except IndexError: + if self.settings['servers']: raise ApiValueError( "Invalid host index. Must be 0 <= index < %s" % len(self.settings['servers']) ) - else: - try: - _host = self.settings['servers'][0] - except IndexError: - _host = None + _host = None for key, value in six.iteritems(kwargs): if key not in self.params_map['all']: @@ -800,7 +1046,11 @@ def call_with_http_info(self, **kwargs): " to method `%s`" % (key, self.settings['operation_id']) ) - if key not in self.params_map['nullable'] and value is None: + # only throw this nullable ApiValueError if _check_input_type + # is False, if _check_input_type==True we catch this case + # in self.__validate_inputs + if (key not in self.params_map['nullable'] and value is None + and kwargs['_check_input_type'] is False): raise ApiValueError( "Value may not be None for non-nullable parameter `%s`" " when calling `%s`" % @@ -839,9 +1089,10 @@ def call_with_http_info(self, **kwargs): files=params['file'], response_type=self.settings['response_type'], auth_settings=self.settings['auth'], - async_req=kwargs.get('async_req'), - _return_http_data_only=kwargs.get('_return_http_data_only'), - _preload_content=kwargs.get('_preload_content', True), - _request_timeout=kwargs.get('_request_timeout'), + async_req=kwargs['async_req'], + _check_type=kwargs['_check_return_type'], + _return_http_data_only=kwargs['_return_http_data_only'], + _preload_content=kwargs['_preload_content'], + _request_timeout=kwargs['_request_timeout'], _host=_host, collection_formats=params['collection_format']) diff --git a/samples/client/petstore/python-experimental/petstore_api/api_client.py b/samples/client/petstore/python-experimental/petstore_api/api_client.py index 7afd6306dcfc..bcf83024ce47 100644 --- a/samples/client/petstore/python-experimental/petstore_api/api_client.py +++ b/samples/client/petstore/python-experimental/petstore_api/api_client.py @@ -10,27 +10,29 @@ from __future__ import absolute_import -import datetime -import inspect import json import mimetypes from multiprocessing.pool import ThreadPool import os -import re -import tempfile # python 2 and python 3 compatibility library import six from six.moves.urllib.parse import quote -import petstore_api.models from petstore_api import rest from petstore_api.configuration import Configuration +from petstore_api.exceptions import ApiValueError from petstore_api.model_utils import ( ModelNormal, - ModelSimple + ModelSimple, + date, + datetime, + deserialize_file, + file_type, + model_to_dict, + str, + validate_and_convert_types ) -from petstore_api.exceptions import ApiValueError class ApiClient(object): @@ -55,17 +57,11 @@ class ApiClient(object): to the API. More threads means more concurrent API requests. """ - PRIMITIVE_TYPES = (float, bool, bytes, six.text_type) + six.integer_types - NATIVE_TYPES_MAPPING = { - 'int': int, - 'long': int if six.PY3 else long, # noqa: F821 - 'float': float, - 'str': str, - 'bool': bool, - 'date': datetime.date, - 'datetime': datetime.datetime, - 'object': object, - } + # six.binary_type python2=str, python3=bytes + # six.text_type python2=unicode, python3=str + PRIMITIVE_TYPES = ( + (float, bool, six.binary_type, six.text_type) + six.integer_types + ) _pool = None def __init__(self, configuration=None, header_name=None, header_value=None, @@ -115,7 +111,8 @@ def __call_api( query_params=None, header_params=None, body=None, post_params=None, files=None, response_type=None, auth_settings=None, _return_http_data_only=None, collection_formats=None, - _preload_content=True, _request_timeout=None, _host=None): + _preload_content=True, _request_timeout=None, _host=None, + _check_type=None): config = self.configuration @@ -182,7 +179,11 @@ def __call_api( if _preload_content: # deserialize response data if response_type: - return_data = self.deserialize(response_data, response_type) + return_data = self.deserialize( + response_data, + response_type, + _check_type + ) else: return_data = None @@ -216,93 +217,73 @@ def sanitize_for_serialization(self, obj): elif isinstance(obj, tuple): return tuple(self.sanitize_for_serialization(sub_obj) for sub_obj in obj) - elif isinstance(obj, (datetime.datetime, datetime.date)): + elif isinstance(obj, (datetime, date)): return obj.isoformat() if isinstance(obj, dict): obj_dict = obj elif isinstance(obj, ModelNormal): - # Convert model obj to dict except - # attributes `openapi_types`, `attribute_map` - # and attributes which value is not None. + # Convert model obj to dict # Convert attribute name to json key in - # model definition for request. - obj_dict = {obj.attribute_map[attr]: getattr(obj, attr) - for attr, _ in six.iteritems(obj.openapi_types) - if getattr(obj, attr) is not None} + # model definition for request + obj_dict = model_to_dict(obj, serialize=True) elif isinstance(obj, ModelSimple): return self.sanitize_for_serialization(obj.value) return {key: self.sanitize_for_serialization(val) for key, val in six.iteritems(obj_dict)} - def deserialize(self, response, response_type): + def deserialize(self, response, response_type, _check_type): """Deserializes response into an object. :param response: RESTResponse object to be deserialized. - :param response_type: class literal for - deserialized object, or string of class name. + :param response_type: For the response, a tuple containing: + valid classes + a list containing valid classes (for list schemas) + a dict containing a tuple of valid classes as the value + Example values: + (str,) + (Pet,) + (float, none_type) + ([int, none_type],) + ({str: (bool, str, int, float, date, datetime, str, none_type)},) + :param _check_type: boolean, whether to check the types of the data + received from the server :return: deserialized object. """ # handle file downloading # save response body into a tmp file and return the instance - if response_type == "file": - return self.__deserialize_file(response) + if response_type == (file_type,): + content_disposition = response.getheader("Content-Disposition") + return deserialize_file(response.data, self.configuration, + content_disposition=content_disposition) # fetch data from response object try: - data = json.loads(response.data) + received_data = json.loads(response.data) except ValueError: - data = response.data - - return self.__deserialize(data, response_type) - - def __deserialize(self, data, klass): - """Deserializes dict, list, str into an object. - - :param data: dict, list or str. - :param klass: class literal, or string of class name. - - :return: object. - """ - if data is None: - return None - - if type(klass) == str: - if klass.startswith('list['): - sub_kls = re.match(r'list\[(.*)\]', klass).group(1) - return [self.__deserialize(sub_data, sub_kls) - for sub_data in data] - - if klass.startswith('dict('): - sub_kls = re.match(r'dict\(([^,]*), (.*)\)', klass).group(2) - return {k: self.__deserialize(v, sub_kls) - for k, v in six.iteritems(data)} - - # convert str to class - if klass in self.NATIVE_TYPES_MAPPING: - klass = self.NATIVE_TYPES_MAPPING[klass] - else: - klass = getattr(petstore_api.models, klass) - - if klass in self.PRIMITIVE_TYPES: - return self.__deserialize_primitive(data, klass) - elif klass == object: - return self.__deserialize_object(data) - elif klass == datetime.date: - return self.__deserialize_date(data) - elif klass == datetime.datetime: - return self.__deserialize_datatime(data) - else: - return self.__deserialize_model(data, klass) + received_data = response.data + + # store our data under the key of 'received_data' so users have some + # context if they are deserializing a string and the data type is wrong + deserialized_data = validate_and_convert_types( + received_data, + response_type, + ['received_data'], + True, + _check_type, + configuration=self.configuration + ) + return deserialized_data def call_api(self, resource_path, method, path_params=None, query_params=None, header_params=None, body=None, post_params=None, files=None, response_type=None, auth_settings=None, async_req=None, _return_http_data_only=None, collection_formats=None, - _preload_content=True, _request_timeout=None, _host=None): + _preload_content=True, _request_timeout=None, _host=None, + _check_type=None): """Makes the HTTP request (synchronous) and returns deserialized data. To make an async_req request, set the async_req parameter. @@ -317,7 +298,16 @@ def call_api(self, resource_path, method, :param post_params dict: Request post form parameters, for `application/x-www-form-urlencoded`, `multipart/form-data`. :param auth_settings list: Auth Settings names for the request. - :param response: Response data type. + :param response_type: For the response, a tuple containing: + valid classes + a list containing valid classes (for list schemas) + a dict containing a tuple of valid classes as the value + Example values: + (str,) + (Pet,) + (float, none_type) + ([int, none_type],) + ({str: (bool, str, int, float, date, datetime, str, none_type)},) :param files dict: key -> filename, value -> filepath, for `multipart/form-data`. :param async_req bool: execute request asynchronously @@ -332,6 +322,8 @@ def call_api(self, resource_path, method, number provided, it will be total request timeout. It can also be a pair (tuple) of (connection, read) timeouts. + :param _check_type: boolean describing if the data back from the server + should have its type checked. :return: If async_req parameter is True, the request will be called asynchronously. @@ -345,7 +337,8 @@ def call_api(self, resource_path, method, body, post_params, files, response_type, auth_settings, _return_http_data_only, collection_formats, - _preload_content, _request_timeout, _host) + _preload_content, _request_timeout, _host, + _check_type) else: thread = self.pool.apply_async(self.__call_api, (resource_path, method, path_params, query_params, @@ -356,7 +349,7 @@ def call_api(self, resource_path, method, collection_formats, _preload_content, _request_timeout, - _host)) + _host, _check_type)) return thread def request(self, method, url, query_params=None, headers=None, @@ -453,24 +446,29 @@ def parameters_to_tuples(self, params, collection_formats): def files_parameters(self, files=None): """Builds form parameters. - :param files: File parameters. - :return: Form parameters with files. + :param files: None or a dict with key=param_name and value=file_object + :return: List of tuples of form parameters with file data """ - params = [] + if files is None: + return [] - if files: - for k, v in six.iteritems(files): - if not v: - continue - file_names = v if type(v) is list else [v] - for n in file_names: - with open(n, 'rb') as f: - filename = os.path.basename(f.name) - filedata = f.read() - mimetype = (mimetypes.guess_type(filename)[0] or - 'application/octet-stream') - params.append( - tuple([k, tuple([filename, filedata, mimetype])])) + params = [] + for param_name, file_instance in six.iteritems(files): + if file_instance is None: + # if the file field is nullable, skip None values + continue + if file_instance.closed is True: + raise ApiValueError( + "Cannot read a closed file. The passed in file_type for " + "%s must be open." % param_name + ) + filename = os.path.basename(file_instance.name) + filedata = file_instance.read() + mimetype = (mimetypes.guess_type(filename)[0] or + 'application/octet-stream') + params.append( + tuple([param_name, tuple([filename, filedata, mimetype])])) + file_instance.close() return params @@ -531,133 +529,3 @@ def update_params_for_auth(self, headers, querys, auth_settings): raise ApiValueError( 'Authentication token must be in `query` or `header`' ) - - def __deserialize_file(self, response): - """Deserializes body to file - - Saves response body into a file in a temporary folder, - using the filename from the `Content-Disposition` header if provided. - - :param response: RESTResponse. - :return: file path. - """ - fd, path = tempfile.mkstemp(dir=self.configuration.temp_folder_path) - os.close(fd) - os.remove(path) - - content_disposition = response.getheader("Content-Disposition") - if content_disposition: - filename = re.search(r'filename=[\'"]?([^\'"\s]+)[\'"]?', - content_disposition).group(1) - path = os.path.join(os.path.dirname(path), filename) - - with open(path, "wb") as f: - f.write(response.data) - - return path - - def __deserialize_primitive(self, data, klass): - """Deserializes string to primitive type. - - :param data: str. - :param klass: class literal. - - :return: int, long, float, str, bool. - """ - try: - return klass(data) - except UnicodeEncodeError: - return six.text_type(data) - except TypeError: - return data - except ValueError as exc: - raise ApiValueError(str(exc)) - - def __deserialize_object(self, value): - """Return an original value. - - :return: object. - """ - return value - - def __deserialize_date(self, string): - """Deserializes string to date. - - :param string: str. - :return: date. - """ - try: - from dateutil.parser import parse - return parse(string).date() - except ImportError: - return string - except ValueError: - raise rest.ApiException( - status=0, - reason="Failed to parse `{0}` as date object".format(string) - ) - - def __deserialize_datatime(self, string): - """Deserializes string to datetime. - - The string should be in iso8601 datetime format. - - :param string: str. - :return: datetime. - """ - try: - from dateutil.parser import parse - return parse(string) - except ImportError: - return string - except ValueError: - raise rest.ApiException( - status=0, - reason=( - "Failed to parse `{0}` as datetime object" - .format(string) - ) - ) - - def __deserialize_model(self, data, klass): - """Deserializes list or dict to model. - - :param data: dict, list. - :param klass: class literal, ModelSimple or ModelNormal - :return: model object. - """ - - if issubclass(klass, ModelSimple): - value = self.__deserialize(data, klass.openapi_types['value']) - return klass(value) - - # code to handle ModelNormal - used_data = data - if not isinstance(data, (list, dict)): - used_data = [data] - keyword_args = {} - positional_args = [] - if klass.openapi_types is not None: - for attr, attr_type in six.iteritems(klass.openapi_types): - if (data is not None and - klass.attribute_map[attr] in used_data): - value = used_data[klass.attribute_map[attr]] - keyword_args[attr] = self.__deserialize(value, attr_type) - end_index = None - argspec = inspect.getargspec(getattr(klass, '__init__')) - if argspec.defaults: - end_index = -len(argspec.defaults) - required_positional_args = argspec.args[1:end_index] - for index, req_positional_arg in enumerate(required_positional_args): - if keyword_args and req_positional_arg in keyword_args: - positional_args.append(keyword_args[req_positional_arg]) - del keyword_args[req_positional_arg] - elif (not keyword_args and index < len(used_data) and - isinstance(used_data, list)): - positional_args.append(used_data[index]) - instance = klass(*positional_args, **keyword_args) - if hasattr(instance, 'get_real_child_model'): - klass_name = instance.get_real_child_model(data) - if klass_name: - instance = self.__deserialize(data, klass_name) - return instance diff --git a/samples/client/petstore/python-experimental/petstore_api/model_utils.py b/samples/client/petstore/python-experimental/petstore_api/model_utils.py index 57ca211a0f7c..22d9ee459de7 100644 --- a/samples/client/petstore/python-experimental/petstore_api/model_utils.py +++ b/samples/client/petstore/python-experimental/petstore_api/model_utils.py @@ -9,13 +9,162 @@ Generated by: https://openapi-generator.tech """ + +import copy +from datetime import date, datetime # noqa: F401 +import inspect +import os import re +import tempfile + +from dateutil.parser import parse +import six + +from petstore_api.exceptions import ( + ApiKeyError, + ApiTypeError, + ApiValueError, +) + +none_type = type(None) +if six.PY3: + import io + file_type = io.IOBase + # these are needed for when other modules import str and int from here + str = str + int = int +else: + file_type = file # noqa: F821 + str_py2 = str + unicode_py2 = unicode # noqa: F821 + long_py2 = long # noqa: F821 + int_py2 = int + # this requires that the future library is installed + from builtins import int, str + + +class OpenApiModel(object): + """The base class for all OpenAPIModels""" + + +class ModelSimple(OpenApiModel): + """the parent class of models whose type != object in their + swagger/openapi""" -from petstore_api.exceptions import ApiValueError +class ModelNormal(OpenApiModel): + """the parent class of models whose type == object in their + swagger/openapi""" -def check_allowed_values(allowed_values, input_variable_path, input_values, - validations): + +COERCION_INDEX_BY_TYPE = { + ModelNormal: 0, + ModelSimple: 1, + none_type: 2, + list: 3, + dict: 4, + float: 5, + int: 6, + bool: 7, + datetime: 8, + date: 9, + str: 10, + file_type: 11, +} + +# these are used to limit what type conversions we try to do +# when we have a valid type already and we want to try converting +# to another type +UPCONVERSION_TYPE_PAIRS = ( + (str, datetime), + (str, date), + (list, ModelNormal), + (dict, ModelNormal), + (str, ModelSimple), + (int, ModelSimple), + (float, ModelSimple), + (list, ModelSimple), +) + +COERCIBLE_TYPE_PAIRS = { + False: ( # client instantiation of a model with client data + # (dict, ModelNormal), + # (list, ModelNormal), + # (str, ModelSimple), + # (int, ModelSimple), + # (float, ModelSimple), + # (list, ModelSimple), + # (str, int), + # (str, float), + # (str, datetime), + # (str, date), + # (int, str), + # (float, str), + ), + True: ( # server -> client data + (dict, ModelNormal), + (list, ModelNormal), + (str, ModelSimple), + (int, ModelSimple), + (float, ModelSimple), + (list, ModelSimple), + # (str, int), + # (str, float), + (str, datetime), + (str, date), + # (int, str), + # (float, str), + (str, file_type) + ), +} + + +def get_simple_class(input_value): + """Returns an input_value's simple class that we will use for type checking + Python2: + float and int will return int, where int is the python3 int backport + str and unicode will return str, where str is the python3 str backport + Note: float and int ARE both instances of int backport + Note: str_py2 and unicode_py2 are NOT both instances of str backport + + Args: + input_value (class/class_instance): the item for which we will return + the simple class + """ + if isinstance(input_value, type): + # input_value is a class + return input_value + elif isinstance(input_value, tuple): + return tuple + elif isinstance(input_value, list): + return list + elif isinstance(input_value, dict): + return dict + elif isinstance(input_value, none_type): + return none_type + elif isinstance(input_value, file_type): + return file_type + elif isinstance(input_value, bool): + # this must be higher than the int check because + # isinstance(True, int) == True + return bool + elif isinstance(input_value, int): + # for python2 input_value==long_instance -> return int + # where int is the python3 int backport + return int + elif isinstance(input_value, datetime): + # this must be higher than the date check because + # isinstance(datetime_instance, date) == True + return datetime + elif isinstance(input_value, date): + return date + elif (six.PY2 and isinstance(input_value, (str_py2, unicode_py2, str)) or + isinstance(input_value, str)): + return str + return type(input_value) + + +def check_allowed_values(allowed_values, input_variable_path, input_values): """Raises an exception if the input_values are not allowed Args: @@ -23,14 +172,9 @@ def check_allowed_values(allowed_values, input_variable_path, input_values, input_variable_path (tuple): the path to the input variable input_values (list/str/int/float/date/datetime): the values that we are checking to see if they are in allowed_values - validations (dict): the validations dict """ - min_collection_length = ( - validations.get(input_variable_path, {}).get('min_length') or - validations.get(input_variable_path, {}).get('min_items', 0)) these_allowed_values = list(allowed_values[input_variable_path].values()) if (isinstance(input_values, list) - and len(input_values) > min_collection_length and not set(input_values).issubset( set(these_allowed_values))): invalid_values = ", ".join( @@ -44,7 +188,6 @@ def check_allowed_values(allowed_values, input_variable_path, input_values, ) ) elif (isinstance(input_values, dict) - and len(input_values) > min_collection_length and not set( input_values.keys()).issubset(set(these_allowed_values))): invalid_values = ", ".join( @@ -119,8 +262,21 @@ def check_validations(validations, input_variable_path, input_values): ) ) + items = ('exclusive_maximum', 'inclusive_maximum', 'exclusive_minimum', + 'inclusive_minimum') + if (any(item in current_validations for item in items)): + if isinstance(input_values, list): + max_val = max(input_values) + min_val = min(input_values) + elif isinstance(input_values, dict): + max_val = max(input_values.values()) + min_val = min(input_values.values()) + else: + max_val = input_values + min_val = input_values + if ('exclusive_maximum' in current_validations and - input_values >= current_validations['exclusive_maximum']): + max_val >= current_validations['exclusive_maximum']): raise ApiValueError( "Invalid value for `%s`, must be a value less than `%s`" % ( input_variable_path[0], @@ -129,7 +285,7 @@ def check_validations(validations, input_variable_path, input_values): ) if ('inclusive_maximum' in current_validations and - input_values > current_validations['inclusive_maximum']): + max_val > current_validations['inclusive_maximum']): raise ApiValueError( "Invalid value for `%s`, must be a value less than or equal to " "`%s`" % ( @@ -139,7 +295,7 @@ def check_validations(validations, input_variable_path, input_values): ) if ('exclusive_minimum' in current_validations and - input_values <= current_validations['exclusive_minimum']): + min_val <= current_validations['exclusive_minimum']): raise ApiValueError( "Invalid value for `%s`, must be a value greater than `%s`" % ( @@ -149,7 +305,7 @@ def check_validations(validations, input_variable_path, input_values): ) if ('inclusive_minimum' in current_validations and - input_values < current_validations['inclusive_minimum']): + min_val < current_validations['inclusive_minimum']): raise ApiValueError( "Invalid value for `%s`, must be a value greater than or equal " "to `%s`" % ( @@ -171,13 +327,550 @@ def check_validations(validations, input_variable_path, input_values): ) -class ModelSimple(object): - # the parent class of models whose type != object in their swagger/openapi - # spec - pass +def order_response_types(required_types): + """Returns the required types sorted in coercion order + + Args: + required_types (list/tuple): collection of classes or instance of + list or dict with classs information inside it + + Returns: + (list): coercion order sorted collection of classes or instance + of list or dict with classs information inside it + """ + + def index_getter(class_or_instance): + if isinstance(class_or_instance, list): + return COERCION_INDEX_BY_TYPE[list] + elif isinstance(class_or_instance, dict): + return COERCION_INDEX_BY_TYPE[dict] + elif (inspect.isclass(class_or_instance) + and issubclass(class_or_instance, ModelNormal)): + return COERCION_INDEX_BY_TYPE[ModelNormal] + elif (inspect.isclass(class_or_instance) + and issubclass(class_or_instance, ModelSimple)): + return COERCION_INDEX_BY_TYPE[ModelSimple] + return COERCION_INDEX_BY_TYPE[class_or_instance] + + sorted_types = sorted( + required_types, + key=lambda class_or_instance: index_getter(class_or_instance) + ) + return sorted_types + + +def remove_uncoercible(required_types_classes, current_item, from_server, + must_convert=True): + """Only keeps the type conversions that are possible + + Args: + required_types_classes (tuple): tuple of classes that are required + these should be ordered by COERCION_INDEX_BY_TYPE + from_server (bool): a boolean of whether the data is from the server + if false, the data is from the client + current_item (any): the current item to be converted + + Keyword Args: + must_convert (bool): if True the item to convert is of the wrong + type and we want a big list of coercibles + if False, we want a limited list of coercibles + + Returns: + (list): the remaining coercible required types, classes only + """ + current_type_simple = get_simple_class(current_item) + + results_classes = [] + for required_type_class in required_types_classes: + # convert our models to OpenApiModel + required_type_class_simplified = required_type_class + if isinstance(required_type_class_simplified, type): + if issubclass(required_type_class_simplified, ModelNormal): + required_type_class_simplified = ModelNormal + elif issubclass(required_type_class_simplified, ModelSimple): + required_type_class_simplified = ModelSimple + + if required_type_class_simplified == current_type_simple: + # don't consider converting to one's own class + continue + + class_pair = (current_type_simple, required_type_class_simplified) + if must_convert and class_pair in COERCIBLE_TYPE_PAIRS[from_server]: + results_classes.append(required_type_class) + elif class_pair in UPCONVERSION_TYPE_PAIRS: + results_classes.append(required_type_class) + return results_classes + + +def get_required_type_classes(required_types_mixed): + """Converts the tuple required_types into a tuple and a dict described + below + + Args: + required_types_mixed (tuple/list): will contain either classes or + instance of list or dict + + Returns: + (valid_classes, dict_valid_class_to_child_types_mixed): + valid_classes (tuple): the valid classes that the current item + should be + dict_valid_class_to_child_types_mixed (doct): + valid_class (class): this is the key + child_types_mixed (list/dict/tuple): describes the valid child + types + """ + valid_classes = [] + child_req_types_by_current_type = {} + for required_type in required_types_mixed: + if isinstance(required_type, list): + valid_classes.append(list) + child_req_types_by_current_type[list] = required_type + elif isinstance(required_type, tuple): + valid_classes.append(tuple) + child_req_types_by_current_type[tuple] = required_type + elif isinstance(required_type, dict): + valid_classes.append(dict) + child_req_types_by_current_type[dict] = required_type[str] + else: + valid_classes.append(required_type) + return tuple(valid_classes), child_req_types_by_current_type + + +def change_keys_js_to_python(input_dict, model_class): + """ + Converts from javascript_key keys in the input_dict to python_keys in + the output dict using the mapping in model_class + """ + + output_dict = {} + reversed_attr_map = {value: key for key, value in + six.iteritems(model_class.attribute_map)} + for javascript_key, value in six.iteritems(input_dict): + python_key = reversed_attr_map.get(javascript_key) + if python_key is None: + # if the key is unknown, it is in error or it is an + # additionalProperties variable + python_key = javascript_key + output_dict[python_key] = value + return output_dict + + +def get_type_error(var_value, path_to_item, valid_classes, key_type=False): + error_msg = type_error_message( + var_name=path_to_item[-1], + var_value=var_value, + valid_classes=valid_classes, + key_type=key_type + ) + return ApiTypeError( + error_msg, + path_to_item=path_to_item, + valid_classes=valid_classes, + key_type=key_type + ) + + +def deserialize_primitive(data, klass, path_to_item): + """Deserializes string to primitive type. + + :param data: str/int/float + :param klass: str/class the class to convert to + + :return: int, float, str, bool, date, datetime + """ + additional_message = "" + try: + if klass in {datetime, date}: + additional_message = ( + "If you need your parameter to have a fallback " + "string value, please set its type as `type: {}` in your " + "spec. That allows the value to be any type. " + ) + if klass == datetime: + if len(data) < 8: + raise ValueError("This is not a datetime") + # The string should be in iso8601 datetime format. + parsed_datetime = parse(data) + date_only = ( + parsed_datetime.hour == 0 and + parsed_datetime.minute == 0 and + parsed_datetime.second == 0 and + parsed_datetime.tzinfo is None and + 8 <= len(data) <= 10 + ) + if date_only: + raise ValueError("This is a date, not a datetime") + return parsed_datetime + elif klass == date: + if len(data) < 8: + raise ValueError("This is not a date") + return parse(data).date() + else: + converted_value = klass(data) + if isinstance(data, str) and klass == float: + if str(converted_value) != data: + # '7' -> 7.0 -> '7.0' != '7' + raise ValueError('This is not a float') + return converted_value + except (OverflowError, ValueError): + # parse can raise OverflowError + raise ApiValueError( + "{0}Failed to parse {1} as {2}".format( + additional_message, repr(data), get_py3_class_name(klass) + ), + path_to_item=path_to_item + ) + + +def deserialize_model(model_data, model_class, path_to_item, check_type, + configuration, from_server): + """Deserializes model_data to model instance. + + Args: + model_data (list/dict): data to instantiate the model + model_class (OpenApiModel): the model class + path_to_item (list): path to the model in the received data + check_type (bool): whether to check the data tupe for the values in + the model + configuration (Configuration): the instance to use to convert files + from_server (bool): True if the data is from the server + False if the data is from the client + + Returns: + model instance + + Raise: + ApiTypeError + ApiValueError + ApiKeyError + """ + fixed_model_data = copy.deepcopy(model_data) + + if isinstance(fixed_model_data, dict): + fixed_model_data = change_keys_js_to_python(fixed_model_data, + model_class) + + kw_args = dict(_check_type=check_type, + _path_to_item=path_to_item, + _configuration=configuration, + _from_server=from_server) + + if hasattr(model_class, 'get_real_child_model'): + # discriminator case + discriminator_class = model_class.get_real_child_model(model_data) + if discriminator_class: + if isinstance(model_data, list): + instance = discriminator_class(*model_data, **kw_args) + elif isinstance(model_data, dict): + fixed_model_data = change_keys_js_to_python( + fixed_model_data, + discriminator_class + ) + kw_args.update(fixed_model_data) + instance = discriminator_class(**kw_args) + else: + # all other cases + if isinstance(model_data, list): + instance = model_class(*model_data, **kw_args) + if isinstance(model_data, dict): + fixed_model_data = change_keys_js_to_python(fixed_model_data, + model_class) + kw_args.update(fixed_model_data) + instance = model_class(**kw_args) + else: + instance = model_class(model_data, **kw_args) + + return instance + + +def deserialize_file(response_data, configuration, content_disposition=None): + """Deserializes body to file + + Saves response body into a file in a temporary folder, + using the filename from the `Content-Disposition` header if provided. + + Args: + param response_data (str): the file data to write + configuration (Configuration): the instance to use to convert files + + Keyword Args: + content_disposition (str): the value of the Content-Disposition + header + + Returns: + (file_type): the deserialized file which is open + The user is responsible for closing and reading the file + """ + fd, path = tempfile.mkstemp(dir=configuration.temp_folder_path) + os.close(fd) + os.remove(path) + + if content_disposition: + filename = re.search(r'filename=[\'"]?([^\'"\s]+)[\'"]?', + content_disposition).group(1) + path = os.path.join(os.path.dirname(path), filename) + + with open(path, "wb") as f: + if six.PY3 and isinstance(response_data, str): + # in python3 change str to bytes so we can write it + response_data = response_data.encode('utf-8') + f.write(response_data) + + f = open(path, "rb") + return f + + +def attempt_convert_item(input_value, valid_classes, path_to_item, + configuration, from_server, key_type=False, + must_convert=False, check_type=True): + """ + Args: + input_value (any): the data to convert + valid_classes (any): the classes that are valid + path_to_item (list): the path to the item to convert + configuration (Configuration): the instance to use to convert files + from_server (bool): True if data is from the server, False is data is + from the client + key_type (bool): if True we need to convert a key type (not supported) + must_convert (bool): if True we must convert + check_type (bool): if True we check the type or the returned data in + ModelNormal and ModelSimple instances + + Returns: + instance (any) the fixed item + + Raises: + ApiTypeError + ApiValueError + ApiKeyError + """ + valid_classes_ordered = order_response_types(valid_classes) + valid_classes_coercible = remove_uncoercible( + valid_classes_ordered, input_value, from_server) + if not valid_classes_coercible or key_type: + # we do not handle keytype errors, json will take care + # of this for us + raise get_type_error(input_value, path_to_item, valid_classes, + key_type=key_type) + for valid_class in valid_classes_coercible: + try: + if issubclass(valid_class, OpenApiModel): + return deserialize_model(input_value, valid_class, + path_to_item, check_type, + configuration, from_server) + elif valid_class == file_type: + return deserialize_file(input_value, configuration) + return deserialize_primitive(input_value, valid_class, + path_to_item) + except (ApiTypeError, ApiValueError, ApiKeyError) as conversion_exc: + if must_convert: + raise conversion_exc + # if we have conversion errors when must_convert == False + # we ignore the exception and move on to the next class + continue + # we were unable to convert, must_convert == False + return input_value + + +def validate_and_convert_types(input_value, required_types_mixed, path_to_item, + from_server, _check_type, configuration=None): + """Raises a TypeError is there is a problem, otherwise returns value + + Args: + input_value (any): the data to validate/convert + required_types_mixed (list/dict/tuple): A list of + valid classes, or a list tuples of valid classes, or a dict where + the value is a tuple of value classes + path_to_item: (list) the path to the data being validated + this stores a list of keys or indices to get to the data being + validated + from_server (bool): True if data is from the server + False if data is from the client + _check_type: (boolean) if true, type will be checked and conversion + will be attempted. + configuration: (Configuration): the configuration class to use + when converting file_type items. + If passed, conversion will be attempted when possible + If not passed, no conversions will be attempted and + exceptions will be raised + + Returns: + the correctly typed value + + Raises: + ApiTypeError + """ + results = get_required_type_classes(required_types_mixed) + valid_classes, child_req_types_by_current_type = results + + input_class_simple = get_simple_class(input_value) + valid_type = input_class_simple in set(valid_classes) + if not valid_type: + if configuration: + # if input_value is not valid_type try to convert it + converted_instance = attempt_convert_item( + input_value, + valid_classes, + path_to_item, + configuration, + from_server, + key_type=False, + must_convert=True + ) + return converted_instance + else: + raise get_type_error(input_value, path_to_item, valid_classes, + key_type=False) + + # input_value's type is in valid_classes + if len(valid_classes) > 1 and configuration: + # there are valid classes which are not the current class + valid_classes_coercible = remove_uncoercible( + valid_classes, input_value, from_server, must_convert=False) + if valid_classes_coercible: + converted_instance = attempt_convert_item( + input_value, + valid_classes_coercible, + path_to_item, + configuration, + from_server, + key_type=False, + must_convert=False + ) + return converted_instance + + if child_req_types_by_current_type == {}: + # all types are of the required types and there are no more inner + # variables left to look at + return input_value + inner_required_types = child_req_types_by_current_type.get( + type(input_value) + ) + if inner_required_types is None: + # for this type, there are not more inner variables left to look at + return input_value + if isinstance(input_value, list): + if input_value == []: + # allow an empty list + return input_value + for index, inner_value in enumerate(input_value): + inner_path = list(path_to_item) + inner_path.append(index) + input_value[index] = validate_and_convert_types( + inner_value, + inner_required_types, + inner_path, + from_server, + _check_type, + configuration=configuration + ) + elif isinstance(input_value, dict): + if input_value == {}: + # allow an empty dict + return input_value + for inner_key, inner_val in six.iteritems(input_value): + inner_path = list(path_to_item) + inner_path.append(inner_key) + if get_simple_class(inner_key) != str: + raise get_type_error(inner_key, inner_path, valid_classes, + key_type=True) + input_value[inner_key] = validate_and_convert_types( + inner_val, + inner_required_types, + inner_path, + from_server, + _check_type, + configuration=configuration + ) + return input_value + + +def model_to_dict(model_instance, serialize=True): + """Returns the model properties as a dict + + Args: + model_instance (one of your model instances): the model instance that + will be converted to a dict. + + Keyword Args: + serialize (bool): if True, the keys in the dict will be values from + attribute_map + """ + result = {} + + for attr, value in six.iteritems(model_instance._data_store): + if serialize: + # we use get here because additional property key names do not + # exist in attribute_map + attr = model_instance.attribute_map.get(attr, attr) + if isinstance(value, list): + result[attr] = list(map( + lambda x: model_to_dict(x, serialize=serialize) + if hasattr(x, '_data_store') else x, value + )) + elif isinstance(value, dict): + result[attr] = dict(map( + lambda item: (item[0], + model_to_dict(item[1], serialize=serialize)) + if hasattr(item[1], '_data_store') else item, + value.items() + )) + elif hasattr(value, '_data_store'): + result[attr] = model_to_dict(value, serialize=serialize) + else: + result[attr] = value + + return result + + +def type_error_message(var_value=None, var_name=None, valid_classes=None, + key_type=None): + """ + Keyword Args: + var_value (any): the variable which has the type_error + var_name (str): the name of the variable which has the typ error + valid_classes (tuple): the accepted classes for current_item's + value + key_type (bool): False if our value is a value in a dict + True if it is a key in a dict + False if our item is an item in a list + """ + key_or_value = 'value' + if key_type: + key_or_value = 'key' + valid_classes_phrase = get_valid_classes_phrase(valid_classes) + msg = ( + "Invalid type for variable '{0}'. Required {1} type {2} and " + "passed type was {3}".format( + var_name, + key_or_value, + valid_classes_phrase, + type(var_value).__name__, + ) + ) + return msg + + +def get_valid_classes_phrase(input_classes): + """Returns a string phrase describing what types are allowed + Note: Adds the extra valid classes in python2 + """ + all_classes = list(input_classes) + if six.PY2 and str in input_classes: + all_classes.extend([str_py2, unicode_py2]) + if six.PY2 and int in input_classes: + all_classes.extend([int_py2, long_py2]) + all_classes = sorted(all_classes, key=lambda cls: cls.__name__) + all_class_names = [cls.__name__ for cls in all_classes] + if len(all_class_names) == 1: + return 'is {0}'.format(all_class_names[0]) + return "is one of [{0}]".format(", ".join(all_class_names)) -class ModelNormal(object): - # the parent class of models whose type == object in their swagger/openapi - # spec - pass +def get_py3_class_name(input_class): + if six.PY2: + if input_class == str: + return 'str' + elif input_class == int: + return 'int' + return input_class.__name__ diff --git a/samples/client/petstore/python-experimental/petstore_api/models/additional_properties_any_type.py b/samples/client/petstore/python-experimental/petstore_api/models/additional_properties_any_type.py index 25e165ed7b57..16b3e933e7fe 100644 --- a/samples/client/petstore/python-experimental/petstore_api/models/additional_properties_any_type.py +++ b/samples/client/petstore/python-experimental/petstore_api/models/additional_properties_any_type.py @@ -15,12 +15,26 @@ import six # noqa: F401 -from petstore_api.exceptions import ApiValueError # noqa: F401 +from petstore_api.exceptions import ( # noqa: F401 + ApiKeyError, + ApiTypeError, + ApiValueError, +) from petstore_api.model_utils import ( # noqa: F401 ModelNormal, ModelSimple, check_allowed_values, - check_validations + check_validations, + date, + datetime, + file_type, + get_simple_class, + int, + model_to_dict, + none_type, + str, + type_error_message, + validate_and_convert_types ) @@ -46,6 +60,8 @@ class AdditionalPropertiesAnyType(ModelNormal): 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 = { @@ -56,69 +72,132 @@ class AdditionalPropertiesAnyType(ModelNormal): } openapi_types = { - 'name': 'str' + 'name': (str,), # noqa: E501 } validations = { } - def __init__(self, name=None): # noqa: E501 - """AdditionalPropertiesAnyType - a model defined in OpenAPI""" # noqa: E501 - - self._name = None - self.discriminator = None + additional_properties_type = (bool, date, datetime, dict, float, int, list, str,) # noqa: E501 + + discriminator = None + + def __init__(self, _check_type=True, _from_server=False, _path_to_item=(), _configuration=None, **kwargs): # noqa: E501 + """AdditionalPropertiesAnyType - 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 + _from_server (bool): True if the data is from the server + False if the data is from the client (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. + name (str): [optional] # noqa: E501 + """ + self._data_store = {} + self._check_type = _check_type + self._from_server = _from_server + self._path_to_item = _path_to_item + self._configuration = _configuration + + for var_name, var_value in six.iteritems(kwargs): + self.__set_item(var_name, var_value) + + def __set_item(self, name, value): + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + + if name in self.openapi_types: + required_types_mixed = self.openapi_types[name] + elif self.additional_properties_type is None: + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + path_to_item + ) + elif self.additional_properties_type is not None: + required_types_mixed = self.additional_properties_type + + if get_simple_class(name) != str: + error_msg = type_error_message( + var_name=name, + var_value=name, + valid_classes=(str,), + key_type=True + ) + raise ApiTypeError( + error_msg, + path_to_item=path_to_item, + valid_classes=(str,), + key_type=True + ) - if name is not None: - self.name = ( - name + if self._check_type: + value = validate_and_convert_types( + value, required_types_mixed, path_to_item, self._from_server, + self._check_type, configuration=self._configuration) + if (name,) in self.allowed_values: + check_allowed_values( + self.allowed_values, + (name,), + value ) + if (name,) in self.validations: + check_validations( + self.validations, + (name,), + value + ) + self._data_store[name] = value + + def __get_item(self, name): + if name in self._data_store: + return self._data_store[name] + + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + [name] + ) + + def __setitem__(self, name, value): + """this allows us to set values with instance[field_name] = val""" + self.__set_item(name, value) + + def __getitem__(self, name): + """this allows us to get a value with val = instance[field_name]""" + return self.__get_item(name) @property def name(self): """Gets the name of this AdditionalPropertiesAnyType. # noqa: E501 - - :return: The name of this AdditionalPropertiesAnyType. # noqa: E501 - :rtype: str + Returns: + (str): The name of this AdditionalPropertiesAnyType. # noqa: E501 """ - return self._name + return self.__get_item('name') @name.setter - def name(self, name): # noqa: E501 - """Sets the name of this AdditionalPropertiesAnyType. - - - :param name: The name of this AdditionalPropertiesAnyType. # noqa: E501 - :type: str + def name(self, value): + """Sets the name of this AdditionalPropertiesAnyType. # noqa: E501 """ - - self._name = ( - name - ) + return self.__set_item('name', value) def to_dict(self): """Returns the model properties as a dict""" - result = {} - - for attr, _ in six.iteritems(self.openapi_types): - value = getattr(self, attr) - if isinstance(value, list): - result[attr] = list(map( - lambda x: x.to_dict() if hasattr(x, "to_dict") else x, - value - )) - elif hasattr(value, "to_dict"): - result[attr] = value.to_dict() - elif isinstance(value, dict): - result[attr] = dict(map( - lambda item: (item[0], item[1].to_dict()) - if hasattr(item[1], "to_dict") else item, - value.items() - )) - else: - result[attr] = value - - return result + return model_to_dict(self, serialize=False) def to_str(self): """Returns the string representation of the model""" @@ -133,7 +212,22 @@ def __eq__(self, other): if not isinstance(other, AdditionalPropertiesAnyType): return False - return self.__dict__ == other.__dict__ + if not set(self._data_store.keys()) == set(other._data_store.keys()): + return False + for _var_name, this_val in six.iteritems(self._data_store): + that_val = other._data_store[_var_name] + types = set() + types.add(this_val.__class__) + types.add(that_val.__class__) + vals_equal = this_val == that_val + if (not six.PY3 and + len(types) == 2 and unicode in types): # noqa: F821 + vals_equal = ( + this_val.encode('utf-8') == that_val.encode('utf-8') + ) + if not vals_equal: + return False + return True def __ne__(self, other): """Returns true if both objects are not equal""" diff --git a/samples/client/petstore/python-experimental/petstore_api/models/additional_properties_array.py b/samples/client/petstore/python-experimental/petstore_api/models/additional_properties_array.py index 5de262b864d9..91e75256f551 100644 --- a/samples/client/petstore/python-experimental/petstore_api/models/additional_properties_array.py +++ b/samples/client/petstore/python-experimental/petstore_api/models/additional_properties_array.py @@ -15,12 +15,26 @@ import six # noqa: F401 -from petstore_api.exceptions import ApiValueError # noqa: F401 +from petstore_api.exceptions import ( # noqa: F401 + ApiKeyError, + ApiTypeError, + ApiValueError, +) from petstore_api.model_utils import ( # noqa: F401 ModelNormal, ModelSimple, check_allowed_values, - check_validations + check_validations, + date, + datetime, + file_type, + get_simple_class, + int, + model_to_dict, + none_type, + str, + type_error_message, + validate_and_convert_types ) @@ -46,6 +60,8 @@ class AdditionalPropertiesArray(ModelNormal): 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 = { @@ -56,69 +72,132 @@ class AdditionalPropertiesArray(ModelNormal): } openapi_types = { - 'name': 'str' + 'name': (str,), # noqa: E501 } validations = { } - def __init__(self, name=None): # noqa: E501 - """AdditionalPropertiesArray - a model defined in OpenAPI""" # noqa: E501 - - self._name = None - self.discriminator = None + additional_properties_type = ([bool, date, datetime, dict, float, int, list, str],) # noqa: E501 + + discriminator = None + + def __init__(self, _check_type=True, _from_server=False, _path_to_item=(), _configuration=None, **kwargs): # noqa: E501 + """AdditionalPropertiesArray - 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 + _from_server (bool): True if the data is from the server + False if the data is from the client (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. + name (str): [optional] # noqa: E501 + """ + self._data_store = {} + self._check_type = _check_type + self._from_server = _from_server + self._path_to_item = _path_to_item + self._configuration = _configuration + + for var_name, var_value in six.iteritems(kwargs): + self.__set_item(var_name, var_value) + + def __set_item(self, name, value): + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + + if name in self.openapi_types: + required_types_mixed = self.openapi_types[name] + elif self.additional_properties_type is None: + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + path_to_item + ) + elif self.additional_properties_type is not None: + required_types_mixed = self.additional_properties_type + + if get_simple_class(name) != str: + error_msg = type_error_message( + var_name=name, + var_value=name, + valid_classes=(str,), + key_type=True + ) + raise ApiTypeError( + error_msg, + path_to_item=path_to_item, + valid_classes=(str,), + key_type=True + ) - if name is not None: - self.name = ( - name + if self._check_type: + value = validate_and_convert_types( + value, required_types_mixed, path_to_item, self._from_server, + self._check_type, configuration=self._configuration) + if (name,) in self.allowed_values: + check_allowed_values( + self.allowed_values, + (name,), + value ) + if (name,) in self.validations: + check_validations( + self.validations, + (name,), + value + ) + self._data_store[name] = value + + def __get_item(self, name): + if name in self._data_store: + return self._data_store[name] + + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + [name] + ) + + def __setitem__(self, name, value): + """this allows us to set values with instance[field_name] = val""" + self.__set_item(name, value) + + def __getitem__(self, name): + """this allows us to get a value with val = instance[field_name]""" + return self.__get_item(name) @property def name(self): """Gets the name of this AdditionalPropertiesArray. # noqa: E501 - - :return: The name of this AdditionalPropertiesArray. # noqa: E501 - :rtype: str + Returns: + (str): The name of this AdditionalPropertiesArray. # noqa: E501 """ - return self._name + return self.__get_item('name') @name.setter - def name(self, name): # noqa: E501 - """Sets the name of this AdditionalPropertiesArray. - - - :param name: The name of this AdditionalPropertiesArray. # noqa: E501 - :type: str + def name(self, value): + """Sets the name of this AdditionalPropertiesArray. # noqa: E501 """ - - self._name = ( - name - ) + return self.__set_item('name', value) def to_dict(self): """Returns the model properties as a dict""" - result = {} - - for attr, _ in six.iteritems(self.openapi_types): - value = getattr(self, attr) - if isinstance(value, list): - result[attr] = list(map( - lambda x: x.to_dict() if hasattr(x, "to_dict") else x, - value - )) - elif hasattr(value, "to_dict"): - result[attr] = value.to_dict() - elif isinstance(value, dict): - result[attr] = dict(map( - lambda item: (item[0], item[1].to_dict()) - if hasattr(item[1], "to_dict") else item, - value.items() - )) - else: - result[attr] = value - - return result + return model_to_dict(self, serialize=False) def to_str(self): """Returns the string representation of the model""" @@ -133,7 +212,22 @@ def __eq__(self, other): if not isinstance(other, AdditionalPropertiesArray): return False - return self.__dict__ == other.__dict__ + if not set(self._data_store.keys()) == set(other._data_store.keys()): + return False + for _var_name, this_val in six.iteritems(self._data_store): + that_val = other._data_store[_var_name] + types = set() + types.add(this_val.__class__) + types.add(that_val.__class__) + vals_equal = this_val == that_val + if (not six.PY3 and + len(types) == 2 and unicode in types): # noqa: F821 + vals_equal = ( + this_val.encode('utf-8') == that_val.encode('utf-8') + ) + if not vals_equal: + return False + return True def __ne__(self, other): """Returns true if both objects are not equal""" diff --git a/samples/client/petstore/python-experimental/petstore_api/models/additional_properties_boolean.py b/samples/client/petstore/python-experimental/petstore_api/models/additional_properties_boolean.py index 70675c7d3aee..ee30aacc80bf 100644 --- a/samples/client/petstore/python-experimental/petstore_api/models/additional_properties_boolean.py +++ b/samples/client/petstore/python-experimental/petstore_api/models/additional_properties_boolean.py @@ -15,12 +15,26 @@ import six # noqa: F401 -from petstore_api.exceptions import ApiValueError # noqa: F401 +from petstore_api.exceptions import ( # noqa: F401 + ApiKeyError, + ApiTypeError, + ApiValueError, +) from petstore_api.model_utils import ( # noqa: F401 ModelNormal, ModelSimple, check_allowed_values, - check_validations + check_validations, + date, + datetime, + file_type, + get_simple_class, + int, + model_to_dict, + none_type, + str, + type_error_message, + validate_and_convert_types ) @@ -46,6 +60,8 @@ class AdditionalPropertiesBoolean(ModelNormal): 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 = { @@ -56,69 +72,132 @@ class AdditionalPropertiesBoolean(ModelNormal): } openapi_types = { - 'name': 'str' + 'name': (str,), # noqa: E501 } validations = { } - def __init__(self, name=None): # noqa: E501 - """AdditionalPropertiesBoolean - a model defined in OpenAPI""" # noqa: E501 - - self._name = None - self.discriminator = None + additional_properties_type = (bool,) # noqa: E501 + + discriminator = None + + def __init__(self, _check_type=True, _from_server=False, _path_to_item=(), _configuration=None, **kwargs): # noqa: E501 + """AdditionalPropertiesBoolean - 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 + _from_server (bool): True if the data is from the server + False if the data is from the client (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. + name (str): [optional] # noqa: E501 + """ + self._data_store = {} + self._check_type = _check_type + self._from_server = _from_server + self._path_to_item = _path_to_item + self._configuration = _configuration + + for var_name, var_value in six.iteritems(kwargs): + self.__set_item(var_name, var_value) + + def __set_item(self, name, value): + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + + if name in self.openapi_types: + required_types_mixed = self.openapi_types[name] + elif self.additional_properties_type is None: + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + path_to_item + ) + elif self.additional_properties_type is not None: + required_types_mixed = self.additional_properties_type + + if get_simple_class(name) != str: + error_msg = type_error_message( + var_name=name, + var_value=name, + valid_classes=(str,), + key_type=True + ) + raise ApiTypeError( + error_msg, + path_to_item=path_to_item, + valid_classes=(str,), + key_type=True + ) - if name is not None: - self.name = ( - name + if self._check_type: + value = validate_and_convert_types( + value, required_types_mixed, path_to_item, self._from_server, + self._check_type, configuration=self._configuration) + if (name,) in self.allowed_values: + check_allowed_values( + self.allowed_values, + (name,), + value ) + if (name,) in self.validations: + check_validations( + self.validations, + (name,), + value + ) + self._data_store[name] = value + + def __get_item(self, name): + if name in self._data_store: + return self._data_store[name] + + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + [name] + ) + + def __setitem__(self, name, value): + """this allows us to set values with instance[field_name] = val""" + self.__set_item(name, value) + + def __getitem__(self, name): + """this allows us to get a value with val = instance[field_name]""" + return self.__get_item(name) @property def name(self): """Gets the name of this AdditionalPropertiesBoolean. # noqa: E501 - - :return: The name of this AdditionalPropertiesBoolean. # noqa: E501 - :rtype: str + Returns: + (str): The name of this AdditionalPropertiesBoolean. # noqa: E501 """ - return self._name + return self.__get_item('name') @name.setter - def name(self, name): # noqa: E501 - """Sets the name of this AdditionalPropertiesBoolean. - - - :param name: The name of this AdditionalPropertiesBoolean. # noqa: E501 - :type: str + def name(self, value): + """Sets the name of this AdditionalPropertiesBoolean. # noqa: E501 """ - - self._name = ( - name - ) + return self.__set_item('name', value) def to_dict(self): """Returns the model properties as a dict""" - result = {} - - for attr, _ in six.iteritems(self.openapi_types): - value = getattr(self, attr) - if isinstance(value, list): - result[attr] = list(map( - lambda x: x.to_dict() if hasattr(x, "to_dict") else x, - value - )) - elif hasattr(value, "to_dict"): - result[attr] = value.to_dict() - elif isinstance(value, dict): - result[attr] = dict(map( - lambda item: (item[0], item[1].to_dict()) - if hasattr(item[1], "to_dict") else item, - value.items() - )) - else: - result[attr] = value - - return result + return model_to_dict(self, serialize=False) def to_str(self): """Returns the string representation of the model""" @@ -133,7 +212,22 @@ def __eq__(self, other): if not isinstance(other, AdditionalPropertiesBoolean): return False - return self.__dict__ == other.__dict__ + if not set(self._data_store.keys()) == set(other._data_store.keys()): + return False + for _var_name, this_val in six.iteritems(self._data_store): + that_val = other._data_store[_var_name] + types = set() + types.add(this_val.__class__) + types.add(that_val.__class__) + vals_equal = this_val == that_val + if (not six.PY3 and + len(types) == 2 and unicode in types): # noqa: F821 + vals_equal = ( + this_val.encode('utf-8') == that_val.encode('utf-8') + ) + if not vals_equal: + return False + return True def __ne__(self, other): """Returns true if both objects are not equal""" diff --git a/samples/client/petstore/python-experimental/petstore_api/models/additional_properties_class.py b/samples/client/petstore/python-experimental/petstore_api/models/additional_properties_class.py index efa4d6a09d19..407b63975b78 100644 --- a/samples/client/petstore/python-experimental/petstore_api/models/additional_properties_class.py +++ b/samples/client/petstore/python-experimental/petstore_api/models/additional_properties_class.py @@ -15,12 +15,26 @@ import six # noqa: F401 -from petstore_api.exceptions import ApiValueError # noqa: F401 +from petstore_api.exceptions import ( # noqa: F401 + ApiKeyError, + ApiTypeError, + ApiValueError, +) from petstore_api.model_utils import ( # noqa: F401 ModelNormal, ModelSimple, check_allowed_values, - check_validations + check_validations, + date, + datetime, + file_type, + get_simple_class, + int, + model_to_dict, + none_type, + str, + type_error_message, + validate_and_convert_types ) @@ -46,6 +60,8 @@ class AdditionalPropertiesClass(ModelNormal): 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 = { @@ -66,359 +82,302 @@ class AdditionalPropertiesClass(ModelNormal): } openapi_types = { - 'map_string': 'dict(str, str)', - 'map_number': 'dict(str, float)', - 'map_integer': 'dict(str, int)', - 'map_boolean': 'dict(str, bool)', - 'map_array_integer': 'dict(str, list[int])', - 'map_array_anytype': 'dict(str, list[object])', - 'map_map_string': 'dict(str, dict(str, str))', - 'map_map_anytype': 'dict(str, dict(str, object))', - 'anytype_1': 'object', - 'anytype_2': 'object', - 'anytype_3': 'object' + 'map_string': ({str: (str,)},), # noqa: E501 + 'map_number': ({str: (float,)},), # noqa: E501 + 'map_integer': ({str: (int,)},), # noqa: E501 + 'map_boolean': ({str: (bool,)},), # noqa: E501 + 'map_array_integer': ({str: ([int],)},), # noqa: E501 + 'map_array_anytype': ({str: ([bool, date, datetime, dict, float, int, list, str],)},), # noqa: E501 + 'map_map_string': ({str: ({str: (str,)},)},), # noqa: E501 + 'map_map_anytype': ({str: ({str: (bool, date, datetime, dict, float, int, list, str,)},)},), # noqa: E501 + 'anytype_1': (bool, date, datetime, dict, float, int, list, str,), # noqa: E501 + 'anytype_2': (bool, date, datetime, dict, float, int, list, str,), # noqa: E501 + 'anytype_3': (bool, date, datetime, dict, float, int, list, str,), # noqa: E501 } validations = { } - def __init__(self, map_string=None, map_number=None, map_integer=None, map_boolean=None, map_array_integer=None, map_array_anytype=None, map_map_string=None, map_map_anytype=None, anytype_1=None, anytype_2=None, anytype_3=None): # noqa: E501 - """AdditionalPropertiesClass - a model defined in OpenAPI""" # noqa: E501 - - self._map_string = None - self._map_number = None - self._map_integer = None - self._map_boolean = None - self._map_array_integer = None - self._map_array_anytype = None - self._map_map_string = None - self._map_map_anytype = None - self._anytype_1 = None - self._anytype_2 = None - self._anytype_3 = None - self.discriminator = None - - if map_string is not None: - self.map_string = ( - map_string - ) - if map_number is not None: - self.map_number = ( - map_number - ) - if map_integer is not None: - self.map_integer = ( - map_integer - ) - if map_boolean is not None: - self.map_boolean = ( - map_boolean - ) - if map_array_integer is not None: - self.map_array_integer = ( - map_array_integer - ) - if map_array_anytype is not None: - self.map_array_anytype = ( - map_array_anytype - ) - if map_map_string is not None: - self.map_map_string = ( - map_map_string + additional_properties_type = None + + discriminator = None + + def __init__(self, _check_type=True, _from_server=False, _path_to_item=(), _configuration=None, **kwargs): # noqa: E501 + """AdditionalPropertiesClass - 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 + _from_server (bool): True if the data is from the server + False if the data is from the client (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. + map_string ({str: (str,)}): [optional] # noqa: E501 + map_number ({str: (float,)}): [optional] # noqa: E501 + map_integer ({str: (int,)}): [optional] # noqa: E501 + map_boolean ({str: (bool,)}): [optional] # noqa: E501 + map_array_integer ({str: ([int],)}): [optional] # noqa: E501 + map_array_anytype ({str: ([bool, date, datetime, dict, float, int, list, str],)}): [optional] # noqa: E501 + map_map_string ({str: ({str: (str,)},)}): [optional] # noqa: E501 + map_map_anytype ({str: ({str: (bool, date, datetime, dict, float, int, list, str,)},)}): [optional] # noqa: E501 + anytype_1 (bool, date, datetime, dict, float, int, list, str): [optional] # noqa: E501 + anytype_2 (bool, date, datetime, dict, float, int, list, str): [optional] # noqa: E501 + anytype_3 (bool, date, datetime, dict, float, int, list, str): [optional] # noqa: E501 + """ + self._data_store = {} + self._check_type = _check_type + self._from_server = _from_server + self._path_to_item = _path_to_item + self._configuration = _configuration + + for var_name, var_value in six.iteritems(kwargs): + self.__set_item(var_name, var_value) + + def __set_item(self, name, value): + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + + if name in self.openapi_types: + required_types_mixed = self.openapi_types[name] + elif self.additional_properties_type is None: + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + path_to_item ) - if map_map_anytype is not None: - self.map_map_anytype = ( - map_map_anytype + elif self.additional_properties_type is not None: + required_types_mixed = self.additional_properties_type + + if get_simple_class(name) != str: + error_msg = type_error_message( + var_name=name, + var_value=name, + valid_classes=(str,), + key_type=True ) - if anytype_1 is not None: - self.anytype_1 = ( - anytype_1 + raise ApiTypeError( + error_msg, + path_to_item=path_to_item, + valid_classes=(str,), + key_type=True ) - if anytype_2 is not None: - self.anytype_2 = ( - anytype_2 + + if self._check_type: + value = validate_and_convert_types( + value, required_types_mixed, path_to_item, self._from_server, + self._check_type, configuration=self._configuration) + if (name,) in self.allowed_values: + check_allowed_values( + self.allowed_values, + (name,), + value ) - if anytype_3 is not None: - self.anytype_3 = ( - anytype_3 + if (name,) in self.validations: + check_validations( + self.validations, + (name,), + value ) + self._data_store[name] = value + + def __get_item(self, name): + if name in self._data_store: + return self._data_store[name] + + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + [name] + ) + + def __setitem__(self, name, value): + """this allows us to set values with instance[field_name] = val""" + self.__set_item(name, value) + + def __getitem__(self, name): + """this allows us to get a value with val = instance[field_name]""" + return self.__get_item(name) @property def map_string(self): """Gets the map_string of this AdditionalPropertiesClass. # noqa: E501 - - :return: The map_string of this AdditionalPropertiesClass. # noqa: E501 - :rtype: dict(str, str) + Returns: + ({str: (str,)}): The map_string of this AdditionalPropertiesClass. # noqa: E501 """ - return self._map_string + return self.__get_item('map_string') @map_string.setter - def map_string(self, map_string): # noqa: E501 - """Sets the map_string of this AdditionalPropertiesClass. - - - :param map_string: The map_string of this AdditionalPropertiesClass. # noqa: E501 - :type: dict(str, str) + def map_string(self, value): + """Sets the map_string of this AdditionalPropertiesClass. # noqa: E501 """ - - self._map_string = ( - map_string - ) + return self.__set_item('map_string', value) @property def map_number(self): """Gets the map_number of this AdditionalPropertiesClass. # noqa: E501 - - :return: The map_number of this AdditionalPropertiesClass. # noqa: E501 - :rtype: dict(str, float) + Returns: + ({str: (float,)}): The map_number of this AdditionalPropertiesClass. # noqa: E501 """ - return self._map_number + return self.__get_item('map_number') @map_number.setter - def map_number(self, map_number): # noqa: E501 - """Sets the map_number of this AdditionalPropertiesClass. - - - :param map_number: The map_number of this AdditionalPropertiesClass. # noqa: E501 - :type: dict(str, float) + def map_number(self, value): + """Sets the map_number of this AdditionalPropertiesClass. # noqa: E501 """ - - self._map_number = ( - map_number - ) + return self.__set_item('map_number', value) @property def map_integer(self): """Gets the map_integer of this AdditionalPropertiesClass. # noqa: E501 - - :return: The map_integer of this AdditionalPropertiesClass. # noqa: E501 - :rtype: dict(str, int) + Returns: + ({str: (int,)}): The map_integer of this AdditionalPropertiesClass. # noqa: E501 """ - return self._map_integer + return self.__get_item('map_integer') @map_integer.setter - def map_integer(self, map_integer): # noqa: E501 - """Sets the map_integer of this AdditionalPropertiesClass. - - - :param map_integer: The map_integer of this AdditionalPropertiesClass. # noqa: E501 - :type: dict(str, int) + def map_integer(self, value): + """Sets the map_integer of this AdditionalPropertiesClass. # noqa: E501 """ - - self._map_integer = ( - map_integer - ) + return self.__set_item('map_integer', value) @property def map_boolean(self): """Gets the map_boolean of this AdditionalPropertiesClass. # noqa: E501 - - :return: The map_boolean of this AdditionalPropertiesClass. # noqa: E501 - :rtype: dict(str, bool) + Returns: + ({str: (bool,)}): The map_boolean of this AdditionalPropertiesClass. # noqa: E501 """ - return self._map_boolean + return self.__get_item('map_boolean') @map_boolean.setter - def map_boolean(self, map_boolean): # noqa: E501 - """Sets the map_boolean of this AdditionalPropertiesClass. - - - :param map_boolean: The map_boolean of this AdditionalPropertiesClass. # noqa: E501 - :type: dict(str, bool) + def map_boolean(self, value): + """Sets the map_boolean of this AdditionalPropertiesClass. # noqa: E501 """ - - self._map_boolean = ( - map_boolean - ) + return self.__set_item('map_boolean', value) @property def map_array_integer(self): """Gets the map_array_integer of this AdditionalPropertiesClass. # noqa: E501 - - :return: The map_array_integer of this AdditionalPropertiesClass. # noqa: E501 - :rtype: dict(str, list[int]) + Returns: + ({str: ([int],)}): The map_array_integer of this AdditionalPropertiesClass. # noqa: E501 """ - return self._map_array_integer + return self.__get_item('map_array_integer') @map_array_integer.setter - def map_array_integer(self, map_array_integer): # noqa: E501 - """Sets the map_array_integer of this AdditionalPropertiesClass. - - - :param map_array_integer: The map_array_integer of this AdditionalPropertiesClass. # noqa: E501 - :type: dict(str, list[int]) + def map_array_integer(self, value): + """Sets the map_array_integer of this AdditionalPropertiesClass. # noqa: E501 """ - - self._map_array_integer = ( - map_array_integer - ) + return self.__set_item('map_array_integer', value) @property def map_array_anytype(self): """Gets the map_array_anytype of this AdditionalPropertiesClass. # noqa: E501 - - :return: The map_array_anytype of this AdditionalPropertiesClass. # noqa: E501 - :rtype: dict(str, list[object]) + Returns: + ({str: ([bool, date, datetime, dict, float, int, list, str],)}): The map_array_anytype of this AdditionalPropertiesClass. # noqa: E501 """ - return self._map_array_anytype + return self.__get_item('map_array_anytype') @map_array_anytype.setter - def map_array_anytype(self, map_array_anytype): # noqa: E501 - """Sets the map_array_anytype of this AdditionalPropertiesClass. - - - :param map_array_anytype: The map_array_anytype of this AdditionalPropertiesClass. # noqa: E501 - :type: dict(str, list[object]) + def map_array_anytype(self, value): + """Sets the map_array_anytype of this AdditionalPropertiesClass. # noqa: E501 """ - - self._map_array_anytype = ( - map_array_anytype - ) + return self.__set_item('map_array_anytype', value) @property def map_map_string(self): """Gets the map_map_string of this AdditionalPropertiesClass. # noqa: E501 - - :return: The map_map_string of this AdditionalPropertiesClass. # noqa: E501 - :rtype: dict(str, dict(str, str)) + Returns: + ({str: ({str: (str,)},)}): The map_map_string of this AdditionalPropertiesClass. # noqa: E501 """ - return self._map_map_string + return self.__get_item('map_map_string') @map_map_string.setter - def map_map_string(self, map_map_string): # noqa: E501 - """Sets the map_map_string of this AdditionalPropertiesClass. - - - :param map_map_string: The map_map_string of this AdditionalPropertiesClass. # noqa: E501 - :type: dict(str, dict(str, str)) + def map_map_string(self, value): + """Sets the map_map_string of this AdditionalPropertiesClass. # noqa: E501 """ - - self._map_map_string = ( - map_map_string - ) + return self.__set_item('map_map_string', value) @property def map_map_anytype(self): """Gets the map_map_anytype of this AdditionalPropertiesClass. # noqa: E501 - - :return: The map_map_anytype of this AdditionalPropertiesClass. # noqa: E501 - :rtype: dict(str, dict(str, object)) + Returns: + ({str: ({str: (bool, date, datetime, dict, float, int, list, str,)},)}): The map_map_anytype of this AdditionalPropertiesClass. # noqa: E501 """ - return self._map_map_anytype + return self.__get_item('map_map_anytype') @map_map_anytype.setter - def map_map_anytype(self, map_map_anytype): # noqa: E501 - """Sets the map_map_anytype of this AdditionalPropertiesClass. - - - :param map_map_anytype: The map_map_anytype of this AdditionalPropertiesClass. # noqa: E501 - :type: dict(str, dict(str, object)) + def map_map_anytype(self, value): + """Sets the map_map_anytype of this AdditionalPropertiesClass. # noqa: E501 """ - - self._map_map_anytype = ( - map_map_anytype - ) + return self.__set_item('map_map_anytype', value) @property def anytype_1(self): """Gets the anytype_1 of this AdditionalPropertiesClass. # noqa: E501 - - :return: The anytype_1 of this AdditionalPropertiesClass. # noqa: E501 - :rtype: object + Returns: + (bool, date, datetime, dict, float, int, list, str): The anytype_1 of this AdditionalPropertiesClass. # noqa: E501 """ - return self._anytype_1 + return self.__get_item('anytype_1') @anytype_1.setter - def anytype_1(self, anytype_1): # noqa: E501 - """Sets the anytype_1 of this AdditionalPropertiesClass. - - - :param anytype_1: The anytype_1 of this AdditionalPropertiesClass. # noqa: E501 - :type: object + def anytype_1(self, value): + """Sets the anytype_1 of this AdditionalPropertiesClass. # noqa: E501 """ - - self._anytype_1 = ( - anytype_1 - ) + return self.__set_item('anytype_1', value) @property def anytype_2(self): """Gets the anytype_2 of this AdditionalPropertiesClass. # noqa: E501 - - :return: The anytype_2 of this AdditionalPropertiesClass. # noqa: E501 - :rtype: object + Returns: + (bool, date, datetime, dict, float, int, list, str): The anytype_2 of this AdditionalPropertiesClass. # noqa: E501 """ - return self._anytype_2 + return self.__get_item('anytype_2') @anytype_2.setter - def anytype_2(self, anytype_2): # noqa: E501 - """Sets the anytype_2 of this AdditionalPropertiesClass. - - - :param anytype_2: The anytype_2 of this AdditionalPropertiesClass. # noqa: E501 - :type: object + def anytype_2(self, value): + """Sets the anytype_2 of this AdditionalPropertiesClass. # noqa: E501 """ - - self._anytype_2 = ( - anytype_2 - ) + return self.__set_item('anytype_2', value) @property def anytype_3(self): """Gets the anytype_3 of this AdditionalPropertiesClass. # noqa: E501 - - :return: The anytype_3 of this AdditionalPropertiesClass. # noqa: E501 - :rtype: object + Returns: + (bool, date, datetime, dict, float, int, list, str): The anytype_3 of this AdditionalPropertiesClass. # noqa: E501 """ - return self._anytype_3 + return self.__get_item('anytype_3') @anytype_3.setter - def anytype_3(self, anytype_3): # noqa: E501 - """Sets the anytype_3 of this AdditionalPropertiesClass. - - - :param anytype_3: The anytype_3 of this AdditionalPropertiesClass. # noqa: E501 - :type: object + def anytype_3(self, value): + """Sets the anytype_3 of this AdditionalPropertiesClass. # noqa: E501 """ - - self._anytype_3 = ( - anytype_3 - ) + return self.__set_item('anytype_3', value) def to_dict(self): """Returns the model properties as a dict""" - result = {} - - for attr, _ in six.iteritems(self.openapi_types): - value = getattr(self, attr) - if isinstance(value, list): - result[attr] = list(map( - lambda x: x.to_dict() if hasattr(x, "to_dict") else x, - value - )) - elif hasattr(value, "to_dict"): - result[attr] = value.to_dict() - elif isinstance(value, dict): - result[attr] = dict(map( - lambda item: (item[0], item[1].to_dict()) - if hasattr(item[1], "to_dict") else item, - value.items() - )) - else: - result[attr] = value - - return result + return model_to_dict(self, serialize=False) def to_str(self): """Returns the string representation of the model""" @@ -433,7 +392,22 @@ def __eq__(self, other): if not isinstance(other, AdditionalPropertiesClass): return False - return self.__dict__ == other.__dict__ + if not set(self._data_store.keys()) == set(other._data_store.keys()): + return False + for _var_name, this_val in six.iteritems(self._data_store): + that_val = other._data_store[_var_name] + types = set() + types.add(this_val.__class__) + types.add(that_val.__class__) + vals_equal = this_val == that_val + if (not six.PY3 and + len(types) == 2 and unicode in types): # noqa: F821 + vals_equal = ( + this_val.encode('utf-8') == that_val.encode('utf-8') + ) + if not vals_equal: + return False + return True def __ne__(self, other): """Returns true if both objects are not equal""" diff --git a/samples/client/petstore/python-experimental/petstore_api/models/additional_properties_integer.py b/samples/client/petstore/python-experimental/petstore_api/models/additional_properties_integer.py index 55ba58e1e20a..558f48422a43 100644 --- a/samples/client/petstore/python-experimental/petstore_api/models/additional_properties_integer.py +++ b/samples/client/petstore/python-experimental/petstore_api/models/additional_properties_integer.py @@ -15,12 +15,26 @@ import six # noqa: F401 -from petstore_api.exceptions import ApiValueError # noqa: F401 +from petstore_api.exceptions import ( # noqa: F401 + ApiKeyError, + ApiTypeError, + ApiValueError, +) from petstore_api.model_utils import ( # noqa: F401 ModelNormal, ModelSimple, check_allowed_values, - check_validations + check_validations, + date, + datetime, + file_type, + get_simple_class, + int, + model_to_dict, + none_type, + str, + type_error_message, + validate_and_convert_types ) @@ -46,6 +60,8 @@ class AdditionalPropertiesInteger(ModelNormal): 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 = { @@ -56,69 +72,132 @@ class AdditionalPropertiesInteger(ModelNormal): } openapi_types = { - 'name': 'str' + 'name': (str,), # noqa: E501 } validations = { } - def __init__(self, name=None): # noqa: E501 - """AdditionalPropertiesInteger - a model defined in OpenAPI""" # noqa: E501 - - self._name = None - self.discriminator = None + additional_properties_type = (int,) # noqa: E501 + + discriminator = None + + def __init__(self, _check_type=True, _from_server=False, _path_to_item=(), _configuration=None, **kwargs): # noqa: E501 + """AdditionalPropertiesInteger - 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 + _from_server (bool): True if the data is from the server + False if the data is from the client (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. + name (str): [optional] # noqa: E501 + """ + self._data_store = {} + self._check_type = _check_type + self._from_server = _from_server + self._path_to_item = _path_to_item + self._configuration = _configuration + + for var_name, var_value in six.iteritems(kwargs): + self.__set_item(var_name, var_value) + + def __set_item(self, name, value): + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + + if name in self.openapi_types: + required_types_mixed = self.openapi_types[name] + elif self.additional_properties_type is None: + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + path_to_item + ) + elif self.additional_properties_type is not None: + required_types_mixed = self.additional_properties_type + + if get_simple_class(name) != str: + error_msg = type_error_message( + var_name=name, + var_value=name, + valid_classes=(str,), + key_type=True + ) + raise ApiTypeError( + error_msg, + path_to_item=path_to_item, + valid_classes=(str,), + key_type=True + ) - if name is not None: - self.name = ( - name + if self._check_type: + value = validate_and_convert_types( + value, required_types_mixed, path_to_item, self._from_server, + self._check_type, configuration=self._configuration) + if (name,) in self.allowed_values: + check_allowed_values( + self.allowed_values, + (name,), + value ) + if (name,) in self.validations: + check_validations( + self.validations, + (name,), + value + ) + self._data_store[name] = value + + def __get_item(self, name): + if name in self._data_store: + return self._data_store[name] + + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + [name] + ) + + def __setitem__(self, name, value): + """this allows us to set values with instance[field_name] = val""" + self.__set_item(name, value) + + def __getitem__(self, name): + """this allows us to get a value with val = instance[field_name]""" + return self.__get_item(name) @property def name(self): """Gets the name of this AdditionalPropertiesInteger. # noqa: E501 - - :return: The name of this AdditionalPropertiesInteger. # noqa: E501 - :rtype: str + Returns: + (str): The name of this AdditionalPropertiesInteger. # noqa: E501 """ - return self._name + return self.__get_item('name') @name.setter - def name(self, name): # noqa: E501 - """Sets the name of this AdditionalPropertiesInteger. - - - :param name: The name of this AdditionalPropertiesInteger. # noqa: E501 - :type: str + def name(self, value): + """Sets the name of this AdditionalPropertiesInteger. # noqa: E501 """ - - self._name = ( - name - ) + return self.__set_item('name', value) def to_dict(self): """Returns the model properties as a dict""" - result = {} - - for attr, _ in six.iteritems(self.openapi_types): - value = getattr(self, attr) - if isinstance(value, list): - result[attr] = list(map( - lambda x: x.to_dict() if hasattr(x, "to_dict") else x, - value - )) - elif hasattr(value, "to_dict"): - result[attr] = value.to_dict() - elif isinstance(value, dict): - result[attr] = dict(map( - lambda item: (item[0], item[1].to_dict()) - if hasattr(item[1], "to_dict") else item, - value.items() - )) - else: - result[attr] = value - - return result + return model_to_dict(self, serialize=False) def to_str(self): """Returns the string representation of the model""" @@ -133,7 +212,22 @@ def __eq__(self, other): if not isinstance(other, AdditionalPropertiesInteger): return False - return self.__dict__ == other.__dict__ + if not set(self._data_store.keys()) == set(other._data_store.keys()): + return False + for _var_name, this_val in six.iteritems(self._data_store): + that_val = other._data_store[_var_name] + types = set() + types.add(this_val.__class__) + types.add(that_val.__class__) + vals_equal = this_val == that_val + if (not six.PY3 and + len(types) == 2 and unicode in types): # noqa: F821 + vals_equal = ( + this_val.encode('utf-8') == that_val.encode('utf-8') + ) + if not vals_equal: + return False + return True def __ne__(self, other): """Returns true if both objects are not equal""" diff --git a/samples/client/petstore/python-experimental/petstore_api/models/additional_properties_number.py b/samples/client/petstore/python-experimental/petstore_api/models/additional_properties_number.py index 32a59a5bc522..25c9298cea98 100644 --- a/samples/client/petstore/python-experimental/petstore_api/models/additional_properties_number.py +++ b/samples/client/petstore/python-experimental/petstore_api/models/additional_properties_number.py @@ -15,12 +15,26 @@ import six # noqa: F401 -from petstore_api.exceptions import ApiValueError # noqa: F401 +from petstore_api.exceptions import ( # noqa: F401 + ApiKeyError, + ApiTypeError, + ApiValueError, +) from petstore_api.model_utils import ( # noqa: F401 ModelNormal, ModelSimple, check_allowed_values, - check_validations + check_validations, + date, + datetime, + file_type, + get_simple_class, + int, + model_to_dict, + none_type, + str, + type_error_message, + validate_and_convert_types ) @@ -46,6 +60,8 @@ class AdditionalPropertiesNumber(ModelNormal): 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 = { @@ -56,69 +72,132 @@ class AdditionalPropertiesNumber(ModelNormal): } openapi_types = { - 'name': 'str' + 'name': (str,), # noqa: E501 } validations = { } - def __init__(self, name=None): # noqa: E501 - """AdditionalPropertiesNumber - a model defined in OpenAPI""" # noqa: E501 - - self._name = None - self.discriminator = None + additional_properties_type = (float,) # noqa: E501 + + discriminator = None + + def __init__(self, _check_type=True, _from_server=False, _path_to_item=(), _configuration=None, **kwargs): # noqa: E501 + """AdditionalPropertiesNumber - 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 + _from_server (bool): True if the data is from the server + False if the data is from the client (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. + name (str): [optional] # noqa: E501 + """ + self._data_store = {} + self._check_type = _check_type + self._from_server = _from_server + self._path_to_item = _path_to_item + self._configuration = _configuration + + for var_name, var_value in six.iteritems(kwargs): + self.__set_item(var_name, var_value) + + def __set_item(self, name, value): + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + + if name in self.openapi_types: + required_types_mixed = self.openapi_types[name] + elif self.additional_properties_type is None: + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + path_to_item + ) + elif self.additional_properties_type is not None: + required_types_mixed = self.additional_properties_type + + if get_simple_class(name) != str: + error_msg = type_error_message( + var_name=name, + var_value=name, + valid_classes=(str,), + key_type=True + ) + raise ApiTypeError( + error_msg, + path_to_item=path_to_item, + valid_classes=(str,), + key_type=True + ) - if name is not None: - self.name = ( - name + if self._check_type: + value = validate_and_convert_types( + value, required_types_mixed, path_to_item, self._from_server, + self._check_type, configuration=self._configuration) + if (name,) in self.allowed_values: + check_allowed_values( + self.allowed_values, + (name,), + value ) + if (name,) in self.validations: + check_validations( + self.validations, + (name,), + value + ) + self._data_store[name] = value + + def __get_item(self, name): + if name in self._data_store: + return self._data_store[name] + + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + [name] + ) + + def __setitem__(self, name, value): + """this allows us to set values with instance[field_name] = val""" + self.__set_item(name, value) + + def __getitem__(self, name): + """this allows us to get a value with val = instance[field_name]""" + return self.__get_item(name) @property def name(self): """Gets the name of this AdditionalPropertiesNumber. # noqa: E501 - - :return: The name of this AdditionalPropertiesNumber. # noqa: E501 - :rtype: str + Returns: + (str): The name of this AdditionalPropertiesNumber. # noqa: E501 """ - return self._name + return self.__get_item('name') @name.setter - def name(self, name): # noqa: E501 - """Sets the name of this AdditionalPropertiesNumber. - - - :param name: The name of this AdditionalPropertiesNumber. # noqa: E501 - :type: str + def name(self, value): + """Sets the name of this AdditionalPropertiesNumber. # noqa: E501 """ - - self._name = ( - name - ) + return self.__set_item('name', value) def to_dict(self): """Returns the model properties as a dict""" - result = {} - - for attr, _ in six.iteritems(self.openapi_types): - value = getattr(self, attr) - if isinstance(value, list): - result[attr] = list(map( - lambda x: x.to_dict() if hasattr(x, "to_dict") else x, - value - )) - elif hasattr(value, "to_dict"): - result[attr] = value.to_dict() - elif isinstance(value, dict): - result[attr] = dict(map( - lambda item: (item[0], item[1].to_dict()) - if hasattr(item[1], "to_dict") else item, - value.items() - )) - else: - result[attr] = value - - return result + return model_to_dict(self, serialize=False) def to_str(self): """Returns the string representation of the model""" @@ -133,7 +212,22 @@ def __eq__(self, other): if not isinstance(other, AdditionalPropertiesNumber): return False - return self.__dict__ == other.__dict__ + if not set(self._data_store.keys()) == set(other._data_store.keys()): + return False + for _var_name, this_val in six.iteritems(self._data_store): + that_val = other._data_store[_var_name] + types = set() + types.add(this_val.__class__) + types.add(that_val.__class__) + vals_equal = this_val == that_val + if (not six.PY3 and + len(types) == 2 and unicode in types): # noqa: F821 + vals_equal = ( + this_val.encode('utf-8') == that_val.encode('utf-8') + ) + if not vals_equal: + return False + return True def __ne__(self, other): """Returns true if both objects are not equal""" diff --git a/samples/client/petstore/python-experimental/petstore_api/models/additional_properties_object.py b/samples/client/petstore/python-experimental/petstore_api/models/additional_properties_object.py index 362023c8460e..67acc4099b8a 100644 --- a/samples/client/petstore/python-experimental/petstore_api/models/additional_properties_object.py +++ b/samples/client/petstore/python-experimental/petstore_api/models/additional_properties_object.py @@ -15,12 +15,26 @@ import six # noqa: F401 -from petstore_api.exceptions import ApiValueError # noqa: F401 +from petstore_api.exceptions import ( # noqa: F401 + ApiKeyError, + ApiTypeError, + ApiValueError, +) from petstore_api.model_utils import ( # noqa: F401 ModelNormal, ModelSimple, check_allowed_values, - check_validations + check_validations, + date, + datetime, + file_type, + get_simple_class, + int, + model_to_dict, + none_type, + str, + type_error_message, + validate_and_convert_types ) @@ -46,6 +60,8 @@ class AdditionalPropertiesObject(ModelNormal): 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 = { @@ -56,69 +72,132 @@ class AdditionalPropertiesObject(ModelNormal): } openapi_types = { - 'name': 'str' + 'name': (str,), # noqa: E501 } validations = { } - def __init__(self, name=None): # noqa: E501 - """AdditionalPropertiesObject - a model defined in OpenAPI""" # noqa: E501 - - self._name = None - self.discriminator = None + additional_properties_type = ({str: (bool, date, datetime, dict, float, int, list, str,)},) # noqa: E501 + + discriminator = None + + def __init__(self, _check_type=True, _from_server=False, _path_to_item=(), _configuration=None, **kwargs): # noqa: E501 + """AdditionalPropertiesObject - 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 + _from_server (bool): True if the data is from the server + False if the data is from the client (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. + name (str): [optional] # noqa: E501 + """ + self._data_store = {} + self._check_type = _check_type + self._from_server = _from_server + self._path_to_item = _path_to_item + self._configuration = _configuration + + for var_name, var_value in six.iteritems(kwargs): + self.__set_item(var_name, var_value) + + def __set_item(self, name, value): + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + + if name in self.openapi_types: + required_types_mixed = self.openapi_types[name] + elif self.additional_properties_type is None: + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + path_to_item + ) + elif self.additional_properties_type is not None: + required_types_mixed = self.additional_properties_type + + if get_simple_class(name) != str: + error_msg = type_error_message( + var_name=name, + var_value=name, + valid_classes=(str,), + key_type=True + ) + raise ApiTypeError( + error_msg, + path_to_item=path_to_item, + valid_classes=(str,), + key_type=True + ) - if name is not None: - self.name = ( - name + if self._check_type: + value = validate_and_convert_types( + value, required_types_mixed, path_to_item, self._from_server, + self._check_type, configuration=self._configuration) + if (name,) in self.allowed_values: + check_allowed_values( + self.allowed_values, + (name,), + value ) + if (name,) in self.validations: + check_validations( + self.validations, + (name,), + value + ) + self._data_store[name] = value + + def __get_item(self, name): + if name in self._data_store: + return self._data_store[name] + + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + [name] + ) + + def __setitem__(self, name, value): + """this allows us to set values with instance[field_name] = val""" + self.__set_item(name, value) + + def __getitem__(self, name): + """this allows us to get a value with val = instance[field_name]""" + return self.__get_item(name) @property def name(self): """Gets the name of this AdditionalPropertiesObject. # noqa: E501 - - :return: The name of this AdditionalPropertiesObject. # noqa: E501 - :rtype: str + Returns: + (str): The name of this AdditionalPropertiesObject. # noqa: E501 """ - return self._name + return self.__get_item('name') @name.setter - def name(self, name): # noqa: E501 - """Sets the name of this AdditionalPropertiesObject. - - - :param name: The name of this AdditionalPropertiesObject. # noqa: E501 - :type: str + def name(self, value): + """Sets the name of this AdditionalPropertiesObject. # noqa: E501 """ - - self._name = ( - name - ) + return self.__set_item('name', value) def to_dict(self): """Returns the model properties as a dict""" - result = {} - - for attr, _ in six.iteritems(self.openapi_types): - value = getattr(self, attr) - if isinstance(value, list): - result[attr] = list(map( - lambda x: x.to_dict() if hasattr(x, "to_dict") else x, - value - )) - elif hasattr(value, "to_dict"): - result[attr] = value.to_dict() - elif isinstance(value, dict): - result[attr] = dict(map( - lambda item: (item[0], item[1].to_dict()) - if hasattr(item[1], "to_dict") else item, - value.items() - )) - else: - result[attr] = value - - return result + return model_to_dict(self, serialize=False) def to_str(self): """Returns the string representation of the model""" @@ -133,7 +212,22 @@ def __eq__(self, other): if not isinstance(other, AdditionalPropertiesObject): return False - return self.__dict__ == other.__dict__ + if not set(self._data_store.keys()) == set(other._data_store.keys()): + return False + for _var_name, this_val in six.iteritems(self._data_store): + that_val = other._data_store[_var_name] + types = set() + types.add(this_val.__class__) + types.add(that_val.__class__) + vals_equal = this_val == that_val + if (not six.PY3 and + len(types) == 2 and unicode in types): # noqa: F821 + vals_equal = ( + this_val.encode('utf-8') == that_val.encode('utf-8') + ) + if not vals_equal: + return False + return True def __ne__(self, other): """Returns true if both objects are not equal""" diff --git a/samples/client/petstore/python-experimental/petstore_api/models/additional_properties_string.py b/samples/client/petstore/python-experimental/petstore_api/models/additional_properties_string.py index e01ff7028f23..5906157a158c 100644 --- a/samples/client/petstore/python-experimental/petstore_api/models/additional_properties_string.py +++ b/samples/client/petstore/python-experimental/petstore_api/models/additional_properties_string.py @@ -15,12 +15,26 @@ import six # noqa: F401 -from petstore_api.exceptions import ApiValueError # noqa: F401 +from petstore_api.exceptions import ( # noqa: F401 + ApiKeyError, + ApiTypeError, + ApiValueError, +) from petstore_api.model_utils import ( # noqa: F401 ModelNormal, ModelSimple, check_allowed_values, - check_validations + check_validations, + date, + datetime, + file_type, + get_simple_class, + int, + model_to_dict, + none_type, + str, + type_error_message, + validate_and_convert_types ) @@ -46,6 +60,8 @@ class AdditionalPropertiesString(ModelNormal): 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 = { @@ -56,69 +72,132 @@ class AdditionalPropertiesString(ModelNormal): } openapi_types = { - 'name': 'str' + 'name': (str,), # noqa: E501 } validations = { } - def __init__(self, name=None): # noqa: E501 - """AdditionalPropertiesString - a model defined in OpenAPI""" # noqa: E501 - - self._name = None - self.discriminator = None + additional_properties_type = (str,) # noqa: E501 + + discriminator = None + + def __init__(self, _check_type=True, _from_server=False, _path_to_item=(), _configuration=None, **kwargs): # noqa: E501 + """AdditionalPropertiesString - 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 + _from_server (bool): True if the data is from the server + False if the data is from the client (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. + name (str): [optional] # noqa: E501 + """ + self._data_store = {} + self._check_type = _check_type + self._from_server = _from_server + self._path_to_item = _path_to_item + self._configuration = _configuration + + for var_name, var_value in six.iteritems(kwargs): + self.__set_item(var_name, var_value) + + def __set_item(self, name, value): + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + + if name in self.openapi_types: + required_types_mixed = self.openapi_types[name] + elif self.additional_properties_type is None: + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + path_to_item + ) + elif self.additional_properties_type is not None: + required_types_mixed = self.additional_properties_type + + if get_simple_class(name) != str: + error_msg = type_error_message( + var_name=name, + var_value=name, + valid_classes=(str,), + key_type=True + ) + raise ApiTypeError( + error_msg, + path_to_item=path_to_item, + valid_classes=(str,), + key_type=True + ) - if name is not None: - self.name = ( - name + if self._check_type: + value = validate_and_convert_types( + value, required_types_mixed, path_to_item, self._from_server, + self._check_type, configuration=self._configuration) + if (name,) in self.allowed_values: + check_allowed_values( + self.allowed_values, + (name,), + value ) + if (name,) in self.validations: + check_validations( + self.validations, + (name,), + value + ) + self._data_store[name] = value + + def __get_item(self, name): + if name in self._data_store: + return self._data_store[name] + + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + [name] + ) + + def __setitem__(self, name, value): + """this allows us to set values with instance[field_name] = val""" + self.__set_item(name, value) + + def __getitem__(self, name): + """this allows us to get a value with val = instance[field_name]""" + return self.__get_item(name) @property def name(self): """Gets the name of this AdditionalPropertiesString. # noqa: E501 - - :return: The name of this AdditionalPropertiesString. # noqa: E501 - :rtype: str + Returns: + (str): The name of this AdditionalPropertiesString. # noqa: E501 """ - return self._name + return self.__get_item('name') @name.setter - def name(self, name): # noqa: E501 - """Sets the name of this AdditionalPropertiesString. - - - :param name: The name of this AdditionalPropertiesString. # noqa: E501 - :type: str + def name(self, value): + """Sets the name of this AdditionalPropertiesString. # noqa: E501 """ - - self._name = ( - name - ) + return self.__set_item('name', value) def to_dict(self): """Returns the model properties as a dict""" - result = {} - - for attr, _ in six.iteritems(self.openapi_types): - value = getattr(self, attr) - if isinstance(value, list): - result[attr] = list(map( - lambda x: x.to_dict() if hasattr(x, "to_dict") else x, - value - )) - elif hasattr(value, "to_dict"): - result[attr] = value.to_dict() - elif isinstance(value, dict): - result[attr] = dict(map( - lambda item: (item[0], item[1].to_dict()) - if hasattr(item[1], "to_dict") else item, - value.items() - )) - else: - result[attr] = value - - return result + return model_to_dict(self, serialize=False) def to_str(self): """Returns the string representation of the model""" @@ -133,7 +212,22 @@ def __eq__(self, other): if not isinstance(other, AdditionalPropertiesString): return False - return self.__dict__ == other.__dict__ + if not set(self._data_store.keys()) == set(other._data_store.keys()): + return False + for _var_name, this_val in six.iteritems(self._data_store): + that_val = other._data_store[_var_name] + types = set() + types.add(this_val.__class__) + types.add(that_val.__class__) + vals_equal = this_val == that_val + if (not six.PY3 and + len(types) == 2 and unicode in types): # noqa: F821 + vals_equal = ( + this_val.encode('utf-8') == that_val.encode('utf-8') + ) + if not vals_equal: + return False + return True def __ne__(self, other): """Returns true if both objects are not equal""" diff --git a/samples/client/petstore/python-experimental/petstore_api/models/animal.py b/samples/client/petstore/python-experimental/petstore_api/models/animal.py index a2ce846a64d7..d625389dd634 100644 --- a/samples/client/petstore/python-experimental/petstore_api/models/animal.py +++ b/samples/client/petstore/python-experimental/petstore_api/models/animal.py @@ -15,13 +15,29 @@ import six # noqa: F401 -from petstore_api.exceptions import ApiValueError # noqa: F401 +from petstore_api.exceptions import ( # noqa: F401 + ApiKeyError, + ApiTypeError, + ApiValueError, +) from petstore_api.model_utils import ( # noqa: F401 ModelNormal, ModelSimple, check_allowed_values, - check_validations + check_validations, + date, + datetime, + file_type, + get_simple_class, + int, + model_to_dict, + none_type, + str, + type_error_message, + validate_and_convert_types ) +from petstore_api.models.cat import Cat +from petstore_api.models.dog import Dog class Animal(ModelNormal): @@ -46,6 +62,8 @@ class Animal(ModelNormal): 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 = { @@ -57,108 +75,165 @@ class Animal(ModelNormal): } discriminator_value_class_map = { - 'Dog': 'Dog', - 'Cat': 'Cat' + 'Dog': Dog, + 'Cat': Cat } openapi_types = { - 'class_name': 'str', - 'color': 'str' + 'class_name': (str,), # noqa: E501 + 'color': (str,), # noqa: E501 } validations = { } - def __init__(self, class_name=None, color='red'): # noqa: E501 - """Animal - a model defined in OpenAPI""" # noqa: E501 - - self._class_name = None - self._color = None - self.discriminator = 'class_name' + additional_properties_type = None + + discriminator = 'class_name' + + def __init__(self, class_name, _check_type=True, _from_server=False, _path_to_item=(), _configuration=None, **kwargs): # noqa: E501 + """Animal - a model defined in OpenAPI + + Args: + class_name (str): + + 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 + _from_server (bool): True if the data is from the server + False if the data is from the client (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. + color (str): [optional] if omitted the server will use the default value of 'red' # noqa: E501 + """ + self._data_store = {} + self._check_type = _check_type + self._from_server = _from_server + self._path_to_item = _path_to_item + self._configuration = _configuration + + self.__set_item('class_name', class_name) + for var_name, var_value in six.iteritems(kwargs): + self.__set_item(var_name, var_value) + + def __set_item(self, name, value): + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + + if name in self.openapi_types: + required_types_mixed = self.openapi_types[name] + elif self.additional_properties_type is None: + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + path_to_item + ) + elif self.additional_properties_type is not None: + required_types_mixed = self.additional_properties_type + + if get_simple_class(name) != str: + error_msg = type_error_message( + var_name=name, + var_value=name, + valid_classes=(str,), + key_type=True + ) + raise ApiTypeError( + error_msg, + path_to_item=path_to_item, + valid_classes=(str,), + key_type=True + ) - self.class_name = class_name - if color is not None: - self.color = ( - color + if self._check_type: + value = validate_and_convert_types( + value, required_types_mixed, path_to_item, self._from_server, + self._check_type, configuration=self._configuration) + if (name,) in self.allowed_values: + check_allowed_values( + self.allowed_values, + (name,), + value ) + if (name,) in self.validations: + check_validations( + self.validations, + (name,), + value + ) + self._data_store[name] = value + + def __get_item(self, name): + if name in self._data_store: + return self._data_store[name] + + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + [name] + ) + + def __setitem__(self, name, value): + """this allows us to set values with instance[field_name] = val""" + self.__set_item(name, value) + + def __getitem__(self, name): + """this allows us to get a value with val = instance[field_name]""" + return self.__get_item(name) @property def class_name(self): """Gets the class_name of this Animal. # noqa: E501 - - :return: The class_name of this Animal. # noqa: E501 - :rtype: str + Returns: + (str): The class_name of this Animal. # noqa: E501 """ - return self._class_name + return self.__get_item('class_name') @class_name.setter - def class_name(self, class_name): # noqa: E501 - """Sets the class_name of this Animal. - - - :param class_name: The class_name of this Animal. # noqa: E501 - :type: str + def class_name(self, value): + """Sets the class_name of this Animal. # noqa: E501 """ - if class_name is None: - raise ApiValueError("Invalid value for `class_name`, must not be `None`") # noqa: E501 - - self._class_name = ( - class_name - ) + return self.__set_item('class_name', value) @property def color(self): """Gets the color of this Animal. # noqa: E501 - - :return: The color of this Animal. # noqa: E501 - :rtype: str + Returns: + (str): The color of this Animal. # noqa: E501 """ - return self._color + return self.__get_item('color') @color.setter - def color(self, color): # noqa: E501 - """Sets the color of this Animal. - - - :param color: The color of this Animal. # noqa: E501 - :type: str + def color(self, value): + """Sets the color of this Animal. # noqa: E501 """ + return self.__set_item('color', value) - self._color = ( - color - ) - - def get_real_child_model(self, data): - """Returns the real base class specified by the discriminator""" - discriminator_key = self.attribute_map[self.discriminator] + @classmethod + def get_real_child_model(cls, data): + """Returns the real base class specified by the discriminator + We assume that data has javascript keys + """ + discriminator_key = cls.attribute_map[cls.discriminator] discriminator_value = data[discriminator_key] - return self.discriminator_value_class_map.get(discriminator_value) + return cls.discriminator_value_class_map.get(discriminator_value) def to_dict(self): """Returns the model properties as a dict""" - result = {} - - for attr, _ in six.iteritems(self.openapi_types): - value = getattr(self, attr) - if isinstance(value, list): - result[attr] = list(map( - lambda x: x.to_dict() if hasattr(x, "to_dict") else x, - value - )) - elif hasattr(value, "to_dict"): - result[attr] = value.to_dict() - elif isinstance(value, dict): - result[attr] = dict(map( - lambda item: (item[0], item[1].to_dict()) - if hasattr(item[1], "to_dict") else item, - value.items() - )) - else: - result[attr] = value - - return result + return model_to_dict(self, serialize=False) def to_str(self): """Returns the string representation of the model""" @@ -173,7 +248,22 @@ def __eq__(self, other): if not isinstance(other, Animal): return False - return self.__dict__ == other.__dict__ + if not set(self._data_store.keys()) == set(other._data_store.keys()): + return False + for _var_name, this_val in six.iteritems(self._data_store): + that_val = other._data_store[_var_name] + types = set() + types.add(this_val.__class__) + types.add(that_val.__class__) + vals_equal = this_val == that_val + if (not six.PY3 and + len(types) == 2 and unicode in types): # noqa: F821 + vals_equal = ( + this_val.encode('utf-8') == that_val.encode('utf-8') + ) + if not vals_equal: + return False + return True def __ne__(self, other): """Returns true if both objects are not equal""" diff --git a/samples/client/petstore/python-experimental/petstore_api/models/api_response.py b/samples/client/petstore/python-experimental/petstore_api/models/api_response.py index 4f9f3a12bd47..40713b75479a 100644 --- a/samples/client/petstore/python-experimental/petstore_api/models/api_response.py +++ b/samples/client/petstore/python-experimental/petstore_api/models/api_response.py @@ -15,12 +15,26 @@ import six # noqa: F401 -from petstore_api.exceptions import ApiValueError # noqa: F401 +from petstore_api.exceptions import ( # noqa: F401 + ApiKeyError, + ApiTypeError, + ApiValueError, +) from petstore_api.model_utils import ( # noqa: F401 ModelNormal, ModelSimple, check_allowed_values, - check_validations + check_validations, + date, + datetime, + file_type, + get_simple_class, + int, + model_to_dict, + none_type, + str, + type_error_message, + validate_and_convert_types ) @@ -46,6 +60,8 @@ class ApiResponse(ModelNormal): 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 = { @@ -58,127 +74,166 @@ class ApiResponse(ModelNormal): } openapi_types = { - 'code': 'int', - 'type': 'str', - 'message': 'str' + 'code': (int,), # noqa: E501 + 'type': (str,), # noqa: E501 + 'message': (str,), # noqa: E501 } validations = { } - def __init__(self, code=None, type=None, message=None): # noqa: E501 - """ApiResponse - a model defined in OpenAPI""" # noqa: E501 - - self._code = None - self._type = None - self._message = None - self.discriminator = None - - if code is not None: - self.code = ( - code + additional_properties_type = None + + discriminator = None + + def __init__(self, _check_type=True, _from_server=False, _path_to_item=(), _configuration=None, **kwargs): # noqa: E501 + """ApiResponse - 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 + _from_server (bool): True if the data is from the server + False if the data is from the client (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. + code (int): [optional] # noqa: E501 + type (str): [optional] # noqa: E501 + message (str): [optional] # noqa: E501 + """ + self._data_store = {} + self._check_type = _check_type + self._from_server = _from_server + self._path_to_item = _path_to_item + self._configuration = _configuration + + for var_name, var_value in six.iteritems(kwargs): + self.__set_item(var_name, var_value) + + def __set_item(self, name, value): + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + + if name in self.openapi_types: + required_types_mixed = self.openapi_types[name] + elif self.additional_properties_type is None: + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + path_to_item ) - if type is not None: - self.type = ( - type + elif self.additional_properties_type is not None: + required_types_mixed = self.additional_properties_type + + if get_simple_class(name) != str: + error_msg = type_error_message( + var_name=name, + var_value=name, + valid_classes=(str,), + key_type=True ) - if message is not None: - self.message = ( - message + raise ApiTypeError( + error_msg, + path_to_item=path_to_item, + valid_classes=(str,), + key_type=True ) + if self._check_type: + value = validate_and_convert_types( + value, required_types_mixed, path_to_item, self._from_server, + self._check_type, configuration=self._configuration) + if (name,) in self.allowed_values: + check_allowed_values( + self.allowed_values, + (name,), + value + ) + if (name,) in self.validations: + check_validations( + self.validations, + (name,), + value + ) + self._data_store[name] = value + + def __get_item(self, name): + if name in self._data_store: + return self._data_store[name] + + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + [name] + ) + + def __setitem__(self, name, value): + """this allows us to set values with instance[field_name] = val""" + self.__set_item(name, value) + + def __getitem__(self, name): + """this allows us to get a value with val = instance[field_name]""" + return self.__get_item(name) + @property def code(self): """Gets the code of this ApiResponse. # noqa: E501 - - :return: The code of this ApiResponse. # noqa: E501 - :rtype: int + Returns: + (int): The code of this ApiResponse. # noqa: E501 """ - return self._code + return self.__get_item('code') @code.setter - def code(self, code): # noqa: E501 - """Sets the code of this ApiResponse. - - - :param code: The code of this ApiResponse. # noqa: E501 - :type: int + def code(self, value): + """Sets the code of this ApiResponse. # noqa: E501 """ - - self._code = ( - code - ) + return self.__set_item('code', value) @property def type(self): """Gets the type of this ApiResponse. # noqa: E501 - - :return: The type of this ApiResponse. # noqa: E501 - :rtype: str + Returns: + (str): The type of this ApiResponse. # noqa: E501 """ - return self._type + return self.__get_item('type') @type.setter - def type(self, type): # noqa: E501 - """Sets the type of this ApiResponse. - - - :param type: The type of this ApiResponse. # noqa: E501 - :type: str + def type(self, value): + """Sets the type of this ApiResponse. # noqa: E501 """ - - self._type = ( - type - ) + return self.__set_item('type', value) @property def message(self): """Gets the message of this ApiResponse. # noqa: E501 - - :return: The message of this ApiResponse. # noqa: E501 - :rtype: str + Returns: + (str): The message of this ApiResponse. # noqa: E501 """ - return self._message + return self.__get_item('message') @message.setter - def message(self, message): # noqa: E501 - """Sets the message of this ApiResponse. - - - :param message: The message of this ApiResponse. # noqa: E501 - :type: str + def message(self, value): + """Sets the message of this ApiResponse. # noqa: E501 """ - - self._message = ( - message - ) + return self.__set_item('message', value) def to_dict(self): """Returns the model properties as a dict""" - result = {} - - for attr, _ in six.iteritems(self.openapi_types): - value = getattr(self, attr) - if isinstance(value, list): - result[attr] = list(map( - lambda x: x.to_dict() if hasattr(x, "to_dict") else x, - value - )) - elif hasattr(value, "to_dict"): - result[attr] = value.to_dict() - elif isinstance(value, dict): - result[attr] = dict(map( - lambda item: (item[0], item[1].to_dict()) - if hasattr(item[1], "to_dict") else item, - value.items() - )) - else: - result[attr] = value - - return result + return model_to_dict(self, serialize=False) def to_str(self): """Returns the string representation of the model""" @@ -193,7 +248,22 @@ def __eq__(self, other): if not isinstance(other, ApiResponse): return False - return self.__dict__ == other.__dict__ + if not set(self._data_store.keys()) == set(other._data_store.keys()): + return False + for _var_name, this_val in six.iteritems(self._data_store): + that_val = other._data_store[_var_name] + types = set() + types.add(this_val.__class__) + types.add(that_val.__class__) + vals_equal = this_val == that_val + if (not six.PY3 and + len(types) == 2 and unicode in types): # noqa: F821 + vals_equal = ( + this_val.encode('utf-8') == that_val.encode('utf-8') + ) + if not vals_equal: + return False + return True def __ne__(self, other): """Returns true if both objects are not equal""" diff --git a/samples/client/petstore/python-experimental/petstore_api/models/array_of_array_of_number_only.py b/samples/client/petstore/python-experimental/petstore_api/models/array_of_array_of_number_only.py index 2beb87728306..a2e3c7326a68 100644 --- a/samples/client/petstore/python-experimental/petstore_api/models/array_of_array_of_number_only.py +++ b/samples/client/petstore/python-experimental/petstore_api/models/array_of_array_of_number_only.py @@ -15,12 +15,26 @@ import six # noqa: F401 -from petstore_api.exceptions import ApiValueError # noqa: F401 +from petstore_api.exceptions import ( # noqa: F401 + ApiKeyError, + ApiTypeError, + ApiValueError, +) from petstore_api.model_utils import ( # noqa: F401 ModelNormal, ModelSimple, check_allowed_values, - check_validations + check_validations, + date, + datetime, + file_type, + get_simple_class, + int, + model_to_dict, + none_type, + str, + type_error_message, + validate_and_convert_types ) @@ -46,6 +60,8 @@ class ArrayOfArrayOfNumberOnly(ModelNormal): 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 = { @@ -56,69 +72,132 @@ class ArrayOfArrayOfNumberOnly(ModelNormal): } openapi_types = { - 'array_array_number': 'list[list[float]]' + 'array_array_number': ([[float]],), # noqa: E501 } validations = { } - def __init__(self, array_array_number=None): # noqa: E501 - """ArrayOfArrayOfNumberOnly - a model defined in OpenAPI""" # noqa: E501 - - self._array_array_number = None - self.discriminator = None + additional_properties_type = None + + discriminator = None + + def __init__(self, _check_type=True, _from_server=False, _path_to_item=(), _configuration=None, **kwargs): # noqa: E501 + """ArrayOfArrayOfNumberOnly - 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 + _from_server (bool): True if the data is from the server + False if the data is from the client (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. + array_array_number ([[float]]): [optional] # noqa: E501 + """ + self._data_store = {} + self._check_type = _check_type + self._from_server = _from_server + self._path_to_item = _path_to_item + self._configuration = _configuration + + for var_name, var_value in six.iteritems(kwargs): + self.__set_item(var_name, var_value) + + def __set_item(self, name, value): + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + + if name in self.openapi_types: + required_types_mixed = self.openapi_types[name] + elif self.additional_properties_type is None: + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + path_to_item + ) + elif self.additional_properties_type is not None: + required_types_mixed = self.additional_properties_type + + if get_simple_class(name) != str: + error_msg = type_error_message( + var_name=name, + var_value=name, + valid_classes=(str,), + key_type=True + ) + raise ApiTypeError( + error_msg, + path_to_item=path_to_item, + valid_classes=(str,), + key_type=True + ) - if array_array_number is not None: - self.array_array_number = ( - array_array_number + if self._check_type: + value = validate_and_convert_types( + value, required_types_mixed, path_to_item, self._from_server, + self._check_type, configuration=self._configuration) + if (name,) in self.allowed_values: + check_allowed_values( + self.allowed_values, + (name,), + value ) + if (name,) in self.validations: + check_validations( + self.validations, + (name,), + value + ) + self._data_store[name] = value + + def __get_item(self, name): + if name in self._data_store: + return self._data_store[name] + + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + [name] + ) + + def __setitem__(self, name, value): + """this allows us to set values with instance[field_name] = val""" + self.__set_item(name, value) + + def __getitem__(self, name): + """this allows us to get a value with val = instance[field_name]""" + return self.__get_item(name) @property def array_array_number(self): """Gets the array_array_number of this ArrayOfArrayOfNumberOnly. # noqa: E501 - - :return: The array_array_number of this ArrayOfArrayOfNumberOnly. # noqa: E501 - :rtype: list[list[float]] + Returns: + ([[float]]): The array_array_number of this ArrayOfArrayOfNumberOnly. # noqa: E501 """ - return self._array_array_number + return self.__get_item('array_array_number') @array_array_number.setter - def array_array_number(self, array_array_number): # noqa: E501 - """Sets the array_array_number of this ArrayOfArrayOfNumberOnly. - - - :param array_array_number: The array_array_number of this ArrayOfArrayOfNumberOnly. # noqa: E501 - :type: list[list[float]] + def array_array_number(self, value): + """Sets the array_array_number of this ArrayOfArrayOfNumberOnly. # noqa: E501 """ - - self._array_array_number = ( - array_array_number - ) + return self.__set_item('array_array_number', value) def to_dict(self): """Returns the model properties as a dict""" - result = {} - - for attr, _ in six.iteritems(self.openapi_types): - value = getattr(self, attr) - if isinstance(value, list): - result[attr] = list(map( - lambda x: x.to_dict() if hasattr(x, "to_dict") else x, - value - )) - elif hasattr(value, "to_dict"): - result[attr] = value.to_dict() - elif isinstance(value, dict): - result[attr] = dict(map( - lambda item: (item[0], item[1].to_dict()) - if hasattr(item[1], "to_dict") else item, - value.items() - )) - else: - result[attr] = value - - return result + return model_to_dict(self, serialize=False) def to_str(self): """Returns the string representation of the model""" @@ -133,7 +212,22 @@ def __eq__(self, other): if not isinstance(other, ArrayOfArrayOfNumberOnly): return False - return self.__dict__ == other.__dict__ + if not set(self._data_store.keys()) == set(other._data_store.keys()): + return False + for _var_name, this_val in six.iteritems(self._data_store): + that_val = other._data_store[_var_name] + types = set() + types.add(this_val.__class__) + types.add(that_val.__class__) + vals_equal = this_val == that_val + if (not six.PY3 and + len(types) == 2 and unicode in types): # noqa: F821 + vals_equal = ( + this_val.encode('utf-8') == that_val.encode('utf-8') + ) + if not vals_equal: + return False + return True def __ne__(self, other): """Returns true if both objects are not equal""" diff --git a/samples/client/petstore/python-experimental/petstore_api/models/array_of_number_only.py b/samples/client/petstore/python-experimental/petstore_api/models/array_of_number_only.py index 7c67bcf59d77..c35c8e59631c 100644 --- a/samples/client/petstore/python-experimental/petstore_api/models/array_of_number_only.py +++ b/samples/client/petstore/python-experimental/petstore_api/models/array_of_number_only.py @@ -15,12 +15,26 @@ import six # noqa: F401 -from petstore_api.exceptions import ApiValueError # noqa: F401 +from petstore_api.exceptions import ( # noqa: F401 + ApiKeyError, + ApiTypeError, + ApiValueError, +) from petstore_api.model_utils import ( # noqa: F401 ModelNormal, ModelSimple, check_allowed_values, - check_validations + check_validations, + date, + datetime, + file_type, + get_simple_class, + int, + model_to_dict, + none_type, + str, + type_error_message, + validate_and_convert_types ) @@ -46,6 +60,8 @@ class ArrayOfNumberOnly(ModelNormal): 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 = { @@ -56,69 +72,132 @@ class ArrayOfNumberOnly(ModelNormal): } openapi_types = { - 'array_number': 'list[float]' + 'array_number': ([float],), # noqa: E501 } validations = { } - def __init__(self, array_number=None): # noqa: E501 - """ArrayOfNumberOnly - a model defined in OpenAPI""" # noqa: E501 - - self._array_number = None - self.discriminator = None + additional_properties_type = None + + discriminator = None + + def __init__(self, _check_type=True, _from_server=False, _path_to_item=(), _configuration=None, **kwargs): # noqa: E501 + """ArrayOfNumberOnly - 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 + _from_server (bool): True if the data is from the server + False if the data is from the client (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. + array_number ([float]): [optional] # noqa: E501 + """ + self._data_store = {} + self._check_type = _check_type + self._from_server = _from_server + self._path_to_item = _path_to_item + self._configuration = _configuration + + for var_name, var_value in six.iteritems(kwargs): + self.__set_item(var_name, var_value) + + def __set_item(self, name, value): + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + + if name in self.openapi_types: + required_types_mixed = self.openapi_types[name] + elif self.additional_properties_type is None: + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + path_to_item + ) + elif self.additional_properties_type is not None: + required_types_mixed = self.additional_properties_type + + if get_simple_class(name) != str: + error_msg = type_error_message( + var_name=name, + var_value=name, + valid_classes=(str,), + key_type=True + ) + raise ApiTypeError( + error_msg, + path_to_item=path_to_item, + valid_classes=(str,), + key_type=True + ) - if array_number is not None: - self.array_number = ( - array_number + if self._check_type: + value = validate_and_convert_types( + value, required_types_mixed, path_to_item, self._from_server, + self._check_type, configuration=self._configuration) + if (name,) in self.allowed_values: + check_allowed_values( + self.allowed_values, + (name,), + value ) + if (name,) in self.validations: + check_validations( + self.validations, + (name,), + value + ) + self._data_store[name] = value + + def __get_item(self, name): + if name in self._data_store: + return self._data_store[name] + + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + [name] + ) + + def __setitem__(self, name, value): + """this allows us to set values with instance[field_name] = val""" + self.__set_item(name, value) + + def __getitem__(self, name): + """this allows us to get a value with val = instance[field_name]""" + return self.__get_item(name) @property def array_number(self): """Gets the array_number of this ArrayOfNumberOnly. # noqa: E501 - - :return: The array_number of this ArrayOfNumberOnly. # noqa: E501 - :rtype: list[float] + Returns: + ([float]): The array_number of this ArrayOfNumberOnly. # noqa: E501 """ - return self._array_number + return self.__get_item('array_number') @array_number.setter - def array_number(self, array_number): # noqa: E501 - """Sets the array_number of this ArrayOfNumberOnly. - - - :param array_number: The array_number of this ArrayOfNumberOnly. # noqa: E501 - :type: list[float] + def array_number(self, value): + """Sets the array_number of this ArrayOfNumberOnly. # noqa: E501 """ - - self._array_number = ( - array_number - ) + return self.__set_item('array_number', value) def to_dict(self): """Returns the model properties as a dict""" - result = {} - - for attr, _ in six.iteritems(self.openapi_types): - value = getattr(self, attr) - if isinstance(value, list): - result[attr] = list(map( - lambda x: x.to_dict() if hasattr(x, "to_dict") else x, - value - )) - elif hasattr(value, "to_dict"): - result[attr] = value.to_dict() - elif isinstance(value, dict): - result[attr] = dict(map( - lambda item: (item[0], item[1].to_dict()) - if hasattr(item[1], "to_dict") else item, - value.items() - )) - else: - result[attr] = value - - return result + return model_to_dict(self, serialize=False) def to_str(self): """Returns the string representation of the model""" @@ -133,7 +212,22 @@ def __eq__(self, other): if not isinstance(other, ArrayOfNumberOnly): return False - return self.__dict__ == other.__dict__ + if not set(self._data_store.keys()) == set(other._data_store.keys()): + return False + for _var_name, this_val in six.iteritems(self._data_store): + that_val = other._data_store[_var_name] + types = set() + types.add(this_val.__class__) + types.add(that_val.__class__) + vals_equal = this_val == that_val + if (not six.PY3 and + len(types) == 2 and unicode in types): # noqa: F821 + vals_equal = ( + this_val.encode('utf-8') == that_val.encode('utf-8') + ) + if not vals_equal: + return False + return True def __ne__(self, other): """Returns true if both objects are not equal""" diff --git a/samples/client/petstore/python-experimental/petstore_api/models/array_test.py b/samples/client/petstore/python-experimental/petstore_api/models/array_test.py index adcb8690dea0..cc52f04d318f 100644 --- a/samples/client/petstore/python-experimental/petstore_api/models/array_test.py +++ b/samples/client/petstore/python-experimental/petstore_api/models/array_test.py @@ -15,13 +15,28 @@ import six # noqa: F401 -from petstore_api.exceptions import ApiValueError # noqa: F401 +from petstore_api.exceptions import ( # noqa: F401 + ApiKeyError, + ApiTypeError, + ApiValueError, +) from petstore_api.model_utils import ( # noqa: F401 ModelNormal, ModelSimple, check_allowed_values, - check_validations + check_validations, + date, + datetime, + file_type, + get_simple_class, + int, + model_to_dict, + none_type, + str, + type_error_message, + validate_and_convert_types ) +from petstore_api.models.read_only_first import ReadOnlyFirst class ArrayTest(ModelNormal): @@ -46,6 +61,8 @@ class ArrayTest(ModelNormal): 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 = { @@ -58,127 +75,166 @@ class ArrayTest(ModelNormal): } openapi_types = { - 'array_of_string': 'list[str]', - 'array_array_of_integer': 'list[list[int]]', - 'array_array_of_model': 'list[list[ReadOnlyFirst]]' + 'array_of_string': ([str],), # noqa: E501 + 'array_array_of_integer': ([[int]],), # noqa: E501 + 'array_array_of_model': ([[ReadOnlyFirst]],), # noqa: E501 } validations = { } - def __init__(self, array_of_string=None, array_array_of_integer=None, array_array_of_model=None): # noqa: E501 - """ArrayTest - a model defined in OpenAPI""" # noqa: E501 - - self._array_of_string = None - self._array_array_of_integer = None - self._array_array_of_model = None - self.discriminator = None - - if array_of_string is not None: - self.array_of_string = ( - array_of_string + additional_properties_type = None + + discriminator = None + + def __init__(self, _check_type=True, _from_server=False, _path_to_item=(), _configuration=None, **kwargs): # noqa: E501 + """ArrayTest - 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 + _from_server (bool): True if the data is from the server + False if the data is from the client (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. + array_of_string ([str]): [optional] # noqa: E501 + array_array_of_integer ([[int]]): [optional] # noqa: E501 + array_array_of_model ([[ReadOnlyFirst]]): [optional] # noqa: E501 + """ + self._data_store = {} + self._check_type = _check_type + self._from_server = _from_server + self._path_to_item = _path_to_item + self._configuration = _configuration + + for var_name, var_value in six.iteritems(kwargs): + self.__set_item(var_name, var_value) + + def __set_item(self, name, value): + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + + if name in self.openapi_types: + required_types_mixed = self.openapi_types[name] + elif self.additional_properties_type is None: + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + path_to_item ) - if array_array_of_integer is not None: - self.array_array_of_integer = ( - array_array_of_integer + elif self.additional_properties_type is not None: + required_types_mixed = self.additional_properties_type + + if get_simple_class(name) != str: + error_msg = type_error_message( + var_name=name, + var_value=name, + valid_classes=(str,), + key_type=True ) - if array_array_of_model is not None: - self.array_array_of_model = ( - array_array_of_model + raise ApiTypeError( + error_msg, + path_to_item=path_to_item, + valid_classes=(str,), + key_type=True ) + if self._check_type: + value = validate_and_convert_types( + value, required_types_mixed, path_to_item, self._from_server, + self._check_type, configuration=self._configuration) + if (name,) in self.allowed_values: + check_allowed_values( + self.allowed_values, + (name,), + value + ) + if (name,) in self.validations: + check_validations( + self.validations, + (name,), + value + ) + self._data_store[name] = value + + def __get_item(self, name): + if name in self._data_store: + return self._data_store[name] + + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + [name] + ) + + def __setitem__(self, name, value): + """this allows us to set values with instance[field_name] = val""" + self.__set_item(name, value) + + def __getitem__(self, name): + """this allows us to get a value with val = instance[field_name]""" + return self.__get_item(name) + @property def array_of_string(self): """Gets the array_of_string of this ArrayTest. # noqa: E501 - - :return: The array_of_string of this ArrayTest. # noqa: E501 - :rtype: list[str] + Returns: + ([str]): The array_of_string of this ArrayTest. # noqa: E501 """ - return self._array_of_string + return self.__get_item('array_of_string') @array_of_string.setter - def array_of_string(self, array_of_string): # noqa: E501 - """Sets the array_of_string of this ArrayTest. - - - :param array_of_string: The array_of_string of this ArrayTest. # noqa: E501 - :type: list[str] + def array_of_string(self, value): + """Sets the array_of_string of this ArrayTest. # noqa: E501 """ - - self._array_of_string = ( - array_of_string - ) + return self.__set_item('array_of_string', value) @property def array_array_of_integer(self): """Gets the array_array_of_integer of this ArrayTest. # noqa: E501 - - :return: The array_array_of_integer of this ArrayTest. # noqa: E501 - :rtype: list[list[int]] + Returns: + ([[int]]): The array_array_of_integer of this ArrayTest. # noqa: E501 """ - return self._array_array_of_integer + return self.__get_item('array_array_of_integer') @array_array_of_integer.setter - def array_array_of_integer(self, array_array_of_integer): # noqa: E501 - """Sets the array_array_of_integer of this ArrayTest. - - - :param array_array_of_integer: The array_array_of_integer of this ArrayTest. # noqa: E501 - :type: list[list[int]] + def array_array_of_integer(self, value): + """Sets the array_array_of_integer of this ArrayTest. # noqa: E501 """ - - self._array_array_of_integer = ( - array_array_of_integer - ) + return self.__set_item('array_array_of_integer', value) @property def array_array_of_model(self): """Gets the array_array_of_model of this ArrayTest. # noqa: E501 - - :return: The array_array_of_model of this ArrayTest. # noqa: E501 - :rtype: list[list[ReadOnlyFirst]] + Returns: + ([[ReadOnlyFirst]]): The array_array_of_model of this ArrayTest. # noqa: E501 """ - return self._array_array_of_model + return self.__get_item('array_array_of_model') @array_array_of_model.setter - def array_array_of_model(self, array_array_of_model): # noqa: E501 - """Sets the array_array_of_model of this ArrayTest. - - - :param array_array_of_model: The array_array_of_model of this ArrayTest. # noqa: E501 - :type: list[list[ReadOnlyFirst]] + def array_array_of_model(self, value): + """Sets the array_array_of_model of this ArrayTest. # noqa: E501 """ - - self._array_array_of_model = ( - array_array_of_model - ) + return self.__set_item('array_array_of_model', value) def to_dict(self): """Returns the model properties as a dict""" - result = {} - - for attr, _ in six.iteritems(self.openapi_types): - value = getattr(self, attr) - if isinstance(value, list): - result[attr] = list(map( - lambda x: x.to_dict() if hasattr(x, "to_dict") else x, - value - )) - elif hasattr(value, "to_dict"): - result[attr] = value.to_dict() - elif isinstance(value, dict): - result[attr] = dict(map( - lambda item: (item[0], item[1].to_dict()) - if hasattr(item[1], "to_dict") else item, - value.items() - )) - else: - result[attr] = value - - return result + return model_to_dict(self, serialize=False) def to_str(self): """Returns the string representation of the model""" @@ -193,7 +249,22 @@ def __eq__(self, other): if not isinstance(other, ArrayTest): return False - return self.__dict__ == other.__dict__ + if not set(self._data_store.keys()) == set(other._data_store.keys()): + return False + for _var_name, this_val in six.iteritems(self._data_store): + that_val = other._data_store[_var_name] + types = set() + types.add(this_val.__class__) + types.add(that_val.__class__) + vals_equal = this_val == that_val + if (not six.PY3 and + len(types) == 2 and unicode in types): # noqa: F821 + vals_equal = ( + this_val.encode('utf-8') == that_val.encode('utf-8') + ) + if not vals_equal: + return False + return True def __ne__(self, other): """Returns true if both objects are not equal""" diff --git a/samples/client/petstore/python-experimental/petstore_api/models/capitalization.py b/samples/client/petstore/python-experimental/petstore_api/models/capitalization.py index 5eeafb5ac7bc..9134f5e4251f 100644 --- a/samples/client/petstore/python-experimental/petstore_api/models/capitalization.py +++ b/samples/client/petstore/python-experimental/petstore_api/models/capitalization.py @@ -15,12 +15,26 @@ import six # noqa: F401 -from petstore_api.exceptions import ApiValueError # noqa: F401 +from petstore_api.exceptions import ( # noqa: F401 + ApiKeyError, + ApiTypeError, + ApiValueError, +) from petstore_api.model_utils import ( # noqa: F401 ModelNormal, ModelSimple, check_allowed_values, - check_validations + check_validations, + date, + datetime, + file_type, + get_simple_class, + int, + model_to_dict, + none_type, + str, + type_error_message, + validate_and_convert_types ) @@ -46,6 +60,8 @@ class Capitalization(ModelNormal): 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 = { @@ -61,216 +77,219 @@ class Capitalization(ModelNormal): } openapi_types = { - 'small_camel': 'str', - 'capital_camel': 'str', - 'small_snake': 'str', - 'capital_snake': 'str', - 'sca_eth_flow_points': 'str', - 'att_name': 'str' + 'small_camel': (str,), # noqa: E501 + 'capital_camel': (str,), # noqa: E501 + 'small_snake': (str,), # noqa: E501 + 'capital_snake': (str,), # noqa: E501 + 'sca_eth_flow_points': (str,), # noqa: E501 + 'att_name': (str,), # noqa: E501 } validations = { } - def __init__(self, small_camel=None, capital_camel=None, small_snake=None, capital_snake=None, sca_eth_flow_points=None, att_name=None): # noqa: E501 - """Capitalization - a model defined in OpenAPI""" # noqa: E501 - - self._small_camel = None - self._capital_camel = None - self._small_snake = None - self._capital_snake = None - self._sca_eth_flow_points = None - self._att_name = None - self.discriminator = None - - if small_camel is not None: - self.small_camel = ( - small_camel - ) - if capital_camel is not None: - self.capital_camel = ( - capital_camel + additional_properties_type = None + + discriminator = None + + def __init__(self, _check_type=True, _from_server=False, _path_to_item=(), _configuration=None, **kwargs): # noqa: E501 + """Capitalization - 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 + _from_server (bool): True if the data is from the server + False if the data is from the client (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. + small_camel (str): [optional] # noqa: E501 + capital_camel (str): [optional] # noqa: E501 + small_snake (str): [optional] # noqa: E501 + capital_snake (str): [optional] # noqa: E501 + sca_eth_flow_points (str): [optional] # noqa: E501 + att_name (str): Name of the pet . [optional] # noqa: E501 + """ + self._data_store = {} + self._check_type = _check_type + self._from_server = _from_server + self._path_to_item = _path_to_item + self._configuration = _configuration + + for var_name, var_value in six.iteritems(kwargs): + self.__set_item(var_name, var_value) + + def __set_item(self, name, value): + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + + if name in self.openapi_types: + required_types_mixed = self.openapi_types[name] + elif self.additional_properties_type is None: + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + path_to_item ) - if small_snake is not None: - self.small_snake = ( - small_snake + elif self.additional_properties_type is not None: + required_types_mixed = self.additional_properties_type + + if get_simple_class(name) != str: + error_msg = type_error_message( + var_name=name, + var_value=name, + valid_classes=(str,), + key_type=True ) - if capital_snake is not None: - self.capital_snake = ( - capital_snake + raise ApiTypeError( + error_msg, + path_to_item=path_to_item, + valid_classes=(str,), + key_type=True ) - if sca_eth_flow_points is not None: - self.sca_eth_flow_points = ( - sca_eth_flow_points + + if self._check_type: + value = validate_and_convert_types( + value, required_types_mixed, path_to_item, self._from_server, + self._check_type, configuration=self._configuration) + if (name,) in self.allowed_values: + check_allowed_values( + self.allowed_values, + (name,), + value ) - if att_name is not None: - self.att_name = ( - att_name + if (name,) in self.validations: + check_validations( + self.validations, + (name,), + value ) + self._data_store[name] = value + + def __get_item(self, name): + if name in self._data_store: + return self._data_store[name] + + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + [name] + ) + + def __setitem__(self, name, value): + """this allows us to set values with instance[field_name] = val""" + self.__set_item(name, value) + + def __getitem__(self, name): + """this allows us to get a value with val = instance[field_name]""" + return self.__get_item(name) @property def small_camel(self): """Gets the small_camel of this Capitalization. # noqa: E501 - - :return: The small_camel of this Capitalization. # noqa: E501 - :rtype: str + Returns: + (str): The small_camel of this Capitalization. # noqa: E501 """ - return self._small_camel + return self.__get_item('small_camel') @small_camel.setter - def small_camel(self, small_camel): # noqa: E501 - """Sets the small_camel of this Capitalization. - - - :param small_camel: The small_camel of this Capitalization. # noqa: E501 - :type: str + def small_camel(self, value): + """Sets the small_camel of this Capitalization. # noqa: E501 """ - - self._small_camel = ( - small_camel - ) + return self.__set_item('small_camel', value) @property def capital_camel(self): """Gets the capital_camel of this Capitalization. # noqa: E501 - - :return: The capital_camel of this Capitalization. # noqa: E501 - :rtype: str + Returns: + (str): The capital_camel of this Capitalization. # noqa: E501 """ - return self._capital_camel + return self.__get_item('capital_camel') @capital_camel.setter - def capital_camel(self, capital_camel): # noqa: E501 - """Sets the capital_camel of this Capitalization. - - - :param capital_camel: The capital_camel of this Capitalization. # noqa: E501 - :type: str + def capital_camel(self, value): + """Sets the capital_camel of this Capitalization. # noqa: E501 """ - - self._capital_camel = ( - capital_camel - ) + return self.__set_item('capital_camel', value) @property def small_snake(self): """Gets the small_snake of this Capitalization. # noqa: E501 - - :return: The small_snake of this Capitalization. # noqa: E501 - :rtype: str + Returns: + (str): The small_snake of this Capitalization. # noqa: E501 """ - return self._small_snake + return self.__get_item('small_snake') @small_snake.setter - def small_snake(self, small_snake): # noqa: E501 - """Sets the small_snake of this Capitalization. - - - :param small_snake: The small_snake of this Capitalization. # noqa: E501 - :type: str + def small_snake(self, value): + """Sets the small_snake of this Capitalization. # noqa: E501 """ - - self._small_snake = ( - small_snake - ) + return self.__set_item('small_snake', value) @property def capital_snake(self): """Gets the capital_snake of this Capitalization. # noqa: E501 - - :return: The capital_snake of this Capitalization. # noqa: E501 - :rtype: str + Returns: + (str): The capital_snake of this Capitalization. # noqa: E501 """ - return self._capital_snake + return self.__get_item('capital_snake') @capital_snake.setter - def capital_snake(self, capital_snake): # noqa: E501 - """Sets the capital_snake of this Capitalization. - - - :param capital_snake: The capital_snake of this Capitalization. # noqa: E501 - :type: str + def capital_snake(self, value): + """Sets the capital_snake of this Capitalization. # noqa: E501 """ - - self._capital_snake = ( - capital_snake - ) + return self.__set_item('capital_snake', value) @property def sca_eth_flow_points(self): """Gets the sca_eth_flow_points of this Capitalization. # noqa: E501 - - :return: The sca_eth_flow_points of this Capitalization. # noqa: E501 - :rtype: str + Returns: + (str): The sca_eth_flow_points of this Capitalization. # noqa: E501 """ - return self._sca_eth_flow_points + return self.__get_item('sca_eth_flow_points') @sca_eth_flow_points.setter - def sca_eth_flow_points(self, sca_eth_flow_points): # noqa: E501 - """Sets the sca_eth_flow_points of this Capitalization. - - - :param sca_eth_flow_points: The sca_eth_flow_points of this Capitalization. # noqa: E501 - :type: str + def sca_eth_flow_points(self, value): + """Sets the sca_eth_flow_points of this Capitalization. # noqa: E501 """ - - self._sca_eth_flow_points = ( - sca_eth_flow_points - ) + return self.__set_item('sca_eth_flow_points', value) @property def att_name(self): """Gets the att_name of this Capitalization. # noqa: E501 - Name of the pet # noqa: E501 - :return: The att_name of this Capitalization. # noqa: E501 - :rtype: str + Returns: + (str): The att_name of this Capitalization. # noqa: E501 """ - return self._att_name + return self.__get_item('att_name') @att_name.setter - def att_name(self, att_name): # noqa: E501 - """Sets the att_name of this Capitalization. - + def att_name(self, value): + """Sets the att_name of this Capitalization. # noqa: E501 Name of the pet # noqa: E501 - - :param att_name: The att_name of this Capitalization. # noqa: E501 - :type: str """ - - self._att_name = ( - att_name - ) + return self.__set_item('att_name', value) def to_dict(self): """Returns the model properties as a dict""" - result = {} - - for attr, _ in six.iteritems(self.openapi_types): - value = getattr(self, attr) - if isinstance(value, list): - result[attr] = list(map( - lambda x: x.to_dict() if hasattr(x, "to_dict") else x, - value - )) - elif hasattr(value, "to_dict"): - result[attr] = value.to_dict() - elif isinstance(value, dict): - result[attr] = dict(map( - lambda item: (item[0], item[1].to_dict()) - if hasattr(item[1], "to_dict") else item, - value.items() - )) - else: - result[attr] = value - - return result + return model_to_dict(self, serialize=False) def to_str(self): """Returns the string representation of the model""" @@ -285,7 +304,22 @@ def __eq__(self, other): if not isinstance(other, Capitalization): return False - return self.__dict__ == other.__dict__ + if not set(self._data_store.keys()) == set(other._data_store.keys()): + return False + for _var_name, this_val in six.iteritems(self._data_store): + that_val = other._data_store[_var_name] + types = set() + types.add(this_val.__class__) + types.add(that_val.__class__) + vals_equal = this_val == that_val + if (not six.PY3 and + len(types) == 2 and unicode in types): # noqa: F821 + vals_equal = ( + this_val.encode('utf-8') == that_val.encode('utf-8') + ) + if not vals_equal: + return False + return True def __ne__(self, other): """Returns true if both objects are not equal""" diff --git a/samples/client/petstore/python-experimental/petstore_api/models/cat.py b/samples/client/petstore/python-experimental/petstore_api/models/cat.py index b496a13fe98e..40508dd3ce79 100644 --- a/samples/client/petstore/python-experimental/petstore_api/models/cat.py +++ b/samples/client/petstore/python-experimental/petstore_api/models/cat.py @@ -15,12 +15,26 @@ import six # noqa: F401 -from petstore_api.exceptions import ApiValueError # noqa: F401 +from petstore_api.exceptions import ( # noqa: F401 + ApiKeyError, + ApiTypeError, + ApiValueError, +) from petstore_api.model_utils import ( # noqa: F401 ModelNormal, ModelSimple, check_allowed_values, - check_validations + check_validations, + date, + datetime, + file_type, + get_simple_class, + int, + model_to_dict, + none_type, + str, + type_error_message, + validate_and_convert_types ) @@ -46,79 +60,182 @@ class Cat(ModelNormal): 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 = { } attribute_map = { + 'class_name': 'className', # noqa: E501 + 'color': 'color', # noqa: E501 'declawed': 'declawed' # noqa: E501 } openapi_types = { - 'declawed': 'bool' + 'class_name': (str,), # noqa: E501 + 'color': (str,), # noqa: E501 + 'declawed': (bool,), # noqa: E501 } validations = { } - def __init__(self, declawed=None): # noqa: E501 - """Cat - a model defined in OpenAPI""" # noqa: E501 - - self._declawed = None - self.discriminator = None + additional_properties_type = None + + discriminator = None + + def __init__(self, class_name, _check_type=True, _from_server=False, _path_to_item=(), _configuration=None, **kwargs): # noqa: E501 + """Cat - a model defined in OpenAPI + + Args: + class_name (str): + + 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 + _from_server (bool): True if the data is from the server + False if the data is from the client (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. + declawed (bool): [optional] # noqa: E501 + color (str): [optional] if omitted the server will use the default value of 'red' # noqa: E501 + """ + self._data_store = {} + self._check_type = _check_type + self._from_server = _from_server + self._path_to_item = _path_to_item + self._configuration = _configuration + + self.__set_item('class_name', class_name) + for var_name, var_value in six.iteritems(kwargs): + self.__set_item(var_name, var_value) + + def __set_item(self, name, value): + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + + if name in self.openapi_types: + required_types_mixed = self.openapi_types[name] + elif self.additional_properties_type is None: + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + path_to_item + ) + elif self.additional_properties_type is not None: + required_types_mixed = self.additional_properties_type + + if get_simple_class(name) != str: + error_msg = type_error_message( + var_name=name, + var_value=name, + valid_classes=(str,), + key_type=True + ) + raise ApiTypeError( + error_msg, + path_to_item=path_to_item, + valid_classes=(str,), + key_type=True + ) - if declawed is not None: - self.declawed = ( - declawed + if self._check_type: + value = validate_and_convert_types( + value, required_types_mixed, path_to_item, self._from_server, + self._check_type, configuration=self._configuration) + if (name,) in self.allowed_values: + check_allowed_values( + self.allowed_values, + (name,), + value + ) + if (name,) in self.validations: + check_validations( + self.validations, + (name,), + value ) + self._data_store[name] = value + + def __get_item(self, name): + if name in self._data_store: + return self._data_store[name] + + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + [name] + ) + + def __setitem__(self, name, value): + """this allows us to set values with instance[field_name] = val""" + self.__set_item(name, value) + + def __getitem__(self, name): + """this allows us to get a value with val = instance[field_name]""" + return self.__get_item(name) @property - def declawed(self): - """Gets the declawed of this Cat. # noqa: E501 + def class_name(self): + """Gets the class_name of this Cat. # noqa: E501 + + Returns: + (str): The class_name of this Cat. # noqa: E501 + """ + return self.__get_item('class_name') + + @class_name.setter + def class_name(self, value): + """Sets the class_name of this Cat. # noqa: E501 + """ + return self.__set_item('class_name', value) + @property + def color(self): + """Gets the color of this Cat. # noqa: E501 - :return: The declawed of this Cat. # noqa: E501 - :rtype: bool + Returns: + (str): The color of this Cat. # noqa: E501 """ - return self._declawed + return self.__get_item('color') - @declawed.setter - def declawed(self, declawed): # noqa: E501 - """Sets the declawed of this Cat. + @color.setter + def color(self, value): + """Sets the color of this Cat. # noqa: E501 + """ + return self.__set_item('color', value) + @property + def declawed(self): + """Gets the declawed of this Cat. # noqa: E501 - :param declawed: The declawed of this Cat. # noqa: E501 - :type: bool + Returns: + (bool): The declawed of this Cat. # noqa: E501 """ + return self.__get_item('declawed') - self._declawed = ( - declawed - ) + @declawed.setter + def declawed(self, value): + """Sets the declawed of this Cat. # noqa: E501 + """ + return self.__set_item('declawed', value) def to_dict(self): """Returns the model properties as a dict""" - result = {} - - for attr, _ in six.iteritems(self.openapi_types): - value = getattr(self, attr) - if isinstance(value, list): - result[attr] = list(map( - lambda x: x.to_dict() if hasattr(x, "to_dict") else x, - value - )) - elif hasattr(value, "to_dict"): - result[attr] = value.to_dict() - elif isinstance(value, dict): - result[attr] = dict(map( - lambda item: (item[0], item[1].to_dict()) - if hasattr(item[1], "to_dict") else item, - value.items() - )) - else: - result[attr] = value - - return result + return model_to_dict(self, serialize=False) def to_str(self): """Returns the string representation of the model""" @@ -133,7 +250,22 @@ def __eq__(self, other): if not isinstance(other, Cat): return False - return self.__dict__ == other.__dict__ + if not set(self._data_store.keys()) == set(other._data_store.keys()): + return False + for _var_name, this_val in six.iteritems(self._data_store): + that_val = other._data_store[_var_name] + types = set() + types.add(this_val.__class__) + types.add(that_val.__class__) + vals_equal = this_val == that_val + if (not six.PY3 and + len(types) == 2 and unicode in types): # noqa: F821 + vals_equal = ( + this_val.encode('utf-8') == that_val.encode('utf-8') + ) + if not vals_equal: + return False + return True def __ne__(self, other): """Returns true if both objects are not equal""" diff --git a/samples/client/petstore/python-experimental/petstore_api/models/cat_all_of.py b/samples/client/petstore/python-experimental/petstore_api/models/cat_all_of.py index 0a8267293dd3..cb1f0d815a0f 100644 --- a/samples/client/petstore/python-experimental/petstore_api/models/cat_all_of.py +++ b/samples/client/petstore/python-experimental/petstore_api/models/cat_all_of.py @@ -15,12 +15,26 @@ import six # noqa: F401 -from petstore_api.exceptions import ApiValueError # noqa: F401 +from petstore_api.exceptions import ( # noqa: F401 + ApiKeyError, + ApiTypeError, + ApiValueError, +) from petstore_api.model_utils import ( # noqa: F401 ModelNormal, ModelSimple, check_allowed_values, - check_validations + check_validations, + date, + datetime, + file_type, + get_simple_class, + int, + model_to_dict, + none_type, + str, + type_error_message, + validate_and_convert_types ) @@ -46,6 +60,8 @@ class CatAllOf(ModelNormal): 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 = { @@ -56,69 +72,132 @@ class CatAllOf(ModelNormal): } openapi_types = { - 'declawed': 'bool' + 'declawed': (bool,), # noqa: E501 } validations = { } - def __init__(self, declawed=None): # noqa: E501 - """CatAllOf - a model defined in OpenAPI""" # noqa: E501 - - self._declawed = None - self.discriminator = None + additional_properties_type = None + + discriminator = None + + def __init__(self, _check_type=True, _from_server=False, _path_to_item=(), _configuration=None, **kwargs): # noqa: E501 + """CatAllOf - 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 + _from_server (bool): True if the data is from the server + False if the data is from the client (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. + declawed (bool): [optional] # noqa: E501 + """ + self._data_store = {} + self._check_type = _check_type + self._from_server = _from_server + self._path_to_item = _path_to_item + self._configuration = _configuration + + for var_name, var_value in six.iteritems(kwargs): + self.__set_item(var_name, var_value) + + def __set_item(self, name, value): + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + + if name in self.openapi_types: + required_types_mixed = self.openapi_types[name] + elif self.additional_properties_type is None: + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + path_to_item + ) + elif self.additional_properties_type is not None: + required_types_mixed = self.additional_properties_type + + if get_simple_class(name) != str: + error_msg = type_error_message( + var_name=name, + var_value=name, + valid_classes=(str,), + key_type=True + ) + raise ApiTypeError( + error_msg, + path_to_item=path_to_item, + valid_classes=(str,), + key_type=True + ) - if declawed is not None: - self.declawed = ( - declawed + if self._check_type: + value = validate_and_convert_types( + value, required_types_mixed, path_to_item, self._from_server, + self._check_type, configuration=self._configuration) + if (name,) in self.allowed_values: + check_allowed_values( + self.allowed_values, + (name,), + value ) + if (name,) in self.validations: + check_validations( + self.validations, + (name,), + value + ) + self._data_store[name] = value + + def __get_item(self, name): + if name in self._data_store: + return self._data_store[name] + + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + [name] + ) + + def __setitem__(self, name, value): + """this allows us to set values with instance[field_name] = val""" + self.__set_item(name, value) + + def __getitem__(self, name): + """this allows us to get a value with val = instance[field_name]""" + return self.__get_item(name) @property def declawed(self): """Gets the declawed of this CatAllOf. # noqa: E501 - - :return: The declawed of this CatAllOf. # noqa: E501 - :rtype: bool + Returns: + (bool): The declawed of this CatAllOf. # noqa: E501 """ - return self._declawed + return self.__get_item('declawed') @declawed.setter - def declawed(self, declawed): # noqa: E501 - """Sets the declawed of this CatAllOf. - - - :param declawed: The declawed of this CatAllOf. # noqa: E501 - :type: bool + def declawed(self, value): + """Sets the declawed of this CatAllOf. # noqa: E501 """ - - self._declawed = ( - declawed - ) + return self.__set_item('declawed', value) def to_dict(self): """Returns the model properties as a dict""" - result = {} - - for attr, _ in six.iteritems(self.openapi_types): - value = getattr(self, attr) - if isinstance(value, list): - result[attr] = list(map( - lambda x: x.to_dict() if hasattr(x, "to_dict") else x, - value - )) - elif hasattr(value, "to_dict"): - result[attr] = value.to_dict() - elif isinstance(value, dict): - result[attr] = dict(map( - lambda item: (item[0], item[1].to_dict()) - if hasattr(item[1], "to_dict") else item, - value.items() - )) - else: - result[attr] = value - - return result + return model_to_dict(self, serialize=False) def to_str(self): """Returns the string representation of the model""" @@ -133,7 +212,22 @@ def __eq__(self, other): if not isinstance(other, CatAllOf): return False - return self.__dict__ == other.__dict__ + if not set(self._data_store.keys()) == set(other._data_store.keys()): + return False + for _var_name, this_val in six.iteritems(self._data_store): + that_val = other._data_store[_var_name] + types = set() + types.add(this_val.__class__) + types.add(that_val.__class__) + vals_equal = this_val == that_val + if (not six.PY3 and + len(types) == 2 and unicode in types): # noqa: F821 + vals_equal = ( + this_val.encode('utf-8') == that_val.encode('utf-8') + ) + if not vals_equal: + return False + return True def __ne__(self, other): """Returns true if both objects are not equal""" diff --git a/samples/client/petstore/python-experimental/petstore_api/models/category.py b/samples/client/petstore/python-experimental/petstore_api/models/category.py index bf117a1317df..ca367ad9c3d2 100644 --- a/samples/client/petstore/python-experimental/petstore_api/models/category.py +++ b/samples/client/petstore/python-experimental/petstore_api/models/category.py @@ -15,12 +15,26 @@ import six # noqa: F401 -from petstore_api.exceptions import ApiValueError # noqa: F401 +from petstore_api.exceptions import ( # noqa: F401 + ApiKeyError, + ApiTypeError, + ApiValueError, +) from petstore_api.model_utils import ( # noqa: F401 ModelNormal, ModelSimple, check_allowed_values, - check_validations + check_validations, + date, + datetime, + file_type, + get_simple_class, + int, + model_to_dict, + none_type, + str, + type_error_message, + validate_and_convert_types ) @@ -46,6 +60,8 @@ class Category(ModelNormal): 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 = { @@ -57,97 +73,151 @@ class Category(ModelNormal): } openapi_types = { - 'id': 'int', - 'name': 'str' + 'id': (int,), # noqa: E501 + 'name': (str,), # noqa: E501 } validations = { } - def __init__(self, id=None, name='default-name'): # noqa: E501 - """Category - a model defined in OpenAPI""" # noqa: E501 - - self._id = None - self._name = None - self.discriminator = None + additional_properties_type = None + + discriminator = None + + def __init__(self, name='default-name', _check_type=True, _from_server=False, _path_to_item=(), _configuration=None, **kwargs): # noqa: E501 + """Category - a model defined in OpenAPI + + Args: + + Keyword Args: + name (str): defaults to 'default-name', must be one of ['default-name'] # noqa: E501 + _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 + _from_server (bool): True if the data is from the server + False if the data is from the client (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. + id (int): [optional] # noqa: E501 + """ + self._data_store = {} + self._check_type = _check_type + self._from_server = _from_server + self._path_to_item = _path_to_item + self._configuration = _configuration + + self.__set_item('name', name) + for var_name, var_value in six.iteritems(kwargs): + self.__set_item(var_name, var_value) + + def __set_item(self, name, value): + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + + if name in self.openapi_types: + required_types_mixed = self.openapi_types[name] + elif self.additional_properties_type is None: + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + path_to_item + ) + elif self.additional_properties_type is not None: + required_types_mixed = self.additional_properties_type + + if get_simple_class(name) != str: + error_msg = type_error_message( + var_name=name, + var_value=name, + valid_classes=(str,), + key_type=True + ) + raise ApiTypeError( + error_msg, + path_to_item=path_to_item, + valid_classes=(str,), + key_type=True + ) - if id is not None: - self.id = ( - id + if self._check_type: + value = validate_and_convert_types( + value, required_types_mixed, path_to_item, self._from_server, + self._check_type, configuration=self._configuration) + if (name,) in self.allowed_values: + check_allowed_values( + self.allowed_values, + (name,), + value ) - self.name = name + if (name,) in self.validations: + check_validations( + self.validations, + (name,), + value + ) + self._data_store[name] = value + + def __get_item(self, name): + if name in self._data_store: + return self._data_store[name] + + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + [name] + ) + + def __setitem__(self, name, value): + """this allows us to set values with instance[field_name] = val""" + self.__set_item(name, value) + + def __getitem__(self, name): + """this allows us to get a value with val = instance[field_name]""" + return self.__get_item(name) @property def id(self): """Gets the id of this Category. # noqa: E501 - - :return: The id of this Category. # noqa: E501 - :rtype: int + Returns: + (int): The id of this Category. # noqa: E501 """ - return self._id + return self.__get_item('id') @id.setter - def id(self, id): # noqa: E501 - """Sets the id of this Category. - - - :param id: The id of this Category. # noqa: E501 - :type: int + def id(self, value): + """Sets the id of this Category. # noqa: E501 """ - - self._id = ( - id - ) + return self.__set_item('id', value) @property def name(self): """Gets the name of this Category. # noqa: E501 - - :return: The name of this Category. # noqa: E501 - :rtype: str + Returns: + (str): The name of this Category. # noqa: E501 """ - return self._name + return self.__get_item('name') @name.setter - def name(self, name): # noqa: E501 - """Sets the name of this Category. - - - :param name: The name of this Category. # noqa: E501 - :type: str + def name(self, value): + """Sets the name of this Category. # noqa: E501 """ - if name is None: - raise ApiValueError("Invalid value for `name`, must not be `None`") # noqa: E501 - - self._name = ( - name - ) + return self.__set_item('name', value) def to_dict(self): """Returns the model properties as a dict""" - result = {} - - for attr, _ in six.iteritems(self.openapi_types): - value = getattr(self, attr) - if isinstance(value, list): - result[attr] = list(map( - lambda x: x.to_dict() if hasattr(x, "to_dict") else x, - value - )) - elif hasattr(value, "to_dict"): - result[attr] = value.to_dict() - elif isinstance(value, dict): - result[attr] = dict(map( - lambda item: (item[0], item[1].to_dict()) - if hasattr(item[1], "to_dict") else item, - value.items() - )) - else: - result[attr] = value - - return result + return model_to_dict(self, serialize=False) def to_str(self): """Returns the string representation of the model""" @@ -162,7 +232,22 @@ def __eq__(self, other): if not isinstance(other, Category): return False - return self.__dict__ == other.__dict__ + if not set(self._data_store.keys()) == set(other._data_store.keys()): + return False + for _var_name, this_val in six.iteritems(self._data_store): + that_val = other._data_store[_var_name] + types = set() + types.add(this_val.__class__) + types.add(that_val.__class__) + vals_equal = this_val == that_val + if (not six.PY3 and + len(types) == 2 and unicode in types): # noqa: F821 + vals_equal = ( + this_val.encode('utf-8') == that_val.encode('utf-8') + ) + if not vals_equal: + return False + return True def __ne__(self, other): """Returns true if both objects are not equal""" diff --git a/samples/client/petstore/python-experimental/petstore_api/models/class_model.py b/samples/client/petstore/python-experimental/petstore_api/models/class_model.py index 907e0f6ce2db..b44cdb80aae0 100644 --- a/samples/client/petstore/python-experimental/petstore_api/models/class_model.py +++ b/samples/client/petstore/python-experimental/petstore_api/models/class_model.py @@ -15,12 +15,26 @@ import six # noqa: F401 -from petstore_api.exceptions import ApiValueError # noqa: F401 +from petstore_api.exceptions import ( # noqa: F401 + ApiKeyError, + ApiTypeError, + ApiValueError, +) from petstore_api.model_utils import ( # noqa: F401 ModelNormal, ModelSimple, check_allowed_values, - check_validations + check_validations, + date, + datetime, + file_type, + get_simple_class, + int, + model_to_dict, + none_type, + str, + type_error_message, + validate_and_convert_types ) @@ -46,6 +60,8 @@ class ClassModel(ModelNormal): 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 = { @@ -56,69 +72,132 @@ class ClassModel(ModelNormal): } openapi_types = { - '_class': 'str' + '_class': (str,), # noqa: E501 } validations = { } - def __init__(self, _class=None): # noqa: E501 - """ClassModel - a model defined in OpenAPI""" # noqa: E501 - - self.__class = None - self.discriminator = None + additional_properties_type = None + + discriminator = None + + def __init__(self, _check_type=True, _from_server=False, _path_to_item=(), _configuration=None, **kwargs): # noqa: E501 + """ClassModel - 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 + _from_server (bool): True if the data is from the server + False if the data is from the client (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. + _class (str): [optional] # noqa: E501 + """ + self._data_store = {} + self._check_type = _check_type + self._from_server = _from_server + self._path_to_item = _path_to_item + self._configuration = _configuration + + for var_name, var_value in six.iteritems(kwargs): + self.__set_item(var_name, var_value) + + def __set_item(self, name, value): + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + + if name in self.openapi_types: + required_types_mixed = self.openapi_types[name] + elif self.additional_properties_type is None: + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + path_to_item + ) + elif self.additional_properties_type is not None: + required_types_mixed = self.additional_properties_type + + if get_simple_class(name) != str: + error_msg = type_error_message( + var_name=name, + var_value=name, + valid_classes=(str,), + key_type=True + ) + raise ApiTypeError( + error_msg, + path_to_item=path_to_item, + valid_classes=(str,), + key_type=True + ) - if _class is not None: - self._class = ( - _class + if self._check_type: + value = validate_and_convert_types( + value, required_types_mixed, path_to_item, self._from_server, + self._check_type, configuration=self._configuration) + if (name,) in self.allowed_values: + check_allowed_values( + self.allowed_values, + (name,), + value ) + if (name,) in self.validations: + check_validations( + self.validations, + (name,), + value + ) + self._data_store[name] = value + + def __get_item(self, name): + if name in self._data_store: + return self._data_store[name] + + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + [name] + ) + + def __setitem__(self, name, value): + """this allows us to set values with instance[field_name] = val""" + self.__set_item(name, value) + + def __getitem__(self, name): + """this allows us to get a value with val = instance[field_name]""" + return self.__get_item(name) @property def _class(self): """Gets the _class of this ClassModel. # noqa: E501 - - :return: The _class of this ClassModel. # noqa: E501 - :rtype: str + Returns: + (str): The _class of this ClassModel. # noqa: E501 """ - return self.__class + return self.__get_item('_class') @_class.setter - def _class(self, _class): # noqa: E501 - """Sets the _class of this ClassModel. - - - :param _class: The _class of this ClassModel. # noqa: E501 - :type: str + def _class(self, value): + """Sets the _class of this ClassModel. # noqa: E501 """ - - self.__class = ( - _class - ) + return self.__set_item('_class', value) def to_dict(self): """Returns the model properties as a dict""" - result = {} - - for attr, _ in six.iteritems(self.openapi_types): - value = getattr(self, attr) - if isinstance(value, list): - result[attr] = list(map( - lambda x: x.to_dict() if hasattr(x, "to_dict") else x, - value - )) - elif hasattr(value, "to_dict"): - result[attr] = value.to_dict() - elif isinstance(value, dict): - result[attr] = dict(map( - lambda item: (item[0], item[1].to_dict()) - if hasattr(item[1], "to_dict") else item, - value.items() - )) - else: - result[attr] = value - - return result + return model_to_dict(self, serialize=False) def to_str(self): """Returns the string representation of the model""" @@ -133,7 +212,22 @@ def __eq__(self, other): if not isinstance(other, ClassModel): return False - return self.__dict__ == other.__dict__ + if not set(self._data_store.keys()) == set(other._data_store.keys()): + return False + for _var_name, this_val in six.iteritems(self._data_store): + that_val = other._data_store[_var_name] + types = set() + types.add(this_val.__class__) + types.add(that_val.__class__) + vals_equal = this_val == that_val + if (not six.PY3 and + len(types) == 2 and unicode in types): # noqa: F821 + vals_equal = ( + this_val.encode('utf-8') == that_val.encode('utf-8') + ) + if not vals_equal: + return False + return True def __ne__(self, other): """Returns true if both objects are not equal""" diff --git a/samples/client/petstore/python-experimental/petstore_api/models/client.py b/samples/client/petstore/python-experimental/petstore_api/models/client.py index 7b133a387147..5e1699a2196b 100644 --- a/samples/client/petstore/python-experimental/petstore_api/models/client.py +++ b/samples/client/petstore/python-experimental/petstore_api/models/client.py @@ -15,12 +15,26 @@ import six # noqa: F401 -from petstore_api.exceptions import ApiValueError # noqa: F401 +from petstore_api.exceptions import ( # noqa: F401 + ApiKeyError, + ApiTypeError, + ApiValueError, +) from petstore_api.model_utils import ( # noqa: F401 ModelNormal, ModelSimple, check_allowed_values, - check_validations + check_validations, + date, + datetime, + file_type, + get_simple_class, + int, + model_to_dict, + none_type, + str, + type_error_message, + validate_and_convert_types ) @@ -46,6 +60,8 @@ class Client(ModelNormal): 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 = { @@ -56,69 +72,132 @@ class Client(ModelNormal): } openapi_types = { - 'client': 'str' + 'client': (str,), # noqa: E501 } validations = { } - def __init__(self, client=None): # noqa: E501 - """Client - a model defined in OpenAPI""" # noqa: E501 - - self._client = None - self.discriminator = None + additional_properties_type = None + + discriminator = None + + def __init__(self, _check_type=True, _from_server=False, _path_to_item=(), _configuration=None, **kwargs): # noqa: E501 + """Client - 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 + _from_server (bool): True if the data is from the server + False if the data is from the client (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. + client (str): [optional] # noqa: E501 + """ + self._data_store = {} + self._check_type = _check_type + self._from_server = _from_server + self._path_to_item = _path_to_item + self._configuration = _configuration + + for var_name, var_value in six.iteritems(kwargs): + self.__set_item(var_name, var_value) + + def __set_item(self, name, value): + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + + if name in self.openapi_types: + required_types_mixed = self.openapi_types[name] + elif self.additional_properties_type is None: + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + path_to_item + ) + elif self.additional_properties_type is not None: + required_types_mixed = self.additional_properties_type + + if get_simple_class(name) != str: + error_msg = type_error_message( + var_name=name, + var_value=name, + valid_classes=(str,), + key_type=True + ) + raise ApiTypeError( + error_msg, + path_to_item=path_to_item, + valid_classes=(str,), + key_type=True + ) - if client is not None: - self.client = ( - client + if self._check_type: + value = validate_and_convert_types( + value, required_types_mixed, path_to_item, self._from_server, + self._check_type, configuration=self._configuration) + if (name,) in self.allowed_values: + check_allowed_values( + self.allowed_values, + (name,), + value ) + if (name,) in self.validations: + check_validations( + self.validations, + (name,), + value + ) + self._data_store[name] = value + + def __get_item(self, name): + if name in self._data_store: + return self._data_store[name] + + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + [name] + ) + + def __setitem__(self, name, value): + """this allows us to set values with instance[field_name] = val""" + self.__set_item(name, value) + + def __getitem__(self, name): + """this allows us to get a value with val = instance[field_name]""" + return self.__get_item(name) @property def client(self): """Gets the client of this Client. # noqa: E501 - - :return: The client of this Client. # noqa: E501 - :rtype: str + Returns: + (str): The client of this Client. # noqa: E501 """ - return self._client + return self.__get_item('client') @client.setter - def client(self, client): # noqa: E501 - """Sets the client of this Client. - - - :param client: The client of this Client. # noqa: E501 - :type: str + def client(self, value): + """Sets the client of this Client. # noqa: E501 """ - - self._client = ( - client - ) + return self.__set_item('client', value) def to_dict(self): """Returns the model properties as a dict""" - result = {} - - for attr, _ in six.iteritems(self.openapi_types): - value = getattr(self, attr) - if isinstance(value, list): - result[attr] = list(map( - lambda x: x.to_dict() if hasattr(x, "to_dict") else x, - value - )) - elif hasattr(value, "to_dict"): - result[attr] = value.to_dict() - elif isinstance(value, dict): - result[attr] = dict(map( - lambda item: (item[0], item[1].to_dict()) - if hasattr(item[1], "to_dict") else item, - value.items() - )) - else: - result[attr] = value - - return result + return model_to_dict(self, serialize=False) def to_str(self): """Returns the string representation of the model""" @@ -133,7 +212,22 @@ def __eq__(self, other): if not isinstance(other, Client): return False - return self.__dict__ == other.__dict__ + if not set(self._data_store.keys()) == set(other._data_store.keys()): + return False + for _var_name, this_val in six.iteritems(self._data_store): + that_val = other._data_store[_var_name] + types = set() + types.add(this_val.__class__) + types.add(that_val.__class__) + vals_equal = this_val == that_val + if (not six.PY3 and + len(types) == 2 and unicode in types): # noqa: F821 + vals_equal = ( + this_val.encode('utf-8') == that_val.encode('utf-8') + ) + if not vals_equal: + return False + return True def __ne__(self, other): """Returns true if both objects are not equal""" diff --git a/samples/client/petstore/python-experimental/petstore_api/models/dog.py b/samples/client/petstore/python-experimental/petstore_api/models/dog.py index 61ef9958fc40..bac013b867d9 100644 --- a/samples/client/petstore/python-experimental/petstore_api/models/dog.py +++ b/samples/client/petstore/python-experimental/petstore_api/models/dog.py @@ -15,12 +15,26 @@ import six # noqa: F401 -from petstore_api.exceptions import ApiValueError # noqa: F401 +from petstore_api.exceptions import ( # noqa: F401 + ApiKeyError, + ApiTypeError, + ApiValueError, +) from petstore_api.model_utils import ( # noqa: F401 ModelNormal, ModelSimple, check_allowed_values, - check_validations + check_validations, + date, + datetime, + file_type, + get_simple_class, + int, + model_to_dict, + none_type, + str, + type_error_message, + validate_and_convert_types ) @@ -46,79 +60,182 @@ class Dog(ModelNormal): 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 = { } attribute_map = { + 'class_name': 'className', # noqa: E501 + 'color': 'color', # noqa: E501 'breed': 'breed' # noqa: E501 } openapi_types = { - 'breed': 'str' + 'class_name': (str,), # noqa: E501 + 'color': (str,), # noqa: E501 + 'breed': (str,), # noqa: E501 } validations = { } - def __init__(self, breed=None): # noqa: E501 - """Dog - a model defined in OpenAPI""" # noqa: E501 - - self._breed = None - self.discriminator = None + additional_properties_type = None + + discriminator = None + + def __init__(self, class_name, _check_type=True, _from_server=False, _path_to_item=(), _configuration=None, **kwargs): # noqa: E501 + """Dog - a model defined in OpenAPI + + Args: + class_name (str): + + 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 + _from_server (bool): True if the data is from the server + False if the data is from the client (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. + breed (str): [optional] # noqa: E501 + color (str): [optional] if omitted the server will use the default value of 'red' # noqa: E501 + """ + self._data_store = {} + self._check_type = _check_type + self._from_server = _from_server + self._path_to_item = _path_to_item + self._configuration = _configuration + + self.__set_item('class_name', class_name) + for var_name, var_value in six.iteritems(kwargs): + self.__set_item(var_name, var_value) + + def __set_item(self, name, value): + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + + if name in self.openapi_types: + required_types_mixed = self.openapi_types[name] + elif self.additional_properties_type is None: + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + path_to_item + ) + elif self.additional_properties_type is not None: + required_types_mixed = self.additional_properties_type + + if get_simple_class(name) != str: + error_msg = type_error_message( + var_name=name, + var_value=name, + valid_classes=(str,), + key_type=True + ) + raise ApiTypeError( + error_msg, + path_to_item=path_to_item, + valid_classes=(str,), + key_type=True + ) - if breed is not None: - self.breed = ( - breed + if self._check_type: + value = validate_and_convert_types( + value, required_types_mixed, path_to_item, self._from_server, + self._check_type, configuration=self._configuration) + if (name,) in self.allowed_values: + check_allowed_values( + self.allowed_values, + (name,), + value + ) + if (name,) in self.validations: + check_validations( + self.validations, + (name,), + value ) + self._data_store[name] = value + + def __get_item(self, name): + if name in self._data_store: + return self._data_store[name] + + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + [name] + ) + + def __setitem__(self, name, value): + """this allows us to set values with instance[field_name] = val""" + self.__set_item(name, value) + + def __getitem__(self, name): + """this allows us to get a value with val = instance[field_name]""" + return self.__get_item(name) @property - def breed(self): - """Gets the breed of this Dog. # noqa: E501 + def class_name(self): + """Gets the class_name of this Dog. # noqa: E501 + + Returns: + (str): The class_name of this Dog. # noqa: E501 + """ + return self.__get_item('class_name') + + @class_name.setter + def class_name(self, value): + """Sets the class_name of this Dog. # noqa: E501 + """ + return self.__set_item('class_name', value) + @property + def color(self): + """Gets the color of this Dog. # noqa: E501 - :return: The breed of this Dog. # noqa: E501 - :rtype: str + Returns: + (str): The color of this Dog. # noqa: E501 """ - return self._breed + return self.__get_item('color') - @breed.setter - def breed(self, breed): # noqa: E501 - """Sets the breed of this Dog. + @color.setter + def color(self, value): + """Sets the color of this Dog. # noqa: E501 + """ + return self.__set_item('color', value) + @property + def breed(self): + """Gets the breed of this Dog. # noqa: E501 - :param breed: The breed of this Dog. # noqa: E501 - :type: str + Returns: + (str): The breed of this Dog. # noqa: E501 """ + return self.__get_item('breed') - self._breed = ( - breed - ) + @breed.setter + def breed(self, value): + """Sets the breed of this Dog. # noqa: E501 + """ + return self.__set_item('breed', value) def to_dict(self): """Returns the model properties as a dict""" - result = {} - - for attr, _ in six.iteritems(self.openapi_types): - value = getattr(self, attr) - if isinstance(value, list): - result[attr] = list(map( - lambda x: x.to_dict() if hasattr(x, "to_dict") else x, - value - )) - elif hasattr(value, "to_dict"): - result[attr] = value.to_dict() - elif isinstance(value, dict): - result[attr] = dict(map( - lambda item: (item[0], item[1].to_dict()) - if hasattr(item[1], "to_dict") else item, - value.items() - )) - else: - result[attr] = value - - return result + return model_to_dict(self, serialize=False) def to_str(self): """Returns the string representation of the model""" @@ -133,7 +250,22 @@ def __eq__(self, other): if not isinstance(other, Dog): return False - return self.__dict__ == other.__dict__ + if not set(self._data_store.keys()) == set(other._data_store.keys()): + return False + for _var_name, this_val in six.iteritems(self._data_store): + that_val = other._data_store[_var_name] + types = set() + types.add(this_val.__class__) + types.add(that_val.__class__) + vals_equal = this_val == that_val + if (not six.PY3 and + len(types) == 2 and unicode in types): # noqa: F821 + vals_equal = ( + this_val.encode('utf-8') == that_val.encode('utf-8') + ) + if not vals_equal: + return False + return True def __ne__(self, other): """Returns true if both objects are not equal""" diff --git a/samples/client/petstore/python-experimental/petstore_api/models/dog_all_of.py b/samples/client/petstore/python-experimental/petstore_api/models/dog_all_of.py index cc082b5b3576..7d9a33bbe365 100644 --- a/samples/client/petstore/python-experimental/petstore_api/models/dog_all_of.py +++ b/samples/client/petstore/python-experimental/petstore_api/models/dog_all_of.py @@ -15,12 +15,26 @@ import six # noqa: F401 -from petstore_api.exceptions import ApiValueError # noqa: F401 +from petstore_api.exceptions import ( # noqa: F401 + ApiKeyError, + ApiTypeError, + ApiValueError, +) from petstore_api.model_utils import ( # noqa: F401 ModelNormal, ModelSimple, check_allowed_values, - check_validations + check_validations, + date, + datetime, + file_type, + get_simple_class, + int, + model_to_dict, + none_type, + str, + type_error_message, + validate_and_convert_types ) @@ -46,6 +60,8 @@ class DogAllOf(ModelNormal): 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 = { @@ -56,69 +72,132 @@ class DogAllOf(ModelNormal): } openapi_types = { - 'breed': 'str' + 'breed': (str,), # noqa: E501 } validations = { } - def __init__(self, breed=None): # noqa: E501 - """DogAllOf - a model defined in OpenAPI""" # noqa: E501 - - self._breed = None - self.discriminator = None + additional_properties_type = None + + discriminator = None + + def __init__(self, _check_type=True, _from_server=False, _path_to_item=(), _configuration=None, **kwargs): # noqa: E501 + """DogAllOf - 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 + _from_server (bool): True if the data is from the server + False if the data is from the client (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. + breed (str): [optional] # noqa: E501 + """ + self._data_store = {} + self._check_type = _check_type + self._from_server = _from_server + self._path_to_item = _path_to_item + self._configuration = _configuration + + for var_name, var_value in six.iteritems(kwargs): + self.__set_item(var_name, var_value) + + def __set_item(self, name, value): + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + + if name in self.openapi_types: + required_types_mixed = self.openapi_types[name] + elif self.additional_properties_type is None: + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + path_to_item + ) + elif self.additional_properties_type is not None: + required_types_mixed = self.additional_properties_type + + if get_simple_class(name) != str: + error_msg = type_error_message( + var_name=name, + var_value=name, + valid_classes=(str,), + key_type=True + ) + raise ApiTypeError( + error_msg, + path_to_item=path_to_item, + valid_classes=(str,), + key_type=True + ) - if breed is not None: - self.breed = ( - breed + if self._check_type: + value = validate_and_convert_types( + value, required_types_mixed, path_to_item, self._from_server, + self._check_type, configuration=self._configuration) + if (name,) in self.allowed_values: + check_allowed_values( + self.allowed_values, + (name,), + value ) + if (name,) in self.validations: + check_validations( + self.validations, + (name,), + value + ) + self._data_store[name] = value + + def __get_item(self, name): + if name in self._data_store: + return self._data_store[name] + + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + [name] + ) + + def __setitem__(self, name, value): + """this allows us to set values with instance[field_name] = val""" + self.__set_item(name, value) + + def __getitem__(self, name): + """this allows us to get a value with val = instance[field_name]""" + return self.__get_item(name) @property def breed(self): """Gets the breed of this DogAllOf. # noqa: E501 - - :return: The breed of this DogAllOf. # noqa: E501 - :rtype: str + Returns: + (str): The breed of this DogAllOf. # noqa: E501 """ - return self._breed + return self.__get_item('breed') @breed.setter - def breed(self, breed): # noqa: E501 - """Sets the breed of this DogAllOf. - - - :param breed: The breed of this DogAllOf. # noqa: E501 - :type: str + def breed(self, value): + """Sets the breed of this DogAllOf. # noqa: E501 """ - - self._breed = ( - breed - ) + return self.__set_item('breed', value) def to_dict(self): """Returns the model properties as a dict""" - result = {} - - for attr, _ in six.iteritems(self.openapi_types): - value = getattr(self, attr) - if isinstance(value, list): - result[attr] = list(map( - lambda x: x.to_dict() if hasattr(x, "to_dict") else x, - value - )) - elif hasattr(value, "to_dict"): - result[attr] = value.to_dict() - elif isinstance(value, dict): - result[attr] = dict(map( - lambda item: (item[0], item[1].to_dict()) - if hasattr(item[1], "to_dict") else item, - value.items() - )) - else: - result[attr] = value - - return result + return model_to_dict(self, serialize=False) def to_str(self): """Returns the string representation of the model""" @@ -133,7 +212,22 @@ def __eq__(self, other): if not isinstance(other, DogAllOf): return False - return self.__dict__ == other.__dict__ + if not set(self._data_store.keys()) == set(other._data_store.keys()): + return False + for _var_name, this_val in six.iteritems(self._data_store): + that_val = other._data_store[_var_name] + types = set() + types.add(this_val.__class__) + types.add(that_val.__class__) + vals_equal = this_val == that_val + if (not six.PY3 and + len(types) == 2 and unicode in types): # noqa: F821 + vals_equal = ( + this_val.encode('utf-8') == that_val.encode('utf-8') + ) + if not vals_equal: + return False + return True def __ne__(self, other): """Returns true if both objects are not equal""" diff --git a/samples/client/petstore/python-experimental/petstore_api/models/enum_arrays.py b/samples/client/petstore/python-experimental/petstore_api/models/enum_arrays.py index fe8355e7defa..477193e858f4 100644 --- a/samples/client/petstore/python-experimental/petstore_api/models/enum_arrays.py +++ b/samples/client/petstore/python-experimental/petstore_api/models/enum_arrays.py @@ -15,12 +15,26 @@ import six # noqa: F401 -from petstore_api.exceptions import ApiValueError # noqa: F401 +from petstore_api.exceptions import ( # noqa: F401 + ApiKeyError, + ApiTypeError, + ApiValueError, +) from petstore_api.model_utils import ( # noqa: F401 ModelNormal, ModelSimple, check_allowed_values, - check_validations + check_validations, + date, + datetime, + file_type, + get_simple_class, + int, + model_to_dict, + none_type, + str, + type_error_message, + validate_and_convert_types ) @@ -46,16 +60,18 @@ class EnumArrays(ModelNormal): 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 = { ('just_symbol',): { '>=': ">=", - '$': "$" + '$': "$", }, ('array_enum',): { 'FISH': "fish", - 'CRAB': "crab" + 'CRAB': "crab", }, } @@ -65,110 +81,149 @@ class EnumArrays(ModelNormal): } openapi_types = { - 'just_symbol': 'str', - 'array_enum': 'list[str]' + 'just_symbol': (str,), # noqa: E501 + 'array_enum': ([str],), # noqa: E501 } validations = { } - def __init__(self, just_symbol=None, array_enum=None): # noqa: E501 - """EnumArrays - a model defined in OpenAPI""" # noqa: E501 - - self._just_symbol = None - self._array_enum = None - self.discriminator = None + additional_properties_type = None + + discriminator = None + + def __init__(self, _check_type=True, _from_server=False, _path_to_item=(), _configuration=None, **kwargs): # noqa: E501 + """EnumArrays - 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 + _from_server (bool): True if the data is from the server + False if the data is from the client (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. + just_symbol (str): [optional] # noqa: E501 + array_enum ([str]): [optional] # noqa: E501 + """ + self._data_store = {} + self._check_type = _check_type + self._from_server = _from_server + self._path_to_item = _path_to_item + self._configuration = _configuration + + for var_name, var_value in six.iteritems(kwargs): + self.__set_item(var_name, var_value) + + def __set_item(self, name, value): + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + + if name in self.openapi_types: + required_types_mixed = self.openapi_types[name] + elif self.additional_properties_type is None: + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + path_to_item + ) + elif self.additional_properties_type is not None: + required_types_mixed = self.additional_properties_type + + if get_simple_class(name) != str: + error_msg = type_error_message( + var_name=name, + var_value=name, + valid_classes=(str,), + key_type=True + ) + raise ApiTypeError( + error_msg, + path_to_item=path_to_item, + valid_classes=(str,), + key_type=True + ) - if just_symbol is not None: - self.just_symbol = ( - just_symbol + if self._check_type: + value = validate_and_convert_types( + value, required_types_mixed, path_to_item, self._from_server, + self._check_type, configuration=self._configuration) + if (name,) in self.allowed_values: + check_allowed_values( + self.allowed_values, + (name,), + value ) - if array_enum is not None: - self.array_enum = ( - array_enum + if (name,) in self.validations: + check_validations( + self.validations, + (name,), + value ) + self._data_store[name] = value + + def __get_item(self, name): + if name in self._data_store: + return self._data_store[name] + + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + [name] + ) + + def __setitem__(self, name, value): + """this allows us to set values with instance[field_name] = val""" + self.__set_item(name, value) + + def __getitem__(self, name): + """this allows us to get a value with val = instance[field_name]""" + return self.__get_item(name) @property def just_symbol(self): """Gets the just_symbol of this EnumArrays. # noqa: E501 - - :return: The just_symbol of this EnumArrays. # noqa: E501 - :rtype: str + Returns: + (str): The just_symbol of this EnumArrays. # noqa: E501 """ - return self._just_symbol + return self.__get_item('just_symbol') @just_symbol.setter - def just_symbol(self, just_symbol): # noqa: E501 - """Sets the just_symbol of this EnumArrays. - - - :param just_symbol: The just_symbol of this EnumArrays. # noqa: E501 - :type: str + def just_symbol(self, value): + """Sets the just_symbol of this EnumArrays. # noqa: E501 """ - check_allowed_values( - self.allowed_values, - ('just_symbol',), - just_symbol, - self.validations - ) - - self._just_symbol = ( - just_symbol - ) + return self.__set_item('just_symbol', value) @property def array_enum(self): """Gets the array_enum of this EnumArrays. # noqa: E501 - - :return: The array_enum of this EnumArrays. # noqa: E501 - :rtype: list[str] + Returns: + ([str]): The array_enum of this EnumArrays. # noqa: E501 """ - return self._array_enum + return self.__get_item('array_enum') @array_enum.setter - def array_enum(self, array_enum): # noqa: E501 - """Sets the array_enum of this EnumArrays. - - - :param array_enum: The array_enum of this EnumArrays. # noqa: E501 - :type: list[str] + def array_enum(self, value): + """Sets the array_enum of this EnumArrays. # noqa: E501 """ - check_allowed_values( - self.allowed_values, - ('array_enum',), - array_enum, - self.validations - ) - - self._array_enum = ( - array_enum - ) + return self.__set_item('array_enum', value) def to_dict(self): """Returns the model properties as a dict""" - result = {} - - for attr, _ in six.iteritems(self.openapi_types): - value = getattr(self, attr) - if isinstance(value, list): - result[attr] = list(map( - lambda x: x.to_dict() if hasattr(x, "to_dict") else x, - value - )) - elif hasattr(value, "to_dict"): - result[attr] = value.to_dict() - elif isinstance(value, dict): - result[attr] = dict(map( - lambda item: (item[0], item[1].to_dict()) - if hasattr(item[1], "to_dict") else item, - value.items() - )) - else: - result[attr] = value - - return result + return model_to_dict(self, serialize=False) def to_str(self): """Returns the string representation of the model""" @@ -183,7 +238,22 @@ def __eq__(self, other): if not isinstance(other, EnumArrays): return False - return self.__dict__ == other.__dict__ + if not set(self._data_store.keys()) == set(other._data_store.keys()): + return False + for _var_name, this_val in six.iteritems(self._data_store): + that_val = other._data_store[_var_name] + types = set() + types.add(this_val.__class__) + types.add(that_val.__class__) + vals_equal = this_val == that_val + if (not six.PY3 and + len(types) == 2 and unicode in types): # noqa: F821 + vals_equal = ( + this_val.encode('utf-8') == that_val.encode('utf-8') + ) + if not vals_equal: + return False + return True def __ne__(self, other): """Returns true if both objects are not equal""" diff --git a/samples/client/petstore/python-experimental/petstore_api/models/enum_class.py b/samples/client/petstore/python-experimental/petstore_api/models/enum_class.py index 60d4f64e9c17..0b3bca10a53e 100644 --- a/samples/client/petstore/python-experimental/petstore_api/models/enum_class.py +++ b/samples/client/petstore/python-experimental/petstore_api/models/enum_class.py @@ -15,12 +15,26 @@ import six # noqa: F401 -from petstore_api.exceptions import ApiValueError # noqa: F401 +from petstore_api.exceptions import ( # noqa: F401 + ApiKeyError, + ApiTypeError, + ApiValueError, +) from petstore_api.model_utils import ( # noqa: F401 ModelNormal, ModelSimple, check_allowed_values, - check_validations + check_validations, + date, + datetime, + file_type, + get_simple_class, + int, + model_to_dict, + none_type, + str, + type_error_message, + validate_and_convert_types ) @@ -42,65 +56,147 @@ class EnumClass(ModelSimple): 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 = { ('value',): { '_ABC': "_abc", '-EFG': "-efg", - '(XYZ)': "(xyz)" + '(XYZ)': "(xyz)", }, } openapi_types = { - 'value': 'str' + 'value': (str,), # noqa: E501 } validations = { } - def __init__(self, value='-efg'): # noqa: E501 - """EnumClass - a model defined in OpenAPI""" # noqa: E501 + additional_properties_type = None + + discriminator = None + + def __init__(self, value='-efg', _check_type=True, _from_server=False, _path_to_item=(), _configuration=None, **kwargs): # noqa: E501 + """EnumClass - a model defined in OpenAPI + + Args: + + Keyword Args: + value (str): defaults to '-efg', must be one of ['-efg'] # noqa: E501 + _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 + _from_server (bool): True if the data is from the server + False if the data is from the client (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. + """ + self._data_store = {} + self._check_type = _check_type + self._from_server = _from_server + self._path_to_item = _path_to_item + self._configuration = _configuration + + self.__set_item('value', value) + for var_name, var_value in six.iteritems(kwargs): + self.__set_item(var_name, var_value) + + def __set_item(self, name, value): + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + + if name in self.openapi_types: + required_types_mixed = self.openapi_types[name] + elif self.additional_properties_type is None: + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + path_to_item + ) + elif self.additional_properties_type is not None: + required_types_mixed = self.additional_properties_type + + if get_simple_class(name) != str: + error_msg = type_error_message( + var_name=name, + var_value=name, + valid_classes=(str,), + key_type=True + ) + raise ApiTypeError( + error_msg, + path_to_item=path_to_item, + valid_classes=(str,), + key_type=True + ) + + if self._check_type: + value = validate_and_convert_types( + value, required_types_mixed, path_to_item, self._from_server, + self._check_type, configuration=self._configuration) + if (name,) in self.allowed_values: + check_allowed_values( + self.allowed_values, + (name,), + value + ) + if (name,) in self.validations: + check_validations( + self.validations, + (name,), + value + ) + self._data_store[name] = value + + def __get_item(self, name): + if name in self._data_store: + return self._data_store[name] + + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + [name] + ) - self._value = None - self.discriminator = None + def __setitem__(self, name, value): + """this allows us to set values with instance[field_name] = val""" + self.__set_item(name, value) - self.value = value + def __getitem__(self, name): + """this allows us to get a value with val = instance[field_name]""" + return self.__get_item(name) @property def value(self): """Gets the value of this EnumClass. # noqa: E501 - - :return: The value of this EnumClass. # noqa: E501 - :rtype: str + Returns: + (str): The value of this EnumClass. # noqa: E501 """ - return self._value + return self.__get_item('value') @value.setter - def value(self, value): # noqa: E501 - """Sets the value of this EnumClass. - - - :param value: The value of this EnumClass. # noqa: E501 - :type: str + def value(self, value): + """Sets the value of this EnumClass. # noqa: E501 """ - if value is None: - raise ApiValueError("Invalid value for `value`, must not be `None`") # noqa: E501 - check_allowed_values( - self.allowed_values, - ('value',), - value, - self.validations - ) - - self._value = ( - value - ) + return self.__set_item('value', value) def to_str(self): """Returns the string representation of the model""" - return str(self._value) + return str(self.value) def __repr__(self): """For `print` and `pprint`""" @@ -111,7 +207,19 @@ def __eq__(self, other): if not isinstance(other, EnumClass): return False - return self.__dict__ == other.__dict__ + this_val = self._data_store['value'] + that_val = other._data_store['value'] + types = set() + types.add(this_val.__class__) + types.add(that_val.__class__) + vals_equal = this_val == that_val + if not six.PY3 and len(types) == 2 and unicode in types: # noqa: F821 + vals_equal = ( + this_val.encode('utf-8') == that_val.encode('utf-8') + ) + if not vals_equal: + return False + return True def __ne__(self, other): """Returns true if both objects are not equal""" diff --git a/samples/client/petstore/python-experimental/petstore_api/models/enum_test.py b/samples/client/petstore/python-experimental/petstore_api/models/enum_test.py index 0ec5096c0abd..83f6d78c3f8f 100644 --- a/samples/client/petstore/python-experimental/petstore_api/models/enum_test.py +++ b/samples/client/petstore/python-experimental/petstore_api/models/enum_test.py @@ -15,13 +15,28 @@ import six # noqa: F401 -from petstore_api.exceptions import ApiValueError # noqa: F401 +from petstore_api.exceptions import ( # noqa: F401 + ApiKeyError, + ApiTypeError, + ApiValueError, +) from petstore_api.model_utils import ( # noqa: F401 ModelNormal, ModelSimple, check_allowed_values, - check_validations + check_validations, + date, + datetime, + file_type, + get_simple_class, + int, + model_to_dict, + none_type, + str, + type_error_message, + validate_and_convert_types ) +from petstore_api.models.outer_enum import OuterEnum class EnumTest(ModelNormal): @@ -46,26 +61,28 @@ class EnumTest(ModelNormal): 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 = { ('enum_string',): { 'UPPER': "UPPER", 'LOWER': "lower", - 'EMPTY': "" + 'EMPTY': "", }, ('enum_string_required',): { 'UPPER': "UPPER", 'LOWER': "lower", - 'EMPTY': "" + 'EMPTY': "", }, ('enum_integer',): { '1': 1, - '-1': -1 + '-1': -1, }, ('enum_number',): { '1.1': 1.1, - '-1.2': -1.2 + '-1.2': -1.2, }, } @@ -78,208 +95,202 @@ class EnumTest(ModelNormal): } openapi_types = { - 'enum_string': 'str', - 'enum_string_required': 'str', - 'enum_integer': 'int', - 'enum_number': 'float', - 'outer_enum': 'OuterEnum' + 'enum_string': (str,), # noqa: E501 + 'enum_string_required': (str,), # noqa: E501 + 'enum_integer': (int,), # noqa: E501 + 'enum_number': (float,), # noqa: E501 + 'outer_enum': (OuterEnum,), # noqa: E501 } validations = { } - def __init__(self, enum_string=None, enum_string_required=None, enum_integer=None, enum_number=None, outer_enum=None): # noqa: E501 - """EnumTest - a model defined in OpenAPI""" # noqa: E501 - - self._enum_string = None - self._enum_string_required = None - self._enum_integer = None - self._enum_number = None - self._outer_enum = None - self.discriminator = None - - if enum_string is not None: - self.enum_string = ( - enum_string + additional_properties_type = None + + discriminator = None + + def __init__(self, enum_string_required, _check_type=True, _from_server=False, _path_to_item=(), _configuration=None, **kwargs): # noqa: E501 + """EnumTest - a model defined in OpenAPI + + Args: + enum_string_required (str): + + 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 + _from_server (bool): True if the data is from the server + False if the data is from the client (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. + enum_string (str): [optional] # noqa: E501 + enum_integer (int): [optional] # noqa: E501 + enum_number (float): [optional] # noqa: E501 + outer_enum (OuterEnum): [optional] # noqa: E501 + """ + self._data_store = {} + self._check_type = _check_type + self._from_server = _from_server + self._path_to_item = _path_to_item + self._configuration = _configuration + + self.__set_item('enum_string_required', enum_string_required) + for var_name, var_value in six.iteritems(kwargs): + self.__set_item(var_name, var_value) + + def __set_item(self, name, value): + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + + if name in self.openapi_types: + required_types_mixed = self.openapi_types[name] + elif self.additional_properties_type is None: + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + path_to_item + ) + elif self.additional_properties_type is not None: + required_types_mixed = self.additional_properties_type + + if get_simple_class(name) != str: + error_msg = type_error_message( + var_name=name, + var_value=name, + valid_classes=(str,), + key_type=True ) - self.enum_string_required = enum_string_required - if enum_integer is not None: - self.enum_integer = ( - enum_integer + raise ApiTypeError( + error_msg, + path_to_item=path_to_item, + valid_classes=(str,), + key_type=True ) - if enum_number is not None: - self.enum_number = ( - enum_number + + if self._check_type: + value = validate_and_convert_types( + value, required_types_mixed, path_to_item, self._from_server, + self._check_type, configuration=self._configuration) + if (name,) in self.allowed_values: + check_allowed_values( + self.allowed_values, + (name,), + value ) - if outer_enum is not None: - self.outer_enum = ( - outer_enum + if (name,) in self.validations: + check_validations( + self.validations, + (name,), + value ) + self._data_store[name] = value + + def __get_item(self, name): + if name in self._data_store: + return self._data_store[name] + + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + [name] + ) + + def __setitem__(self, name, value): + """this allows us to set values with instance[field_name] = val""" + self.__set_item(name, value) + + def __getitem__(self, name): + """this allows us to get a value with val = instance[field_name]""" + return self.__get_item(name) @property def enum_string(self): """Gets the enum_string of this EnumTest. # noqa: E501 - - :return: The enum_string of this EnumTest. # noqa: E501 - :rtype: str + Returns: + (str): The enum_string of this EnumTest. # noqa: E501 """ - return self._enum_string + return self.__get_item('enum_string') @enum_string.setter - def enum_string(self, enum_string): # noqa: E501 - """Sets the enum_string of this EnumTest. - - - :param enum_string: The enum_string of this EnumTest. # noqa: E501 - :type: str + def enum_string(self, value): + """Sets the enum_string of this EnumTest. # noqa: E501 """ - check_allowed_values( - self.allowed_values, - ('enum_string',), - enum_string, - self.validations - ) - - self._enum_string = ( - enum_string - ) + return self.__set_item('enum_string', value) @property def enum_string_required(self): """Gets the enum_string_required of this EnumTest. # noqa: E501 - - :return: The enum_string_required of this EnumTest. # noqa: E501 - :rtype: str + Returns: + (str): The enum_string_required of this EnumTest. # noqa: E501 """ - return self._enum_string_required + return self.__get_item('enum_string_required') @enum_string_required.setter - def enum_string_required(self, enum_string_required): # noqa: E501 - """Sets the enum_string_required of this EnumTest. - - - :param enum_string_required: The enum_string_required of this EnumTest. # noqa: E501 - :type: str + def enum_string_required(self, value): + """Sets the enum_string_required of this EnumTest. # noqa: E501 """ - if enum_string_required is None: - raise ApiValueError("Invalid value for `enum_string_required`, must not be `None`") # noqa: E501 - check_allowed_values( - self.allowed_values, - ('enum_string_required',), - enum_string_required, - self.validations - ) - - self._enum_string_required = ( - enum_string_required - ) + return self.__set_item('enum_string_required', value) @property def enum_integer(self): """Gets the enum_integer of this EnumTest. # noqa: E501 - - :return: The enum_integer of this EnumTest. # noqa: E501 - :rtype: int + Returns: + (int): The enum_integer of this EnumTest. # noqa: E501 """ - return self._enum_integer + return self.__get_item('enum_integer') @enum_integer.setter - def enum_integer(self, enum_integer): # noqa: E501 - """Sets the enum_integer of this EnumTest. - - - :param enum_integer: The enum_integer of this EnumTest. # noqa: E501 - :type: int + def enum_integer(self, value): + """Sets the enum_integer of this EnumTest. # noqa: E501 """ - check_allowed_values( - self.allowed_values, - ('enum_integer',), - enum_integer, - self.validations - ) - - self._enum_integer = ( - enum_integer - ) + return self.__set_item('enum_integer', value) @property def enum_number(self): """Gets the enum_number of this EnumTest. # noqa: E501 - - :return: The enum_number of this EnumTest. # noqa: E501 - :rtype: float + Returns: + (float): The enum_number of this EnumTest. # noqa: E501 """ - return self._enum_number + return self.__get_item('enum_number') @enum_number.setter - def enum_number(self, enum_number): # noqa: E501 - """Sets the enum_number of this EnumTest. - - - :param enum_number: The enum_number of this EnumTest. # noqa: E501 - :type: float + def enum_number(self, value): + """Sets the enum_number of this EnumTest. # noqa: E501 """ - check_allowed_values( - self.allowed_values, - ('enum_number',), - enum_number, - self.validations - ) - - self._enum_number = ( - enum_number - ) + return self.__set_item('enum_number', value) @property def outer_enum(self): """Gets the outer_enum of this EnumTest. # noqa: E501 - - :return: The outer_enum of this EnumTest. # noqa: E501 - :rtype: OuterEnum + Returns: + (OuterEnum): The outer_enum of this EnumTest. # noqa: E501 """ - return self._outer_enum + return self.__get_item('outer_enum') @outer_enum.setter - def outer_enum(self, outer_enum): # noqa: E501 - """Sets the outer_enum of this EnumTest. - - - :param outer_enum: The outer_enum of this EnumTest. # noqa: E501 - :type: OuterEnum + def outer_enum(self, value): + """Sets the outer_enum of this EnumTest. # noqa: E501 """ - - self._outer_enum = ( - outer_enum - ) + return self.__set_item('outer_enum', value) def to_dict(self): """Returns the model properties as a dict""" - result = {} - - for attr, _ in six.iteritems(self.openapi_types): - value = getattr(self, attr) - if isinstance(value, list): - result[attr] = list(map( - lambda x: x.to_dict() if hasattr(x, "to_dict") else x, - value - )) - elif hasattr(value, "to_dict"): - result[attr] = value.to_dict() - elif isinstance(value, dict): - result[attr] = dict(map( - lambda item: (item[0], item[1].to_dict()) - if hasattr(item[1], "to_dict") else item, - value.items() - )) - else: - result[attr] = value - - return result + return model_to_dict(self, serialize=False) def to_str(self): """Returns the string representation of the model""" @@ -294,7 +305,22 @@ def __eq__(self, other): if not isinstance(other, EnumTest): return False - return self.__dict__ == other.__dict__ + if not set(self._data_store.keys()) == set(other._data_store.keys()): + return False + for _var_name, this_val in six.iteritems(self._data_store): + that_val = other._data_store[_var_name] + types = set() + types.add(this_val.__class__) + types.add(that_val.__class__) + vals_equal = this_val == that_val + if (not six.PY3 and + len(types) == 2 and unicode in types): # noqa: F821 + vals_equal = ( + this_val.encode('utf-8') == that_val.encode('utf-8') + ) + if not vals_equal: + return False + return True def __ne__(self, other): """Returns true if both objects are not equal""" diff --git a/samples/client/petstore/python-experimental/petstore_api/models/file.py b/samples/client/petstore/python-experimental/petstore_api/models/file.py index 6411e70e07b9..7da4e025a205 100644 --- a/samples/client/petstore/python-experimental/petstore_api/models/file.py +++ b/samples/client/petstore/python-experimental/petstore_api/models/file.py @@ -15,12 +15,26 @@ import six # noqa: F401 -from petstore_api.exceptions import ApiValueError # noqa: F401 +from petstore_api.exceptions import ( # noqa: F401 + ApiKeyError, + ApiTypeError, + ApiValueError, +) from petstore_api.model_utils import ( # noqa: F401 ModelNormal, ModelSimple, check_allowed_values, - check_validations + check_validations, + date, + datetime, + file_type, + get_simple_class, + int, + model_to_dict, + none_type, + str, + type_error_message, + validate_and_convert_types ) @@ -46,6 +60,8 @@ class File(ModelNormal): 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 = { @@ -56,71 +72,134 @@ class File(ModelNormal): } openapi_types = { - 'source_uri': 'str' + 'source_uri': (str,), # noqa: E501 } validations = { } - def __init__(self, source_uri=None): # noqa: E501 - """File - a model defined in OpenAPI""" # noqa: E501 - - self._source_uri = None - self.discriminator = None + additional_properties_type = None + + discriminator = None + + def __init__(self, _check_type=True, _from_server=False, _path_to_item=(), _configuration=None, **kwargs): # noqa: E501 + """File - 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 + _from_server (bool): True if the data is from the server + False if the data is from the client (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. + source_uri (str): Test capitalization. [optional] # noqa: E501 + """ + self._data_store = {} + self._check_type = _check_type + self._from_server = _from_server + self._path_to_item = _path_to_item + self._configuration = _configuration + + for var_name, var_value in six.iteritems(kwargs): + self.__set_item(var_name, var_value) + + def __set_item(self, name, value): + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + + if name in self.openapi_types: + required_types_mixed = self.openapi_types[name] + elif self.additional_properties_type is None: + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + path_to_item + ) + elif self.additional_properties_type is not None: + required_types_mixed = self.additional_properties_type + + if get_simple_class(name) != str: + error_msg = type_error_message( + var_name=name, + var_value=name, + valid_classes=(str,), + key_type=True + ) + raise ApiTypeError( + error_msg, + path_to_item=path_to_item, + valid_classes=(str,), + key_type=True + ) - if source_uri is not None: - self.source_uri = ( - source_uri + if self._check_type: + value = validate_and_convert_types( + value, required_types_mixed, path_to_item, self._from_server, + self._check_type, configuration=self._configuration) + if (name,) in self.allowed_values: + check_allowed_values( + self.allowed_values, + (name,), + value ) + if (name,) in self.validations: + check_validations( + self.validations, + (name,), + value + ) + self._data_store[name] = value + + def __get_item(self, name): + if name in self._data_store: + return self._data_store[name] + + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + [name] + ) + + def __setitem__(self, name, value): + """this allows us to set values with instance[field_name] = val""" + self.__set_item(name, value) + + def __getitem__(self, name): + """this allows us to get a value with val = instance[field_name]""" + return self.__get_item(name) @property def source_uri(self): """Gets the source_uri of this File. # noqa: E501 - Test capitalization # noqa: E501 - :return: The source_uri of this File. # noqa: E501 - :rtype: str + Returns: + (str): The source_uri of this File. # noqa: E501 """ - return self._source_uri + return self.__get_item('source_uri') @source_uri.setter - def source_uri(self, source_uri): # noqa: E501 - """Sets the source_uri of this File. - + def source_uri(self, value): + """Sets the source_uri of this File. # noqa: E501 Test capitalization # noqa: E501 - - :param source_uri: The source_uri of this File. # noqa: E501 - :type: str """ - - self._source_uri = ( - source_uri - ) + return self.__set_item('source_uri', value) def to_dict(self): """Returns the model properties as a dict""" - result = {} - - for attr, _ in six.iteritems(self.openapi_types): - value = getattr(self, attr) - if isinstance(value, list): - result[attr] = list(map( - lambda x: x.to_dict() if hasattr(x, "to_dict") else x, - value - )) - elif hasattr(value, "to_dict"): - result[attr] = value.to_dict() - elif isinstance(value, dict): - result[attr] = dict(map( - lambda item: (item[0], item[1].to_dict()) - if hasattr(item[1], "to_dict") else item, - value.items() - )) - else: - result[attr] = value - - return result + return model_to_dict(self, serialize=False) def to_str(self): """Returns the string representation of the model""" @@ -135,7 +214,22 @@ def __eq__(self, other): if not isinstance(other, File): return False - return self.__dict__ == other.__dict__ + if not set(self._data_store.keys()) == set(other._data_store.keys()): + return False + for _var_name, this_val in six.iteritems(self._data_store): + that_val = other._data_store[_var_name] + types = set() + types.add(this_val.__class__) + types.add(that_val.__class__) + vals_equal = this_val == that_val + if (not six.PY3 and + len(types) == 2 and unicode in types): # noqa: F821 + vals_equal = ( + this_val.encode('utf-8') == that_val.encode('utf-8') + ) + if not vals_equal: + return False + return True def __ne__(self, other): """Returns true if both objects are not equal""" diff --git a/samples/client/petstore/python-experimental/petstore_api/models/file_schema_test_class.py b/samples/client/petstore/python-experimental/petstore_api/models/file_schema_test_class.py index e773e2cb194c..5e0ca0498d9a 100644 --- a/samples/client/petstore/python-experimental/petstore_api/models/file_schema_test_class.py +++ b/samples/client/petstore/python-experimental/petstore_api/models/file_schema_test_class.py @@ -15,13 +15,28 @@ import six # noqa: F401 -from petstore_api.exceptions import ApiValueError # noqa: F401 +from petstore_api.exceptions import ( # noqa: F401 + ApiKeyError, + ApiTypeError, + ApiValueError, +) from petstore_api.model_utils import ( # noqa: F401 ModelNormal, ModelSimple, check_allowed_values, - check_validations + check_validations, + date, + datetime, + file_type, + get_simple_class, + int, + model_to_dict, + none_type, + str, + type_error_message, + validate_and_convert_types ) +from petstore_api.models.file import File class FileSchemaTestClass(ModelNormal): @@ -46,6 +61,8 @@ class FileSchemaTestClass(ModelNormal): 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 = { @@ -57,98 +74,149 @@ class FileSchemaTestClass(ModelNormal): } openapi_types = { - 'file': 'File', - 'files': 'list[File]' + 'file': (File,), # noqa: E501 + 'files': ([File],), # noqa: E501 } validations = { } - def __init__(self, file=None, files=None): # noqa: E501 - """FileSchemaTestClass - a model defined in OpenAPI""" # noqa: E501 - - self._file = None - self._files = None - self.discriminator = None + additional_properties_type = None + + discriminator = None + + def __init__(self, _check_type=True, _from_server=False, _path_to_item=(), _configuration=None, **kwargs): # noqa: E501 + """FileSchemaTestClass - 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 + _from_server (bool): True if the data is from the server + False if the data is from the client (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. + file (File): [optional] # noqa: E501 + files ([File]): [optional] # noqa: E501 + """ + self._data_store = {} + self._check_type = _check_type + self._from_server = _from_server + self._path_to_item = _path_to_item + self._configuration = _configuration + + for var_name, var_value in six.iteritems(kwargs): + self.__set_item(var_name, var_value) + + def __set_item(self, name, value): + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + + if name in self.openapi_types: + required_types_mixed = self.openapi_types[name] + elif self.additional_properties_type is None: + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + path_to_item + ) + elif self.additional_properties_type is not None: + required_types_mixed = self.additional_properties_type + + if get_simple_class(name) != str: + error_msg = type_error_message( + var_name=name, + var_value=name, + valid_classes=(str,), + key_type=True + ) + raise ApiTypeError( + error_msg, + path_to_item=path_to_item, + valid_classes=(str,), + key_type=True + ) - if file is not None: - self.file = ( - file + if self._check_type: + value = validate_and_convert_types( + value, required_types_mixed, path_to_item, self._from_server, + self._check_type, configuration=self._configuration) + if (name,) in self.allowed_values: + check_allowed_values( + self.allowed_values, + (name,), + value ) - if files is not None: - self.files = ( - files + if (name,) in self.validations: + check_validations( + self.validations, + (name,), + value ) + self._data_store[name] = value + + def __get_item(self, name): + if name in self._data_store: + return self._data_store[name] + + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + [name] + ) + + def __setitem__(self, name, value): + """this allows us to set values with instance[field_name] = val""" + self.__set_item(name, value) + + def __getitem__(self, name): + """this allows us to get a value with val = instance[field_name]""" + return self.__get_item(name) @property def file(self): """Gets the file of this FileSchemaTestClass. # noqa: E501 - - :return: The file of this FileSchemaTestClass. # noqa: E501 - :rtype: File + Returns: + (File): The file of this FileSchemaTestClass. # noqa: E501 """ - return self._file + return self.__get_item('file') @file.setter - def file(self, file): # noqa: E501 - """Sets the file of this FileSchemaTestClass. - - - :param file: The file of this FileSchemaTestClass. # noqa: E501 - :type: File + def file(self, value): + """Sets the file of this FileSchemaTestClass. # noqa: E501 """ - - self._file = ( - file - ) + return self.__set_item('file', value) @property def files(self): """Gets the files of this FileSchemaTestClass. # noqa: E501 - - :return: The files of this FileSchemaTestClass. # noqa: E501 - :rtype: list[File] + Returns: + ([File]): The files of this FileSchemaTestClass. # noqa: E501 """ - return self._files + return self.__get_item('files') @files.setter - def files(self, files): # noqa: E501 - """Sets the files of this FileSchemaTestClass. - - - :param files: The files of this FileSchemaTestClass. # noqa: E501 - :type: list[File] + def files(self, value): + """Sets the files of this FileSchemaTestClass. # noqa: E501 """ - - self._files = ( - files - ) + return self.__set_item('files', value) def to_dict(self): """Returns the model properties as a dict""" - result = {} - - for attr, _ in six.iteritems(self.openapi_types): - value = getattr(self, attr) - if isinstance(value, list): - result[attr] = list(map( - lambda x: x.to_dict() if hasattr(x, "to_dict") else x, - value - )) - elif hasattr(value, "to_dict"): - result[attr] = value.to_dict() - elif isinstance(value, dict): - result[attr] = dict(map( - lambda item: (item[0], item[1].to_dict()) - if hasattr(item[1], "to_dict") else item, - value.items() - )) - else: - result[attr] = value - - return result + return model_to_dict(self, serialize=False) def to_str(self): """Returns the string representation of the model""" @@ -163,7 +231,22 @@ def __eq__(self, other): if not isinstance(other, FileSchemaTestClass): return False - return self.__dict__ == other.__dict__ + if not set(self._data_store.keys()) == set(other._data_store.keys()): + return False + for _var_name, this_val in six.iteritems(self._data_store): + that_val = other._data_store[_var_name] + types = set() + types.add(this_val.__class__) + types.add(that_val.__class__) + vals_equal = this_val == that_val + if (not six.PY3 and + len(types) == 2 and unicode in types): # noqa: F821 + vals_equal = ( + this_val.encode('utf-8') == that_val.encode('utf-8') + ) + if not vals_equal: + return False + return True def __ne__(self, other): """Returns true if both objects are not equal""" diff --git a/samples/client/petstore/python-experimental/petstore_api/models/format_test.py b/samples/client/petstore/python-experimental/petstore_api/models/format_test.py index 8b1a5143e013..de33c15695b6 100644 --- a/samples/client/petstore/python-experimental/petstore_api/models/format_test.py +++ b/samples/client/petstore/python-experimental/petstore_api/models/format_test.py @@ -15,12 +15,26 @@ import six # noqa: F401 -from petstore_api.exceptions import ApiValueError # noqa: F401 +from petstore_api.exceptions import ( # noqa: F401 + ApiKeyError, + ApiTypeError, + ApiValueError, +) from petstore_api.model_utils import ( # noqa: F401 ModelNormal, ModelSimple, check_allowed_values, - check_validations + check_validations, + date, + datetime, + file_type, + get_simple_class, + int, + model_to_dict, + none_type, + str, + type_error_message, + validate_and_convert_types ) @@ -46,6 +60,8 @@ class FormatTest(ModelNormal): 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 = { @@ -68,56 +84,49 @@ class FormatTest(ModelNormal): } openapi_types = { - 'integer': 'int', - 'int32': 'int', - 'int64': 'int', - 'number': 'float', - 'float': 'float', - 'double': 'float', - 'string': 'str', - 'byte': 'str', - 'binary': 'file', - 'date': 'date', - 'date_time': 'datetime', - 'uuid': 'str', - 'password': 'str' + 'integer': (int,), # noqa: E501 + 'int32': (int,), # noqa: E501 + 'int64': (int,), # noqa: E501 + 'number': (float,), # noqa: E501 + 'float': (float,), # noqa: E501 + 'double': (float,), # noqa: E501 + 'string': (str,), # noqa: E501 + 'byte': (str,), # noqa: E501 + 'binary': (file_type,), # noqa: E501 + 'date': (date,), # noqa: E501 + 'date_time': (datetime,), # noqa: E501 + 'uuid': (str,), # noqa: E501 + 'password': (str,), # noqa: E501 } validations = { ('integer',): { - 'inclusive_maximum': 100, 'inclusive_minimum': 10, }, ('int32',): { - 'inclusive_maximum': 200, 'inclusive_minimum': 20, }, ('number',): { - 'inclusive_maximum': 543.2, 'inclusive_minimum': 32.1, }, ('float',): { - 'inclusive_maximum': 987.6, 'inclusive_minimum': 54.3, }, ('double',): { - 'inclusive_maximum': 123.4, 'inclusive_minimum': 67.8, }, ('string',): { - 'regex': { 'pattern': r'^[a-z]+$', # noqa: E501 'flags': (re.IGNORECASE) }, }, ('byte',): { - 'regex': { 'pattern': r'^(?:[A-Za-z0-9+\/]{4})*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=)?$', # noqa: E501 }, @@ -128,435 +137,323 @@ class FormatTest(ModelNormal): }, } - def __init__(self, integer=None, int32=None, int64=None, number=None, float=None, double=None, string=None, byte=None, binary=None, date=None, date_time=None, uuid=None, password=None): # noqa: E501 - """FormatTest - a model defined in OpenAPI""" # noqa: E501 - - self._integer = None - self._int32 = None - self._int64 = None - self._number = None - self._float = None - self._double = None - self._string = None - self._byte = None - self._binary = None - self._date = None - self._date_time = None - self._uuid = None - self._password = None - self.discriminator = None - - if integer is not None: - self.integer = ( - integer - ) - if int32 is not None: - self.int32 = ( - int32 - ) - if int64 is not None: - self.int64 = ( - int64 - ) - self.number = number - if float is not None: - self.float = ( - float - ) - if double is not None: - self.double = ( - double + additional_properties_type = None + + discriminator = None + + def __init__(self, number, byte, date, password, _check_type=True, _from_server=False, _path_to_item=(), _configuration=None, **kwargs): # noqa: E501 + """FormatTest - a model defined in OpenAPI + + Args: + number (float): + byte (str): + date (date): + password (str): + + 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 + _from_server (bool): True if the data is from the server + False if the data is from the client (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. + integer (int): [optional] # noqa: E501 + int32 (int): [optional] # noqa: E501 + int64 (int): [optional] # noqa: E501 + float (float): [optional] # noqa: E501 + double (float): [optional] # noqa: E501 + string (str): [optional] # noqa: E501 + binary (file_type): [optional] # noqa: E501 + date_time (datetime): [optional] # noqa: E501 + uuid (str): [optional] # noqa: E501 + """ + self._data_store = {} + self._check_type = _check_type + self._from_server = _from_server + self._path_to_item = _path_to_item + self._configuration = _configuration + + self.__set_item('number', number) + self.__set_item('byte', byte) + self.__set_item('date', date) + self.__set_item('password', password) + for var_name, var_value in six.iteritems(kwargs): + self.__set_item(var_name, var_value) + + def __set_item(self, name, value): + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + + if name in self.openapi_types: + required_types_mixed = self.openapi_types[name] + elif self.additional_properties_type is None: + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + path_to_item ) - if string is not None: - self.string = ( - string + elif self.additional_properties_type is not None: + required_types_mixed = self.additional_properties_type + + if get_simple_class(name) != str: + error_msg = type_error_message( + var_name=name, + var_value=name, + valid_classes=(str,), + key_type=True ) - self.byte = byte - if binary is not None: - self.binary = ( - binary + raise ApiTypeError( + error_msg, + path_to_item=path_to_item, + valid_classes=(str,), + key_type=True ) - self.date = date - if date_time is not None: - self.date_time = ( - date_time + + if self._check_type: + value = validate_and_convert_types( + value, required_types_mixed, path_to_item, self._from_server, + self._check_type, configuration=self._configuration) + if (name,) in self.allowed_values: + check_allowed_values( + self.allowed_values, + (name,), + value ) - if uuid is not None: - self.uuid = ( - uuid + if (name,) in self.validations: + check_validations( + self.validations, + (name,), + value ) - self.password = password + self._data_store[name] = value + + def __get_item(self, name): + if name in self._data_store: + return self._data_store[name] + + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + [name] + ) + + def __setitem__(self, name, value): + """this allows us to set values with instance[field_name] = val""" + self.__set_item(name, value) + + def __getitem__(self, name): + """this allows us to get a value with val = instance[field_name]""" + return self.__get_item(name) @property def integer(self): """Gets the integer of this FormatTest. # noqa: E501 - - :return: The integer of this FormatTest. # noqa: E501 - :rtype: int + Returns: + (int): The integer of this FormatTest. # noqa: E501 """ - return self._integer + return self.__get_item('integer') @integer.setter - def integer(self, integer): # noqa: E501 - """Sets the integer of this FormatTest. - - - :param integer: The integer of this FormatTest. # noqa: E501 - :type: int + def integer(self, value): + """Sets the integer of this FormatTest. # noqa: E501 """ - check_validations( - self.validations, - ('integer',), - integer - ) - - self._integer = ( - integer - ) + return self.__set_item('integer', value) @property def int32(self): """Gets the int32 of this FormatTest. # noqa: E501 - - :return: The int32 of this FormatTest. # noqa: E501 - :rtype: int + Returns: + (int): The int32 of this FormatTest. # noqa: E501 """ - return self._int32 + return self.__get_item('int32') @int32.setter - def int32(self, int32): # noqa: E501 - """Sets the int32 of this FormatTest. - - - :param int32: The int32 of this FormatTest. # noqa: E501 - :type: int + def int32(self, value): + """Sets the int32 of this FormatTest. # noqa: E501 """ - check_validations( - self.validations, - ('int32',), - int32 - ) - - self._int32 = ( - int32 - ) + return self.__set_item('int32', value) @property def int64(self): """Gets the int64 of this FormatTest. # noqa: E501 - - :return: The int64 of this FormatTest. # noqa: E501 - :rtype: int + Returns: + (int): The int64 of this FormatTest. # noqa: E501 """ - return self._int64 + return self.__get_item('int64') @int64.setter - def int64(self, int64): # noqa: E501 - """Sets the int64 of this FormatTest. - - - :param int64: The int64 of this FormatTest. # noqa: E501 - :type: int + def int64(self, value): + """Sets the int64 of this FormatTest. # noqa: E501 """ - - self._int64 = ( - int64 - ) + return self.__set_item('int64', value) @property def number(self): """Gets the number of this FormatTest. # noqa: E501 - - :return: The number of this FormatTest. # noqa: E501 - :rtype: float + Returns: + (float): The number of this FormatTest. # noqa: E501 """ - return self._number + return self.__get_item('number') @number.setter - def number(self, number): # noqa: E501 - """Sets the number of this FormatTest. - - - :param number: The number of this FormatTest. # noqa: E501 - :type: float + def number(self, value): + """Sets the number of this FormatTest. # noqa: E501 """ - if number is None: - raise ApiValueError("Invalid value for `number`, must not be `None`") # noqa: E501 - check_validations( - self.validations, - ('number',), - number - ) - - self._number = ( - number - ) + return self.__set_item('number', value) @property def float(self): """Gets the float of this FormatTest. # noqa: E501 - - :return: The float of this FormatTest. # noqa: E501 - :rtype: float + Returns: + (float): The float of this FormatTest. # noqa: E501 """ - return self._float + return self.__get_item('float') @float.setter - def float(self, float): # noqa: E501 - """Sets the float of this FormatTest. - - - :param float: The float of this FormatTest. # noqa: E501 - :type: float + def float(self, value): + """Sets the float of this FormatTest. # noqa: E501 """ - check_validations( - self.validations, - ('float',), - float - ) - - self._float = ( - float - ) + return self.__set_item('float', value) @property def double(self): """Gets the double of this FormatTest. # noqa: E501 - - :return: The double of this FormatTest. # noqa: E501 - :rtype: float + Returns: + (float): The double of this FormatTest. # noqa: E501 """ - return self._double + return self.__get_item('double') @double.setter - def double(self, double): # noqa: E501 - """Sets the double of this FormatTest. - - - :param double: The double of this FormatTest. # noqa: E501 - :type: float + def double(self, value): + """Sets the double of this FormatTest. # noqa: E501 """ - check_validations( - self.validations, - ('double',), - double - ) - - self._double = ( - double - ) + return self.__set_item('double', value) @property def string(self): """Gets the string of this FormatTest. # noqa: E501 - - :return: The string of this FormatTest. # noqa: E501 - :rtype: str + Returns: + (str): The string of this FormatTest. # noqa: E501 """ - return self._string + return self.__get_item('string') @string.setter - def string(self, string): # noqa: E501 - """Sets the string of this FormatTest. - - - :param string: The string of this FormatTest. # noqa: E501 - :type: str + def string(self, value): + """Sets the string of this FormatTest. # noqa: E501 """ - check_validations( - self.validations, - ('string',), - string - ) - - self._string = ( - string - ) + return self.__set_item('string', value) @property def byte(self): """Gets the byte of this FormatTest. # noqa: E501 - - :return: The byte of this FormatTest. # noqa: E501 - :rtype: str + Returns: + (str): The byte of this FormatTest. # noqa: E501 """ - return self._byte + return self.__get_item('byte') @byte.setter - def byte(self, byte): # noqa: E501 - """Sets the byte of this FormatTest. - - - :param byte: The byte of this FormatTest. # noqa: E501 - :type: str + def byte(self, value): + """Sets the byte of this FormatTest. # noqa: E501 """ - if byte is None: - raise ApiValueError("Invalid value for `byte`, must not be `None`") # noqa: E501 - check_validations( - self.validations, - ('byte',), - byte - ) - - self._byte = ( - byte - ) + return self.__set_item('byte', value) @property def binary(self): """Gets the binary of this FormatTest. # noqa: E501 - - :return: The binary of this FormatTest. # noqa: E501 - :rtype: file + Returns: + (file_type): The binary of this FormatTest. # noqa: E501 """ - return self._binary + return self.__get_item('binary') @binary.setter - def binary(self, binary): # noqa: E501 - """Sets the binary of this FormatTest. - - - :param binary: The binary of this FormatTest. # noqa: E501 - :type: file + def binary(self, value): + """Sets the binary of this FormatTest. # noqa: E501 """ - - self._binary = ( - binary - ) + return self.__set_item('binary', value) @property def date(self): """Gets the date of this FormatTest. # noqa: E501 - - :return: The date of this FormatTest. # noqa: E501 - :rtype: date + Returns: + (date): The date of this FormatTest. # noqa: E501 """ - return self._date + return self.__get_item('date') @date.setter - def date(self, date): # noqa: E501 - """Sets the date of this FormatTest. - - - :param date: The date of this FormatTest. # noqa: E501 - :type: date + def date(self, value): + """Sets the date of this FormatTest. # noqa: E501 """ - if date is None: - raise ApiValueError("Invalid value for `date`, must not be `None`") # noqa: E501 - - self._date = ( - date - ) + return self.__set_item('date', value) @property def date_time(self): """Gets the date_time of this FormatTest. # noqa: E501 - - :return: The date_time of this FormatTest. # noqa: E501 - :rtype: datetime + Returns: + (datetime): The date_time of this FormatTest. # noqa: E501 """ - return self._date_time + return self.__get_item('date_time') @date_time.setter - def date_time(self, date_time): # noqa: E501 - """Sets the date_time of this FormatTest. - - - :param date_time: The date_time of this FormatTest. # noqa: E501 - :type: datetime + def date_time(self, value): + """Sets the date_time of this FormatTest. # noqa: E501 """ - - self._date_time = ( - date_time - ) + return self.__set_item('date_time', value) @property def uuid(self): """Gets the uuid of this FormatTest. # noqa: E501 - - :return: The uuid of this FormatTest. # noqa: E501 - :rtype: str + Returns: + (str): The uuid of this FormatTest. # noqa: E501 """ - return self._uuid + return self.__get_item('uuid') @uuid.setter - def uuid(self, uuid): # noqa: E501 - """Sets the uuid of this FormatTest. - - - :param uuid: The uuid of this FormatTest. # noqa: E501 - :type: str + def uuid(self, value): + """Sets the uuid of this FormatTest. # noqa: E501 """ - - self._uuid = ( - uuid - ) + return self.__set_item('uuid', value) @property def password(self): """Gets the password of this FormatTest. # noqa: E501 - - :return: The password of this FormatTest. # noqa: E501 - :rtype: str + Returns: + (str): The password of this FormatTest. # noqa: E501 """ - return self._password + return self.__get_item('password') @password.setter - def password(self, password): # noqa: E501 - """Sets the password of this FormatTest. - - - :param password: The password of this FormatTest. # noqa: E501 - :type: str + def password(self, value): + """Sets the password of this FormatTest. # noqa: E501 """ - if password is None: - raise ApiValueError("Invalid value for `password`, must not be `None`") # noqa: E501 - check_validations( - self.validations, - ('password',), - password - ) - - self._password = ( - password - ) + return self.__set_item('password', value) def to_dict(self): """Returns the model properties as a dict""" - result = {} - - for attr, _ in six.iteritems(self.openapi_types): - value = getattr(self, attr) - if isinstance(value, list): - result[attr] = list(map( - lambda x: x.to_dict() if hasattr(x, "to_dict") else x, - value - )) - elif hasattr(value, "to_dict"): - result[attr] = value.to_dict() - elif isinstance(value, dict): - result[attr] = dict(map( - lambda item: (item[0], item[1].to_dict()) - if hasattr(item[1], "to_dict") else item, - value.items() - )) - else: - result[attr] = value - - return result + return model_to_dict(self, serialize=False) def to_str(self): """Returns the string representation of the model""" @@ -571,7 +468,22 @@ def __eq__(self, other): if not isinstance(other, FormatTest): return False - return self.__dict__ == other.__dict__ + if not set(self._data_store.keys()) == set(other._data_store.keys()): + return False + for _var_name, this_val in six.iteritems(self._data_store): + that_val = other._data_store[_var_name] + types = set() + types.add(this_val.__class__) + types.add(that_val.__class__) + vals_equal = this_val == that_val + if (not six.PY3 and + len(types) == 2 and unicode in types): # noqa: F821 + vals_equal = ( + this_val.encode('utf-8') == that_val.encode('utf-8') + ) + if not vals_equal: + return False + return True def __ne__(self, other): """Returns true if both objects are not equal""" diff --git a/samples/client/petstore/python-experimental/petstore_api/models/has_only_read_only.py b/samples/client/petstore/python-experimental/petstore_api/models/has_only_read_only.py index 2ef64381ea32..ecf201d21e81 100644 --- a/samples/client/petstore/python-experimental/petstore_api/models/has_only_read_only.py +++ b/samples/client/petstore/python-experimental/petstore_api/models/has_only_read_only.py @@ -15,12 +15,26 @@ import six # noqa: F401 -from petstore_api.exceptions import ApiValueError # noqa: F401 +from petstore_api.exceptions import ( # noqa: F401 + ApiKeyError, + ApiTypeError, + ApiValueError, +) from petstore_api.model_utils import ( # noqa: F401 ModelNormal, ModelSimple, check_allowed_values, - check_validations + check_validations, + date, + datetime, + file_type, + get_simple_class, + int, + model_to_dict, + none_type, + str, + type_error_message, + validate_and_convert_types ) @@ -46,6 +60,8 @@ class HasOnlyReadOnly(ModelNormal): 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 = { @@ -57,98 +73,149 @@ class HasOnlyReadOnly(ModelNormal): } openapi_types = { - 'bar': 'str', - 'foo': 'str' + 'bar': (str,), # noqa: E501 + 'foo': (str,), # noqa: E501 } validations = { } - def __init__(self, bar=None, foo=None): # noqa: E501 - """HasOnlyReadOnly - a model defined in OpenAPI""" # noqa: E501 - - self._bar = None - self._foo = None - self.discriminator = None + additional_properties_type = None + + discriminator = None + + def __init__(self, _check_type=True, _from_server=False, _path_to_item=(), _configuration=None, **kwargs): # noqa: E501 + """HasOnlyReadOnly - 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 + _from_server (bool): True if the data is from the server + False if the data is from the client (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. + bar (str): [optional] # noqa: E501 + foo (str): [optional] # noqa: E501 + """ + self._data_store = {} + self._check_type = _check_type + self._from_server = _from_server + self._path_to_item = _path_to_item + self._configuration = _configuration + + for var_name, var_value in six.iteritems(kwargs): + self.__set_item(var_name, var_value) + + def __set_item(self, name, value): + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + + if name in self.openapi_types: + required_types_mixed = self.openapi_types[name] + elif self.additional_properties_type is None: + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + path_to_item + ) + elif self.additional_properties_type is not None: + required_types_mixed = self.additional_properties_type + + if get_simple_class(name) != str: + error_msg = type_error_message( + var_name=name, + var_value=name, + valid_classes=(str,), + key_type=True + ) + raise ApiTypeError( + error_msg, + path_to_item=path_to_item, + valid_classes=(str,), + key_type=True + ) - if bar is not None: - self.bar = ( - bar + if self._check_type: + value = validate_and_convert_types( + value, required_types_mixed, path_to_item, self._from_server, + self._check_type, configuration=self._configuration) + if (name,) in self.allowed_values: + check_allowed_values( + self.allowed_values, + (name,), + value ) - if foo is not None: - self.foo = ( - foo + if (name,) in self.validations: + check_validations( + self.validations, + (name,), + value ) + self._data_store[name] = value + + def __get_item(self, name): + if name in self._data_store: + return self._data_store[name] + + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + [name] + ) + + def __setitem__(self, name, value): + """this allows us to set values with instance[field_name] = val""" + self.__set_item(name, value) + + def __getitem__(self, name): + """this allows us to get a value with val = instance[field_name]""" + return self.__get_item(name) @property def bar(self): """Gets the bar of this HasOnlyReadOnly. # noqa: E501 - - :return: The bar of this HasOnlyReadOnly. # noqa: E501 - :rtype: str + Returns: + (str): The bar of this HasOnlyReadOnly. # noqa: E501 """ - return self._bar + return self.__get_item('bar') @bar.setter - def bar(self, bar): # noqa: E501 - """Sets the bar of this HasOnlyReadOnly. - - - :param bar: The bar of this HasOnlyReadOnly. # noqa: E501 - :type: str + def bar(self, value): + """Sets the bar of this HasOnlyReadOnly. # noqa: E501 """ - - self._bar = ( - bar - ) + return self.__set_item('bar', value) @property def foo(self): """Gets the foo of this HasOnlyReadOnly. # noqa: E501 - - :return: The foo of this HasOnlyReadOnly. # noqa: E501 - :rtype: str + Returns: + (str): The foo of this HasOnlyReadOnly. # noqa: E501 """ - return self._foo + return self.__get_item('foo') @foo.setter - def foo(self, foo): # noqa: E501 - """Sets the foo of this HasOnlyReadOnly. - - - :param foo: The foo of this HasOnlyReadOnly. # noqa: E501 - :type: str + def foo(self, value): + """Sets the foo of this HasOnlyReadOnly. # noqa: E501 """ - - self._foo = ( - foo - ) + return self.__set_item('foo', value) def to_dict(self): """Returns the model properties as a dict""" - result = {} - - for attr, _ in six.iteritems(self.openapi_types): - value = getattr(self, attr) - if isinstance(value, list): - result[attr] = list(map( - lambda x: x.to_dict() if hasattr(x, "to_dict") else x, - value - )) - elif hasattr(value, "to_dict"): - result[attr] = value.to_dict() - elif isinstance(value, dict): - result[attr] = dict(map( - lambda item: (item[0], item[1].to_dict()) - if hasattr(item[1], "to_dict") else item, - value.items() - )) - else: - result[attr] = value - - return result + return model_to_dict(self, serialize=False) def to_str(self): """Returns the string representation of the model""" @@ -163,7 +230,22 @@ def __eq__(self, other): if not isinstance(other, HasOnlyReadOnly): return False - return self.__dict__ == other.__dict__ + if not set(self._data_store.keys()) == set(other._data_store.keys()): + return False + for _var_name, this_val in six.iteritems(self._data_store): + that_val = other._data_store[_var_name] + types = set() + types.add(this_val.__class__) + types.add(that_val.__class__) + vals_equal = this_val == that_val + if (not six.PY3 and + len(types) == 2 and unicode in types): # noqa: F821 + vals_equal = ( + this_val.encode('utf-8') == that_val.encode('utf-8') + ) + if not vals_equal: + return False + return True def __ne__(self, other): """Returns true if both objects are not equal""" diff --git a/samples/client/petstore/python-experimental/petstore_api/models/list.py b/samples/client/petstore/python-experimental/petstore_api/models/list.py index 388989603a92..79ff6c81bede 100644 --- a/samples/client/petstore/python-experimental/petstore_api/models/list.py +++ b/samples/client/petstore/python-experimental/petstore_api/models/list.py @@ -15,12 +15,26 @@ import six # noqa: F401 -from petstore_api.exceptions import ApiValueError # noqa: F401 +from petstore_api.exceptions import ( # noqa: F401 + ApiKeyError, + ApiTypeError, + ApiValueError, +) from petstore_api.model_utils import ( # noqa: F401 ModelNormal, ModelSimple, check_allowed_values, - check_validations + check_validations, + date, + datetime, + file_type, + get_simple_class, + int, + model_to_dict, + none_type, + str, + type_error_message, + validate_and_convert_types ) @@ -46,6 +60,8 @@ class List(ModelNormal): 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 = { @@ -56,69 +72,132 @@ class List(ModelNormal): } openapi_types = { - '_123_list': 'str' + '_123_list': (str,), # noqa: E501 } validations = { } - def __init__(self, _123_list=None): # noqa: E501 - """List - a model defined in OpenAPI""" # noqa: E501 - - self.__123_list = None - self.discriminator = None + additional_properties_type = None + + discriminator = None + + def __init__(self, _check_type=True, _from_server=False, _path_to_item=(), _configuration=None, **kwargs): # noqa: E501 + """List - 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 + _from_server (bool): True if the data is from the server + False if the data is from the client (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. + _123_list (str): [optional] # noqa: E501 + """ + self._data_store = {} + self._check_type = _check_type + self._from_server = _from_server + self._path_to_item = _path_to_item + self._configuration = _configuration + + for var_name, var_value in six.iteritems(kwargs): + self.__set_item(var_name, var_value) + + def __set_item(self, name, value): + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + + if name in self.openapi_types: + required_types_mixed = self.openapi_types[name] + elif self.additional_properties_type is None: + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + path_to_item + ) + elif self.additional_properties_type is not None: + required_types_mixed = self.additional_properties_type + + if get_simple_class(name) != str: + error_msg = type_error_message( + var_name=name, + var_value=name, + valid_classes=(str,), + key_type=True + ) + raise ApiTypeError( + error_msg, + path_to_item=path_to_item, + valid_classes=(str,), + key_type=True + ) - if _123_list is not None: - self._123_list = ( - _123_list + if self._check_type: + value = validate_and_convert_types( + value, required_types_mixed, path_to_item, self._from_server, + self._check_type, configuration=self._configuration) + if (name,) in self.allowed_values: + check_allowed_values( + self.allowed_values, + (name,), + value ) + if (name,) in self.validations: + check_validations( + self.validations, + (name,), + value + ) + self._data_store[name] = value + + def __get_item(self, name): + if name in self._data_store: + return self._data_store[name] + + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + [name] + ) + + def __setitem__(self, name, value): + """this allows us to set values with instance[field_name] = val""" + self.__set_item(name, value) + + def __getitem__(self, name): + """this allows us to get a value with val = instance[field_name]""" + return self.__get_item(name) @property def _123_list(self): """Gets the _123_list of this List. # noqa: E501 - - :return: The _123_list of this List. # noqa: E501 - :rtype: str + Returns: + (str): The _123_list of this List. # noqa: E501 """ - return self.__123_list + return self.__get_item('_123_list') @_123_list.setter - def _123_list(self, _123_list): # noqa: E501 - """Sets the _123_list of this List. - - - :param _123_list: The _123_list of this List. # noqa: E501 - :type: str + def _123_list(self, value): + """Sets the _123_list of this List. # noqa: E501 """ - - self.__123_list = ( - _123_list - ) + return self.__set_item('_123_list', value) def to_dict(self): """Returns the model properties as a dict""" - result = {} - - for attr, _ in six.iteritems(self.openapi_types): - value = getattr(self, attr) - if isinstance(value, list): - result[attr] = list(map( - lambda x: x.to_dict() if hasattr(x, "to_dict") else x, - value - )) - elif hasattr(value, "to_dict"): - result[attr] = value.to_dict() - elif isinstance(value, dict): - result[attr] = dict(map( - lambda item: (item[0], item[1].to_dict()) - if hasattr(item[1], "to_dict") else item, - value.items() - )) - else: - result[attr] = value - - return result + return model_to_dict(self, serialize=False) def to_str(self): """Returns the string representation of the model""" @@ -133,7 +212,22 @@ def __eq__(self, other): if not isinstance(other, List): return False - return self.__dict__ == other.__dict__ + if not set(self._data_store.keys()) == set(other._data_store.keys()): + return False + for _var_name, this_val in six.iteritems(self._data_store): + that_val = other._data_store[_var_name] + types = set() + types.add(this_val.__class__) + types.add(that_val.__class__) + vals_equal = this_val == that_val + if (not six.PY3 and + len(types) == 2 and unicode in types): # noqa: F821 + vals_equal = ( + this_val.encode('utf-8') == that_val.encode('utf-8') + ) + if not vals_equal: + return False + return True def __ne__(self, other): """Returns true if both objects are not equal""" diff --git a/samples/client/petstore/python-experimental/petstore_api/models/map_test.py b/samples/client/petstore/python-experimental/petstore_api/models/map_test.py index 171791435046..84b07abdcc8d 100644 --- a/samples/client/petstore/python-experimental/petstore_api/models/map_test.py +++ b/samples/client/petstore/python-experimental/petstore_api/models/map_test.py @@ -15,13 +15,28 @@ import six # noqa: F401 -from petstore_api.exceptions import ApiValueError # noqa: F401 +from petstore_api.exceptions import ( # noqa: F401 + ApiKeyError, + ApiTypeError, + ApiValueError, +) from petstore_api.model_utils import ( # noqa: F401 ModelNormal, ModelSimple, check_allowed_values, - check_validations + check_validations, + date, + datetime, + file_type, + get_simple_class, + int, + model_to_dict, + none_type, + str, + type_error_message, + validate_and_convert_types ) +from petstore_api.models.string_boolean_map import StringBooleanMap class MapTest(ModelNormal): @@ -46,12 +61,14 @@ class MapTest(ModelNormal): 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 = { ('map_of_enum_string',): { 'UPPER': "UPPER", - 'LOWER': "lower" + 'LOWER': "lower", }, } @@ -63,162 +80,183 @@ class MapTest(ModelNormal): } openapi_types = { - 'map_map_of_string': 'dict(str, dict(str, str))', - 'map_of_enum_string': 'dict(str, str)', - 'direct_map': 'dict(str, bool)', - 'indirect_map': 'StringBooleanMap' + 'map_map_of_string': ({str: ({str: (str,)},)},), # noqa: E501 + 'map_of_enum_string': ({str: (str,)},), # noqa: E501 + 'direct_map': ({str: (bool,)},), # noqa: E501 + 'indirect_map': (StringBooleanMap,), # noqa: E501 } validations = { } - def __init__(self, map_map_of_string=None, map_of_enum_string=None, direct_map=None, indirect_map=None): # noqa: E501 - """MapTest - a model defined in OpenAPI""" # noqa: E501 - - self._map_map_of_string = None - self._map_of_enum_string = None - self._direct_map = None - self._indirect_map = None - self.discriminator = None - - if map_map_of_string is not None: - self.map_map_of_string = ( - map_map_of_string + additional_properties_type = None + + discriminator = None + + def __init__(self, _check_type=True, _from_server=False, _path_to_item=(), _configuration=None, **kwargs): # noqa: E501 + """MapTest - 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 + _from_server (bool): True if the data is from the server + False if the data is from the client (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. + map_map_of_string ({str: ({str: (str,)},)}): [optional] # noqa: E501 + map_of_enum_string ({str: (str,)}): [optional] # noqa: E501 + direct_map ({str: (bool,)}): [optional] # noqa: E501 + indirect_map (StringBooleanMap): [optional] # noqa: E501 + """ + self._data_store = {} + self._check_type = _check_type + self._from_server = _from_server + self._path_to_item = _path_to_item + self._configuration = _configuration + + for var_name, var_value in six.iteritems(kwargs): + self.__set_item(var_name, var_value) + + def __set_item(self, name, value): + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + + if name in self.openapi_types: + required_types_mixed = self.openapi_types[name] + elif self.additional_properties_type is None: + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + path_to_item ) - if map_of_enum_string is not None: - self.map_of_enum_string = ( - map_of_enum_string + elif self.additional_properties_type is not None: + required_types_mixed = self.additional_properties_type + + if get_simple_class(name) != str: + error_msg = type_error_message( + var_name=name, + var_value=name, + valid_classes=(str,), + key_type=True ) - if direct_map is not None: - self.direct_map = ( - direct_map + raise ApiTypeError( + error_msg, + path_to_item=path_to_item, + valid_classes=(str,), + key_type=True ) - if indirect_map is not None: - self.indirect_map = ( - indirect_map + + if self._check_type: + value = validate_and_convert_types( + value, required_types_mixed, path_to_item, self._from_server, + self._check_type, configuration=self._configuration) + if (name,) in self.allowed_values: + check_allowed_values( + self.allowed_values, + (name,), + value + ) + if (name,) in self.validations: + check_validations( + self.validations, + (name,), + value ) + self._data_store[name] = value + + def __get_item(self, name): + if name in self._data_store: + return self._data_store[name] + + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + [name] + ) + + def __setitem__(self, name, value): + """this allows us to set values with instance[field_name] = val""" + self.__set_item(name, value) + + def __getitem__(self, name): + """this allows us to get a value with val = instance[field_name]""" + return self.__get_item(name) @property def map_map_of_string(self): """Gets the map_map_of_string of this MapTest. # noqa: E501 - - :return: The map_map_of_string of this MapTest. # noqa: E501 - :rtype: dict(str, dict(str, str)) + Returns: + ({str: ({str: (str,)},)}): The map_map_of_string of this MapTest. # noqa: E501 """ - return self._map_map_of_string + return self.__get_item('map_map_of_string') @map_map_of_string.setter - def map_map_of_string(self, map_map_of_string): # noqa: E501 - """Sets the map_map_of_string of this MapTest. - - - :param map_map_of_string: The map_map_of_string of this MapTest. # noqa: E501 - :type: dict(str, dict(str, str)) + def map_map_of_string(self, value): + """Sets the map_map_of_string of this MapTest. # noqa: E501 """ - - self._map_map_of_string = ( - map_map_of_string - ) + return self.__set_item('map_map_of_string', value) @property def map_of_enum_string(self): """Gets the map_of_enum_string of this MapTest. # noqa: E501 - - :return: The map_of_enum_string of this MapTest. # noqa: E501 - :rtype: dict(str, str) + Returns: + ({str: (str,)}): The map_of_enum_string of this MapTest. # noqa: E501 """ - return self._map_of_enum_string + return self.__get_item('map_of_enum_string') @map_of_enum_string.setter - def map_of_enum_string(self, map_of_enum_string): # noqa: E501 - """Sets the map_of_enum_string of this MapTest. - - - :param map_of_enum_string: The map_of_enum_string of this MapTest. # noqa: E501 - :type: dict(str, str) + def map_of_enum_string(self, value): + """Sets the map_of_enum_string of this MapTest. # noqa: E501 """ - check_allowed_values( - self.allowed_values, - ('map_of_enum_string',), - map_of_enum_string, - self.validations - ) - - self._map_of_enum_string = ( - map_of_enum_string - ) + return self.__set_item('map_of_enum_string', value) @property def direct_map(self): """Gets the direct_map of this MapTest. # noqa: E501 - - :return: The direct_map of this MapTest. # noqa: E501 - :rtype: dict(str, bool) + Returns: + ({str: (bool,)}): The direct_map of this MapTest. # noqa: E501 """ - return self._direct_map + return self.__get_item('direct_map') @direct_map.setter - def direct_map(self, direct_map): # noqa: E501 - """Sets the direct_map of this MapTest. - - - :param direct_map: The direct_map of this MapTest. # noqa: E501 - :type: dict(str, bool) + def direct_map(self, value): + """Sets the direct_map of this MapTest. # noqa: E501 """ - - self._direct_map = ( - direct_map - ) + return self.__set_item('direct_map', value) @property def indirect_map(self): """Gets the indirect_map of this MapTest. # noqa: E501 - - :return: The indirect_map of this MapTest. # noqa: E501 - :rtype: StringBooleanMap + Returns: + (StringBooleanMap): The indirect_map of this MapTest. # noqa: E501 """ - return self._indirect_map + return self.__get_item('indirect_map') @indirect_map.setter - def indirect_map(self, indirect_map): # noqa: E501 - """Sets the indirect_map of this MapTest. - - - :param indirect_map: The indirect_map of this MapTest. # noqa: E501 - :type: StringBooleanMap + def indirect_map(self, value): + """Sets the indirect_map of this MapTest. # noqa: E501 """ - - self._indirect_map = ( - indirect_map - ) + return self.__set_item('indirect_map', value) def to_dict(self): """Returns the model properties as a dict""" - result = {} - - for attr, _ in six.iteritems(self.openapi_types): - value = getattr(self, attr) - if isinstance(value, list): - result[attr] = list(map( - lambda x: x.to_dict() if hasattr(x, "to_dict") else x, - value - )) - elif hasattr(value, "to_dict"): - result[attr] = value.to_dict() - elif isinstance(value, dict): - result[attr] = dict(map( - lambda item: (item[0], item[1].to_dict()) - if hasattr(item[1], "to_dict") else item, - value.items() - )) - else: - result[attr] = value - - return result + return model_to_dict(self, serialize=False) def to_str(self): """Returns the string representation of the model""" @@ -233,7 +271,22 @@ def __eq__(self, other): if not isinstance(other, MapTest): return False - return self.__dict__ == other.__dict__ + if not set(self._data_store.keys()) == set(other._data_store.keys()): + return False + for _var_name, this_val in six.iteritems(self._data_store): + that_val = other._data_store[_var_name] + types = set() + types.add(this_val.__class__) + types.add(that_val.__class__) + vals_equal = this_val == that_val + if (not six.PY3 and + len(types) == 2 and unicode in types): # noqa: F821 + vals_equal = ( + this_val.encode('utf-8') == that_val.encode('utf-8') + ) + if not vals_equal: + return False + return True def __ne__(self, other): """Returns true if both objects are not equal""" diff --git a/samples/client/petstore/python-experimental/petstore_api/models/mixed_properties_and_additional_properties_class.py b/samples/client/petstore/python-experimental/petstore_api/models/mixed_properties_and_additional_properties_class.py index 670e5d9905ed..a8f9efb42974 100644 --- a/samples/client/petstore/python-experimental/petstore_api/models/mixed_properties_and_additional_properties_class.py +++ b/samples/client/petstore/python-experimental/petstore_api/models/mixed_properties_and_additional_properties_class.py @@ -15,13 +15,28 @@ import six # noqa: F401 -from petstore_api.exceptions import ApiValueError # noqa: F401 +from petstore_api.exceptions import ( # noqa: F401 + ApiKeyError, + ApiTypeError, + ApiValueError, +) from petstore_api.model_utils import ( # noqa: F401 ModelNormal, ModelSimple, check_allowed_values, - check_validations + check_validations, + date, + datetime, + file_type, + get_simple_class, + int, + model_to_dict, + none_type, + str, + type_error_message, + validate_and_convert_types ) +from petstore_api.models.animal import Animal class MixedPropertiesAndAdditionalPropertiesClass(ModelNormal): @@ -46,6 +61,8 @@ class MixedPropertiesAndAdditionalPropertiesClass(ModelNormal): 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 = { @@ -58,127 +75,166 @@ class MixedPropertiesAndAdditionalPropertiesClass(ModelNormal): } openapi_types = { - 'uuid': 'str', - 'date_time': 'datetime', - 'map': 'dict(str, Animal)' + 'uuid': (str,), # noqa: E501 + 'date_time': (datetime,), # noqa: E501 + 'map': ({str: (Animal,)},), # noqa: E501 } validations = { } - def __init__(self, uuid=None, date_time=None, map=None): # noqa: E501 - """MixedPropertiesAndAdditionalPropertiesClass - a model defined in OpenAPI""" # noqa: E501 - - self._uuid = None - self._date_time = None - self._map = None - self.discriminator = None - - if uuid is not None: - self.uuid = ( - uuid + additional_properties_type = None + + discriminator = None + + def __init__(self, _check_type=True, _from_server=False, _path_to_item=(), _configuration=None, **kwargs): # noqa: E501 + """MixedPropertiesAndAdditionalPropertiesClass - 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 + _from_server (bool): True if the data is from the server + False if the data is from the client (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. + uuid (str): [optional] # noqa: E501 + date_time (datetime): [optional] # noqa: E501 + map ({str: (Animal,)}): [optional] # noqa: E501 + """ + self._data_store = {} + self._check_type = _check_type + self._from_server = _from_server + self._path_to_item = _path_to_item + self._configuration = _configuration + + for var_name, var_value in six.iteritems(kwargs): + self.__set_item(var_name, var_value) + + def __set_item(self, name, value): + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + + if name in self.openapi_types: + required_types_mixed = self.openapi_types[name] + elif self.additional_properties_type is None: + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + path_to_item ) - if date_time is not None: - self.date_time = ( - date_time + elif self.additional_properties_type is not None: + required_types_mixed = self.additional_properties_type + + if get_simple_class(name) != str: + error_msg = type_error_message( + var_name=name, + var_value=name, + valid_classes=(str,), + key_type=True ) - if map is not None: - self.map = ( - map + raise ApiTypeError( + error_msg, + path_to_item=path_to_item, + valid_classes=(str,), + key_type=True ) + if self._check_type: + value = validate_and_convert_types( + value, required_types_mixed, path_to_item, self._from_server, + self._check_type, configuration=self._configuration) + if (name,) in self.allowed_values: + check_allowed_values( + self.allowed_values, + (name,), + value + ) + if (name,) in self.validations: + check_validations( + self.validations, + (name,), + value + ) + self._data_store[name] = value + + def __get_item(self, name): + if name in self._data_store: + return self._data_store[name] + + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + [name] + ) + + def __setitem__(self, name, value): + """this allows us to set values with instance[field_name] = val""" + self.__set_item(name, value) + + def __getitem__(self, name): + """this allows us to get a value with val = instance[field_name]""" + return self.__get_item(name) + @property def uuid(self): """Gets the uuid of this MixedPropertiesAndAdditionalPropertiesClass. # noqa: E501 - - :return: The uuid of this MixedPropertiesAndAdditionalPropertiesClass. # noqa: E501 - :rtype: str + Returns: + (str): The uuid of this MixedPropertiesAndAdditionalPropertiesClass. # noqa: E501 """ - return self._uuid + return self.__get_item('uuid') @uuid.setter - def uuid(self, uuid): # noqa: E501 - """Sets the uuid of this MixedPropertiesAndAdditionalPropertiesClass. - - - :param uuid: The uuid of this MixedPropertiesAndAdditionalPropertiesClass. # noqa: E501 - :type: str + def uuid(self, value): + """Sets the uuid of this MixedPropertiesAndAdditionalPropertiesClass. # noqa: E501 """ - - self._uuid = ( - uuid - ) + return self.__set_item('uuid', value) @property def date_time(self): """Gets the date_time of this MixedPropertiesAndAdditionalPropertiesClass. # noqa: E501 - - :return: The date_time of this MixedPropertiesAndAdditionalPropertiesClass. # noqa: E501 - :rtype: datetime + Returns: + (datetime): The date_time of this MixedPropertiesAndAdditionalPropertiesClass. # noqa: E501 """ - return self._date_time + return self.__get_item('date_time') @date_time.setter - def date_time(self, date_time): # noqa: E501 - """Sets the date_time of this MixedPropertiesAndAdditionalPropertiesClass. - - - :param date_time: The date_time of this MixedPropertiesAndAdditionalPropertiesClass. # noqa: E501 - :type: datetime + def date_time(self, value): + """Sets the date_time of this MixedPropertiesAndAdditionalPropertiesClass. # noqa: E501 """ - - self._date_time = ( - date_time - ) + return self.__set_item('date_time', value) @property def map(self): """Gets the map of this MixedPropertiesAndAdditionalPropertiesClass. # noqa: E501 - - :return: The map of this MixedPropertiesAndAdditionalPropertiesClass. # noqa: E501 - :rtype: dict(str, Animal) + Returns: + ({str: (Animal,)}): The map of this MixedPropertiesAndAdditionalPropertiesClass. # noqa: E501 """ - return self._map + return self.__get_item('map') @map.setter - def map(self, map): # noqa: E501 - """Sets the map of this MixedPropertiesAndAdditionalPropertiesClass. - - - :param map: The map of this MixedPropertiesAndAdditionalPropertiesClass. # noqa: E501 - :type: dict(str, Animal) + def map(self, value): + """Sets the map of this MixedPropertiesAndAdditionalPropertiesClass. # noqa: E501 """ - - self._map = ( - map - ) + return self.__set_item('map', value) def to_dict(self): """Returns the model properties as a dict""" - result = {} - - for attr, _ in six.iteritems(self.openapi_types): - value = getattr(self, attr) - if isinstance(value, list): - result[attr] = list(map( - lambda x: x.to_dict() if hasattr(x, "to_dict") else x, - value - )) - elif hasattr(value, "to_dict"): - result[attr] = value.to_dict() - elif isinstance(value, dict): - result[attr] = dict(map( - lambda item: (item[0], item[1].to_dict()) - if hasattr(item[1], "to_dict") else item, - value.items() - )) - else: - result[attr] = value - - return result + return model_to_dict(self, serialize=False) def to_str(self): """Returns the string representation of the model""" @@ -193,7 +249,22 @@ def __eq__(self, other): if not isinstance(other, MixedPropertiesAndAdditionalPropertiesClass): return False - return self.__dict__ == other.__dict__ + if not set(self._data_store.keys()) == set(other._data_store.keys()): + return False + for _var_name, this_val in six.iteritems(self._data_store): + that_val = other._data_store[_var_name] + types = set() + types.add(this_val.__class__) + types.add(that_val.__class__) + vals_equal = this_val == that_val + if (not six.PY3 and + len(types) == 2 and unicode in types): # noqa: F821 + vals_equal = ( + this_val.encode('utf-8') == that_val.encode('utf-8') + ) + if not vals_equal: + return False + return True def __ne__(self, other): """Returns true if both objects are not equal""" diff --git a/samples/client/petstore/python-experimental/petstore_api/models/model200_response.py b/samples/client/petstore/python-experimental/petstore_api/models/model200_response.py index f110d0208258..4bb72561e846 100644 --- a/samples/client/petstore/python-experimental/petstore_api/models/model200_response.py +++ b/samples/client/petstore/python-experimental/petstore_api/models/model200_response.py @@ -15,12 +15,26 @@ import six # noqa: F401 -from petstore_api.exceptions import ApiValueError # noqa: F401 +from petstore_api.exceptions import ( # noqa: F401 + ApiKeyError, + ApiTypeError, + ApiValueError, +) from petstore_api.model_utils import ( # noqa: F401 ModelNormal, ModelSimple, check_allowed_values, - check_validations + check_validations, + date, + datetime, + file_type, + get_simple_class, + int, + model_to_dict, + none_type, + str, + type_error_message, + validate_and_convert_types ) @@ -46,6 +60,8 @@ class Model200Response(ModelNormal): 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 = { @@ -57,98 +73,149 @@ class Model200Response(ModelNormal): } openapi_types = { - 'name': 'int', - '_class': 'str' + 'name': (int,), # noqa: E501 + '_class': (str,), # noqa: E501 } validations = { } - def __init__(self, name=None, _class=None): # noqa: E501 - """Model200Response - a model defined in OpenAPI""" # noqa: E501 - - self._name = None - self.__class = None - self.discriminator = None + additional_properties_type = None + + discriminator = None + + def __init__(self, _check_type=True, _from_server=False, _path_to_item=(), _configuration=None, **kwargs): # noqa: E501 + """Model200Response - 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 + _from_server (bool): True if the data is from the server + False if the data is from the client (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. + name (int): [optional] # noqa: E501 + _class (str): [optional] # noqa: E501 + """ + self._data_store = {} + self._check_type = _check_type + self._from_server = _from_server + self._path_to_item = _path_to_item + self._configuration = _configuration + + for var_name, var_value in six.iteritems(kwargs): + self.__set_item(var_name, var_value) + + def __set_item(self, name, value): + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + + if name in self.openapi_types: + required_types_mixed = self.openapi_types[name] + elif self.additional_properties_type is None: + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + path_to_item + ) + elif self.additional_properties_type is not None: + required_types_mixed = self.additional_properties_type + + if get_simple_class(name) != str: + error_msg = type_error_message( + var_name=name, + var_value=name, + valid_classes=(str,), + key_type=True + ) + raise ApiTypeError( + error_msg, + path_to_item=path_to_item, + valid_classes=(str,), + key_type=True + ) - if name is not None: - self.name = ( - name + if self._check_type: + value = validate_and_convert_types( + value, required_types_mixed, path_to_item, self._from_server, + self._check_type, configuration=self._configuration) + if (name,) in self.allowed_values: + check_allowed_values( + self.allowed_values, + (name,), + value ) - if _class is not None: - self._class = ( - _class + if (name,) in self.validations: + check_validations( + self.validations, + (name,), + value ) + self._data_store[name] = value + + def __get_item(self, name): + if name in self._data_store: + return self._data_store[name] + + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + [name] + ) + + def __setitem__(self, name, value): + """this allows us to set values with instance[field_name] = val""" + self.__set_item(name, value) + + def __getitem__(self, name): + """this allows us to get a value with val = instance[field_name]""" + return self.__get_item(name) @property def name(self): """Gets the name of this Model200Response. # noqa: E501 - - :return: The name of this Model200Response. # noqa: E501 - :rtype: int + Returns: + (int): The name of this Model200Response. # noqa: E501 """ - return self._name + return self.__get_item('name') @name.setter - def name(self, name): # noqa: E501 - """Sets the name of this Model200Response. - - - :param name: The name of this Model200Response. # noqa: E501 - :type: int + def name(self, value): + """Sets the name of this Model200Response. # noqa: E501 """ - - self._name = ( - name - ) + return self.__set_item('name', value) @property def _class(self): """Gets the _class of this Model200Response. # noqa: E501 - - :return: The _class of this Model200Response. # noqa: E501 - :rtype: str + Returns: + (str): The _class of this Model200Response. # noqa: E501 """ - return self.__class + return self.__get_item('_class') @_class.setter - def _class(self, _class): # noqa: E501 - """Sets the _class of this Model200Response. - - - :param _class: The _class of this Model200Response. # noqa: E501 - :type: str + def _class(self, value): + """Sets the _class of this Model200Response. # noqa: E501 """ - - self.__class = ( - _class - ) + return self.__set_item('_class', value) def to_dict(self): """Returns the model properties as a dict""" - result = {} - - for attr, _ in six.iteritems(self.openapi_types): - value = getattr(self, attr) - if isinstance(value, list): - result[attr] = list(map( - lambda x: x.to_dict() if hasattr(x, "to_dict") else x, - value - )) - elif hasattr(value, "to_dict"): - result[attr] = value.to_dict() - elif isinstance(value, dict): - result[attr] = dict(map( - lambda item: (item[0], item[1].to_dict()) - if hasattr(item[1], "to_dict") else item, - value.items() - )) - else: - result[attr] = value - - return result + return model_to_dict(self, serialize=False) def to_str(self): """Returns the string representation of the model""" @@ -163,7 +230,22 @@ def __eq__(self, other): if not isinstance(other, Model200Response): return False - return self.__dict__ == other.__dict__ + if not set(self._data_store.keys()) == set(other._data_store.keys()): + return False + for _var_name, this_val in six.iteritems(self._data_store): + that_val = other._data_store[_var_name] + types = set() + types.add(this_val.__class__) + types.add(that_val.__class__) + vals_equal = this_val == that_val + if (not six.PY3 and + len(types) == 2 and unicode in types): # noqa: F821 + vals_equal = ( + this_val.encode('utf-8') == that_val.encode('utf-8') + ) + if not vals_equal: + return False + return True def __ne__(self, other): """Returns true if both objects are not equal""" diff --git a/samples/client/petstore/python-experimental/petstore_api/models/model_return.py b/samples/client/petstore/python-experimental/petstore_api/models/model_return.py index 0ba8ad99b99b..1ca322750bf4 100644 --- a/samples/client/petstore/python-experimental/petstore_api/models/model_return.py +++ b/samples/client/petstore/python-experimental/petstore_api/models/model_return.py @@ -15,12 +15,26 @@ import six # noqa: F401 -from petstore_api.exceptions import ApiValueError # noqa: F401 +from petstore_api.exceptions import ( # noqa: F401 + ApiKeyError, + ApiTypeError, + ApiValueError, +) from petstore_api.model_utils import ( # noqa: F401 ModelNormal, ModelSimple, check_allowed_values, - check_validations + check_validations, + date, + datetime, + file_type, + get_simple_class, + int, + model_to_dict, + none_type, + str, + type_error_message, + validate_and_convert_types ) @@ -46,6 +60,8 @@ class ModelReturn(ModelNormal): 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 = { @@ -56,69 +72,132 @@ class ModelReturn(ModelNormal): } openapi_types = { - '_return': 'int' + '_return': (int,), # noqa: E501 } validations = { } - def __init__(self, _return=None): # noqa: E501 - """ModelReturn - a model defined in OpenAPI""" # noqa: E501 - - self.__return = None - self.discriminator = None + additional_properties_type = None + + discriminator = None + + def __init__(self, _check_type=True, _from_server=False, _path_to_item=(), _configuration=None, **kwargs): # noqa: E501 + """ModelReturn - 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 + _from_server (bool): True if the data is from the server + False if the data is from the client (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. + _return (int): [optional] # noqa: E501 + """ + self._data_store = {} + self._check_type = _check_type + self._from_server = _from_server + self._path_to_item = _path_to_item + self._configuration = _configuration + + for var_name, var_value in six.iteritems(kwargs): + self.__set_item(var_name, var_value) + + def __set_item(self, name, value): + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + + if name in self.openapi_types: + required_types_mixed = self.openapi_types[name] + elif self.additional_properties_type is None: + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + path_to_item + ) + elif self.additional_properties_type is not None: + required_types_mixed = self.additional_properties_type + + if get_simple_class(name) != str: + error_msg = type_error_message( + var_name=name, + var_value=name, + valid_classes=(str,), + key_type=True + ) + raise ApiTypeError( + error_msg, + path_to_item=path_to_item, + valid_classes=(str,), + key_type=True + ) - if _return is not None: - self._return = ( - _return + if self._check_type: + value = validate_and_convert_types( + value, required_types_mixed, path_to_item, self._from_server, + self._check_type, configuration=self._configuration) + if (name,) in self.allowed_values: + check_allowed_values( + self.allowed_values, + (name,), + value ) + if (name,) in self.validations: + check_validations( + self.validations, + (name,), + value + ) + self._data_store[name] = value + + def __get_item(self, name): + if name in self._data_store: + return self._data_store[name] + + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + [name] + ) + + def __setitem__(self, name, value): + """this allows us to set values with instance[field_name] = val""" + self.__set_item(name, value) + + def __getitem__(self, name): + """this allows us to get a value with val = instance[field_name]""" + return self.__get_item(name) @property def _return(self): """Gets the _return of this ModelReturn. # noqa: E501 - - :return: The _return of this ModelReturn. # noqa: E501 - :rtype: int + Returns: + (int): The _return of this ModelReturn. # noqa: E501 """ - return self.__return + return self.__get_item('_return') @_return.setter - def _return(self, _return): # noqa: E501 - """Sets the _return of this ModelReturn. - - - :param _return: The _return of this ModelReturn. # noqa: E501 - :type: int + def _return(self, value): + """Sets the _return of this ModelReturn. # noqa: E501 """ - - self.__return = ( - _return - ) + return self.__set_item('_return', value) def to_dict(self): """Returns the model properties as a dict""" - result = {} - - for attr, _ in six.iteritems(self.openapi_types): - value = getattr(self, attr) - if isinstance(value, list): - result[attr] = list(map( - lambda x: x.to_dict() if hasattr(x, "to_dict") else x, - value - )) - elif hasattr(value, "to_dict"): - result[attr] = value.to_dict() - elif isinstance(value, dict): - result[attr] = dict(map( - lambda item: (item[0], item[1].to_dict()) - if hasattr(item[1], "to_dict") else item, - value.items() - )) - else: - result[attr] = value - - return result + return model_to_dict(self, serialize=False) def to_str(self): """Returns the string representation of the model""" @@ -133,7 +212,22 @@ def __eq__(self, other): if not isinstance(other, ModelReturn): return False - return self.__dict__ == other.__dict__ + if not set(self._data_store.keys()) == set(other._data_store.keys()): + return False + for _var_name, this_val in six.iteritems(self._data_store): + that_val = other._data_store[_var_name] + types = set() + types.add(this_val.__class__) + types.add(that_val.__class__) + vals_equal = this_val == that_val + if (not six.PY3 and + len(types) == 2 and unicode in types): # noqa: F821 + vals_equal = ( + this_val.encode('utf-8') == that_val.encode('utf-8') + ) + if not vals_equal: + return False + return True def __ne__(self, other): """Returns true if both objects are not equal""" diff --git a/samples/client/petstore/python-experimental/petstore_api/models/name.py b/samples/client/petstore/python-experimental/petstore_api/models/name.py index 59c5429366d3..b4c205ae08c9 100644 --- a/samples/client/petstore/python-experimental/petstore_api/models/name.py +++ b/samples/client/petstore/python-experimental/petstore_api/models/name.py @@ -15,12 +15,26 @@ import six # noqa: F401 -from petstore_api.exceptions import ApiValueError # noqa: F401 +from petstore_api.exceptions import ( # noqa: F401 + ApiKeyError, + ApiTypeError, + ApiValueError, +) from petstore_api.model_utils import ( # noqa: F401 ModelNormal, ModelSimple, check_allowed_values, - check_validations + check_validations, + date, + datetime, + file_type, + get_simple_class, + int, + model_to_dict, + none_type, + str, + type_error_message, + validate_and_convert_types ) @@ -46,6 +60,8 @@ class Name(ModelNormal): 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 = { @@ -59,155 +75,185 @@ class Name(ModelNormal): } openapi_types = { - 'name': 'int', - 'snake_case': 'int', - '_property': 'str', - '_123_number': 'int' + 'name': (int,), # noqa: E501 + 'snake_case': (int,), # noqa: E501 + '_property': (str,), # noqa: E501 + '_123_number': (int,), # noqa: E501 } validations = { } - def __init__(self, name=None, snake_case=None, _property=None, _123_number=None): # noqa: E501 - """Name - a model defined in OpenAPI""" # noqa: E501 - - self._name = None - self._snake_case = None - self.__property = None - self.__123_number = None - self.discriminator = None - - self.name = name - if snake_case is not None: - self.snake_case = ( - snake_case + additional_properties_type = None + + discriminator = None + + def __init__(self, name, _check_type=True, _from_server=False, _path_to_item=(), _configuration=None, **kwargs): # noqa: E501 + """Name - a model defined in OpenAPI + + Args: + name (int): + + 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 + _from_server (bool): True if the data is from the server + False if the data is from the client (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. + snake_case (int): [optional] # noqa: E501 + _property (str): [optional] # noqa: E501 + _123_number (int): [optional] # noqa: E501 + """ + self._data_store = {} + self._check_type = _check_type + self._from_server = _from_server + self._path_to_item = _path_to_item + self._configuration = _configuration + + self.__set_item('name', name) + for var_name, var_value in six.iteritems(kwargs): + self.__set_item(var_name, var_value) + + def __set_item(self, name, value): + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + + if name in self.openapi_types: + required_types_mixed = self.openapi_types[name] + elif self.additional_properties_type is None: + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + path_to_item ) - if _property is not None: - self._property = ( - _property + elif self.additional_properties_type is not None: + required_types_mixed = self.additional_properties_type + + if get_simple_class(name) != str: + error_msg = type_error_message( + var_name=name, + var_value=name, + valid_classes=(str,), + key_type=True ) - if _123_number is not None: - self._123_number = ( - _123_number + raise ApiTypeError( + error_msg, + path_to_item=path_to_item, + valid_classes=(str,), + key_type=True ) + if self._check_type: + value = validate_and_convert_types( + value, required_types_mixed, path_to_item, self._from_server, + self._check_type, configuration=self._configuration) + if (name,) in self.allowed_values: + check_allowed_values( + self.allowed_values, + (name,), + value + ) + if (name,) in self.validations: + check_validations( + self.validations, + (name,), + value + ) + self._data_store[name] = value + + def __get_item(self, name): + if name in self._data_store: + return self._data_store[name] + + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + [name] + ) + + def __setitem__(self, name, value): + """this allows us to set values with instance[field_name] = val""" + self.__set_item(name, value) + + def __getitem__(self, name): + """this allows us to get a value with val = instance[field_name]""" + return self.__get_item(name) + @property def name(self): """Gets the name of this Name. # noqa: E501 - - :return: The name of this Name. # noqa: E501 - :rtype: int + Returns: + (int): The name of this Name. # noqa: E501 """ - return self._name + return self.__get_item('name') @name.setter - def name(self, name): # noqa: E501 - """Sets the name of this Name. - - - :param name: The name of this Name. # noqa: E501 - :type: int + def name(self, value): + """Sets the name of this Name. # noqa: E501 """ - if name is None: - raise ApiValueError("Invalid value for `name`, must not be `None`") # noqa: E501 - - self._name = ( - name - ) + return self.__set_item('name', value) @property def snake_case(self): """Gets the snake_case of this Name. # noqa: E501 - - :return: The snake_case of this Name. # noqa: E501 - :rtype: int + Returns: + (int): The snake_case of this Name. # noqa: E501 """ - return self._snake_case + return self.__get_item('snake_case') @snake_case.setter - def snake_case(self, snake_case): # noqa: E501 - """Sets the snake_case of this Name. - - - :param snake_case: The snake_case of this Name. # noqa: E501 - :type: int + def snake_case(self, value): + """Sets the snake_case of this Name. # noqa: E501 """ - - self._snake_case = ( - snake_case - ) + return self.__set_item('snake_case', value) @property def _property(self): """Gets the _property of this Name. # noqa: E501 - - :return: The _property of this Name. # noqa: E501 - :rtype: str + Returns: + (str): The _property of this Name. # noqa: E501 """ - return self.__property + return self.__get_item('_property') @_property.setter - def _property(self, _property): # noqa: E501 - """Sets the _property of this Name. - - - :param _property: The _property of this Name. # noqa: E501 - :type: str + def _property(self, value): + """Sets the _property of this Name. # noqa: E501 """ - - self.__property = ( - _property - ) + return self.__set_item('_property', value) @property def _123_number(self): """Gets the _123_number of this Name. # noqa: E501 - - :return: The _123_number of this Name. # noqa: E501 - :rtype: int + Returns: + (int): The _123_number of this Name. # noqa: E501 """ - return self.__123_number + return self.__get_item('_123_number') @_123_number.setter - def _123_number(self, _123_number): # noqa: E501 - """Sets the _123_number of this Name. - - - :param _123_number: The _123_number of this Name. # noqa: E501 - :type: int + def _123_number(self, value): + """Sets the _123_number of this Name. # noqa: E501 """ - - self.__123_number = ( - _123_number - ) + return self.__set_item('_123_number', value) def to_dict(self): """Returns the model properties as a dict""" - result = {} - - for attr, _ in six.iteritems(self.openapi_types): - value = getattr(self, attr) - if isinstance(value, list): - result[attr] = list(map( - lambda x: x.to_dict() if hasattr(x, "to_dict") else x, - value - )) - elif hasattr(value, "to_dict"): - result[attr] = value.to_dict() - elif isinstance(value, dict): - result[attr] = dict(map( - lambda item: (item[0], item[1].to_dict()) - if hasattr(item[1], "to_dict") else item, - value.items() - )) - else: - result[attr] = value - - return result + return model_to_dict(self, serialize=False) def to_str(self): """Returns the string representation of the model""" @@ -222,7 +268,22 @@ def __eq__(self, other): if not isinstance(other, Name): return False - return self.__dict__ == other.__dict__ + if not set(self._data_store.keys()) == set(other._data_store.keys()): + return False + for _var_name, this_val in six.iteritems(self._data_store): + that_val = other._data_store[_var_name] + types = set() + types.add(this_val.__class__) + types.add(that_val.__class__) + vals_equal = this_val == that_val + if (not six.PY3 and + len(types) == 2 and unicode in types): # noqa: F821 + vals_equal = ( + this_val.encode('utf-8') == that_val.encode('utf-8') + ) + if not vals_equal: + return False + return True def __ne__(self, other): """Returns true if both objects are not equal""" diff --git a/samples/client/petstore/python-experimental/petstore_api/models/number_only.py b/samples/client/petstore/python-experimental/petstore_api/models/number_only.py index cb7825618738..0761b3d3e323 100644 --- a/samples/client/petstore/python-experimental/petstore_api/models/number_only.py +++ b/samples/client/petstore/python-experimental/petstore_api/models/number_only.py @@ -15,12 +15,26 @@ import six # noqa: F401 -from petstore_api.exceptions import ApiValueError # noqa: F401 +from petstore_api.exceptions import ( # noqa: F401 + ApiKeyError, + ApiTypeError, + ApiValueError, +) from petstore_api.model_utils import ( # noqa: F401 ModelNormal, ModelSimple, check_allowed_values, - check_validations + check_validations, + date, + datetime, + file_type, + get_simple_class, + int, + model_to_dict, + none_type, + str, + type_error_message, + validate_and_convert_types ) @@ -46,6 +60,8 @@ class NumberOnly(ModelNormal): 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 = { @@ -56,69 +72,132 @@ class NumberOnly(ModelNormal): } openapi_types = { - 'just_number': 'float' + 'just_number': (float,), # noqa: E501 } validations = { } - def __init__(self, just_number=None): # noqa: E501 - """NumberOnly - a model defined in OpenAPI""" # noqa: E501 - - self._just_number = None - self.discriminator = None + additional_properties_type = None + + discriminator = None + + def __init__(self, _check_type=True, _from_server=False, _path_to_item=(), _configuration=None, **kwargs): # noqa: E501 + """NumberOnly - 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 + _from_server (bool): True if the data is from the server + False if the data is from the client (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. + just_number (float): [optional] # noqa: E501 + """ + self._data_store = {} + self._check_type = _check_type + self._from_server = _from_server + self._path_to_item = _path_to_item + self._configuration = _configuration + + for var_name, var_value in six.iteritems(kwargs): + self.__set_item(var_name, var_value) + + def __set_item(self, name, value): + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + + if name in self.openapi_types: + required_types_mixed = self.openapi_types[name] + elif self.additional_properties_type is None: + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + path_to_item + ) + elif self.additional_properties_type is not None: + required_types_mixed = self.additional_properties_type + + if get_simple_class(name) != str: + error_msg = type_error_message( + var_name=name, + var_value=name, + valid_classes=(str,), + key_type=True + ) + raise ApiTypeError( + error_msg, + path_to_item=path_to_item, + valid_classes=(str,), + key_type=True + ) - if just_number is not None: - self.just_number = ( - just_number + if self._check_type: + value = validate_and_convert_types( + value, required_types_mixed, path_to_item, self._from_server, + self._check_type, configuration=self._configuration) + if (name,) in self.allowed_values: + check_allowed_values( + self.allowed_values, + (name,), + value ) + if (name,) in self.validations: + check_validations( + self.validations, + (name,), + value + ) + self._data_store[name] = value + + def __get_item(self, name): + if name in self._data_store: + return self._data_store[name] + + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + [name] + ) + + def __setitem__(self, name, value): + """this allows us to set values with instance[field_name] = val""" + self.__set_item(name, value) + + def __getitem__(self, name): + """this allows us to get a value with val = instance[field_name]""" + return self.__get_item(name) @property def just_number(self): """Gets the just_number of this NumberOnly. # noqa: E501 - - :return: The just_number of this NumberOnly. # noqa: E501 - :rtype: float + Returns: + (float): The just_number of this NumberOnly. # noqa: E501 """ - return self._just_number + return self.__get_item('just_number') @just_number.setter - def just_number(self, just_number): # noqa: E501 - """Sets the just_number of this NumberOnly. - - - :param just_number: The just_number of this NumberOnly. # noqa: E501 - :type: float + def just_number(self, value): + """Sets the just_number of this NumberOnly. # noqa: E501 """ - - self._just_number = ( - just_number - ) + return self.__set_item('just_number', value) def to_dict(self): """Returns the model properties as a dict""" - result = {} - - for attr, _ in six.iteritems(self.openapi_types): - value = getattr(self, attr) - if isinstance(value, list): - result[attr] = list(map( - lambda x: x.to_dict() if hasattr(x, "to_dict") else x, - value - )) - elif hasattr(value, "to_dict"): - result[attr] = value.to_dict() - elif isinstance(value, dict): - result[attr] = dict(map( - lambda item: (item[0], item[1].to_dict()) - if hasattr(item[1], "to_dict") else item, - value.items() - )) - else: - result[attr] = value - - return result + return model_to_dict(self, serialize=False) def to_str(self): """Returns the string representation of the model""" @@ -133,7 +212,22 @@ def __eq__(self, other): if not isinstance(other, NumberOnly): return False - return self.__dict__ == other.__dict__ + if not set(self._data_store.keys()) == set(other._data_store.keys()): + return False + for _var_name, this_val in six.iteritems(self._data_store): + that_val = other._data_store[_var_name] + types = set() + types.add(this_val.__class__) + types.add(that_val.__class__) + vals_equal = this_val == that_val + if (not six.PY3 and + len(types) == 2 and unicode in types): # noqa: F821 + vals_equal = ( + this_val.encode('utf-8') == that_val.encode('utf-8') + ) + if not vals_equal: + return False + return True def __ne__(self, other): """Returns true if both objects are not equal""" diff --git a/samples/client/petstore/python-experimental/petstore_api/models/order.py b/samples/client/petstore/python-experimental/petstore_api/models/order.py index 7b866df4c894..64c84902aba5 100644 --- a/samples/client/petstore/python-experimental/petstore_api/models/order.py +++ b/samples/client/petstore/python-experimental/petstore_api/models/order.py @@ -15,12 +15,26 @@ import six # noqa: F401 -from petstore_api.exceptions import ApiValueError # noqa: F401 +from petstore_api.exceptions import ( # noqa: F401 + ApiKeyError, + ApiTypeError, + ApiValueError, +) from petstore_api.model_utils import ( # noqa: F401 ModelNormal, ModelSimple, check_allowed_values, - check_validations + check_validations, + date, + datetime, + file_type, + get_simple_class, + int, + model_to_dict, + none_type, + str, + type_error_message, + validate_and_convert_types ) @@ -46,13 +60,15 @@ class Order(ModelNormal): 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 = { ('status',): { 'PLACED': "placed", 'APPROVED': "approved", - 'DELIVERED': "delivered" + 'DELIVERED': "delivered", }, } @@ -66,222 +82,219 @@ class Order(ModelNormal): } openapi_types = { - 'id': 'int', - 'pet_id': 'int', - 'quantity': 'int', - 'ship_date': 'datetime', - 'status': 'str', - 'complete': 'bool' + 'id': (int,), # noqa: E501 + 'pet_id': (int,), # noqa: E501 + 'quantity': (int,), # noqa: E501 + 'ship_date': (datetime,), # noqa: E501 + 'status': (str,), # noqa: E501 + 'complete': (bool,), # noqa: E501 } validations = { } - def __init__(self, id=None, pet_id=None, quantity=None, ship_date=None, status=None, complete=False): # noqa: E501 - """Order - a model defined in OpenAPI""" # noqa: E501 - - self._id = None - self._pet_id = None - self._quantity = None - self._ship_date = None - self._status = None - self._complete = None - self.discriminator = None - - if id is not None: - self.id = ( - id - ) - if pet_id is not None: - self.pet_id = ( - pet_id + additional_properties_type = None + + discriminator = None + + def __init__(self, _check_type=True, _from_server=False, _path_to_item=(), _configuration=None, **kwargs): # noqa: E501 + """Order - 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 + _from_server (bool): True if the data is from the server + False if the data is from the client (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. + id (int): [optional] # noqa: E501 + pet_id (int): [optional] # noqa: E501 + quantity (int): [optional] # noqa: E501 + ship_date (datetime): [optional] # noqa: E501 + status (str): Order Status. [optional] # noqa: E501 + complete (bool): [optional] if omitted the server will use the default value of False # noqa: E501 + """ + self._data_store = {} + self._check_type = _check_type + self._from_server = _from_server + self._path_to_item = _path_to_item + self._configuration = _configuration + + for var_name, var_value in six.iteritems(kwargs): + self.__set_item(var_name, var_value) + + def __set_item(self, name, value): + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + + if name in self.openapi_types: + required_types_mixed = self.openapi_types[name] + elif self.additional_properties_type is None: + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + path_to_item ) - if quantity is not None: - self.quantity = ( - quantity + elif self.additional_properties_type is not None: + required_types_mixed = self.additional_properties_type + + if get_simple_class(name) != str: + error_msg = type_error_message( + var_name=name, + var_value=name, + valid_classes=(str,), + key_type=True ) - if ship_date is not None: - self.ship_date = ( - ship_date + raise ApiTypeError( + error_msg, + path_to_item=path_to_item, + valid_classes=(str,), + key_type=True ) - if status is not None: - self.status = ( - status + + if self._check_type: + value = validate_and_convert_types( + value, required_types_mixed, path_to_item, self._from_server, + self._check_type, configuration=self._configuration) + if (name,) in self.allowed_values: + check_allowed_values( + self.allowed_values, + (name,), + value ) - if complete is not None: - self.complete = ( - complete + if (name,) in self.validations: + check_validations( + self.validations, + (name,), + value ) + self._data_store[name] = value + + def __get_item(self, name): + if name in self._data_store: + return self._data_store[name] + + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + [name] + ) + + def __setitem__(self, name, value): + """this allows us to set values with instance[field_name] = val""" + self.__set_item(name, value) + + def __getitem__(self, name): + """this allows us to get a value with val = instance[field_name]""" + return self.__get_item(name) @property def id(self): """Gets the id of this Order. # noqa: E501 - - :return: The id of this Order. # noqa: E501 - :rtype: int + Returns: + (int): The id of this Order. # noqa: E501 """ - return self._id + return self.__get_item('id') @id.setter - def id(self, id): # noqa: E501 - """Sets the id of this Order. - - - :param id: The id of this Order. # noqa: E501 - :type: int + def id(self, value): + """Sets the id of this Order. # noqa: E501 """ - - self._id = ( - id - ) + return self.__set_item('id', value) @property def pet_id(self): """Gets the pet_id of this Order. # noqa: E501 - - :return: The pet_id of this Order. # noqa: E501 - :rtype: int + Returns: + (int): The pet_id of this Order. # noqa: E501 """ - return self._pet_id + return self.__get_item('pet_id') @pet_id.setter - def pet_id(self, pet_id): # noqa: E501 - """Sets the pet_id of this Order. - - - :param pet_id: The pet_id of this Order. # noqa: E501 - :type: int + def pet_id(self, value): + """Sets the pet_id of this Order. # noqa: E501 """ - - self._pet_id = ( - pet_id - ) + return self.__set_item('pet_id', value) @property def quantity(self): """Gets the quantity of this Order. # noqa: E501 - - :return: The quantity of this Order. # noqa: E501 - :rtype: int + Returns: + (int): The quantity of this Order. # noqa: E501 """ - return self._quantity + return self.__get_item('quantity') @quantity.setter - def quantity(self, quantity): # noqa: E501 - """Sets the quantity of this Order. - - - :param quantity: The quantity of this Order. # noqa: E501 - :type: int + def quantity(self, value): + """Sets the quantity of this Order. # noqa: E501 """ - - self._quantity = ( - quantity - ) + return self.__set_item('quantity', value) @property def ship_date(self): """Gets the ship_date of this Order. # noqa: E501 - - :return: The ship_date of this Order. # noqa: E501 - :rtype: datetime + Returns: + (datetime): The ship_date of this Order. # noqa: E501 """ - return self._ship_date + return self.__get_item('ship_date') @ship_date.setter - def ship_date(self, ship_date): # noqa: E501 - """Sets the ship_date of this Order. - - - :param ship_date: The ship_date of this Order. # noqa: E501 - :type: datetime + def ship_date(self, value): + """Sets the ship_date of this Order. # noqa: E501 """ - - self._ship_date = ( - ship_date - ) + return self.__set_item('ship_date', value) @property def status(self): """Gets the status of this Order. # noqa: E501 - Order Status # noqa: E501 - :return: The status of this Order. # noqa: E501 - :rtype: str + Returns: + (str): The status of this Order. # noqa: E501 """ - return self._status + return self.__get_item('status') @status.setter - def status(self, status): # noqa: E501 - """Sets the status of this Order. - + def status(self, value): + """Sets the status of this Order. # noqa: E501 Order Status # noqa: E501 - - :param status: The status of this Order. # noqa: E501 - :type: str """ - check_allowed_values( - self.allowed_values, - ('status',), - status, - self.validations - ) - - self._status = ( - status - ) + return self.__set_item('status', value) @property def complete(self): """Gets the complete of this Order. # noqa: E501 - - :return: The complete of this Order. # noqa: E501 - :rtype: bool + Returns: + (bool): The complete of this Order. # noqa: E501 """ - return self._complete + return self.__get_item('complete') @complete.setter - def complete(self, complete): # noqa: E501 - """Sets the complete of this Order. - - - :param complete: The complete of this Order. # noqa: E501 - :type: bool + def complete(self, value): + """Sets the complete of this Order. # noqa: E501 """ - - self._complete = ( - complete - ) + return self.__set_item('complete', value) def to_dict(self): """Returns the model properties as a dict""" - result = {} - - for attr, _ in six.iteritems(self.openapi_types): - value = getattr(self, attr) - if isinstance(value, list): - result[attr] = list(map( - lambda x: x.to_dict() if hasattr(x, "to_dict") else x, - value - )) - elif hasattr(value, "to_dict"): - result[attr] = value.to_dict() - elif isinstance(value, dict): - result[attr] = dict(map( - lambda item: (item[0], item[1].to_dict()) - if hasattr(item[1], "to_dict") else item, - value.items() - )) - else: - result[attr] = value - - return result + return model_to_dict(self, serialize=False) def to_str(self): """Returns the string representation of the model""" @@ -296,7 +309,22 @@ def __eq__(self, other): if not isinstance(other, Order): return False - return self.__dict__ == other.__dict__ + if not set(self._data_store.keys()) == set(other._data_store.keys()): + return False + for _var_name, this_val in six.iteritems(self._data_store): + that_val = other._data_store[_var_name] + types = set() + types.add(this_val.__class__) + types.add(that_val.__class__) + vals_equal = this_val == that_val + if (not six.PY3 and + len(types) == 2 and unicode in types): # noqa: F821 + vals_equal = ( + this_val.encode('utf-8') == that_val.encode('utf-8') + ) + if not vals_equal: + return False + return True def __ne__(self, other): """Returns true if both objects are not equal""" diff --git a/samples/client/petstore/python-experimental/petstore_api/models/outer_composite.py b/samples/client/petstore/python-experimental/petstore_api/models/outer_composite.py index 70c9e7915fb0..61bc50545758 100644 --- a/samples/client/petstore/python-experimental/petstore_api/models/outer_composite.py +++ b/samples/client/petstore/python-experimental/petstore_api/models/outer_composite.py @@ -15,13 +15,28 @@ import six # noqa: F401 -from petstore_api.exceptions import ApiValueError # noqa: F401 +from petstore_api.exceptions import ( # noqa: F401 + ApiKeyError, + ApiTypeError, + ApiValueError, +) from petstore_api.model_utils import ( # noqa: F401 ModelNormal, ModelSimple, check_allowed_values, - check_validations + check_validations, + date, + datetime, + file_type, + get_simple_class, + int, + model_to_dict, + none_type, + str, + type_error_message, + validate_and_convert_types ) +from petstore_api.models.outer_number import OuterNumber class OuterComposite(ModelNormal): @@ -46,6 +61,8 @@ class OuterComposite(ModelNormal): 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 = { @@ -58,127 +75,166 @@ class OuterComposite(ModelNormal): } openapi_types = { - 'my_number': 'OuterNumber', - 'my_string': 'str', - 'my_boolean': 'bool' + 'my_number': (OuterNumber,), # noqa: E501 + 'my_string': (str,), # noqa: E501 + 'my_boolean': (bool,), # noqa: E501 } validations = { } - def __init__(self, my_number=None, my_string=None, my_boolean=None): # noqa: E501 - """OuterComposite - a model defined in OpenAPI""" # noqa: E501 - - self._my_number = None - self._my_string = None - self._my_boolean = None - self.discriminator = None - - if my_number is not None: - self.my_number = ( - my_number + additional_properties_type = None + + discriminator = None + + def __init__(self, _check_type=True, _from_server=False, _path_to_item=(), _configuration=None, **kwargs): # noqa: E501 + """OuterComposite - 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 + _from_server (bool): True if the data is from the server + False if the data is from the client (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. + my_number (OuterNumber): [optional] # noqa: E501 + my_string (str): [optional] # noqa: E501 + my_boolean (bool): [optional] # noqa: E501 + """ + self._data_store = {} + self._check_type = _check_type + self._from_server = _from_server + self._path_to_item = _path_to_item + self._configuration = _configuration + + for var_name, var_value in six.iteritems(kwargs): + self.__set_item(var_name, var_value) + + def __set_item(self, name, value): + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + + if name in self.openapi_types: + required_types_mixed = self.openapi_types[name] + elif self.additional_properties_type is None: + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + path_to_item ) - if my_string is not None: - self.my_string = ( - my_string + elif self.additional_properties_type is not None: + required_types_mixed = self.additional_properties_type + + if get_simple_class(name) != str: + error_msg = type_error_message( + var_name=name, + var_value=name, + valid_classes=(str,), + key_type=True ) - if my_boolean is not None: - self.my_boolean = ( - my_boolean + raise ApiTypeError( + error_msg, + path_to_item=path_to_item, + valid_classes=(str,), + key_type=True ) + if self._check_type: + value = validate_and_convert_types( + value, required_types_mixed, path_to_item, self._from_server, + self._check_type, configuration=self._configuration) + if (name,) in self.allowed_values: + check_allowed_values( + self.allowed_values, + (name,), + value + ) + if (name,) in self.validations: + check_validations( + self.validations, + (name,), + value + ) + self._data_store[name] = value + + def __get_item(self, name): + if name in self._data_store: + return self._data_store[name] + + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + [name] + ) + + def __setitem__(self, name, value): + """this allows us to set values with instance[field_name] = val""" + self.__set_item(name, value) + + def __getitem__(self, name): + """this allows us to get a value with val = instance[field_name]""" + return self.__get_item(name) + @property def my_number(self): """Gets the my_number of this OuterComposite. # noqa: E501 - - :return: The my_number of this OuterComposite. # noqa: E501 - :rtype: OuterNumber + Returns: + (OuterNumber): The my_number of this OuterComposite. # noqa: E501 """ - return self._my_number + return self.__get_item('my_number') @my_number.setter - def my_number(self, my_number): # noqa: E501 - """Sets the my_number of this OuterComposite. - - - :param my_number: The my_number of this OuterComposite. # noqa: E501 - :type: OuterNumber + def my_number(self, value): + """Sets the my_number of this OuterComposite. # noqa: E501 """ - - self._my_number = ( - my_number - ) + return self.__set_item('my_number', value) @property def my_string(self): """Gets the my_string of this OuterComposite. # noqa: E501 - - :return: The my_string of this OuterComposite. # noqa: E501 - :rtype: str + Returns: + (str): The my_string of this OuterComposite. # noqa: E501 """ - return self._my_string + return self.__get_item('my_string') @my_string.setter - def my_string(self, my_string): # noqa: E501 - """Sets the my_string of this OuterComposite. - - - :param my_string: The my_string of this OuterComposite. # noqa: E501 - :type: str + def my_string(self, value): + """Sets the my_string of this OuterComposite. # noqa: E501 """ - - self._my_string = ( - my_string - ) + return self.__set_item('my_string', value) @property def my_boolean(self): """Gets the my_boolean of this OuterComposite. # noqa: E501 - - :return: The my_boolean of this OuterComposite. # noqa: E501 - :rtype: bool + Returns: + (bool): The my_boolean of this OuterComposite. # noqa: E501 """ - return self._my_boolean + return self.__get_item('my_boolean') @my_boolean.setter - def my_boolean(self, my_boolean): # noqa: E501 - """Sets the my_boolean of this OuterComposite. - - - :param my_boolean: The my_boolean of this OuterComposite. # noqa: E501 - :type: bool + def my_boolean(self, value): + """Sets the my_boolean of this OuterComposite. # noqa: E501 """ - - self._my_boolean = ( - my_boolean - ) + return self.__set_item('my_boolean', value) def to_dict(self): """Returns the model properties as a dict""" - result = {} - - for attr, _ in six.iteritems(self.openapi_types): - value = getattr(self, attr) - if isinstance(value, list): - result[attr] = list(map( - lambda x: x.to_dict() if hasattr(x, "to_dict") else x, - value - )) - elif hasattr(value, "to_dict"): - result[attr] = value.to_dict() - elif isinstance(value, dict): - result[attr] = dict(map( - lambda item: (item[0], item[1].to_dict()) - if hasattr(item[1], "to_dict") else item, - value.items() - )) - else: - result[attr] = value - - return result + return model_to_dict(self, serialize=False) def to_str(self): """Returns the string representation of the model""" @@ -193,7 +249,22 @@ def __eq__(self, other): if not isinstance(other, OuterComposite): return False - return self.__dict__ == other.__dict__ + if not set(self._data_store.keys()) == set(other._data_store.keys()): + return False + for _var_name, this_val in six.iteritems(self._data_store): + that_val = other._data_store[_var_name] + types = set() + types.add(this_val.__class__) + types.add(that_val.__class__) + vals_equal = this_val == that_val + if (not six.PY3 and + len(types) == 2 and unicode in types): # noqa: F821 + vals_equal = ( + this_val.encode('utf-8') == that_val.encode('utf-8') + ) + if not vals_equal: + return False + return True def __ne__(self, other): """Returns true if both objects are not equal""" diff --git a/samples/client/petstore/python-experimental/petstore_api/models/outer_enum.py b/samples/client/petstore/python-experimental/petstore_api/models/outer_enum.py index d9cdd3d0c602..e10dfc65118f 100644 --- a/samples/client/petstore/python-experimental/petstore_api/models/outer_enum.py +++ b/samples/client/petstore/python-experimental/petstore_api/models/outer_enum.py @@ -15,12 +15,26 @@ import six # noqa: F401 -from petstore_api.exceptions import ApiValueError # noqa: F401 +from petstore_api.exceptions import ( # noqa: F401 + ApiKeyError, + ApiTypeError, + ApiValueError, +) from petstore_api.model_utils import ( # noqa: F401 ModelNormal, ModelSimple, check_allowed_values, - check_validations + check_validations, + date, + datetime, + file_type, + get_simple_class, + int, + model_to_dict, + none_type, + str, + type_error_message, + validate_and_convert_types ) @@ -42,65 +56,147 @@ class OuterEnum(ModelSimple): 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 = { ('value',): { 'PLACED': "placed", 'APPROVED': "approved", - 'DELIVERED': "delivered" + 'DELIVERED': "delivered", }, } openapi_types = { - 'value': 'str' + 'value': (str,), # noqa: E501 } validations = { } - def __init__(self, value=None): # noqa: E501 - """OuterEnum - a model defined in OpenAPI""" # noqa: E501 + additional_properties_type = None + + discriminator = None + + def __init__(self, value, _check_type=True, _from_server=False, _path_to_item=(), _configuration=None, **kwargs): # noqa: E501 + """OuterEnum - a model defined in OpenAPI + + Args: + value (str): + + 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 + _from_server (bool): True if the data is from the server + False if the data is from the client (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. + """ + self._data_store = {} + self._check_type = _check_type + self._from_server = _from_server + self._path_to_item = _path_to_item + self._configuration = _configuration + + self.__set_item('value', value) + for var_name, var_value in six.iteritems(kwargs): + self.__set_item(var_name, var_value) + + def __set_item(self, name, value): + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + + if name in self.openapi_types: + required_types_mixed = self.openapi_types[name] + elif self.additional_properties_type is None: + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + path_to_item + ) + elif self.additional_properties_type is not None: + required_types_mixed = self.additional_properties_type + + if get_simple_class(name) != str: + error_msg = type_error_message( + var_name=name, + var_value=name, + valid_classes=(str,), + key_type=True + ) + raise ApiTypeError( + error_msg, + path_to_item=path_to_item, + valid_classes=(str,), + key_type=True + ) + + if self._check_type: + value = validate_and_convert_types( + value, required_types_mixed, path_to_item, self._from_server, + self._check_type, configuration=self._configuration) + if (name,) in self.allowed_values: + check_allowed_values( + self.allowed_values, + (name,), + value + ) + if (name,) in self.validations: + check_validations( + self.validations, + (name,), + value + ) + self._data_store[name] = value + + def __get_item(self, name): + if name in self._data_store: + return self._data_store[name] + + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + [name] + ) - self._value = None - self.discriminator = None + def __setitem__(self, name, value): + """this allows us to set values with instance[field_name] = val""" + self.__set_item(name, value) - self.value = value + def __getitem__(self, name): + """this allows us to get a value with val = instance[field_name]""" + return self.__get_item(name) @property def value(self): """Gets the value of this OuterEnum. # noqa: E501 - - :return: The value of this OuterEnum. # noqa: E501 - :rtype: str + Returns: + (str): The value of this OuterEnum. # noqa: E501 """ - return self._value + return self.__get_item('value') @value.setter - def value(self, value): # noqa: E501 - """Sets the value of this OuterEnum. - - - :param value: The value of this OuterEnum. # noqa: E501 - :type: str + def value(self, value): + """Sets the value of this OuterEnum. # noqa: E501 """ - if value is None: - raise ApiValueError("Invalid value for `value`, must not be `None`") # noqa: E501 - check_allowed_values( - self.allowed_values, - ('value',), - value, - self.validations - ) - - self._value = ( - value - ) + return self.__set_item('value', value) def to_str(self): """Returns the string representation of the model""" - return str(self._value) + return str(self.value) def __repr__(self): """For `print` and `pprint`""" @@ -111,7 +207,19 @@ def __eq__(self, other): if not isinstance(other, OuterEnum): return False - return self.__dict__ == other.__dict__ + this_val = self._data_store['value'] + that_val = other._data_store['value'] + types = set() + types.add(this_val.__class__) + types.add(that_val.__class__) + vals_equal = this_val == that_val + if not six.PY3 and len(types) == 2 and unicode in types: # noqa: F821 + vals_equal = ( + this_val.encode('utf-8') == that_val.encode('utf-8') + ) + if not vals_equal: + return False + return True def __ne__(self, other): """Returns true if both objects are not equal""" diff --git a/samples/client/petstore/python-experimental/petstore_api/models/outer_number.py b/samples/client/petstore/python-experimental/petstore_api/models/outer_number.py index 36c2bd3da192..ca2be68a97ec 100644 --- a/samples/client/petstore/python-experimental/petstore_api/models/outer_number.py +++ b/samples/client/petstore/python-experimental/petstore_api/models/outer_number.py @@ -15,12 +15,26 @@ import six # noqa: F401 -from petstore_api.exceptions import ApiValueError # noqa: F401 +from petstore_api.exceptions import ( # noqa: F401 + ApiKeyError, + ApiTypeError, + ApiValueError, +) from petstore_api.model_utils import ( # noqa: F401 ModelNormal, ModelSimple, check_allowed_values, - check_validations + check_validations, + date, + datetime, + file_type, + get_simple_class, + int, + model_to_dict, + none_type, + str, + type_error_message, + validate_and_convert_types ) @@ -42,64 +56,146 @@ class OuterNumber(ModelSimple): 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 = { } openapi_types = { - 'value': 'float' + 'value': (float,), # noqa: E501 } validations = { ('value',): { - 'inclusive_maximum': 2E+1, 'inclusive_minimum': 1E+1, }, } - def __init__(self, value=None): # noqa: E501 - """OuterNumber - a model defined in OpenAPI""" # noqa: E501 + additional_properties_type = None + + discriminator = None + + def __init__(self, value, _check_type=True, _from_server=False, _path_to_item=(), _configuration=None, **kwargs): # noqa: E501 + """OuterNumber - a model defined in OpenAPI + + Args: + value (float): + + 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 + _from_server (bool): True if the data is from the server + False if the data is from the client (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. + """ + self._data_store = {} + self._check_type = _check_type + self._from_server = _from_server + self._path_to_item = _path_to_item + self._configuration = _configuration + + self.__set_item('value', value) + for var_name, var_value in six.iteritems(kwargs): + self.__set_item(var_name, var_value) + + def __set_item(self, name, value): + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + + if name in self.openapi_types: + required_types_mixed = self.openapi_types[name] + elif self.additional_properties_type is None: + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + path_to_item + ) + elif self.additional_properties_type is not None: + required_types_mixed = self.additional_properties_type + + if get_simple_class(name) != str: + error_msg = type_error_message( + var_name=name, + var_value=name, + valid_classes=(str,), + key_type=True + ) + raise ApiTypeError( + error_msg, + path_to_item=path_to_item, + valid_classes=(str,), + key_type=True + ) + + if self._check_type: + value = validate_and_convert_types( + value, required_types_mixed, path_to_item, self._from_server, + self._check_type, configuration=self._configuration) + if (name,) in self.allowed_values: + check_allowed_values( + self.allowed_values, + (name,), + value + ) + if (name,) in self.validations: + check_validations( + self.validations, + (name,), + value + ) + self._data_store[name] = value + + def __get_item(self, name): + if name in self._data_store: + return self._data_store[name] + + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + [name] + ) - self._value = None - self.discriminator = None + def __setitem__(self, name, value): + """this allows us to set values with instance[field_name] = val""" + self.__set_item(name, value) - self.value = value + def __getitem__(self, name): + """this allows us to get a value with val = instance[field_name]""" + return self.__get_item(name) @property def value(self): """Gets the value of this OuterNumber. # noqa: E501 - - :return: The value of this OuterNumber. # noqa: E501 - :rtype: float + Returns: + (float): The value of this OuterNumber. # noqa: E501 """ - return self._value + return self.__get_item('value') @value.setter - def value(self, value): # noqa: E501 - """Sets the value of this OuterNumber. - - - :param value: The value of this OuterNumber. # noqa: E501 - :type: float + def value(self, value): + """Sets the value of this OuterNumber. # noqa: E501 """ - if value is None: - raise ApiValueError("Invalid value for `value`, must not be `None`") # noqa: E501 - check_validations( - self.validations, - ('value',), - value - ) - - self._value = ( - value - ) + return self.__set_item('value', value) def to_str(self): """Returns the string representation of the model""" - return str(self._value) + return str(self.value) def __repr__(self): """For `print` and `pprint`""" @@ -110,7 +206,19 @@ def __eq__(self, other): if not isinstance(other, OuterNumber): return False - return self.__dict__ == other.__dict__ + this_val = self._data_store['value'] + that_val = other._data_store['value'] + types = set() + types.add(this_val.__class__) + types.add(that_val.__class__) + vals_equal = this_val == that_val + if not six.PY3 and len(types) == 2 and unicode in types: # noqa: F821 + vals_equal = ( + this_val.encode('utf-8') == that_val.encode('utf-8') + ) + if not vals_equal: + return False + return True def __ne__(self, other): """Returns true if both objects are not equal""" diff --git a/samples/client/petstore/python-experimental/petstore_api/models/pet.py b/samples/client/petstore/python-experimental/petstore_api/models/pet.py index 07db65229314..3abfdfba760c 100644 --- a/samples/client/petstore/python-experimental/petstore_api/models/pet.py +++ b/samples/client/petstore/python-experimental/petstore_api/models/pet.py @@ -15,13 +15,29 @@ import six # noqa: F401 -from petstore_api.exceptions import ApiValueError # noqa: F401 +from petstore_api.exceptions import ( # noqa: F401 + ApiKeyError, + ApiTypeError, + ApiValueError, +) from petstore_api.model_utils import ( # noqa: F401 ModelNormal, ModelSimple, check_allowed_values, - check_validations + check_validations, + date, + datetime, + file_type, + get_simple_class, + int, + model_to_dict, + none_type, + str, + type_error_message, + validate_and_convert_types ) +from petstore_api.models.category import Category +from petstore_api.models.tag import Tag class Pet(ModelNormal): @@ -46,13 +62,15 @@ class Pet(ModelNormal): 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 = { ('status',): { 'AVAILABLE': "available", 'PENDING': "pending", - 'SOLD': "sold" + 'SOLD': "sold", }, } @@ -66,220 +84,222 @@ class Pet(ModelNormal): } openapi_types = { - 'id': 'int', - 'category': 'Category', - 'name': 'str', - 'photo_urls': 'list[str]', - 'tags': 'list[Tag]', - 'status': 'str' + 'id': (int,), # noqa: E501 + 'category': (Category,), # noqa: E501 + 'name': (str,), # noqa: E501 + 'photo_urls': ([str],), # noqa: E501 + 'tags': ([Tag],), # noqa: E501 + 'status': (str,), # noqa: E501 } validations = { } - def __init__(self, id=None, category=None, name=None, photo_urls=None, tags=None, status=None): # noqa: E501 - """Pet - a model defined in OpenAPI""" # noqa: E501 - - self._id = None - self._category = None - self._name = None - self._photo_urls = None - self._tags = None - self._status = None - self.discriminator = None - - if id is not None: - self.id = ( - id + additional_properties_type = None + + discriminator = None + + def __init__(self, name, photo_urls, _check_type=True, _from_server=False, _path_to_item=(), _configuration=None, **kwargs): # noqa: E501 + """Pet - a model defined in OpenAPI + + Args: + name (str): + photo_urls ([str]): + + 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 + _from_server (bool): True if the data is from the server + False if the data is from the client (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. + id (int): [optional] # noqa: E501 + category (Category): [optional] # noqa: E501 + tags ([Tag]): [optional] # noqa: E501 + status (str): pet status in the store. [optional] # noqa: E501 + """ + self._data_store = {} + self._check_type = _check_type + self._from_server = _from_server + self._path_to_item = _path_to_item + self._configuration = _configuration + + self.__set_item('name', name) + self.__set_item('photo_urls', photo_urls) + for var_name, var_value in six.iteritems(kwargs): + self.__set_item(var_name, var_value) + + def __set_item(self, name, value): + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + + if name in self.openapi_types: + required_types_mixed = self.openapi_types[name] + elif self.additional_properties_type is None: + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + path_to_item + ) + elif self.additional_properties_type is not None: + required_types_mixed = self.additional_properties_type + + if get_simple_class(name) != str: + error_msg = type_error_message( + var_name=name, + var_value=name, + valid_classes=(str,), + key_type=True ) - if category is not None: - self.category = ( - category + raise ApiTypeError( + error_msg, + path_to_item=path_to_item, + valid_classes=(str,), + key_type=True ) - self.name = name - self.photo_urls = photo_urls - if tags is not None: - self.tags = ( - tags + + if self._check_type: + value = validate_and_convert_types( + value, required_types_mixed, path_to_item, self._from_server, + self._check_type, configuration=self._configuration) + if (name,) in self.allowed_values: + check_allowed_values( + self.allowed_values, + (name,), + value ) - if status is not None: - self.status = ( - status + if (name,) in self.validations: + check_validations( + self.validations, + (name,), + value ) + self._data_store[name] = value + + def __get_item(self, name): + if name in self._data_store: + return self._data_store[name] + + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + [name] + ) + + def __setitem__(self, name, value): + """this allows us to set values with instance[field_name] = val""" + self.__set_item(name, value) + + def __getitem__(self, name): + """this allows us to get a value with val = instance[field_name]""" + return self.__get_item(name) @property def id(self): """Gets the id of this Pet. # noqa: E501 - - :return: The id of this Pet. # noqa: E501 - :rtype: int + Returns: + (int): The id of this Pet. # noqa: E501 """ - return self._id + return self.__get_item('id') @id.setter - def id(self, id): # noqa: E501 - """Sets the id of this Pet. - - - :param id: The id of this Pet. # noqa: E501 - :type: int + def id(self, value): + """Sets the id of this Pet. # noqa: E501 """ - - self._id = ( - id - ) + return self.__set_item('id', value) @property def category(self): """Gets the category of this Pet. # noqa: E501 - - :return: The category of this Pet. # noqa: E501 - :rtype: Category + Returns: + (Category): The category of this Pet. # noqa: E501 """ - return self._category + return self.__get_item('category') @category.setter - def category(self, category): # noqa: E501 - """Sets the category of this Pet. - - - :param category: The category of this Pet. # noqa: E501 - :type: Category + def category(self, value): + """Sets the category of this Pet. # noqa: E501 """ - - self._category = ( - category - ) + return self.__set_item('category', value) @property def name(self): """Gets the name of this Pet. # noqa: E501 - - :return: The name of this Pet. # noqa: E501 - :rtype: str + Returns: + (str): The name of this Pet. # noqa: E501 """ - return self._name + return self.__get_item('name') @name.setter - def name(self, name): # noqa: E501 - """Sets the name of this Pet. - - - :param name: The name of this Pet. # noqa: E501 - :type: str + def name(self, value): + """Sets the name of this Pet. # noqa: E501 """ - if name is None: - raise ApiValueError("Invalid value for `name`, must not be `None`") # noqa: E501 - - self._name = ( - name - ) + return self.__set_item('name', value) @property def photo_urls(self): """Gets the photo_urls of this Pet. # noqa: E501 - - :return: The photo_urls of this Pet. # noqa: E501 - :rtype: list[str] + Returns: + ([str]): The photo_urls of this Pet. # noqa: E501 """ - return self._photo_urls + return self.__get_item('photo_urls') @photo_urls.setter - def photo_urls(self, photo_urls): # noqa: E501 - """Sets the photo_urls of this Pet. - - - :param photo_urls: The photo_urls of this Pet. # noqa: E501 - :type: list[str] + def photo_urls(self, value): + """Sets the photo_urls of this Pet. # noqa: E501 """ - if photo_urls is None: - raise ApiValueError("Invalid value for `photo_urls`, must not be `None`") # noqa: E501 - - self._photo_urls = ( - photo_urls - ) + return self.__set_item('photo_urls', value) @property def tags(self): """Gets the tags of this Pet. # noqa: E501 - - :return: The tags of this Pet. # noqa: E501 - :rtype: list[Tag] + Returns: + ([Tag]): The tags of this Pet. # noqa: E501 """ - return self._tags + return self.__get_item('tags') @tags.setter - def tags(self, tags): # noqa: E501 - """Sets the tags of this Pet. - - - :param tags: The tags of this Pet. # noqa: E501 - :type: list[Tag] + def tags(self, value): + """Sets the tags of this Pet. # noqa: E501 """ - - self._tags = ( - tags - ) + return self.__set_item('tags', value) @property def status(self): """Gets the status of this Pet. # noqa: E501 - pet status in the store # noqa: E501 - :return: The status of this Pet. # noqa: E501 - :rtype: str + Returns: + (str): The status of this Pet. # noqa: E501 """ - return self._status + return self.__get_item('status') @status.setter - def status(self, status): # noqa: E501 - """Sets the status of this Pet. - + def status(self, value): + """Sets the status of this Pet. # noqa: E501 pet status in the store # noqa: E501 - - :param status: The status of this Pet. # noqa: E501 - :type: str """ - check_allowed_values( - self.allowed_values, - ('status',), - status, - self.validations - ) - - self._status = ( - status - ) + return self.__set_item('status', value) def to_dict(self): """Returns the model properties as a dict""" - result = {} - - for attr, _ in six.iteritems(self.openapi_types): - value = getattr(self, attr) - if isinstance(value, list): - result[attr] = list(map( - lambda x: x.to_dict() if hasattr(x, "to_dict") else x, - value - )) - elif hasattr(value, "to_dict"): - result[attr] = value.to_dict() - elif isinstance(value, dict): - result[attr] = dict(map( - lambda item: (item[0], item[1].to_dict()) - if hasattr(item[1], "to_dict") else item, - value.items() - )) - else: - result[attr] = value - - return result + return model_to_dict(self, serialize=False) def to_str(self): """Returns the string representation of the model""" @@ -294,7 +314,22 @@ def __eq__(self, other): if not isinstance(other, Pet): return False - return self.__dict__ == other.__dict__ + if not set(self._data_store.keys()) == set(other._data_store.keys()): + return False + for _var_name, this_val in six.iteritems(self._data_store): + that_val = other._data_store[_var_name] + types = set() + types.add(this_val.__class__) + types.add(that_val.__class__) + vals_equal = this_val == that_val + if (not six.PY3 and + len(types) == 2 and unicode in types): # noqa: F821 + vals_equal = ( + this_val.encode('utf-8') == that_val.encode('utf-8') + ) + if not vals_equal: + return False + return True def __ne__(self, other): """Returns true if both objects are not equal""" diff --git a/samples/client/petstore/python-experimental/petstore_api/models/read_only_first.py b/samples/client/petstore/python-experimental/petstore_api/models/read_only_first.py index 96d93afbd2b6..848fbccfa913 100644 --- a/samples/client/petstore/python-experimental/petstore_api/models/read_only_first.py +++ b/samples/client/petstore/python-experimental/petstore_api/models/read_only_first.py @@ -15,12 +15,26 @@ import six # noqa: F401 -from petstore_api.exceptions import ApiValueError # noqa: F401 +from petstore_api.exceptions import ( # noqa: F401 + ApiKeyError, + ApiTypeError, + ApiValueError, +) from petstore_api.model_utils import ( # noqa: F401 ModelNormal, ModelSimple, check_allowed_values, - check_validations + check_validations, + date, + datetime, + file_type, + get_simple_class, + int, + model_to_dict, + none_type, + str, + type_error_message, + validate_and_convert_types ) @@ -46,6 +60,8 @@ class ReadOnlyFirst(ModelNormal): 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 = { @@ -57,98 +73,149 @@ class ReadOnlyFirst(ModelNormal): } openapi_types = { - 'bar': 'str', - 'baz': 'str' + 'bar': (str,), # noqa: E501 + 'baz': (str,), # noqa: E501 } validations = { } - def __init__(self, bar=None, baz=None): # noqa: E501 - """ReadOnlyFirst - a model defined in OpenAPI""" # noqa: E501 - - self._bar = None - self._baz = None - self.discriminator = None + additional_properties_type = None + + discriminator = None + + def __init__(self, _check_type=True, _from_server=False, _path_to_item=(), _configuration=None, **kwargs): # noqa: E501 + """ReadOnlyFirst - 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 + _from_server (bool): True if the data is from the server + False if the data is from the client (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. + bar (str): [optional] # noqa: E501 + baz (str): [optional] # noqa: E501 + """ + self._data_store = {} + self._check_type = _check_type + self._from_server = _from_server + self._path_to_item = _path_to_item + self._configuration = _configuration + + for var_name, var_value in six.iteritems(kwargs): + self.__set_item(var_name, var_value) + + def __set_item(self, name, value): + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + + if name in self.openapi_types: + required_types_mixed = self.openapi_types[name] + elif self.additional_properties_type is None: + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + path_to_item + ) + elif self.additional_properties_type is not None: + required_types_mixed = self.additional_properties_type + + if get_simple_class(name) != str: + error_msg = type_error_message( + var_name=name, + var_value=name, + valid_classes=(str,), + key_type=True + ) + raise ApiTypeError( + error_msg, + path_to_item=path_to_item, + valid_classes=(str,), + key_type=True + ) - if bar is not None: - self.bar = ( - bar + if self._check_type: + value = validate_and_convert_types( + value, required_types_mixed, path_to_item, self._from_server, + self._check_type, configuration=self._configuration) + if (name,) in self.allowed_values: + check_allowed_values( + self.allowed_values, + (name,), + value ) - if baz is not None: - self.baz = ( - baz + if (name,) in self.validations: + check_validations( + self.validations, + (name,), + value ) + self._data_store[name] = value + + def __get_item(self, name): + if name in self._data_store: + return self._data_store[name] + + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + [name] + ) + + def __setitem__(self, name, value): + """this allows us to set values with instance[field_name] = val""" + self.__set_item(name, value) + + def __getitem__(self, name): + """this allows us to get a value with val = instance[field_name]""" + return self.__get_item(name) @property def bar(self): """Gets the bar of this ReadOnlyFirst. # noqa: E501 - - :return: The bar of this ReadOnlyFirst. # noqa: E501 - :rtype: str + Returns: + (str): The bar of this ReadOnlyFirst. # noqa: E501 """ - return self._bar + return self.__get_item('bar') @bar.setter - def bar(self, bar): # noqa: E501 - """Sets the bar of this ReadOnlyFirst. - - - :param bar: The bar of this ReadOnlyFirst. # noqa: E501 - :type: str + def bar(self, value): + """Sets the bar of this ReadOnlyFirst. # noqa: E501 """ - - self._bar = ( - bar - ) + return self.__set_item('bar', value) @property def baz(self): """Gets the baz of this ReadOnlyFirst. # noqa: E501 - - :return: The baz of this ReadOnlyFirst. # noqa: E501 - :rtype: str + Returns: + (str): The baz of this ReadOnlyFirst. # noqa: E501 """ - return self._baz + return self.__get_item('baz') @baz.setter - def baz(self, baz): # noqa: E501 - """Sets the baz of this ReadOnlyFirst. - - - :param baz: The baz of this ReadOnlyFirst. # noqa: E501 - :type: str + def baz(self, value): + """Sets the baz of this ReadOnlyFirst. # noqa: E501 """ - - self._baz = ( - baz - ) + return self.__set_item('baz', value) def to_dict(self): """Returns the model properties as a dict""" - result = {} - - for attr, _ in six.iteritems(self.openapi_types): - value = getattr(self, attr) - if isinstance(value, list): - result[attr] = list(map( - lambda x: x.to_dict() if hasattr(x, "to_dict") else x, - value - )) - elif hasattr(value, "to_dict"): - result[attr] = value.to_dict() - elif isinstance(value, dict): - result[attr] = dict(map( - lambda item: (item[0], item[1].to_dict()) - if hasattr(item[1], "to_dict") else item, - value.items() - )) - else: - result[attr] = value - - return result + return model_to_dict(self, serialize=False) def to_str(self): """Returns the string representation of the model""" @@ -163,7 +230,22 @@ def __eq__(self, other): if not isinstance(other, ReadOnlyFirst): return False - return self.__dict__ == other.__dict__ + if not set(self._data_store.keys()) == set(other._data_store.keys()): + return False + for _var_name, this_val in six.iteritems(self._data_store): + that_val = other._data_store[_var_name] + types = set() + types.add(this_val.__class__) + types.add(that_val.__class__) + vals_equal = this_val == that_val + if (not six.PY3 and + len(types) == 2 and unicode in types): # noqa: F821 + vals_equal = ( + this_val.encode('utf-8') == that_val.encode('utf-8') + ) + if not vals_equal: + return False + return True def __ne__(self, other): """Returns true if both objects are not equal""" diff --git a/samples/client/petstore/python-experimental/petstore_api/models/special_model_name.py b/samples/client/petstore/python-experimental/petstore_api/models/special_model_name.py index 83ab1e65054a..83810bdb8941 100644 --- a/samples/client/petstore/python-experimental/petstore_api/models/special_model_name.py +++ b/samples/client/petstore/python-experimental/petstore_api/models/special_model_name.py @@ -15,12 +15,26 @@ import six # noqa: F401 -from petstore_api.exceptions import ApiValueError # noqa: F401 +from petstore_api.exceptions import ( # noqa: F401 + ApiKeyError, + ApiTypeError, + ApiValueError, +) from petstore_api.model_utils import ( # noqa: F401 ModelNormal, ModelSimple, check_allowed_values, - check_validations + check_validations, + date, + datetime, + file_type, + get_simple_class, + int, + model_to_dict, + none_type, + str, + type_error_message, + validate_and_convert_types ) @@ -46,6 +60,8 @@ class SpecialModelName(ModelNormal): 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 = { @@ -56,69 +72,132 @@ class SpecialModelName(ModelNormal): } openapi_types = { - 'special_property_name': 'int' + 'special_property_name': (int,), # noqa: E501 } validations = { } - def __init__(self, special_property_name=None): # noqa: E501 - """SpecialModelName - a model defined in OpenAPI""" # noqa: E501 - - self._special_property_name = None - self.discriminator = None + additional_properties_type = None + + discriminator = None + + def __init__(self, _check_type=True, _from_server=False, _path_to_item=(), _configuration=None, **kwargs): # noqa: E501 + """SpecialModelName - 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 + _from_server (bool): True if the data is from the server + False if the data is from the client (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. + special_property_name (int): [optional] # noqa: E501 + """ + self._data_store = {} + self._check_type = _check_type + self._from_server = _from_server + self._path_to_item = _path_to_item + self._configuration = _configuration + + for var_name, var_value in six.iteritems(kwargs): + self.__set_item(var_name, var_value) + + def __set_item(self, name, value): + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + + if name in self.openapi_types: + required_types_mixed = self.openapi_types[name] + elif self.additional_properties_type is None: + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + path_to_item + ) + elif self.additional_properties_type is not None: + required_types_mixed = self.additional_properties_type + + if get_simple_class(name) != str: + error_msg = type_error_message( + var_name=name, + var_value=name, + valid_classes=(str,), + key_type=True + ) + raise ApiTypeError( + error_msg, + path_to_item=path_to_item, + valid_classes=(str,), + key_type=True + ) - if special_property_name is not None: - self.special_property_name = ( - special_property_name + if self._check_type: + value = validate_and_convert_types( + value, required_types_mixed, path_to_item, self._from_server, + self._check_type, configuration=self._configuration) + if (name,) in self.allowed_values: + check_allowed_values( + self.allowed_values, + (name,), + value ) + if (name,) in self.validations: + check_validations( + self.validations, + (name,), + value + ) + self._data_store[name] = value + + def __get_item(self, name): + if name in self._data_store: + return self._data_store[name] + + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + [name] + ) + + def __setitem__(self, name, value): + """this allows us to set values with instance[field_name] = val""" + self.__set_item(name, value) + + def __getitem__(self, name): + """this allows us to get a value with val = instance[field_name]""" + return self.__get_item(name) @property def special_property_name(self): """Gets the special_property_name of this SpecialModelName. # noqa: E501 - - :return: The special_property_name of this SpecialModelName. # noqa: E501 - :rtype: int + Returns: + (int): The special_property_name of this SpecialModelName. # noqa: E501 """ - return self._special_property_name + return self.__get_item('special_property_name') @special_property_name.setter - def special_property_name(self, special_property_name): # noqa: E501 - """Sets the special_property_name of this SpecialModelName. - - - :param special_property_name: The special_property_name of this SpecialModelName. # noqa: E501 - :type: int + def special_property_name(self, value): + """Sets the special_property_name of this SpecialModelName. # noqa: E501 """ - - self._special_property_name = ( - special_property_name - ) + return self.__set_item('special_property_name', value) def to_dict(self): """Returns the model properties as a dict""" - result = {} - - for attr, _ in six.iteritems(self.openapi_types): - value = getattr(self, attr) - if isinstance(value, list): - result[attr] = list(map( - lambda x: x.to_dict() if hasattr(x, "to_dict") else x, - value - )) - elif hasattr(value, "to_dict"): - result[attr] = value.to_dict() - elif isinstance(value, dict): - result[attr] = dict(map( - lambda item: (item[0], item[1].to_dict()) - if hasattr(item[1], "to_dict") else item, - value.items() - )) - else: - result[attr] = value - - return result + return model_to_dict(self, serialize=False) def to_str(self): """Returns the string representation of the model""" @@ -133,7 +212,22 @@ def __eq__(self, other): if not isinstance(other, SpecialModelName): return False - return self.__dict__ == other.__dict__ + if not set(self._data_store.keys()) == set(other._data_store.keys()): + return False + for _var_name, this_val in six.iteritems(self._data_store): + that_val = other._data_store[_var_name] + types = set() + types.add(this_val.__class__) + types.add(that_val.__class__) + vals_equal = this_val == that_val + if (not six.PY3 and + len(types) == 2 and unicode in types): # noqa: F821 + vals_equal = ( + this_val.encode('utf-8') == that_val.encode('utf-8') + ) + if not vals_equal: + return False + return True def __ne__(self, other): """Returns true if both objects are not equal""" diff --git a/samples/client/petstore/python-experimental/petstore_api/models/string_boolean_map.py b/samples/client/petstore/python-experimental/petstore_api/models/string_boolean_map.py index 01427c702be3..1d10f9a8d7ed 100644 --- a/samples/client/petstore/python-experimental/petstore_api/models/string_boolean_map.py +++ b/samples/client/petstore/python-experimental/petstore_api/models/string_boolean_map.py @@ -15,12 +15,26 @@ import six # noqa: F401 -from petstore_api.exceptions import ApiValueError # noqa: F401 +from petstore_api.exceptions import ( # noqa: F401 + ApiKeyError, + ApiTypeError, + ApiValueError, +) from petstore_api.model_utils import ( # noqa: F401 ModelNormal, ModelSimple, check_allowed_values, - check_validations + check_validations, + date, + datetime, + file_type, + get_simple_class, + int, + model_to_dict, + none_type, + str, + type_error_message, + validate_and_convert_types ) @@ -46,6 +60,8 @@ class StringBooleanMap(ModelNormal): 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 = { @@ -60,33 +76,110 @@ class StringBooleanMap(ModelNormal): validations = { } - def __init__(self): # noqa: E501 - """StringBooleanMap - a model defined in OpenAPI""" # noqa: E501 - self.discriminator = None + additional_properties_type = (bool,) # noqa: E501 + + discriminator = None + + def __init__(self, _check_type=True, _from_server=False, _path_to_item=(), _configuration=None, **kwargs): # noqa: E501 + """StringBooleanMap - 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 + _from_server (bool): True if the data is from the server + False if the data is from the client (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. + """ + self._data_store = {} + self._check_type = _check_type + self._from_server = _from_server + self._path_to_item = _path_to_item + self._configuration = _configuration + + for var_name, var_value in six.iteritems(kwargs): + self.__set_item(var_name, var_value) + + def __set_item(self, name, value): + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + + if name in self.openapi_types: + required_types_mixed = self.openapi_types[name] + elif self.additional_properties_type is None: + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + path_to_item + ) + elif self.additional_properties_type is not None: + required_types_mixed = self.additional_properties_type + + if get_simple_class(name) != str: + error_msg = type_error_message( + var_name=name, + var_value=name, + valid_classes=(str,), + key_type=True + ) + raise ApiTypeError( + error_msg, + path_to_item=path_to_item, + valid_classes=(str,), + key_type=True + ) + + if self._check_type: + value = validate_and_convert_types( + value, required_types_mixed, path_to_item, self._from_server, + self._check_type, configuration=self._configuration) + if (name,) in self.allowed_values: + check_allowed_values( + self.allowed_values, + (name,), + value + ) + if (name,) in self.validations: + check_validations( + self.validations, + (name,), + value + ) + self._data_store[name] = value + + def __get_item(self, name): + if name in self._data_store: + return self._data_store[name] + + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + [name] + ) + + def __setitem__(self, name, value): + """this allows us to set values with instance[field_name] = val""" + self.__set_item(name, value) + + def __getitem__(self, name): + """this allows us to get a value with val = instance[field_name]""" + return self.__get_item(name) def to_dict(self): """Returns the model properties as a dict""" - result = {} - - for attr, _ in six.iteritems(self.openapi_types): - value = getattr(self, attr) - if isinstance(value, list): - result[attr] = list(map( - lambda x: x.to_dict() if hasattr(x, "to_dict") else x, - value - )) - elif hasattr(value, "to_dict"): - result[attr] = value.to_dict() - elif isinstance(value, dict): - result[attr] = dict(map( - lambda item: (item[0], item[1].to_dict()) - if hasattr(item[1], "to_dict") else item, - value.items() - )) - else: - result[attr] = value - - return result + return model_to_dict(self, serialize=False) def to_str(self): """Returns the string representation of the model""" @@ -101,7 +194,22 @@ def __eq__(self, other): if not isinstance(other, StringBooleanMap): return False - return self.__dict__ == other.__dict__ + if not set(self._data_store.keys()) == set(other._data_store.keys()): + return False + for _var_name, this_val in six.iteritems(self._data_store): + that_val = other._data_store[_var_name] + types = set() + types.add(this_val.__class__) + types.add(that_val.__class__) + vals_equal = this_val == that_val + if (not six.PY3 and + len(types) == 2 and unicode in types): # noqa: F821 + vals_equal = ( + this_val.encode('utf-8') == that_val.encode('utf-8') + ) + if not vals_equal: + return False + return True def __ne__(self, other): """Returns true if both objects are not equal""" diff --git a/samples/client/petstore/python-experimental/petstore_api/models/tag.py b/samples/client/petstore/python-experimental/petstore_api/models/tag.py index f5e08704a007..4e1fd5ef077e 100644 --- a/samples/client/petstore/python-experimental/petstore_api/models/tag.py +++ b/samples/client/petstore/python-experimental/petstore_api/models/tag.py @@ -15,12 +15,26 @@ import six # noqa: F401 -from petstore_api.exceptions import ApiValueError # noqa: F401 +from petstore_api.exceptions import ( # noqa: F401 + ApiKeyError, + ApiTypeError, + ApiValueError, +) from petstore_api.model_utils import ( # noqa: F401 ModelNormal, ModelSimple, check_allowed_values, - check_validations + check_validations, + date, + datetime, + file_type, + get_simple_class, + int, + model_to_dict, + none_type, + str, + type_error_message, + validate_and_convert_types ) @@ -46,6 +60,8 @@ class Tag(ModelNormal): 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 = { @@ -57,98 +73,149 @@ class Tag(ModelNormal): } openapi_types = { - 'id': 'int', - 'name': 'str' + 'id': (int,), # noqa: E501 + 'name': (str,), # noqa: E501 } validations = { } - def __init__(self, id=None, name=None): # noqa: E501 - """Tag - a model defined in OpenAPI""" # noqa: E501 - - self._id = None - self._name = None - self.discriminator = None + additional_properties_type = None + + discriminator = None + + def __init__(self, _check_type=True, _from_server=False, _path_to_item=(), _configuration=None, **kwargs): # noqa: E501 + """Tag - 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 + _from_server (bool): True if the data is from the server + False if the data is from the client (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. + id (int): [optional] # noqa: E501 + name (str): [optional] # noqa: E501 + """ + self._data_store = {} + self._check_type = _check_type + self._from_server = _from_server + self._path_to_item = _path_to_item + self._configuration = _configuration + + for var_name, var_value in six.iteritems(kwargs): + self.__set_item(var_name, var_value) + + def __set_item(self, name, value): + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + + if name in self.openapi_types: + required_types_mixed = self.openapi_types[name] + elif self.additional_properties_type is None: + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + path_to_item + ) + elif self.additional_properties_type is not None: + required_types_mixed = self.additional_properties_type + + if get_simple_class(name) != str: + error_msg = type_error_message( + var_name=name, + var_value=name, + valid_classes=(str,), + key_type=True + ) + raise ApiTypeError( + error_msg, + path_to_item=path_to_item, + valid_classes=(str,), + key_type=True + ) - if id is not None: - self.id = ( - id + if self._check_type: + value = validate_and_convert_types( + value, required_types_mixed, path_to_item, self._from_server, + self._check_type, configuration=self._configuration) + if (name,) in self.allowed_values: + check_allowed_values( + self.allowed_values, + (name,), + value ) - if name is not None: - self.name = ( - name + if (name,) in self.validations: + check_validations( + self.validations, + (name,), + value ) + self._data_store[name] = value + + def __get_item(self, name): + if name in self._data_store: + return self._data_store[name] + + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + [name] + ) + + def __setitem__(self, name, value): + """this allows us to set values with instance[field_name] = val""" + self.__set_item(name, value) + + def __getitem__(self, name): + """this allows us to get a value with val = instance[field_name]""" + return self.__get_item(name) @property def id(self): """Gets the id of this Tag. # noqa: E501 - - :return: The id of this Tag. # noqa: E501 - :rtype: int + Returns: + (int): The id of this Tag. # noqa: E501 """ - return self._id + return self.__get_item('id') @id.setter - def id(self, id): # noqa: E501 - """Sets the id of this Tag. - - - :param id: The id of this Tag. # noqa: E501 - :type: int + def id(self, value): + """Sets the id of this Tag. # noqa: E501 """ - - self._id = ( - id - ) + return self.__set_item('id', value) @property def name(self): """Gets the name of this Tag. # noqa: E501 - - :return: The name of this Tag. # noqa: E501 - :rtype: str + Returns: + (str): The name of this Tag. # noqa: E501 """ - return self._name + return self.__get_item('name') @name.setter - def name(self, name): # noqa: E501 - """Sets the name of this Tag. - - - :param name: The name of this Tag. # noqa: E501 - :type: str + def name(self, value): + """Sets the name of this Tag. # noqa: E501 """ - - self._name = ( - name - ) + return self.__set_item('name', value) def to_dict(self): """Returns the model properties as a dict""" - result = {} - - for attr, _ in six.iteritems(self.openapi_types): - value = getattr(self, attr) - if isinstance(value, list): - result[attr] = list(map( - lambda x: x.to_dict() if hasattr(x, "to_dict") else x, - value - )) - elif hasattr(value, "to_dict"): - result[attr] = value.to_dict() - elif isinstance(value, dict): - result[attr] = dict(map( - lambda item: (item[0], item[1].to_dict()) - if hasattr(item[1], "to_dict") else item, - value.items() - )) - else: - result[attr] = value - - return result + return model_to_dict(self, serialize=False) def to_str(self): """Returns the string representation of the model""" @@ -163,7 +230,22 @@ def __eq__(self, other): if not isinstance(other, Tag): return False - return self.__dict__ == other.__dict__ + if not set(self._data_store.keys()) == set(other._data_store.keys()): + return False + for _var_name, this_val in six.iteritems(self._data_store): + that_val = other._data_store[_var_name] + types = set() + types.add(this_val.__class__) + types.add(that_val.__class__) + vals_equal = this_val == that_val + if (not six.PY3 and + len(types) == 2 and unicode in types): # noqa: F821 + vals_equal = ( + this_val.encode('utf-8') == that_val.encode('utf-8') + ) + if not vals_equal: + return False + return True def __ne__(self, other): """Returns true if both objects are not equal""" diff --git a/samples/client/petstore/python-experimental/petstore_api/models/type_holder_default.py b/samples/client/petstore/python-experimental/petstore_api/models/type_holder_default.py index a27e05e14d21..26f1d9044524 100644 --- a/samples/client/petstore/python-experimental/petstore_api/models/type_holder_default.py +++ b/samples/client/petstore/python-experimental/petstore_api/models/type_holder_default.py @@ -15,12 +15,26 @@ import six # noqa: F401 -from petstore_api.exceptions import ApiValueError # noqa: F401 +from petstore_api.exceptions import ( # noqa: F401 + ApiKeyError, + ApiTypeError, + ApiValueError, +) from petstore_api.model_utils import ( # noqa: F401 ModelNormal, ModelSimple, check_allowed_values, - check_validations + check_validations, + date, + datetime, + file_type, + get_simple_class, + int, + model_to_dict, + none_type, + str, + type_error_message, + validate_and_convert_types ) @@ -46,6 +60,8 @@ class TypeHolderDefault(ModelNormal): 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 = { @@ -62,238 +78,240 @@ class TypeHolderDefault(ModelNormal): } openapi_types = { - 'string_item': 'str', - 'number_item': 'float', - 'integer_item': 'int', - 'bool_item': 'bool', - 'date_item': 'date', - 'datetime_item': 'datetime', - 'array_item': 'list[int]' + 'string_item': (str,), # noqa: E501 + 'number_item': (float,), # noqa: E501 + 'integer_item': (int,), # noqa: E501 + 'bool_item': (bool,), # noqa: E501 + 'date_item': (date,), # noqa: E501 + 'datetime_item': (datetime,), # noqa: E501 + 'array_item': ([int],), # noqa: E501 } validations = { } - def __init__(self, string_item='what', number_item=1.234, integer_item=-2, bool_item=True, date_item=None, datetime_item=None, array_item=None): # noqa: E501 - """TypeHolderDefault - a model defined in OpenAPI""" # noqa: E501 - - self._string_item = None - self._number_item = None - self._integer_item = None - self._bool_item = None - self._date_item = None - self._datetime_item = None - self._array_item = None - self.discriminator = None - - self.string_item = string_item - self.number_item = number_item - self.integer_item = integer_item - self.bool_item = bool_item - if date_item is not None: - self.date_item = ( - date_item + additional_properties_type = None + + discriminator = None + + def __init__(self, array_item, string_item='what', number_item=1.234, integer_item=-2, bool_item=True, _check_type=True, _from_server=False, _path_to_item=(), _configuration=None, **kwargs): # noqa: E501 + """TypeHolderDefault - a model defined in OpenAPI + + Args: + array_item ([int]): + + Keyword Args: + string_item (str): defaults to 'what', must be one of ['what'] # noqa: E501 + number_item (float): defaults to 1.234, must be one of [1.234] # noqa: E501 + integer_item (int): defaults to -2, must be one of [-2] # noqa: E501 + bool_item (bool): defaults to True, must be one of [True] # noqa: E501 + _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 + _from_server (bool): True if the data is from the server + False if the data is from the client (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. + date_item (date): [optional] # noqa: E501 + datetime_item (datetime): [optional] # noqa: E501 + """ + self._data_store = {} + self._check_type = _check_type + self._from_server = _from_server + self._path_to_item = _path_to_item + self._configuration = _configuration + + self.__set_item('string_item', string_item) + self.__set_item('number_item', number_item) + self.__set_item('integer_item', integer_item) + self.__set_item('bool_item', bool_item) + self.__set_item('array_item', array_item) + for var_name, var_value in six.iteritems(kwargs): + self.__set_item(var_name, var_value) + + def __set_item(self, name, value): + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + + if name in self.openapi_types: + required_types_mixed = self.openapi_types[name] + elif self.additional_properties_type is None: + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + path_to_item + ) + elif self.additional_properties_type is not None: + required_types_mixed = self.additional_properties_type + + if get_simple_class(name) != str: + error_msg = type_error_message( + var_name=name, + var_value=name, + valid_classes=(str,), + key_type=True + ) + raise ApiTypeError( + error_msg, + path_to_item=path_to_item, + valid_classes=(str,), + key_type=True + ) + + if self._check_type: + value = validate_and_convert_types( + value, required_types_mixed, path_to_item, self._from_server, + self._check_type, configuration=self._configuration) + if (name,) in self.allowed_values: + check_allowed_values( + self.allowed_values, + (name,), + value ) - if datetime_item is not None: - self.datetime_item = ( - datetime_item + if (name,) in self.validations: + check_validations( + self.validations, + (name,), + value ) - self.array_item = array_item + self._data_store[name] = value + + def __get_item(self, name): + if name in self._data_store: + return self._data_store[name] + + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + [name] + ) + + def __setitem__(self, name, value): + """this allows us to set values with instance[field_name] = val""" + self.__set_item(name, value) + + def __getitem__(self, name): + """this allows us to get a value with val = instance[field_name]""" + return self.__get_item(name) @property def string_item(self): """Gets the string_item of this TypeHolderDefault. # noqa: E501 - - :return: The string_item of this TypeHolderDefault. # noqa: E501 - :rtype: str + Returns: + (str): The string_item of this TypeHolderDefault. # noqa: E501 """ - return self._string_item + return self.__get_item('string_item') @string_item.setter - def string_item(self, string_item): # noqa: E501 - """Sets the string_item of this TypeHolderDefault. - - - :param string_item: The string_item of this TypeHolderDefault. # noqa: E501 - :type: str + def string_item(self, value): + """Sets the string_item of this TypeHolderDefault. # noqa: E501 """ - if string_item is None: - raise ApiValueError("Invalid value for `string_item`, must not be `None`") # noqa: E501 - - self._string_item = ( - string_item - ) + return self.__set_item('string_item', value) @property def number_item(self): """Gets the number_item of this TypeHolderDefault. # noqa: E501 - - :return: The number_item of this TypeHolderDefault. # noqa: E501 - :rtype: float + Returns: + (float): The number_item of this TypeHolderDefault. # noqa: E501 """ - return self._number_item + return self.__get_item('number_item') @number_item.setter - def number_item(self, number_item): # noqa: E501 - """Sets the number_item of this TypeHolderDefault. - - - :param number_item: The number_item of this TypeHolderDefault. # noqa: E501 - :type: float + def number_item(self, value): + """Sets the number_item of this TypeHolderDefault. # noqa: E501 """ - if number_item is None: - raise ApiValueError("Invalid value for `number_item`, must not be `None`") # noqa: E501 - - self._number_item = ( - number_item - ) + return self.__set_item('number_item', value) @property def integer_item(self): """Gets the integer_item of this TypeHolderDefault. # noqa: E501 - - :return: The integer_item of this TypeHolderDefault. # noqa: E501 - :rtype: int + Returns: + (int): The integer_item of this TypeHolderDefault. # noqa: E501 """ - return self._integer_item + return self.__get_item('integer_item') @integer_item.setter - def integer_item(self, integer_item): # noqa: E501 - """Sets the integer_item of this TypeHolderDefault. - - - :param integer_item: The integer_item of this TypeHolderDefault. # noqa: E501 - :type: int + def integer_item(self, value): + """Sets the integer_item of this TypeHolderDefault. # noqa: E501 """ - if integer_item is None: - raise ApiValueError("Invalid value for `integer_item`, must not be `None`") # noqa: E501 - - self._integer_item = ( - integer_item - ) + return self.__set_item('integer_item', value) @property def bool_item(self): """Gets the bool_item of this TypeHolderDefault. # noqa: E501 - - :return: The bool_item of this TypeHolderDefault. # noqa: E501 - :rtype: bool + Returns: + (bool): The bool_item of this TypeHolderDefault. # noqa: E501 """ - return self._bool_item + return self.__get_item('bool_item') @bool_item.setter - def bool_item(self, bool_item): # noqa: E501 - """Sets the bool_item of this TypeHolderDefault. - - - :param bool_item: The bool_item of this TypeHolderDefault. # noqa: E501 - :type: bool + def bool_item(self, value): + """Sets the bool_item of this TypeHolderDefault. # noqa: E501 """ - if bool_item is None: - raise ApiValueError("Invalid value for `bool_item`, must not be `None`") # noqa: E501 - - self._bool_item = ( - bool_item - ) + return self.__set_item('bool_item', value) @property def date_item(self): """Gets the date_item of this TypeHolderDefault. # noqa: E501 - - :return: The date_item of this TypeHolderDefault. # noqa: E501 - :rtype: date + Returns: + (date): The date_item of this TypeHolderDefault. # noqa: E501 """ - return self._date_item + return self.__get_item('date_item') @date_item.setter - def date_item(self, date_item): # noqa: E501 - """Sets the date_item of this TypeHolderDefault. - - - :param date_item: The date_item of this TypeHolderDefault. # noqa: E501 - :type: date + def date_item(self, value): + """Sets the date_item of this TypeHolderDefault. # noqa: E501 """ - - self._date_item = ( - date_item - ) + return self.__set_item('date_item', value) @property def datetime_item(self): """Gets the datetime_item of this TypeHolderDefault. # noqa: E501 - - :return: The datetime_item of this TypeHolderDefault. # noqa: E501 - :rtype: datetime + Returns: + (datetime): The datetime_item of this TypeHolderDefault. # noqa: E501 """ - return self._datetime_item + return self.__get_item('datetime_item') @datetime_item.setter - def datetime_item(self, datetime_item): # noqa: E501 - """Sets the datetime_item of this TypeHolderDefault. - - - :param datetime_item: The datetime_item of this TypeHolderDefault. # noqa: E501 - :type: datetime + def datetime_item(self, value): + """Sets the datetime_item of this TypeHolderDefault. # noqa: E501 """ - - self._datetime_item = ( - datetime_item - ) + return self.__set_item('datetime_item', value) @property def array_item(self): """Gets the array_item of this TypeHolderDefault. # noqa: E501 - - :return: The array_item of this TypeHolderDefault. # noqa: E501 - :rtype: list[int] + Returns: + ([int]): The array_item of this TypeHolderDefault. # noqa: E501 """ - return self._array_item + return self.__get_item('array_item') @array_item.setter - def array_item(self, array_item): # noqa: E501 - """Sets the array_item of this TypeHolderDefault. - - - :param array_item: The array_item of this TypeHolderDefault. # noqa: E501 - :type: list[int] + def array_item(self, value): + """Sets the array_item of this TypeHolderDefault. # noqa: E501 """ - if array_item is None: - raise ApiValueError("Invalid value for `array_item`, must not be `None`") # noqa: E501 - - self._array_item = ( - array_item - ) + return self.__set_item('array_item', value) def to_dict(self): """Returns the model properties as a dict""" - result = {} - - for attr, _ in six.iteritems(self.openapi_types): - value = getattr(self, attr) - if isinstance(value, list): - result[attr] = list(map( - lambda x: x.to_dict() if hasattr(x, "to_dict") else x, - value - )) - elif hasattr(value, "to_dict"): - result[attr] = value.to_dict() - elif isinstance(value, dict): - result[attr] = dict(map( - lambda item: (item[0], item[1].to_dict()) - if hasattr(item[1], "to_dict") else item, - value.items() - )) - else: - result[attr] = value - - return result + return model_to_dict(self, serialize=False) def to_str(self): """Returns the string representation of the model""" @@ -308,7 +326,22 @@ def __eq__(self, other): if not isinstance(other, TypeHolderDefault): return False - return self.__dict__ == other.__dict__ + if not set(self._data_store.keys()) == set(other._data_store.keys()): + return False + for _var_name, this_val in six.iteritems(self._data_store): + that_val = other._data_store[_var_name] + types = set() + types.add(this_val.__class__) + types.add(that_val.__class__) + vals_equal = this_val == that_val + if (not six.PY3 and + len(types) == 2 and unicode in types): # noqa: F821 + vals_equal = ( + this_val.encode('utf-8') == that_val.encode('utf-8') + ) + if not vals_equal: + return False + return True def __ne__(self, other): """Returns true if both objects are not equal""" diff --git a/samples/client/petstore/python-experimental/petstore_api/models/type_holder_example.py b/samples/client/petstore/python-experimental/petstore_api/models/type_holder_example.py index 661bb21a3805..b4fb4770d1e7 100644 --- a/samples/client/petstore/python-experimental/petstore_api/models/type_holder_example.py +++ b/samples/client/petstore/python-experimental/petstore_api/models/type_holder_example.py @@ -15,12 +15,26 @@ import six # noqa: F401 -from petstore_api.exceptions import ApiValueError # noqa: F401 +from petstore_api.exceptions import ( # noqa: F401 + ApiKeyError, + ApiTypeError, + ApiValueError, +) from petstore_api.model_utils import ( # noqa: F401 ModelNormal, ModelSimple, check_allowed_values, - check_validations + check_validations, + date, + datetime, + file_type, + get_simple_class, + int, + model_to_dict, + none_type, + str, + type_error_message, + validate_and_convert_types ) @@ -46,17 +60,19 @@ class TypeHolderExample(ModelNormal): 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 = { ('string_item',): { - 'WHAT': "what" + 'WHAT': "what", }, ('number_item',): { - '1.234': 1.234 + '1.234': 1.234, }, ('integer_item',): { - '-2': -2 + '-2': -2, }, } @@ -69,198 +85,206 @@ class TypeHolderExample(ModelNormal): } openapi_types = { - 'string_item': 'str', - 'number_item': 'float', - 'integer_item': 'int', - 'bool_item': 'bool', - 'array_item': 'list[int]' + 'string_item': (str,), # noqa: E501 + 'number_item': (float,), # noqa: E501 + 'integer_item': (int,), # noqa: E501 + 'bool_item': (bool,), # noqa: E501 + 'array_item': ([int],), # noqa: E501 } validations = { } - def __init__(self, string_item='what', number_item=1.234, integer_item=-2, bool_item=None, array_item=None): # noqa: E501 - """TypeHolderExample - a model defined in OpenAPI""" # noqa: E501 + additional_properties_type = None + + discriminator = None + + def __init__(self, bool_item, array_item, string_item='what', number_item=1.234, integer_item=-2, _check_type=True, _from_server=False, _path_to_item=(), _configuration=None, **kwargs): # noqa: E501 + """TypeHolderExample - a model defined in OpenAPI + + Args: + bool_item (bool): + array_item ([int]): + + Keyword Args: + string_item (str): defaults to 'what', must be one of ['what'] # noqa: E501 + number_item (float): defaults to 1.234, must be one of [1.234] # noqa: E501 + integer_item (int): defaults to -2, must be one of [-2] # noqa: E501 + _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 + _from_server (bool): True if the data is from the server + False if the data is from the client (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. + """ + self._data_store = {} + self._check_type = _check_type + self._from_server = _from_server + self._path_to_item = _path_to_item + self._configuration = _configuration + + self.__set_item('string_item', string_item) + self.__set_item('number_item', number_item) + self.__set_item('integer_item', integer_item) + self.__set_item('bool_item', bool_item) + self.__set_item('array_item', array_item) + for var_name, var_value in six.iteritems(kwargs): + self.__set_item(var_name, var_value) + + def __set_item(self, name, value): + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + + if name in self.openapi_types: + required_types_mixed = self.openapi_types[name] + elif self.additional_properties_type is None: + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + path_to_item + ) + elif self.additional_properties_type is not None: + required_types_mixed = self.additional_properties_type + + if get_simple_class(name) != str: + error_msg = type_error_message( + var_name=name, + var_value=name, + valid_classes=(str,), + key_type=True + ) + raise ApiTypeError( + error_msg, + path_to_item=path_to_item, + valid_classes=(str,), + key_type=True + ) + + if self._check_type: + value = validate_and_convert_types( + value, required_types_mixed, path_to_item, self._from_server, + self._check_type, configuration=self._configuration) + if (name,) in self.allowed_values: + check_allowed_values( + self.allowed_values, + (name,), + value + ) + if (name,) in self.validations: + check_validations( + self.validations, + (name,), + value + ) + self._data_store[name] = value + + def __get_item(self, name): + if name in self._data_store: + return self._data_store[name] + + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + [name] + ) - self._string_item = None - self._number_item = None - self._integer_item = None - self._bool_item = None - self._array_item = None - self.discriminator = None + def __setitem__(self, name, value): + """this allows us to set values with instance[field_name] = val""" + self.__set_item(name, value) - self.string_item = string_item - self.number_item = number_item - self.integer_item = integer_item - self.bool_item = bool_item - self.array_item = array_item + def __getitem__(self, name): + """this allows us to get a value with val = instance[field_name]""" + return self.__get_item(name) @property def string_item(self): """Gets the string_item of this TypeHolderExample. # noqa: E501 - - :return: The string_item of this TypeHolderExample. # noqa: E501 - :rtype: str + Returns: + (str): The string_item of this TypeHolderExample. # noqa: E501 """ - return self._string_item + return self.__get_item('string_item') @string_item.setter - def string_item(self, string_item): # noqa: E501 - """Sets the string_item of this TypeHolderExample. - - - :param string_item: The string_item of this TypeHolderExample. # noqa: E501 - :type: str + def string_item(self, value): + """Sets the string_item of this TypeHolderExample. # noqa: E501 """ - if string_item is None: - raise ApiValueError("Invalid value for `string_item`, must not be `None`") # noqa: E501 - check_allowed_values( - self.allowed_values, - ('string_item',), - string_item, - self.validations - ) - - self._string_item = ( - string_item - ) + return self.__set_item('string_item', value) @property def number_item(self): """Gets the number_item of this TypeHolderExample. # noqa: E501 - - :return: The number_item of this TypeHolderExample. # noqa: E501 - :rtype: float + Returns: + (float): The number_item of this TypeHolderExample. # noqa: E501 """ - return self._number_item + return self.__get_item('number_item') @number_item.setter - def number_item(self, number_item): # noqa: E501 - """Sets the number_item of this TypeHolderExample. - - - :param number_item: The number_item of this TypeHolderExample. # noqa: E501 - :type: float + def number_item(self, value): + """Sets the number_item of this TypeHolderExample. # noqa: E501 """ - if number_item is None: - raise ApiValueError("Invalid value for `number_item`, must not be `None`") # noqa: E501 - check_allowed_values( - self.allowed_values, - ('number_item',), - number_item, - self.validations - ) - - self._number_item = ( - number_item - ) + return self.__set_item('number_item', value) @property def integer_item(self): """Gets the integer_item of this TypeHolderExample. # noqa: E501 - - :return: The integer_item of this TypeHolderExample. # noqa: E501 - :rtype: int + Returns: + (int): The integer_item of this TypeHolderExample. # noqa: E501 """ - return self._integer_item + return self.__get_item('integer_item') @integer_item.setter - def integer_item(self, integer_item): # noqa: E501 - """Sets the integer_item of this TypeHolderExample. - - - :param integer_item: The integer_item of this TypeHolderExample. # noqa: E501 - :type: int + def integer_item(self, value): + """Sets the integer_item of this TypeHolderExample. # noqa: E501 """ - if integer_item is None: - raise ApiValueError("Invalid value for `integer_item`, must not be `None`") # noqa: E501 - check_allowed_values( - self.allowed_values, - ('integer_item',), - integer_item, - self.validations - ) - - self._integer_item = ( - integer_item - ) + return self.__set_item('integer_item', value) @property def bool_item(self): """Gets the bool_item of this TypeHolderExample. # noqa: E501 - - :return: The bool_item of this TypeHolderExample. # noqa: E501 - :rtype: bool + Returns: + (bool): The bool_item of this TypeHolderExample. # noqa: E501 """ - return self._bool_item + return self.__get_item('bool_item') @bool_item.setter - def bool_item(self, bool_item): # noqa: E501 - """Sets the bool_item of this TypeHolderExample. - - - :param bool_item: The bool_item of this TypeHolderExample. # noqa: E501 - :type: bool + def bool_item(self, value): + """Sets the bool_item of this TypeHolderExample. # noqa: E501 """ - if bool_item is None: - raise ApiValueError("Invalid value for `bool_item`, must not be `None`") # noqa: E501 - - self._bool_item = ( - bool_item - ) + return self.__set_item('bool_item', value) @property def array_item(self): """Gets the array_item of this TypeHolderExample. # noqa: E501 - - :return: The array_item of this TypeHolderExample. # noqa: E501 - :rtype: list[int] + Returns: + ([int]): The array_item of this TypeHolderExample. # noqa: E501 """ - return self._array_item + return self.__get_item('array_item') @array_item.setter - def array_item(self, array_item): # noqa: E501 - """Sets the array_item of this TypeHolderExample. - - - :param array_item: The array_item of this TypeHolderExample. # noqa: E501 - :type: list[int] + def array_item(self, value): + """Sets the array_item of this TypeHolderExample. # noqa: E501 """ - if array_item is None: - raise ApiValueError("Invalid value for `array_item`, must not be `None`") # noqa: E501 - - self._array_item = ( - array_item - ) + return self.__set_item('array_item', value) def to_dict(self): """Returns the model properties as a dict""" - result = {} - - for attr, _ in six.iteritems(self.openapi_types): - value = getattr(self, attr) - if isinstance(value, list): - result[attr] = list(map( - lambda x: x.to_dict() if hasattr(x, "to_dict") else x, - value - )) - elif hasattr(value, "to_dict"): - result[attr] = value.to_dict() - elif isinstance(value, dict): - result[attr] = dict(map( - lambda item: (item[0], item[1].to_dict()) - if hasattr(item[1], "to_dict") else item, - value.items() - )) - else: - result[attr] = value - - return result + return model_to_dict(self, serialize=False) def to_str(self): """Returns the string representation of the model""" @@ -275,7 +299,22 @@ def __eq__(self, other): if not isinstance(other, TypeHolderExample): return False - return self.__dict__ == other.__dict__ + if not set(self._data_store.keys()) == set(other._data_store.keys()): + return False + for _var_name, this_val in six.iteritems(self._data_store): + that_val = other._data_store[_var_name] + types = set() + types.add(this_val.__class__) + types.add(that_val.__class__) + vals_equal = this_val == that_val + if (not six.PY3 and + len(types) == 2 and unicode in types): # noqa: F821 + vals_equal = ( + this_val.encode('utf-8') == that_val.encode('utf-8') + ) + if not vals_equal: + return False + return True def __ne__(self, other): """Returns true if both objects are not equal""" diff --git a/samples/client/petstore/python-experimental/petstore_api/models/user.py b/samples/client/petstore/python-experimental/petstore_api/models/user.py index 1dcf8d755325..6d4d4539a849 100644 --- a/samples/client/petstore/python-experimental/petstore_api/models/user.py +++ b/samples/client/petstore/python-experimental/petstore_api/models/user.py @@ -15,12 +15,26 @@ import six # noqa: F401 -from petstore_api.exceptions import ApiValueError # noqa: F401 +from petstore_api.exceptions import ( # noqa: F401 + ApiKeyError, + ApiTypeError, + ApiValueError, +) from petstore_api.model_utils import ( # noqa: F401 ModelNormal, ModelSimple, check_allowed_values, - check_validations + check_validations, + date, + datetime, + file_type, + get_simple_class, + int, + model_to_dict, + none_type, + str, + type_error_message, + validate_and_convert_types ) @@ -46,6 +60,8 @@ class User(ModelNormal): 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 = { @@ -63,274 +79,253 @@ class User(ModelNormal): } openapi_types = { - 'id': 'int', - 'username': 'str', - 'first_name': 'str', - 'last_name': 'str', - 'email': 'str', - 'password': 'str', - 'phone': 'str', - 'user_status': 'int' + 'id': (int,), # noqa: E501 + 'username': (str,), # noqa: E501 + 'first_name': (str,), # noqa: E501 + 'last_name': (str,), # noqa: E501 + 'email': (str,), # noqa: E501 + 'password': (str,), # noqa: E501 + 'phone': (str,), # noqa: E501 + 'user_status': (int,), # noqa: E501 } validations = { } - def __init__(self, id=None, username=None, first_name=None, last_name=None, email=None, password=None, phone=None, user_status=None): # noqa: E501 - """User - a model defined in OpenAPI""" # noqa: E501 - - self._id = None - self._username = None - self._first_name = None - self._last_name = None - self._email = None - self._password = None - self._phone = None - self._user_status = None - self.discriminator = None - - if id is not None: - self.id = ( - id - ) - if username is not None: - self.username = ( - username - ) - if first_name is not None: - self.first_name = ( - first_name - ) - if last_name is not None: - self.last_name = ( - last_name + additional_properties_type = None + + discriminator = None + + def __init__(self, _check_type=True, _from_server=False, _path_to_item=(), _configuration=None, **kwargs): # noqa: E501 + """User - 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 + _from_server (bool): True if the data is from the server + False if the data is from the client (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. + id (int): [optional] # noqa: E501 + username (str): [optional] # noqa: E501 + first_name (str): [optional] # noqa: E501 + last_name (str): [optional] # noqa: E501 + email (str): [optional] # noqa: E501 + password (str): [optional] # noqa: E501 + phone (str): [optional] # noqa: E501 + user_status (int): User Status. [optional] # noqa: E501 + """ + self._data_store = {} + self._check_type = _check_type + self._from_server = _from_server + self._path_to_item = _path_to_item + self._configuration = _configuration + + for var_name, var_value in six.iteritems(kwargs): + self.__set_item(var_name, var_value) + + def __set_item(self, name, value): + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + + if name in self.openapi_types: + required_types_mixed = self.openapi_types[name] + elif self.additional_properties_type is None: + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + path_to_item ) - if email is not None: - self.email = ( - email + elif self.additional_properties_type is not None: + required_types_mixed = self.additional_properties_type + + if get_simple_class(name) != str: + error_msg = type_error_message( + var_name=name, + var_value=name, + valid_classes=(str,), + key_type=True ) - if password is not None: - self.password = ( - password + raise ApiTypeError( + error_msg, + path_to_item=path_to_item, + valid_classes=(str,), + key_type=True ) - if phone is not None: - self.phone = ( - phone + + if self._check_type: + value = validate_and_convert_types( + value, required_types_mixed, path_to_item, self._from_server, + self._check_type, configuration=self._configuration) + if (name,) in self.allowed_values: + check_allowed_values( + self.allowed_values, + (name,), + value ) - if user_status is not None: - self.user_status = ( - user_status + if (name,) in self.validations: + check_validations( + self.validations, + (name,), + value ) + self._data_store[name] = value + + def __get_item(self, name): + if name in self._data_store: + return self._data_store[name] + + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + [name] + ) + + def __setitem__(self, name, value): + """this allows us to set values with instance[field_name] = val""" + self.__set_item(name, value) + + def __getitem__(self, name): + """this allows us to get a value with val = instance[field_name]""" + return self.__get_item(name) @property def id(self): """Gets the id of this User. # noqa: E501 - - :return: The id of this User. # noqa: E501 - :rtype: int + Returns: + (int): The id of this User. # noqa: E501 """ - return self._id + return self.__get_item('id') @id.setter - def id(self, id): # noqa: E501 - """Sets the id of this User. - - - :param id: The id of this User. # noqa: E501 - :type: int + def id(self, value): + """Sets the id of this User. # noqa: E501 """ - - self._id = ( - id - ) + return self.__set_item('id', value) @property def username(self): """Gets the username of this User. # noqa: E501 - - :return: The username of this User. # noqa: E501 - :rtype: str + Returns: + (str): The username of this User. # noqa: E501 """ - return self._username + return self.__get_item('username') @username.setter - def username(self, username): # noqa: E501 - """Sets the username of this User. - - - :param username: The username of this User. # noqa: E501 - :type: str + def username(self, value): + """Sets the username of this User. # noqa: E501 """ - - self._username = ( - username - ) + return self.__set_item('username', value) @property def first_name(self): """Gets the first_name of this User. # noqa: E501 - - :return: The first_name of this User. # noqa: E501 - :rtype: str + Returns: + (str): The first_name of this User. # noqa: E501 """ - return self._first_name + return self.__get_item('first_name') @first_name.setter - def first_name(self, first_name): # noqa: E501 - """Sets the first_name of this User. - - - :param first_name: The first_name of this User. # noqa: E501 - :type: str + def first_name(self, value): + """Sets the first_name of this User. # noqa: E501 """ - - self._first_name = ( - first_name - ) + return self.__set_item('first_name', value) @property def last_name(self): """Gets the last_name of this User. # noqa: E501 - - :return: The last_name of this User. # noqa: E501 - :rtype: str + Returns: + (str): The last_name of this User. # noqa: E501 """ - return self._last_name + return self.__get_item('last_name') @last_name.setter - def last_name(self, last_name): # noqa: E501 - """Sets the last_name of this User. - - - :param last_name: The last_name of this User. # noqa: E501 - :type: str + def last_name(self, value): + """Sets the last_name of this User. # noqa: E501 """ - - self._last_name = ( - last_name - ) + return self.__set_item('last_name', value) @property def email(self): """Gets the email of this User. # noqa: E501 - - :return: The email of this User. # noqa: E501 - :rtype: str + Returns: + (str): The email of this User. # noqa: E501 """ - return self._email + return self.__get_item('email') @email.setter - def email(self, email): # noqa: E501 - """Sets the email of this User. - - - :param email: The email of this User. # noqa: E501 - :type: str + def email(self, value): + """Sets the email of this User. # noqa: E501 """ - - self._email = ( - email - ) + return self.__set_item('email', value) @property def password(self): """Gets the password of this User. # noqa: E501 - - :return: The password of this User. # noqa: E501 - :rtype: str + Returns: + (str): The password of this User. # noqa: E501 """ - return self._password + return self.__get_item('password') @password.setter - def password(self, password): # noqa: E501 - """Sets the password of this User. - - - :param password: The password of this User. # noqa: E501 - :type: str + def password(self, value): + """Sets the password of this User. # noqa: E501 """ - - self._password = ( - password - ) + return self.__set_item('password', value) @property def phone(self): """Gets the phone of this User. # noqa: E501 - - :return: The phone of this User. # noqa: E501 - :rtype: str + Returns: + (str): The phone of this User. # noqa: E501 """ - return self._phone + return self.__get_item('phone') @phone.setter - def phone(self, phone): # noqa: E501 - """Sets the phone of this User. - - - :param phone: The phone of this User. # noqa: E501 - :type: str + def phone(self, value): + """Sets the phone of this User. # noqa: E501 """ - - self._phone = ( - phone - ) + return self.__set_item('phone', value) @property def user_status(self): """Gets the user_status of this User. # noqa: E501 - User Status # noqa: E501 - :return: The user_status of this User. # noqa: E501 - :rtype: int + Returns: + (int): The user_status of this User. # noqa: E501 """ - return self._user_status + return self.__get_item('user_status') @user_status.setter - def user_status(self, user_status): # noqa: E501 - """Sets the user_status of this User. - + def user_status(self, value): + """Sets the user_status of this User. # noqa: E501 User Status # noqa: E501 - - :param user_status: The user_status of this User. # noqa: E501 - :type: int """ - - self._user_status = ( - user_status - ) + return self.__set_item('user_status', value) def to_dict(self): """Returns the model properties as a dict""" - result = {} - - for attr, _ in six.iteritems(self.openapi_types): - value = getattr(self, attr) - if isinstance(value, list): - result[attr] = list(map( - lambda x: x.to_dict() if hasattr(x, "to_dict") else x, - value - )) - elif hasattr(value, "to_dict"): - result[attr] = value.to_dict() - elif isinstance(value, dict): - result[attr] = dict(map( - lambda item: (item[0], item[1].to_dict()) - if hasattr(item[1], "to_dict") else item, - value.items() - )) - else: - result[attr] = value - - return result + return model_to_dict(self, serialize=False) def to_str(self): """Returns the string representation of the model""" @@ -345,7 +340,22 @@ def __eq__(self, other): if not isinstance(other, User): return False - return self.__dict__ == other.__dict__ + if not set(self._data_store.keys()) == set(other._data_store.keys()): + return False + for _var_name, this_val in six.iteritems(self._data_store): + that_val = other._data_store[_var_name] + types = set() + types.add(this_val.__class__) + types.add(that_val.__class__) + vals_equal = this_val == that_val + if (not six.PY3 and + len(types) == 2 and unicode in types): # noqa: F821 + vals_equal = ( + this_val.encode('utf-8') == that_val.encode('utf-8') + ) + if not vals_equal: + return False + return True def __ne__(self, other): """Returns true if both objects are not equal""" diff --git a/samples/client/petstore/python-experimental/petstore_api/models/xml_item.py b/samples/client/petstore/python-experimental/petstore_api/models/xml_item.py index 3657b04b1e6b..f7ded778c292 100644 --- a/samples/client/petstore/python-experimental/petstore_api/models/xml_item.py +++ b/samples/client/petstore/python-experimental/petstore_api/models/xml_item.py @@ -15,12 +15,26 @@ import six # noqa: F401 -from petstore_api.exceptions import ApiValueError # noqa: F401 +from petstore_api.exceptions import ( # noqa: F401 + ApiKeyError, + ApiTypeError, + ApiValueError, +) from petstore_api.model_utils import ( # noqa: F401 ModelNormal, ModelSimple, check_allowed_values, - check_validations + check_validations, + date, + datetime, + file_type, + get_simple_class, + int, + model_to_dict, + none_type, + str, + type_error_message, + validate_and_convert_types ) @@ -46,6 +60,8 @@ class XmlItem(ModelNormal): 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 = { @@ -84,881 +100,608 @@ class XmlItem(ModelNormal): } openapi_types = { - 'attribute_string': 'str', - 'attribute_number': 'float', - 'attribute_integer': 'int', - 'attribute_boolean': 'bool', - 'wrapped_array': 'list[int]', - 'name_string': 'str', - 'name_number': 'float', - 'name_integer': 'int', - 'name_boolean': 'bool', - 'name_array': 'list[int]', - 'name_wrapped_array': 'list[int]', - 'prefix_string': 'str', - 'prefix_number': 'float', - 'prefix_integer': 'int', - 'prefix_boolean': 'bool', - 'prefix_array': 'list[int]', - 'prefix_wrapped_array': 'list[int]', - 'namespace_string': 'str', - 'namespace_number': 'float', - 'namespace_integer': 'int', - 'namespace_boolean': 'bool', - 'namespace_array': 'list[int]', - 'namespace_wrapped_array': 'list[int]', - 'prefix_ns_string': 'str', - 'prefix_ns_number': 'float', - 'prefix_ns_integer': 'int', - 'prefix_ns_boolean': 'bool', - 'prefix_ns_array': 'list[int]', - 'prefix_ns_wrapped_array': 'list[int]' + 'attribute_string': (str,), # noqa: E501 + 'attribute_number': (float,), # noqa: E501 + 'attribute_integer': (int,), # noqa: E501 + 'attribute_boolean': (bool,), # noqa: E501 + 'wrapped_array': ([int],), # noqa: E501 + 'name_string': (str,), # noqa: E501 + 'name_number': (float,), # noqa: E501 + 'name_integer': (int,), # noqa: E501 + 'name_boolean': (bool,), # noqa: E501 + 'name_array': ([int],), # noqa: E501 + 'name_wrapped_array': ([int],), # noqa: E501 + 'prefix_string': (str,), # noqa: E501 + 'prefix_number': (float,), # noqa: E501 + 'prefix_integer': (int,), # noqa: E501 + 'prefix_boolean': (bool,), # noqa: E501 + 'prefix_array': ([int],), # noqa: E501 + 'prefix_wrapped_array': ([int],), # noqa: E501 + 'namespace_string': (str,), # noqa: E501 + 'namespace_number': (float,), # noqa: E501 + 'namespace_integer': (int,), # noqa: E501 + 'namespace_boolean': (bool,), # noqa: E501 + 'namespace_array': ([int],), # noqa: E501 + 'namespace_wrapped_array': ([int],), # noqa: E501 + 'prefix_ns_string': (str,), # noqa: E501 + 'prefix_ns_number': (float,), # noqa: E501 + 'prefix_ns_integer': (int,), # noqa: E501 + 'prefix_ns_boolean': (bool,), # noqa: E501 + 'prefix_ns_array': ([int],), # noqa: E501 + 'prefix_ns_wrapped_array': ([int],), # noqa: E501 } validations = { } - def __init__(self, attribute_string=None, attribute_number=None, attribute_integer=None, attribute_boolean=None, wrapped_array=None, name_string=None, name_number=None, name_integer=None, name_boolean=None, name_array=None, name_wrapped_array=None, prefix_string=None, prefix_number=None, prefix_integer=None, prefix_boolean=None, prefix_array=None, prefix_wrapped_array=None, namespace_string=None, namespace_number=None, namespace_integer=None, namespace_boolean=None, namespace_array=None, namespace_wrapped_array=None, prefix_ns_string=None, prefix_ns_number=None, prefix_ns_integer=None, prefix_ns_boolean=None, prefix_ns_array=None, prefix_ns_wrapped_array=None): # noqa: E501 - """XmlItem - a model defined in OpenAPI""" # noqa: E501 - - self._attribute_string = None - self._attribute_number = None - self._attribute_integer = None - self._attribute_boolean = None - self._wrapped_array = None - self._name_string = None - self._name_number = None - self._name_integer = None - self._name_boolean = None - self._name_array = None - self._name_wrapped_array = None - self._prefix_string = None - self._prefix_number = None - self._prefix_integer = None - self._prefix_boolean = None - self._prefix_array = None - self._prefix_wrapped_array = None - self._namespace_string = None - self._namespace_number = None - self._namespace_integer = None - self._namespace_boolean = None - self._namespace_array = None - self._namespace_wrapped_array = None - self._prefix_ns_string = None - self._prefix_ns_number = None - self._prefix_ns_integer = None - self._prefix_ns_boolean = None - self._prefix_ns_array = None - self._prefix_ns_wrapped_array = None - self.discriminator = None - - if attribute_string is not None: - self.attribute_string = ( - attribute_string - ) - if attribute_number is not None: - self.attribute_number = ( - attribute_number - ) - if attribute_integer is not None: - self.attribute_integer = ( - attribute_integer - ) - if attribute_boolean is not None: - self.attribute_boolean = ( - attribute_boolean - ) - if wrapped_array is not None: - self.wrapped_array = ( - wrapped_array - ) - if name_string is not None: - self.name_string = ( - name_string - ) - if name_number is not None: - self.name_number = ( - name_number - ) - if name_integer is not None: - self.name_integer = ( - name_integer - ) - if name_boolean is not None: - self.name_boolean = ( - name_boolean - ) - if name_array is not None: - self.name_array = ( - name_array - ) - if name_wrapped_array is not None: - self.name_wrapped_array = ( - name_wrapped_array - ) - if prefix_string is not None: - self.prefix_string = ( - prefix_string - ) - if prefix_number is not None: - self.prefix_number = ( - prefix_number - ) - if prefix_integer is not None: - self.prefix_integer = ( - prefix_integer - ) - if prefix_boolean is not None: - self.prefix_boolean = ( - prefix_boolean - ) - if prefix_array is not None: - self.prefix_array = ( - prefix_array - ) - if prefix_wrapped_array is not None: - self.prefix_wrapped_array = ( - prefix_wrapped_array - ) - if namespace_string is not None: - self.namespace_string = ( - namespace_string - ) - if namespace_number is not None: - self.namespace_number = ( - namespace_number - ) - if namespace_integer is not None: - self.namespace_integer = ( - namespace_integer - ) - if namespace_boolean is not None: - self.namespace_boolean = ( - namespace_boolean - ) - if namespace_array is not None: - self.namespace_array = ( - namespace_array + additional_properties_type = None + + discriminator = None + + def __init__(self, _check_type=True, _from_server=False, _path_to_item=(), _configuration=None, **kwargs): # noqa: E501 + """XmlItem - 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 + _from_server (bool): True if the data is from the server + False if the data is from the client (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. + attribute_string (str): [optional] # noqa: E501 + attribute_number (float): [optional] # noqa: E501 + attribute_integer (int): [optional] # noqa: E501 + attribute_boolean (bool): [optional] # noqa: E501 + wrapped_array ([int]): [optional] # noqa: E501 + name_string (str): [optional] # noqa: E501 + name_number (float): [optional] # noqa: E501 + name_integer (int): [optional] # noqa: E501 + name_boolean (bool): [optional] # noqa: E501 + name_array ([int]): [optional] # noqa: E501 + name_wrapped_array ([int]): [optional] # noqa: E501 + prefix_string (str): [optional] # noqa: E501 + prefix_number (float): [optional] # noqa: E501 + prefix_integer (int): [optional] # noqa: E501 + prefix_boolean (bool): [optional] # noqa: E501 + prefix_array ([int]): [optional] # noqa: E501 + prefix_wrapped_array ([int]): [optional] # noqa: E501 + namespace_string (str): [optional] # noqa: E501 + namespace_number (float): [optional] # noqa: E501 + namespace_integer (int): [optional] # noqa: E501 + namespace_boolean (bool): [optional] # noqa: E501 + namespace_array ([int]): [optional] # noqa: E501 + namespace_wrapped_array ([int]): [optional] # noqa: E501 + prefix_ns_string (str): [optional] # noqa: E501 + prefix_ns_number (float): [optional] # noqa: E501 + prefix_ns_integer (int): [optional] # noqa: E501 + prefix_ns_boolean (bool): [optional] # noqa: E501 + prefix_ns_array ([int]): [optional] # noqa: E501 + prefix_ns_wrapped_array ([int]): [optional] # noqa: E501 + """ + self._data_store = {} + self._check_type = _check_type + self._from_server = _from_server + self._path_to_item = _path_to_item + self._configuration = _configuration + + for var_name, var_value in six.iteritems(kwargs): + self.__set_item(var_name, var_value) + + def __set_item(self, name, value): + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + + if name in self.openapi_types: + required_types_mixed = self.openapi_types[name] + elif self.additional_properties_type is None: + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + path_to_item ) - if namespace_wrapped_array is not None: - self.namespace_wrapped_array = ( - namespace_wrapped_array + elif self.additional_properties_type is not None: + required_types_mixed = self.additional_properties_type + + if get_simple_class(name) != str: + error_msg = type_error_message( + var_name=name, + var_value=name, + valid_classes=(str,), + key_type=True ) - if prefix_ns_string is not None: - self.prefix_ns_string = ( - prefix_ns_string + raise ApiTypeError( + error_msg, + path_to_item=path_to_item, + valid_classes=(str,), + key_type=True ) - if prefix_ns_number is not None: - self.prefix_ns_number = ( - prefix_ns_number - ) - if prefix_ns_integer is not None: - self.prefix_ns_integer = ( - prefix_ns_integer - ) - if prefix_ns_boolean is not None: - self.prefix_ns_boolean = ( - prefix_ns_boolean - ) - if prefix_ns_array is not None: - self.prefix_ns_array = ( - prefix_ns_array + + if self._check_type: + value = validate_and_convert_types( + value, required_types_mixed, path_to_item, self._from_server, + self._check_type, configuration=self._configuration) + if (name,) in self.allowed_values: + check_allowed_values( + self.allowed_values, + (name,), + value ) - if prefix_ns_wrapped_array is not None: - self.prefix_ns_wrapped_array = ( - prefix_ns_wrapped_array + if (name,) in self.validations: + check_validations( + self.validations, + (name,), + value ) + self._data_store[name] = value + + def __get_item(self, name): + if name in self._data_store: + return self._data_store[name] + + path_to_item = [] + if self._path_to_item: + path_to_item.extend(self._path_to_item) + path_to_item.append(name) + raise ApiKeyError( + "{0} has no key '{1}'".format(type(self).__name__, name), + [name] + ) + + def __setitem__(self, name, value): + """this allows us to set values with instance[field_name] = val""" + self.__set_item(name, value) + + def __getitem__(self, name): + """this allows us to get a value with val = instance[field_name]""" + return self.__get_item(name) @property def attribute_string(self): """Gets the attribute_string of this XmlItem. # noqa: E501 - - :return: The attribute_string of this XmlItem. # noqa: E501 - :rtype: str + Returns: + (str): The attribute_string of this XmlItem. # noqa: E501 """ - return self._attribute_string + return self.__get_item('attribute_string') @attribute_string.setter - def attribute_string(self, attribute_string): # noqa: E501 - """Sets the attribute_string of this XmlItem. - - - :param attribute_string: The attribute_string of this XmlItem. # noqa: E501 - :type: str + def attribute_string(self, value): + """Sets the attribute_string of this XmlItem. # noqa: E501 """ - - self._attribute_string = ( - attribute_string - ) + return self.__set_item('attribute_string', value) @property def attribute_number(self): """Gets the attribute_number of this XmlItem. # noqa: E501 - - :return: The attribute_number of this XmlItem. # noqa: E501 - :rtype: float + Returns: + (float): The attribute_number of this XmlItem. # noqa: E501 """ - return self._attribute_number + return self.__get_item('attribute_number') @attribute_number.setter - def attribute_number(self, attribute_number): # noqa: E501 - """Sets the attribute_number of this XmlItem. - - - :param attribute_number: The attribute_number of this XmlItem. # noqa: E501 - :type: float + def attribute_number(self, value): + """Sets the attribute_number of this XmlItem. # noqa: E501 """ - - self._attribute_number = ( - attribute_number - ) + return self.__set_item('attribute_number', value) @property def attribute_integer(self): """Gets the attribute_integer of this XmlItem. # noqa: E501 - - :return: The attribute_integer of this XmlItem. # noqa: E501 - :rtype: int + Returns: + (int): The attribute_integer of this XmlItem. # noqa: E501 """ - return self._attribute_integer + return self.__get_item('attribute_integer') @attribute_integer.setter - def attribute_integer(self, attribute_integer): # noqa: E501 - """Sets the attribute_integer of this XmlItem. - - - :param attribute_integer: The attribute_integer of this XmlItem. # noqa: E501 - :type: int + def attribute_integer(self, value): + """Sets the attribute_integer of this XmlItem. # noqa: E501 """ - - self._attribute_integer = ( - attribute_integer - ) + return self.__set_item('attribute_integer', value) @property def attribute_boolean(self): """Gets the attribute_boolean of this XmlItem. # noqa: E501 - - :return: The attribute_boolean of this XmlItem. # noqa: E501 - :rtype: bool + Returns: + (bool): The attribute_boolean of this XmlItem. # noqa: E501 """ - return self._attribute_boolean + return self.__get_item('attribute_boolean') @attribute_boolean.setter - def attribute_boolean(self, attribute_boolean): # noqa: E501 - """Sets the attribute_boolean of this XmlItem. - - - :param attribute_boolean: The attribute_boolean of this XmlItem. # noqa: E501 - :type: bool + def attribute_boolean(self, value): + """Sets the attribute_boolean of this XmlItem. # noqa: E501 """ - - self._attribute_boolean = ( - attribute_boolean - ) + return self.__set_item('attribute_boolean', value) @property def wrapped_array(self): """Gets the wrapped_array of this XmlItem. # noqa: E501 - - :return: The wrapped_array of this XmlItem. # noqa: E501 - :rtype: list[int] + Returns: + ([int]): The wrapped_array of this XmlItem. # noqa: E501 """ - return self._wrapped_array + return self.__get_item('wrapped_array') @wrapped_array.setter - def wrapped_array(self, wrapped_array): # noqa: E501 - """Sets the wrapped_array of this XmlItem. - - - :param wrapped_array: The wrapped_array of this XmlItem. # noqa: E501 - :type: list[int] + def wrapped_array(self, value): + """Sets the wrapped_array of this XmlItem. # noqa: E501 """ - - self._wrapped_array = ( - wrapped_array - ) + return self.__set_item('wrapped_array', value) @property def name_string(self): """Gets the name_string of this XmlItem. # noqa: E501 - - :return: The name_string of this XmlItem. # noqa: E501 - :rtype: str + Returns: + (str): The name_string of this XmlItem. # noqa: E501 """ - return self._name_string + return self.__get_item('name_string') @name_string.setter - def name_string(self, name_string): # noqa: E501 - """Sets the name_string of this XmlItem. - - - :param name_string: The name_string of this XmlItem. # noqa: E501 - :type: str + def name_string(self, value): + """Sets the name_string of this XmlItem. # noqa: E501 """ - - self._name_string = ( - name_string - ) + return self.__set_item('name_string', value) @property def name_number(self): """Gets the name_number of this XmlItem. # noqa: E501 - - :return: The name_number of this XmlItem. # noqa: E501 - :rtype: float + Returns: + (float): The name_number of this XmlItem. # noqa: E501 """ - return self._name_number + return self.__get_item('name_number') @name_number.setter - def name_number(self, name_number): # noqa: E501 - """Sets the name_number of this XmlItem. - - - :param name_number: The name_number of this XmlItem. # noqa: E501 - :type: float + def name_number(self, value): + """Sets the name_number of this XmlItem. # noqa: E501 """ - - self._name_number = ( - name_number - ) + return self.__set_item('name_number', value) @property def name_integer(self): """Gets the name_integer of this XmlItem. # noqa: E501 - - :return: The name_integer of this XmlItem. # noqa: E501 - :rtype: int + Returns: + (int): The name_integer of this XmlItem. # noqa: E501 """ - return self._name_integer + return self.__get_item('name_integer') @name_integer.setter - def name_integer(self, name_integer): # noqa: E501 - """Sets the name_integer of this XmlItem. - - - :param name_integer: The name_integer of this XmlItem. # noqa: E501 - :type: int + def name_integer(self, value): + """Sets the name_integer of this XmlItem. # noqa: E501 """ - - self._name_integer = ( - name_integer - ) + return self.__set_item('name_integer', value) @property def name_boolean(self): """Gets the name_boolean of this XmlItem. # noqa: E501 - - :return: The name_boolean of this XmlItem. # noqa: E501 - :rtype: bool + Returns: + (bool): The name_boolean of this XmlItem. # noqa: E501 """ - return self._name_boolean + return self.__get_item('name_boolean') @name_boolean.setter - def name_boolean(self, name_boolean): # noqa: E501 - """Sets the name_boolean of this XmlItem. - - - :param name_boolean: The name_boolean of this XmlItem. # noqa: E501 - :type: bool + def name_boolean(self, value): + """Sets the name_boolean of this XmlItem. # noqa: E501 """ - - self._name_boolean = ( - name_boolean - ) + return self.__set_item('name_boolean', value) @property def name_array(self): """Gets the name_array of this XmlItem. # noqa: E501 - - :return: The name_array of this XmlItem. # noqa: E501 - :rtype: list[int] + Returns: + ([int]): The name_array of this XmlItem. # noqa: E501 """ - return self._name_array + return self.__get_item('name_array') @name_array.setter - def name_array(self, name_array): # noqa: E501 - """Sets the name_array of this XmlItem. - - - :param name_array: The name_array of this XmlItem. # noqa: E501 - :type: list[int] + def name_array(self, value): + """Sets the name_array of this XmlItem. # noqa: E501 """ - - self._name_array = ( - name_array - ) + return self.__set_item('name_array', value) @property def name_wrapped_array(self): """Gets the name_wrapped_array of this XmlItem. # noqa: E501 - - :return: The name_wrapped_array of this XmlItem. # noqa: E501 - :rtype: list[int] + Returns: + ([int]): The name_wrapped_array of this XmlItem. # noqa: E501 """ - return self._name_wrapped_array + return self.__get_item('name_wrapped_array') @name_wrapped_array.setter - def name_wrapped_array(self, name_wrapped_array): # noqa: E501 - """Sets the name_wrapped_array of this XmlItem. - - - :param name_wrapped_array: The name_wrapped_array of this XmlItem. # noqa: E501 - :type: list[int] + def name_wrapped_array(self, value): + """Sets the name_wrapped_array of this XmlItem. # noqa: E501 """ - - self._name_wrapped_array = ( - name_wrapped_array - ) + return self.__set_item('name_wrapped_array', value) @property def prefix_string(self): """Gets the prefix_string of this XmlItem. # noqa: E501 - - :return: The prefix_string of this XmlItem. # noqa: E501 - :rtype: str + Returns: + (str): The prefix_string of this XmlItem. # noqa: E501 """ - return self._prefix_string + return self.__get_item('prefix_string') @prefix_string.setter - def prefix_string(self, prefix_string): # noqa: E501 - """Sets the prefix_string of this XmlItem. - - - :param prefix_string: The prefix_string of this XmlItem. # noqa: E501 - :type: str + def prefix_string(self, value): + """Sets the prefix_string of this XmlItem. # noqa: E501 """ - - self._prefix_string = ( - prefix_string - ) + return self.__set_item('prefix_string', value) @property def prefix_number(self): """Gets the prefix_number of this XmlItem. # noqa: E501 - - :return: The prefix_number of this XmlItem. # noqa: E501 - :rtype: float + Returns: + (float): The prefix_number of this XmlItem. # noqa: E501 """ - return self._prefix_number + return self.__get_item('prefix_number') @prefix_number.setter - def prefix_number(self, prefix_number): # noqa: E501 - """Sets the prefix_number of this XmlItem. - - - :param prefix_number: The prefix_number of this XmlItem. # noqa: E501 - :type: float + def prefix_number(self, value): + """Sets the prefix_number of this XmlItem. # noqa: E501 """ - - self._prefix_number = ( - prefix_number - ) + return self.__set_item('prefix_number', value) @property def prefix_integer(self): """Gets the prefix_integer of this XmlItem. # noqa: E501 - - :return: The prefix_integer of this XmlItem. # noqa: E501 - :rtype: int + Returns: + (int): The prefix_integer of this XmlItem. # noqa: E501 """ - return self._prefix_integer + return self.__get_item('prefix_integer') @prefix_integer.setter - def prefix_integer(self, prefix_integer): # noqa: E501 - """Sets the prefix_integer of this XmlItem. - - - :param prefix_integer: The prefix_integer of this XmlItem. # noqa: E501 - :type: int + def prefix_integer(self, value): + """Sets the prefix_integer of this XmlItem. # noqa: E501 """ - - self._prefix_integer = ( - prefix_integer - ) + return self.__set_item('prefix_integer', value) @property def prefix_boolean(self): """Gets the prefix_boolean of this XmlItem. # noqa: E501 - - :return: The prefix_boolean of this XmlItem. # noqa: E501 - :rtype: bool + Returns: + (bool): The prefix_boolean of this XmlItem. # noqa: E501 """ - return self._prefix_boolean + return self.__get_item('prefix_boolean') @prefix_boolean.setter - def prefix_boolean(self, prefix_boolean): # noqa: E501 - """Sets the prefix_boolean of this XmlItem. - - - :param prefix_boolean: The prefix_boolean of this XmlItem. # noqa: E501 - :type: bool + def prefix_boolean(self, value): + """Sets the prefix_boolean of this XmlItem. # noqa: E501 """ - - self._prefix_boolean = ( - prefix_boolean - ) + return self.__set_item('prefix_boolean', value) @property def prefix_array(self): """Gets the prefix_array of this XmlItem. # noqa: E501 - - :return: The prefix_array of this XmlItem. # noqa: E501 - :rtype: list[int] + Returns: + ([int]): The prefix_array of this XmlItem. # noqa: E501 """ - return self._prefix_array + return self.__get_item('prefix_array') @prefix_array.setter - def prefix_array(self, prefix_array): # noqa: E501 - """Sets the prefix_array of this XmlItem. - - - :param prefix_array: The prefix_array of this XmlItem. # noqa: E501 - :type: list[int] + def prefix_array(self, value): + """Sets the prefix_array of this XmlItem. # noqa: E501 """ - - self._prefix_array = ( - prefix_array - ) + return self.__set_item('prefix_array', value) @property def prefix_wrapped_array(self): """Gets the prefix_wrapped_array of this XmlItem. # noqa: E501 - - :return: The prefix_wrapped_array of this XmlItem. # noqa: E501 - :rtype: list[int] + Returns: + ([int]): The prefix_wrapped_array of this XmlItem. # noqa: E501 """ - return self._prefix_wrapped_array + return self.__get_item('prefix_wrapped_array') @prefix_wrapped_array.setter - def prefix_wrapped_array(self, prefix_wrapped_array): # noqa: E501 - """Sets the prefix_wrapped_array of this XmlItem. - - - :param prefix_wrapped_array: The prefix_wrapped_array of this XmlItem. # noqa: E501 - :type: list[int] + def prefix_wrapped_array(self, value): + """Sets the prefix_wrapped_array of this XmlItem. # noqa: E501 """ - - self._prefix_wrapped_array = ( - prefix_wrapped_array - ) + return self.__set_item('prefix_wrapped_array', value) @property def namespace_string(self): """Gets the namespace_string of this XmlItem. # noqa: E501 - - :return: The namespace_string of this XmlItem. # noqa: E501 - :rtype: str + Returns: + (str): The namespace_string of this XmlItem. # noqa: E501 """ - return self._namespace_string + return self.__get_item('namespace_string') @namespace_string.setter - def namespace_string(self, namespace_string): # noqa: E501 - """Sets the namespace_string of this XmlItem. - - - :param namespace_string: The namespace_string of this XmlItem. # noqa: E501 - :type: str + def namespace_string(self, value): + """Sets the namespace_string of this XmlItem. # noqa: E501 """ - - self._namespace_string = ( - namespace_string - ) + return self.__set_item('namespace_string', value) @property def namespace_number(self): """Gets the namespace_number of this XmlItem. # noqa: E501 - - :return: The namespace_number of this XmlItem. # noqa: E501 - :rtype: float + Returns: + (float): The namespace_number of this XmlItem. # noqa: E501 """ - return self._namespace_number + return self.__get_item('namespace_number') @namespace_number.setter - def namespace_number(self, namespace_number): # noqa: E501 - """Sets the namespace_number of this XmlItem. - - - :param namespace_number: The namespace_number of this XmlItem. # noqa: E501 - :type: float + def namespace_number(self, value): + """Sets the namespace_number of this XmlItem. # noqa: E501 """ - - self._namespace_number = ( - namespace_number - ) + return self.__set_item('namespace_number', value) @property def namespace_integer(self): """Gets the namespace_integer of this XmlItem. # noqa: E501 - - :return: The namespace_integer of this XmlItem. # noqa: E501 - :rtype: int + Returns: + (int): The namespace_integer of this XmlItem. # noqa: E501 """ - return self._namespace_integer + return self.__get_item('namespace_integer') @namespace_integer.setter - def namespace_integer(self, namespace_integer): # noqa: E501 - """Sets the namespace_integer of this XmlItem. - - - :param namespace_integer: The namespace_integer of this XmlItem. # noqa: E501 - :type: int + def namespace_integer(self, value): + """Sets the namespace_integer of this XmlItem. # noqa: E501 """ - - self._namespace_integer = ( - namespace_integer - ) + return self.__set_item('namespace_integer', value) @property def namespace_boolean(self): """Gets the namespace_boolean of this XmlItem. # noqa: E501 - - :return: The namespace_boolean of this XmlItem. # noqa: E501 - :rtype: bool + Returns: + (bool): The namespace_boolean of this XmlItem. # noqa: E501 """ - return self._namespace_boolean + return self.__get_item('namespace_boolean') @namespace_boolean.setter - def namespace_boolean(self, namespace_boolean): # noqa: E501 - """Sets the namespace_boolean of this XmlItem. - - - :param namespace_boolean: The namespace_boolean of this XmlItem. # noqa: E501 - :type: bool + def namespace_boolean(self, value): + """Sets the namespace_boolean of this XmlItem. # noqa: E501 """ - - self._namespace_boolean = ( - namespace_boolean - ) + return self.__set_item('namespace_boolean', value) @property def namespace_array(self): """Gets the namespace_array of this XmlItem. # noqa: E501 - - :return: The namespace_array of this XmlItem. # noqa: E501 - :rtype: list[int] + Returns: + ([int]): The namespace_array of this XmlItem. # noqa: E501 """ - return self._namespace_array + return self.__get_item('namespace_array') @namespace_array.setter - def namespace_array(self, namespace_array): # noqa: E501 - """Sets the namespace_array of this XmlItem. - - - :param namespace_array: The namespace_array of this XmlItem. # noqa: E501 - :type: list[int] + def namespace_array(self, value): + """Sets the namespace_array of this XmlItem. # noqa: E501 """ - - self._namespace_array = ( - namespace_array - ) + return self.__set_item('namespace_array', value) @property def namespace_wrapped_array(self): """Gets the namespace_wrapped_array of this XmlItem. # noqa: E501 - - :return: The namespace_wrapped_array of this XmlItem. # noqa: E501 - :rtype: list[int] + Returns: + ([int]): The namespace_wrapped_array of this XmlItem. # noqa: E501 """ - return self._namespace_wrapped_array + return self.__get_item('namespace_wrapped_array') @namespace_wrapped_array.setter - def namespace_wrapped_array(self, namespace_wrapped_array): # noqa: E501 - """Sets the namespace_wrapped_array of this XmlItem. - - - :param namespace_wrapped_array: The namespace_wrapped_array of this XmlItem. # noqa: E501 - :type: list[int] + def namespace_wrapped_array(self, value): + """Sets the namespace_wrapped_array of this XmlItem. # noqa: E501 """ - - self._namespace_wrapped_array = ( - namespace_wrapped_array - ) + return self.__set_item('namespace_wrapped_array', value) @property def prefix_ns_string(self): """Gets the prefix_ns_string of this XmlItem. # noqa: E501 - - :return: The prefix_ns_string of this XmlItem. # noqa: E501 - :rtype: str + Returns: + (str): The prefix_ns_string of this XmlItem. # noqa: E501 """ - return self._prefix_ns_string + return self.__get_item('prefix_ns_string') @prefix_ns_string.setter - def prefix_ns_string(self, prefix_ns_string): # noqa: E501 - """Sets the prefix_ns_string of this XmlItem. - - - :param prefix_ns_string: The prefix_ns_string of this XmlItem. # noqa: E501 - :type: str + def prefix_ns_string(self, value): + """Sets the prefix_ns_string of this XmlItem. # noqa: E501 """ - - self._prefix_ns_string = ( - prefix_ns_string - ) + return self.__set_item('prefix_ns_string', value) @property def prefix_ns_number(self): """Gets the prefix_ns_number of this XmlItem. # noqa: E501 - - :return: The prefix_ns_number of this XmlItem. # noqa: E501 - :rtype: float + Returns: + (float): The prefix_ns_number of this XmlItem. # noqa: E501 """ - return self._prefix_ns_number + return self.__get_item('prefix_ns_number') @prefix_ns_number.setter - def prefix_ns_number(self, prefix_ns_number): # noqa: E501 - """Sets the prefix_ns_number of this XmlItem. - - - :param prefix_ns_number: The prefix_ns_number of this XmlItem. # noqa: E501 - :type: float + def prefix_ns_number(self, value): + """Sets the prefix_ns_number of this XmlItem. # noqa: E501 """ - - self._prefix_ns_number = ( - prefix_ns_number - ) + return self.__set_item('prefix_ns_number', value) @property def prefix_ns_integer(self): """Gets the prefix_ns_integer of this XmlItem. # noqa: E501 - - :return: The prefix_ns_integer of this XmlItem. # noqa: E501 - :rtype: int + Returns: + (int): The prefix_ns_integer of this XmlItem. # noqa: E501 """ - return self._prefix_ns_integer + return self.__get_item('prefix_ns_integer') @prefix_ns_integer.setter - def prefix_ns_integer(self, prefix_ns_integer): # noqa: E501 - """Sets the prefix_ns_integer of this XmlItem. - - - :param prefix_ns_integer: The prefix_ns_integer of this XmlItem. # noqa: E501 - :type: int + def prefix_ns_integer(self, value): + """Sets the prefix_ns_integer of this XmlItem. # noqa: E501 """ - - self._prefix_ns_integer = ( - prefix_ns_integer - ) + return self.__set_item('prefix_ns_integer', value) @property def prefix_ns_boolean(self): """Gets the prefix_ns_boolean of this XmlItem. # noqa: E501 - - :return: The prefix_ns_boolean of this XmlItem. # noqa: E501 - :rtype: bool + Returns: + (bool): The prefix_ns_boolean of this XmlItem. # noqa: E501 """ - return self._prefix_ns_boolean + return self.__get_item('prefix_ns_boolean') @prefix_ns_boolean.setter - def prefix_ns_boolean(self, prefix_ns_boolean): # noqa: E501 - """Sets the prefix_ns_boolean of this XmlItem. - - - :param prefix_ns_boolean: The prefix_ns_boolean of this XmlItem. # noqa: E501 - :type: bool + def prefix_ns_boolean(self, value): + """Sets the prefix_ns_boolean of this XmlItem. # noqa: E501 """ - - self._prefix_ns_boolean = ( - prefix_ns_boolean - ) + return self.__set_item('prefix_ns_boolean', value) @property def prefix_ns_array(self): """Gets the prefix_ns_array of this XmlItem. # noqa: E501 - - :return: The prefix_ns_array of this XmlItem. # noqa: E501 - :rtype: list[int] + Returns: + ([int]): The prefix_ns_array of this XmlItem. # noqa: E501 """ - return self._prefix_ns_array + return self.__get_item('prefix_ns_array') @prefix_ns_array.setter - def prefix_ns_array(self, prefix_ns_array): # noqa: E501 - """Sets the prefix_ns_array of this XmlItem. - - - :param prefix_ns_array: The prefix_ns_array of this XmlItem. # noqa: E501 - :type: list[int] + def prefix_ns_array(self, value): + """Sets the prefix_ns_array of this XmlItem. # noqa: E501 """ - - self._prefix_ns_array = ( - prefix_ns_array - ) + return self.__set_item('prefix_ns_array', value) @property def prefix_ns_wrapped_array(self): """Gets the prefix_ns_wrapped_array of this XmlItem. # noqa: E501 - - :return: The prefix_ns_wrapped_array of this XmlItem. # noqa: E501 - :rtype: list[int] + Returns: + ([int]): The prefix_ns_wrapped_array of this XmlItem. # noqa: E501 """ - return self._prefix_ns_wrapped_array + return self.__get_item('prefix_ns_wrapped_array') @prefix_ns_wrapped_array.setter - def prefix_ns_wrapped_array(self, prefix_ns_wrapped_array): # noqa: E501 - """Sets the prefix_ns_wrapped_array of this XmlItem. - - - :param prefix_ns_wrapped_array: The prefix_ns_wrapped_array of this XmlItem. # noqa: E501 - :type: list[int] + def prefix_ns_wrapped_array(self, value): + """Sets the prefix_ns_wrapped_array of this XmlItem. # noqa: E501 """ - - self._prefix_ns_wrapped_array = ( - prefix_ns_wrapped_array - ) + return self.__set_item('prefix_ns_wrapped_array', value) def to_dict(self): """Returns the model properties as a dict""" - result = {} - - for attr, _ in six.iteritems(self.openapi_types): - value = getattr(self, attr) - if isinstance(value, list): - result[attr] = list(map( - lambda x: x.to_dict() if hasattr(x, "to_dict") else x, - value - )) - elif hasattr(value, "to_dict"): - result[attr] = value.to_dict() - elif isinstance(value, dict): - result[attr] = dict(map( - lambda item: (item[0], item[1].to_dict()) - if hasattr(item[1], "to_dict") else item, - value.items() - )) - else: - result[attr] = value - - return result + return model_to_dict(self, serialize=False) def to_str(self): """Returns the string representation of the model""" @@ -973,7 +716,22 @@ def __eq__(self, other): if not isinstance(other, XmlItem): return False - return self.__dict__ == other.__dict__ + if not set(self._data_store.keys()) == set(other._data_store.keys()): + return False + for _var_name, this_val in six.iteritems(self._data_store): + that_val = other._data_store[_var_name] + types = set() + types.add(this_val.__class__) + types.add(that_val.__class__) + vals_equal = this_val == that_val + if (not six.PY3 and + len(types) == 2 and unicode in types): # noqa: F821 + vals_equal = ( + this_val.encode('utf-8') == that_val.encode('utf-8') + ) + if not vals_equal: + return False + return True def __ne__(self, other): """Returns true if both objects are not equal""" diff --git a/samples/client/petstore/python-experimental/requirements.txt b/samples/client/petstore/python-experimental/requirements.txt index bafdc07532f5..eb358efd5bd3 100644 --- a/samples/client/petstore/python-experimental/requirements.txt +++ b/samples/client/petstore/python-experimental/requirements.txt @@ -1,4 +1,5 @@ certifi >= 14.05.14 +future; python_version<="2.7" six >= 1.10 python_dateutil >= 2.5.3 setuptools >= 21.0.0 diff --git a/samples/client/petstore/python-experimental/setup.py b/samples/client/petstore/python-experimental/setup.py index 1d5e7c2915ef..bb88f06e4e4f 100644 --- a/samples/client/petstore/python-experimental/setup.py +++ b/samples/client/petstore/python-experimental/setup.py @@ -22,6 +22,7 @@ # http://pypi.python.org/pypi/setuptools REQUIRES = ["urllib3 >= 1.15", "six >= 1.10", "certifi", "python-dateutil"] +EXTRAS = {':python_version <= "2.7"': ['future']} setup( name=NAME, @@ -31,6 +32,7 @@ url="", keywords=["OpenAPI", "OpenAPI-Generator", "OpenAPI Petstore"], install_requires=REQUIRES, + extras_require=EXTRAS, packages=find_packages(exclude=["test", "tests"]), include_package_data=True, long_description="""\ diff --git a/samples/client/petstore/python-experimental/test/test_additional_properties_array.py b/samples/client/petstore/python-experimental/test/test_additional_properties_array.py index c4cf43499cfa..6c86292cd4a4 100644 --- a/samples/client/petstore/python-experimental/test/test_additional_properties_array.py +++ b/samples/client/petstore/python-experimental/test/test_additional_properties_array.py @@ -17,6 +17,9 @@ import petstore_api from petstore_api.models.additional_properties_array import AdditionalPropertiesArray # noqa: E501 from petstore_api.rest import ApiException +from petstore_api.exceptions import ApiTypeError + +import datetime class TestAdditionalPropertiesArray(unittest.TestCase): @@ -30,9 +33,20 @@ def tearDown(self): def testAdditionalPropertiesArray(self): """Test AdditionalPropertiesArray""" - # FIXME: construct object with mandatory attributes with example values - # model = petstore_api.models.additional_properties_array.AdditionalPropertiesArray() # noqa: E501 - pass + # can make model without additional properties + model = AdditionalPropertiesArray() + + # can make one with additional properties + some_val = [] + model = AdditionalPropertiesArray(some_key=some_val) + assert model['some_key'] == some_val + some_val = [True, datetime.date(1970,1,1), datetime.datetime(1970,1,1), {}, 3.1, 1, [], 'hello'] + model = AdditionalPropertiesArray(some_key=some_val) + assert model['some_key'] == some_val + + # type checking works on additional properties + with self.assertRaises(ApiTypeError) as exc: + model = AdditionalPropertiesArray(some_key='some string') if __name__ == '__main__': diff --git a/samples/client/petstore/python-experimental/test/test_additional_properties_boolean.py b/samples/client/petstore/python-experimental/test/test_additional_properties_boolean.py index cc3cecc8522f..33bcfb90bb61 100644 --- a/samples/client/petstore/python-experimental/test/test_additional_properties_boolean.py +++ b/samples/client/petstore/python-experimental/test/test_additional_properties_boolean.py @@ -17,6 +17,7 @@ import petstore_api from petstore_api.models.additional_properties_boolean import AdditionalPropertiesBoolean # noqa: E501 from petstore_api.rest import ApiException +from petstore_api.exceptions import ApiTypeError class TestAdditionalPropertiesBoolean(unittest.TestCase): @@ -30,9 +31,16 @@ def tearDown(self): def testAdditionalPropertiesBoolean(self): """Test AdditionalPropertiesBoolean""" - # FIXME: construct object with mandatory attributes with example values - # model = petstore_api.models.additional_properties_boolean.AdditionalPropertiesBoolean() # noqa: E501 - pass + # can make model without additional properties + model = AdditionalPropertiesBoolean() + + # can make one with additional properties + model = AdditionalPropertiesBoolean(some_key=True) + assert model['some_key'] == True + + # type checking works on additional properties + with self.assertRaises(ApiTypeError) as exc: + model = AdditionalPropertiesBoolean(some_key='True') if __name__ == '__main__': diff --git a/samples/client/petstore/python-experimental/test/test_additional_properties_integer.py b/samples/client/petstore/python-experimental/test/test_additional_properties_integer.py index 774c367b2109..0029cb9c84c5 100644 --- a/samples/client/petstore/python-experimental/test/test_additional_properties_integer.py +++ b/samples/client/petstore/python-experimental/test/test_additional_properties_integer.py @@ -17,6 +17,7 @@ import petstore_api from petstore_api.models.additional_properties_integer import AdditionalPropertiesInteger # noqa: E501 from petstore_api.rest import ApiException +from petstore_api.exceptions import ApiTypeError class TestAdditionalPropertiesInteger(unittest.TestCase): @@ -30,9 +31,16 @@ def tearDown(self): def testAdditionalPropertiesInteger(self): """Test AdditionalPropertiesInteger""" - # FIXME: construct object with mandatory attributes with example values - # model = petstore_api.models.additional_properties_integer.AdditionalPropertiesInteger() # noqa: E501 - pass + # can make model without additional properties + model = AdditionalPropertiesInteger() + + # can make one with additional properties + model = AdditionalPropertiesInteger(some_key=3) + assert model['some_key'] == 3 + + # type checking works on additional properties + with self.assertRaises(ApiTypeError) as exc: + model = AdditionalPropertiesInteger(some_key=11.3) if __name__ == '__main__': diff --git a/samples/client/petstore/python-experimental/test/test_additional_properties_number.py b/samples/client/petstore/python-experimental/test/test_additional_properties_number.py index 0d370e781b36..28d0b23377a6 100644 --- a/samples/client/petstore/python-experimental/test/test_additional_properties_number.py +++ b/samples/client/petstore/python-experimental/test/test_additional_properties_number.py @@ -17,6 +17,7 @@ import petstore_api from petstore_api.models.additional_properties_number import AdditionalPropertiesNumber # noqa: E501 from petstore_api.rest import ApiException +from petstore_api.exceptions import ApiTypeError class TestAdditionalPropertiesNumber(unittest.TestCase): @@ -30,10 +31,16 @@ def tearDown(self): def testAdditionalPropertiesNumber(self): """Test AdditionalPropertiesNumber""" - # FIXME: construct object with mandatory attributes with example values - # model = petstore_api.models.additional_properties_number.AdditionalPropertiesNumber() # noqa: E501 - pass + # can make model without additional properties + model = AdditionalPropertiesNumber() + + # can make one with additional properties + model = AdditionalPropertiesNumber(some_key=11.3) + assert model['some_key'] == 11.3 + # type checking works on additional properties + with self.assertRaises(ApiTypeError) as exc: + model = AdditionalPropertiesNumber(some_key=10) if __name__ == '__main__': unittest.main() diff --git a/samples/client/petstore/python-experimental/test/test_additional_properties_object.py b/samples/client/petstore/python-experimental/test/test_additional_properties_object.py index 6e718b28cdef..3d135116736c 100644 --- a/samples/client/petstore/python-experimental/test/test_additional_properties_object.py +++ b/samples/client/petstore/python-experimental/test/test_additional_properties_object.py @@ -17,6 +17,9 @@ import petstore_api from petstore_api.models.additional_properties_object import AdditionalPropertiesObject # noqa: E501 from petstore_api.rest import ApiException +from petstore_api.exceptions import ApiTypeError + +import datetime class TestAdditionalPropertiesObject(unittest.TestCase): @@ -30,9 +33,20 @@ def tearDown(self): def testAdditionalPropertiesObject(self): """Test AdditionalPropertiesObject""" - # FIXME: construct object with mandatory attributes with example values - # model = petstore_api.models.additional_properties_object.AdditionalPropertiesObject() # noqa: E501 - pass + # can make model without additional properties + model = AdditionalPropertiesObject() + + # can make one with additional properties + some_val = {} + model = AdditionalPropertiesObject(some_key=some_val) + assert model['some_key'] == some_val + some_val = {'a': True, 'b': datetime.date(1970,1,1), 'c': datetime.datetime(1970,1,1), 'd': {}, 'e': 3.1, 'f': 1, 'g': [], 'h': 'hello'} + model = AdditionalPropertiesObject(some_key=some_val) + assert model['some_key'] == some_val + + # type checking works on additional properties + with self.assertRaises(ApiTypeError) as exc: + model = AdditionalPropertiesObject(some_key='some string') if __name__ == '__main__': diff --git a/samples/client/petstore/python-experimental/test/test_additional_properties_string.py b/samples/client/petstore/python-experimental/test/test_additional_properties_string.py index a46cb3e256dc..0276334ead53 100644 --- a/samples/client/petstore/python-experimental/test/test_additional_properties_string.py +++ b/samples/client/petstore/python-experimental/test/test_additional_properties_string.py @@ -17,6 +17,7 @@ import petstore_api from petstore_api.models.additional_properties_string import AdditionalPropertiesString # noqa: E501 from petstore_api.rest import ApiException +from petstore_api.exceptions import ApiTypeError class TestAdditionalPropertiesString(unittest.TestCase): @@ -30,9 +31,16 @@ def tearDown(self): def testAdditionalPropertiesString(self): """Test AdditionalPropertiesString""" - # FIXME: construct object with mandatory attributes with example values - # model = petstore_api.models.additional_properties_string.AdditionalPropertiesString() # noqa: E501 - pass + # can make model without additional properties + model = AdditionalPropertiesString() + + # can make one with additional properties + model = AdditionalPropertiesString(some_key='some_val') + assert model['some_key'] == 'some_val' + + # type checking works on additional properties + with self.assertRaises(ApiTypeError) as exc: + model = AdditionalPropertiesString(some_key=True) if __name__ == '__main__': diff --git a/samples/client/petstore/python-experimental/test/test_fake_api.py b/samples/client/petstore/python-experimental/test/test_fake_api.py index e8877b915ec1..0f4e875d197d 100644 --- a/samples/client/petstore/python-experimental/test/test_fake_api.py +++ b/samples/client/petstore/python-experimental/test/test_fake_api.py @@ -46,8 +46,8 @@ def test_fake_outer_enum_serialize(self): """ # verify that the input and output are type OuterEnum endpoint = self.api.fake_outer_enum_serialize - assert endpoint.openapi_types['body'] == 'OuterEnum' - assert endpoint.settings['response_type'] == 'OuterEnum' + assert endpoint.openapi_types['body'] == (petstore_api.OuterEnum,) + assert endpoint.settings['response_type'] == (petstore_api.OuterEnum,) def test_fake_outer_number_serialize(self): """Test case for fake_outer_number_serialize @@ -55,8 +55,8 @@ def test_fake_outer_number_serialize(self): """ # verify that the input and output are the correct type endpoint = self.api.fake_outer_number_serialize - assert endpoint.openapi_types['body'] == 'OuterNumber' - assert endpoint.settings['response_type'] == 'OuterNumber' + assert endpoint.openapi_types['body'] == (petstore_api.OuterNumber,) + assert endpoint.settings['response_type'] == (petstore_api.OuterNumber,) def test_fake_outer_string_serialize(self): """Test case for fake_outer_string_serialize diff --git a/samples/client/petstore/python-experimental/test/test_format_test.py b/samples/client/petstore/python-experimental/test/test_format_test.py index ba20d7f811b8..ed926aa031ea 100644 --- a/samples/client/petstore/python-experimental/test/test_format_test.py +++ b/samples/client/petstore/python-experimental/test/test_format_test.py @@ -10,6 +10,7 @@ from __future__ import absolute_import +import datetime import unittest import petstore_api @@ -24,7 +25,7 @@ def setUp(self): self.required_named_args = dict( number=40.1, byte='what', - date='2019-03-23', + date=datetime.date(2019, 3, 23), password='rainbowtable' ) diff --git a/samples/client/petstore/python-experimental/tests/test_api_client.py b/samples/client/petstore/python-experimental/tests/test_api_client.py index a41dbaba9c9f..ad50f1862014 100644 --- a/samples/client/petstore/python-experimental/tests/test_api_client.py +++ b/samples/client/petstore/python-experimental/tests/test_api_client.py @@ -170,3 +170,9 @@ def test_sanitize_for_serialization(self): data = [pet] result = self.api_client.sanitize_for_serialization(data) self.assertEqual(result, list_of_pet_dict) + + # model with additional proerties + model_dict = {'some_key': True} + model = petstore_api.StringBooleanMap(**model_dict) + result = self.api_client.sanitize_for_serialization(model) + self.assertEqual(result, model_dict) diff --git a/samples/client/petstore/python-experimental/tests/test_deserialization.py b/samples/client/petstore/python-experimental/tests/test_deserialization.py index 10c5ecef4239..9ab64b04bba3 100644 --- a/samples/client/petstore/python-experimental/tests/test_deserialization.py +++ b/samples/client/petstore/python-experimental/tests/test_deserialization.py @@ -15,11 +15,25 @@ import unittest import datetime +import six + import petstore_api +from petstore_api.exceptions import ( + ApiTypeError, + ApiKeyError, + ApiValueError, +) -MockResponse = namedtuple('MockResponse', 'data') +from petstore_api.model_utils import ( + file_type, + int, + str, +) +from petstore_api.rest import RESTResponse + +MockResponse = namedtuple('MockResponse', 'data') class DeserializationTests(unittest.TestCase): @@ -40,7 +54,8 @@ def test_enum_test(self): } response = MockResponse(data=json.dumps(data)) - deserialized = self.deserialize(response, 'dict(str, EnumTest)') + deserialized = self.deserialize(response, + ({str: (petstore_api.EnumTest,)},), True) self.assertTrue(isinstance(deserialized, dict)) self.assertTrue( isinstance(deserialized['enum_test'], petstore_api.EnumTest)) @@ -80,7 +95,8 @@ def test_deserialize_dict_str_pet(self): } response = MockResponse(data=json.dumps(data)) - deserialized = self.deserialize(response, 'dict(str, Pet)') + deserialized = self.deserialize(response, + ({str: (petstore_api.Pet,)},), True) self.assertTrue(isinstance(deserialized, dict)) self.assertTrue(isinstance(deserialized['pet'], petstore_api.Pet)) @@ -88,15 +104,15 @@ def test_deserialize_dict_str_dog(self): """ deserialize dict(str, Dog), use discriminator""" data = { 'dog': { - "id": 0, "className": "Dog", "color": "white", - "bread": "Jack Russel Terrier" + "breed": "Jack Russel Terrier" } } response = MockResponse(data=json.dumps(data)) - deserialized = self.deserialize(response, 'dict(str, Animal)') + deserialized = self.deserialize(response, + ({str: (petstore_api.Animal,)},), True) self.assertTrue(isinstance(deserialized, dict)) self.assertTrue(isinstance(deserialized['dog'], petstore_api.Dog)) @@ -107,7 +123,7 @@ def test_deserialize_dict_str_int(self): } response = MockResponse(data=json.dumps(data)) - deserialized = self.deserialize(response, 'dict(str, int)') + deserialized = self.deserialize(response, ({str: (int,)},), True) self.assertTrue(isinstance(deserialized, dict)) self.assertTrue(isinstance(deserialized['integer'], int)) @@ -116,7 +132,7 @@ def test_deserialize_str(self): data = "test str" response = MockResponse(data=json.dumps(data)) - deserialized = self.deserialize(response, "str") + deserialized = self.deserialize(response, (str,), True) self.assertTrue(isinstance(deserialized, str)) def test_deserialize_date(self): @@ -124,7 +140,7 @@ def test_deserialize_date(self): data = "1997-07-16" response = MockResponse(data=json.dumps(data)) - deserialized = self.deserialize(response, "date") + deserialized = self.deserialize(response, (datetime.date,), True) self.assertTrue(isinstance(deserialized, datetime.date)) def test_deserialize_datetime(self): @@ -132,7 +148,7 @@ def test_deserialize_datetime(self): data = "1997-07-16T19:20:30.45+01:00" response = MockResponse(data=json.dumps(data)) - deserialized = self.deserialize(response, "datetime") + deserialized = self.deserialize(response, (datetime.datetime,), True) self.assertTrue(isinstance(deserialized, datetime.datetime)) def test_deserialize_pet(self): @@ -157,7 +173,7 @@ def test_deserialize_pet(self): } response = MockResponse(data=json.dumps(data)) - deserialized = self.deserialize(response, "Pet") + deserialized = self.deserialize(response, (petstore_api.Pet,), True) self.assertTrue(isinstance(deserialized, petstore_api.Pet)) self.assertEqual(deserialized.id, 0) self.assertEqual(deserialized.name, "doggie") @@ -207,7 +223,8 @@ def test_deserialize_list_of_pet(self): }] response = MockResponse(data=json.dumps(data)) - deserialized = self.deserialize(response, "list[Pet]") + deserialized = self.deserialize(response, + ([petstore_api.Pet],), True) self.assertTrue(isinstance(deserialized, list)) self.assertTrue(isinstance(deserialized[0], petstore_api.Pet)) self.assertEqual(deserialized[0].id, 0) @@ -224,7 +241,8 @@ def test_deserialize_nested_dict(self): } response = MockResponse(data=json.dumps(data)) - deserialized = self.deserialize(response, "dict(str, dict(str, int))") + deserialized = self.deserialize(response, + ({str: ({str: (int,)},)},), True) self.assertTrue(isinstance(deserialized, dict)) self.assertTrue(isinstance(deserialized["foo"], dict)) self.assertTrue(isinstance(deserialized["foo"]["bar"], int)) @@ -234,7 +252,7 @@ def test_deserialize_nested_list(self): data = [["foo"]] response = MockResponse(data=json.dumps(data)) - deserialized = self.deserialize(response, "list[list[str]]") + deserialized = self.deserialize(response, ([[str]],), True) self.assertTrue(isinstance(deserialized, list)) self.assertTrue(isinstance(deserialized[0], list)) self.assertTrue(isinstance(deserialized[0][0], str)) @@ -243,16 +261,22 @@ def test_deserialize_none(self): """ deserialize None """ response = MockResponse(data=json.dumps(None)) - deserialized = self.deserialize(response, "datetime") - self.assertIsNone(deserialized) + error_msg = ( + "Invalid type for variable 'received_data'. Required value type is " + "datetime and passed type was NoneType at ['received_data']" + ) + with self.assertRaises(ApiTypeError) as exc: + deserialized = self.deserialize(response, (datetime.datetime,), True) + self.assertEqual(str(exc.exception), error_msg) def test_deserialize_OuterEnum(self): """ deserialize OuterEnum """ # make sure that an exception is thrown on an invalid value - with self.assertRaises(petstore_api.ApiValueError): + with self.assertRaises(ApiValueError): self.deserialize( MockResponse(data=json.dumps("test str")), - "OuterEnum" + (petstore_api.OuterEnum,), + True ) # valid value works @@ -260,29 +284,100 @@ def test_deserialize_OuterEnum(self): petstore_api.OuterEnum.allowed_values[('value',)]["PLACED"] ) response = MockResponse(data=json.dumps(placed_str)) - outer_enum = self.deserialize(response, "OuterEnum") + outer_enum = self.deserialize(response, + (petstore_api.OuterEnum,), True) self.assertTrue(isinstance(outer_enum, petstore_api.OuterEnum)) self.assertTrue(outer_enum.value == placed_str) def test_deserialize_OuterNumber(self): """ deserialize OuterNumber """ # make sure that an exception is thrown on an invalid type value - with self.assertRaises(petstore_api.ApiValueError): + with self.assertRaises(ApiTypeError): deserialized = self.deserialize( MockResponse(data=json.dumps("test str")), - "OuterNumber" + (petstore_api.OuterNumber,), + True ) # make sure that an exception is thrown on an invalid value - with self.assertRaises(petstore_api.ApiValueError): + with self.assertRaises(ApiValueError): deserialized = self.deserialize( - MockResponse(data=json.dumps(21)), - "OuterNumber" + MockResponse(data=json.dumps(21.0)), + (petstore_api.OuterNumber,), + True ) # valid value works - number_val = 11 + number_val = 11.0 response = MockResponse(data=json.dumps(number_val)) - outer_number = self.deserialize(response, "OuterNumber") + outer_number = self.deserialize(response, + (petstore_api.OuterNumber,), True) self.assertTrue(isinstance(outer_number, petstore_api.OuterNumber)) - self.assertTrue(outer_number.value == number_val) \ No newline at end of file + self.assertTrue(outer_number.value == number_val) + + def test_deserialize_file(self): + """Ensures that file deserialization works""" + response_types_mixed = (file_type,) + + # sample from http://www.jtricks.com/download-text + HTTPResponse = namedtuple( + 'urllib3_response_HTTPResponse', + ['status', 'reason', 'data', 'getheaders', 'getheader'] + ) + headers = {'Content-Disposition': 'attachment; filename=content.txt'} + def get_headers(): + return headers + def get_header(name, default=None): + return headers.get(name, default) + file_data = ( + "You are reading text file that was supposed to be downloaded\r\n" + "to your hard disk. If your browser offered to save you the file," + "\r\nthen it handled the Content-Disposition header correctly." + ) + http_response = HTTPResponse( + status=200, + reason='OK', + data=file_data, + getheaders=get_headers, + getheader=get_header + ) + # response which is deserialized to a file + mock_response = RESTResponse(http_response) + file_path = None + try: + file_object = self.deserialize( + mock_response, response_types_mixed, True) + self.assertTrue(isinstance(file_object, file_type)) + file_path = file_object.name + self.assertFalse(file_object.closed) + file_object.close() + if six.PY3: + file_data = file_data.encode('utf-8') + with open(file_path, 'rb') as other_file_object: + self.assertEqual(other_file_object.read(), file_data) + finally: + os.unlink(file_path) + + def test_deserialize_string_boolean_map(self): + """ + Ensures that string boolean (additional properties) + deserialization works + """ + # make sure that an exception is thrown on an invalid type + with self.assertRaises(ApiTypeError): + deserialized = self.deserialize( + MockResponse(data=json.dumps("test str")), + (petstore_api.StringBooleanMap,), + True + ) + + # valid value works + item_val = {'some_key': True} + response = MockResponse(data=json.dumps(item_val)) + model = petstore_api.StringBooleanMap(**item_val) + deserialized = self.deserialize(response, + (petstore_api.StringBooleanMap,), True) + self.assertTrue(isinstance(deserialized, petstore_api.StringBooleanMap)) + self.assertTrue(deserialized['some_key'] == True) + self.assertTrue(deserialized == model) + diff --git a/samples/client/petstore/python-experimental/tests/test_enum_arrays.py b/samples/client/petstore/python-experimental/tests/test_enum_arrays.py index 2f7e347f9c35..9ef5e2532a38 100644 --- a/samples/client/petstore/python-experimental/tests/test_enum_arrays.py +++ b/samples/client/petstore/python-experimental/tests/test_enum_arrays.py @@ -15,6 +15,11 @@ import petstore_api +from petstore_api.exceptions import ( + ApiTypeError, + ApiKeyError, + ApiValueError, +) class EnumArraysTests(unittest.TestCase): @@ -24,7 +29,9 @@ def test_enumarrays_init(self): # fish_or_crab = petstore_api.EnumArrays(just_symbol=">=") self.assertEqual(fish_or_crab.just_symbol, ">=") - self.assertEqual(fish_or_crab.array_enum, None) + # if optional property is unset we raise an exception + with self.assertRaises(ApiKeyError) as exc: + self.assertEqual(fish_or_crab.array_enum, None) fish_or_crab = petstore_api.EnumArrays(just_symbol="$", array_enum=["fish"]) self.assertEqual(fish_or_crab.just_symbol, "$") @@ -34,7 +41,7 @@ def test_enumarrays_init(self): self.assertEqual(fish_or_crab.just_symbol, ">=") self.assertEqual(fish_or_crab.array_enum, ["fish"]) - fish_or_crab = petstore_api.EnumArrays("$", ["crab"]) + fish_or_crab = petstore_api.EnumArrays(just_symbol="$", array_enum=["crab"]) self.assertEqual(fish_or_crab.just_symbol, "$") self.assertEqual(fish_or_crab.array_enum, ["crab"]) @@ -42,23 +49,14 @@ def test_enumarrays_init(self): # # Check if setting invalid values fails # - try: + with self.assertRaises(ApiValueError) as exc: fish_or_crab = petstore_api.EnumArrays(just_symbol="<=") - self.assertTrue(0) - except ValueError: - self.assertTrue(1) - try: + with self.assertRaises(ApiValueError) as exc: fish_or_crab = petstore_api.EnumArrays(just_symbol="$", array_enum=["dog"]) - self.assertTrue(0) - except ValueError: - self.assertTrue(1) - try: - fish_or_crab = petstore_api.EnumArrays(just_symbol=["$"], array_enum=["dog"]) - self.assertTrue(0) - except ValueError: - self.assertTrue(1) + with self.assertRaises(ApiTypeError) as exc: + fish_or_crab = petstore_api.EnumArrays(just_symbol=["$"], array_enum=["crab"]) def test_enumarrays_setter(self): @@ -82,13 +80,13 @@ def test_enumarrays_setter(self): fish_or_crab.array_enum = ["fish", "fish", "fish"] self.assertEqual(fish_or_crab.array_enum, ["fish", "fish", "fish"]) - + fish_or_crab.array_enum = ["crab"] self.assertEqual(fish_or_crab.array_enum, ["crab"]) - + fish_or_crab.array_enum = ["crab", "fish"] self.assertEqual(fish_or_crab.array_enum, ["crab", "fish"]) - + fish_or_crab.array_enum = ["crab", "fish", "crab", "fish"] self.assertEqual(fish_or_crab.array_enum, ["crab", "fish", "crab", "fish"]) @@ -96,30 +94,20 @@ def test_enumarrays_setter(self): # Check if setting invalid values fails # fish_or_crab = petstore_api.EnumArrays() - try: - fish_or_crab.just_symbol = "!=" - except ValueError: - self.assertEqual(fish_or_crab.just_symbol, None) - - try: + with self.assertRaises(ApiValueError) as exc: + fish_or_crab.just_symbol = "!=" + + with self.assertRaises(ApiTypeError) as exc: fish_or_crab.just_symbol = ["fish"] - except ValueError: - self.assertEqual(fish_or_crab.just_symbol, None) - - try: + + with self.assertRaises(ApiValueError) as exc: fish_or_crab.array_enum = ["cat"] - except ValueError: - self.assertEqual(fish_or_crab.array_enum, None) - try: + with self.assertRaises(ApiValueError) as exc: fish_or_crab.array_enum = ["fish", "crab", "dog"] - except ValueError: - self.assertEqual(fish_or_crab.array_enum, None) - try: + with self.assertRaises(ApiTypeError) as exc: fish_or_crab.array_enum = "fish" - except ValueError: - self.assertEqual(fish_or_crab.array_enum, None) def test_todict(self): @@ -131,7 +119,8 @@ def test_todict(self): 'array_enum': ["fish", "crab"] } - dollar_fish_crab = petstore_api.EnumArrays("$", ["fish", "crab"]) + dollar_fish_crab = petstore_api.EnumArrays( + just_symbol="$", array_enum=["fish", "crab"]) self.assertEqual(dollar_fish_crab_dict, dollar_fish_crab.to_dict()) @@ -143,7 +132,8 @@ def test_todict(self): 'array_enum': ["crab", "fish"] } - dollar_fish_crab = petstore_api.EnumArrays("$", ["fish", "crab"]) + dollar_fish_crab = petstore_api.EnumArrays( + just_symbol="$", array_enum=["fish", "crab"]) self.assertNotEqual(dollar_crab_fish_dict, dollar_fish_crab.to_dict()) @@ -152,14 +142,14 @@ def test_equals(self): # # Check if object comparison works # - fish1 = petstore_api.EnumArrays("$", ["fish"]) - fish2 = petstore_api.EnumArrays("$", ["fish"]) + fish1 = petstore_api.EnumArrays(just_symbol="$", array_enum=["fish"]) + fish2 = petstore_api.EnumArrays(just_symbol="$", array_enum=["fish"]) self.assertEqual(fish1, fish2) - fish = petstore_api.EnumArrays("$", ["fish"]) - crab = petstore_api.EnumArrays("$", ["crab"]) - self.assertNotEqual(fish, crab) + fish = petstore_api.EnumArrays(just_symbol="$", array_enum=["fish"]) + crab = petstore_api.EnumArrays(just_symbol="$", array_enum=["crab"]) + self.assertNotEqual(fish, crab) - dollar = petstore_api.EnumArrays("$") - greater = petstore_api.EnumArrays(">=") - self.assertNotEqual(dollar, greater) \ No newline at end of file + dollar = petstore_api.EnumArrays(just_symbol="$") + greater = petstore_api.EnumArrays(just_symbol=">=") + self.assertNotEqual(dollar, greater) \ No newline at end of file diff --git a/samples/client/petstore/python-experimental/tests/test_map_test.py b/samples/client/petstore/python-experimental/tests/test_map_test.py index 6031cebf3a2b..13db5181c9ed 100644 --- a/samples/client/petstore/python-experimental/tests/test_map_test.py +++ b/samples/client/petstore/python-experimental/tests/test_map_test.py @@ -15,6 +15,12 @@ import petstore_api +from petstore_api.exceptions import ( + ApiTypeError, + ApiKeyError, + ApiValueError, +) + class MapTestTests(unittest.TestCase): @@ -23,7 +29,7 @@ def test_maptest_init(self): # Test MapTest construction with valid values # up_or_low_dict = { - 'UPPER': "UP", + 'UPPER': "UP", 'lower': "low" } map_enum_test = petstore_api.MapTest(map_of_enum_string=up_or_low_dict) @@ -31,8 +37,6 @@ def test_maptest_init(self): self.assertEqual(map_enum_test.map_of_enum_string, up_or_low_dict) map_of_map_of_strings = { - 'val1': 1, - 'valText': "Text", 'valueDict': up_or_low_dict } map_enum_test = petstore_api.MapTest(map_map_of_string=map_of_map_of_strings) @@ -43,7 +47,7 @@ def test_maptest_init(self): # Make sure that the init fails for invalid enum values # black_or_white_dict = { - 'black': "UP", + 'black': "UP", 'white': "low" } try: @@ -58,7 +62,7 @@ def test_maptest_setter(self): # map_enum_test = petstore_api.MapTest() up_or_low_dict = { - 'UPPER': "UP", + 'UPPER': "UP", 'lower': "low" } map_enum_test.map_of_enum_string = up_or_low_dict @@ -69,13 +73,11 @@ def test_maptest_setter(self): # map_enum_test = petstore_api.MapTest() black_or_white_dict = { - 'black': "UP", + 'black': "UP", 'white': "low" } - try: + with self.assertRaises(ApiValueError) as exc: map_enum_test.map_of_enum_string = black_or_white_dict - except ValueError: - self.assertEqual(map_enum_test.map_of_enum_string, None) def test_todict(self): # @@ -83,17 +85,15 @@ def test_todict(self): # map_enum_test = petstore_api.MapTest() up_or_low_dict = { - 'UPPER': "UP", + 'UPPER': "UP", 'lower': "low" } map_of_map_of_strings = { - 'val1': 1, - 'valText': "Text", 'valueDict': up_or_low_dict } - indirect_map = { + indirect_map = petstore_api.StringBooleanMap(**{ 'option1': True - } + }) direct_map = { 'option2': False } @@ -101,7 +101,7 @@ def test_todict(self): map_enum_test.map_map_of_string = map_of_map_of_strings map_enum_test.indirect_map = indirect_map map_enum_test.direct_map = direct_map - + self.assertEqual(map_enum_test.map_of_enum_string, up_or_low_dict) self.assertEqual(map_enum_test.map_map_of_string, map_of_map_of_strings) self.assertEqual(map_enum_test.indirect_map, indirect_map) @@ -110,7 +110,7 @@ def test_todict(self): expected_dict = { 'map_of_enum_string': up_or_low_dict, 'map_map_of_string': map_of_map_of_strings, - 'indirect_map': indirect_map, + 'indirect_map': indirect_map.to_dict(), 'direct_map': direct_map } diff --git a/samples/client/petstore/python-experimental/tests/test_pet_api.py b/samples/client/petstore/python-experimental/tests/test_pet_api.py index f536f5ca288e..401cf76eef4c 100644 --- a/samples/client/petstore/python-experimental/tests/test_pet_api.py +++ b/samples/client/petstore/python-experimental/tests/test_pet_api.py @@ -16,7 +16,11 @@ import petstore_api from petstore_api import Configuration -from petstore_api.rest import ApiException + +from petstore_api.exceptions import ( + ApiException, + ApiValueError, +) from .util import id_gen @@ -78,7 +82,6 @@ def setUpModels(self): def setUpFiles(self): self.test_file_dir = os.path.join(os.path.dirname(__file__), "..", "testfiles") self.test_file_dir = os.path.realpath(self.test_file_dir) - self.foo = os.path.join(self.test_file_dir, "foo.png") def test_preload_content_flag(self): self.pet_api.add_pet(self.pet) @@ -173,7 +176,7 @@ def test_async_with_http_info(self): def test_async_exception(self): self.pet_api.add_pet(self.pet) - thread = self.pet_api.get_pet_by_id("-9999999999999", async_req=True) + thread = self.pet_api.get_pet_by_id(-9999999999999, async_req=True) exception = None try: @@ -246,21 +249,35 @@ def test_update_pet_with_form(self): def test_upload_file(self): # upload file with form parameter + file_path = os.path.join(self.test_file_dir, "foo.png") try: + file = open(file_path, "rb") additional_metadata = "special" self.pet_api.upload_file( pet_id=self.pet.id, additional_metadata=additional_metadata, - file=self.foo + file=file ) except ApiException as e: self.fail("upload_file() raised {0} unexpectedly".format(type(e))) + finally: + file.close() # upload only file try: - self.pet_api.upload_file(pet_id=self.pet.id, file=self.foo) + file = open(file_path, "rb") + self.pet_api.upload_file(pet_id=self.pet.id, file=file) except ApiException as e: self.fail("upload_file() raised {0} unexpectedly".format(type(e))) + finally: + file.close() + + # passing in a closed file raises an exception + with self.assertRaises(ApiValueError) as exc: + file = open(file_path, "rb") + file.close() + self.pet_api.upload_file(pet_id=self.pet.id, file=file) + def test_delete_pet(self): self.pet_api.add_pet(self.pet) diff --git a/samples/client/petstore/python-experimental/tests/test_pet_model.py b/samples/client/petstore/python-experimental/tests/test_pet_model.py index 70ab1a007a06..c3352015b973 100644 --- a/samples/client/petstore/python-experimental/tests/test_pet_model.py +++ b/samples/client/petstore/python-experimental/tests/test_pet_model.py @@ -36,7 +36,7 @@ def test_to_str(self): " 'name': 'test name',\n" " 'photo_urls': ['string'],\n" " 'status': 'available',\n" - " 'tags': [{'id': 1, 'name': None}]}") + " 'tags': [{'id': 1}]}") self.assertEqual(data, self.pet.to_str()) def test_equal(self): From 3e71c05794ef19fd304a7bc417368f52c031f2c5 Mon Sep 17 00:00:00 2001 From: Justin Black Date: Mon, 14 Oct 2019 12:41:44 -0700 Subject: [PATCH 02/13] Regenerates python-experimental client --- .../petstore/python-experimental/.openapi-generator/VERSION | 2 +- .../petstore/python-experimental/docs/HasOnlyReadOnly.md | 4 ++-- samples/client/petstore/python-experimental/docs/Name.md | 4 ++-- .../client/petstore/python-experimental/docs/ReadOnlyFirst.md | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/samples/client/petstore/python-experimental/.openapi-generator/VERSION b/samples/client/petstore/python-experimental/.openapi-generator/VERSION index 0e97bd19efbf..c3a2c7076fa8 100644 --- a/samples/client/petstore/python-experimental/.openapi-generator/VERSION +++ b/samples/client/petstore/python-experimental/.openapi-generator/VERSION @@ -1 +1 @@ -4.1.3-SNAPSHOT \ No newline at end of file +4.2.0-SNAPSHOT \ No newline at end of file diff --git a/samples/client/petstore/python-experimental/docs/HasOnlyReadOnly.md b/samples/client/petstore/python-experimental/docs/HasOnlyReadOnly.md index 44ad450b52c5..f731a42eab54 100644 --- a/samples/client/petstore/python-experimental/docs/HasOnlyReadOnly.md +++ b/samples/client/petstore/python-experimental/docs/HasOnlyReadOnly.md @@ -3,8 +3,8 @@ ## Properties Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**bar** | **str** | | [optional] -**foo** | **str** | | [optional] +**bar** | **str** | | [optional] [readonly] +**foo** | **str** | | [optional] [readonly] [[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/client/petstore/python-experimental/docs/Name.md b/samples/client/petstore/python-experimental/docs/Name.md index 542da3f04768..17dc7a38fe69 100644 --- a/samples/client/petstore/python-experimental/docs/Name.md +++ b/samples/client/petstore/python-experimental/docs/Name.md @@ -4,9 +4,9 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **name** | **int** | | -**snake_case** | **int** | | [optional] +**snake_case** | **int** | | [optional] [readonly] **_property** | **str** | | [optional] -**_123_number** | **int** | | [optional] +**_123_number** | **int** | | [optional] [readonly] [[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/client/petstore/python-experimental/docs/ReadOnlyFirst.md b/samples/client/petstore/python-experimental/docs/ReadOnlyFirst.md index 93fed253d01c..6bc1447c1d71 100644 --- a/samples/client/petstore/python-experimental/docs/ReadOnlyFirst.md +++ b/samples/client/petstore/python-experimental/docs/ReadOnlyFirst.md @@ -3,7 +3,7 @@ ## Properties Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**bar** | **str** | | [optional] +**bar** | **str** | | [optional] [readonly] **baz** | **str** | | [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) From 2bdd00ac5606510ff028b4643c81a79d7820cf1f Mon Sep 17 00:00:00 2001 From: Justin Black Date: Tue, 15 Oct 2019 09:30:31 -0700 Subject: [PATCH 03/13] Updates windows python-experimental bat file --- bin/windows/python-experimental-petstore.bat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/windows/python-experimental-petstore.bat b/bin/windows/python-experimental-petstore.bat index 50df98535f41..2680649d00fd 100644 --- a/bin/windows/python-experimental-petstore.bat +++ b/bin/windows/python-experimental-petstore.bat @@ -5,6 +5,6 @@ If Not Exist %executable% ( ) REM set JAVA_OPTS=%JAVA_OPTS% -Xmx1024M -set ags=generate -i modules\openapi-generator\src\test\resources\2_0\petstore-with-fake-endpoints-models-for-testing.yaml -g python-experimental -o samples\client\petstore\python-experimental -DpackageName=petstore_api +set ags=generate -i modules\openapi-generator\src\test\resources\2_0\python-client-experimental\petstore-with-fake-endpoints-models-for-testing.yaml -g python-experimental -o samples\client\petstore\python-experimental --additional-properties packageName=petstore_api java %JAVA_OPTS% -jar %executable% %ags% From 7864c5ac48026d9697c05f25a6ca8dc1022e0f49 Mon Sep 17 00:00:00 2001 From: Justin Black Date: Tue, 15 Oct 2019 10:15:26 -0700 Subject: [PATCH 04/13] Fixes addModelImport so client generation will work with the v2 spec --- .../codegen/languages/PythonClientExperimentalCodegen.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PythonClientExperimentalCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PythonClientExperimentalCodegen.java index 30effec0cd1b..ae4c220d7d26 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PythonClientExperimentalCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PythonClientExperimentalCodegen.java @@ -214,6 +214,10 @@ public String toDefaultValue(Schema p) { public void addModelImport(Map objs, CodegenModel cm, String otherModelName) { // adds the absolute path to otherModelName as an import in CodegenModel cm HashMap referencedModel = (HashMap) objs.get(otherModelName); + if (referencedModel == null) { + // this happens with a model where type=string and format=number which is a non-standard format + return; + } ArrayList myModel = (ArrayList) referencedModel.get("models"); HashMap modelData = (HashMap) myModel.get(0); String importPath = (String) modelData.get("importPath"); From 630499c2751b2653c637aaf57101135df3221b8a Mon Sep 17 00:00:00 2001 From: Justin Black Date: Wed, 16 Oct 2019 10:15:02 -0700 Subject: [PATCH 05/13] Reverts PythonClientCodegen.java --- .../codegen/languages/PythonClientCodegen.java | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PythonClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PythonClientCodegen.java index 5438395949af..0df25cfd1596 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PythonClientCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PythonClientCodegen.java @@ -127,8 +127,7 @@ public PythonClientCodegen() { "and", "del", "from", "not", "while", "as", "elif", "global", "or", "with", "assert", "else", "if", "pass", "yield", "break", "except", "import", "print", "class", "exec", "in", "raise", "continue", "finally", "is", - "return", "def", "for", "lambda", "try", "self", "nonlocal", "None", "True", - "False", "async", "await")); + "return", "def", "for", "lambda", "try", "self", "nonlocal", "None", "True", "False")); regexModifiers = new HashMap(); regexModifiers.put('i', "IGNORECASE"); @@ -190,7 +189,7 @@ public void processOpts() { if (additionalProperties.containsKey(CodegenConstants.PACKAGE_VERSION)) { setPackageVersion((String) additionalProperties.get(CodegenConstants.PACKAGE_VERSION)); - } + } Boolean generateSourceCodeOnly = false; if (additionalProperties.containsKey(CodegenConstants.SOURCECODEONLY_GENERATION)) { @@ -532,7 +531,7 @@ public String toApiFilename(String name) { name = name.replaceAll("-", "_"); // e.g. PhoneNumberApi.py => phone_number_api.py - return underscore(name+ "_" + apiNameSuffix); + return underscore(name) + "_api"; } @Override @@ -542,7 +541,11 @@ public String toApiTestFilename(String name) { @Override public String toApiName(String name) { - return super.toApiName(name); + if (name.length() == 0) { + return "DefaultApi"; + } + // e.g. phone_number_api => PhoneNumberApi + return camelize(name) + "Api"; } @Override @@ -550,7 +553,7 @@ public String toApiVarName(String name) { if (name.length() == 0) { return "default_api"; } - return underscore(name+ "_" + apiNameSuffix); + return underscore(name) + "_api"; } @Override From beff6fec08e512c257604a5698bde129438968d9 Mon Sep 17 00:00:00 2001 From: Justin Black Date: Wed, 16 Oct 2019 10:17:27 -0700 Subject: [PATCH 06/13] Acutally revert PythonClientCodegen.java --- .../codegen/languages/PythonClientCodegen.java | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PythonClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PythonClientCodegen.java index 0df25cfd1596..16ec0bd3c03a 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PythonClientCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PythonClientCodegen.java @@ -127,7 +127,8 @@ public PythonClientCodegen() { "and", "del", "from", "not", "while", "as", "elif", "global", "or", "with", "assert", "else", "if", "pass", "yield", "break", "except", "import", "print", "class", "exec", "in", "raise", "continue", "finally", "is", - "return", "def", "for", "lambda", "try", "self", "nonlocal", "None", "True", "False")); + "return", "def", "for", "lambda", "try", "self", "nonlocal", "None", "True", + "False", "async", "await")); regexModifiers = new HashMap(); regexModifiers.put('i', "IGNORECASE"); @@ -531,7 +532,7 @@ public String toApiFilename(String name) { name = name.replaceAll("-", "_"); // e.g. PhoneNumberApi.py => phone_number_api.py - return underscore(name) + "_api"; + return underscore(name+ "_" + apiNameSuffix); } @Override @@ -541,11 +542,7 @@ public String toApiTestFilename(String name) { @Override public String toApiName(String name) { - if (name.length() == 0) { - return "DefaultApi"; - } - // e.g. phone_number_api => PhoneNumberApi - return camelize(name) + "Api"; + return super.toApiName(name); } @Override @@ -553,7 +550,7 @@ public String toApiVarName(String name) { if (name.length() == 0) { return "default_api"; } - return underscore(name) + "_api"; + return underscore(name+ "_" + apiNameSuffix); } @Override From 2ee49a1a572671168a665f24b801c7e8b31054e7 Mon Sep 17 00:00:00 2001 From: Justin Black Date: Wed, 16 Oct 2019 10:47:46 -0700 Subject: [PATCH 07/13] Updates the sample example for file_type in docs --- .../PythonClientExperimentalCodegen.java | 68 +++++++++++++++++++ .../python-experimental/docs/FakeApi.md | 2 +- .../python-experimental/docs/PetApi.md | 4 +- 3 files changed, 71 insertions(+), 3 deletions(-) diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PythonClientExperimentalCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PythonClientExperimentalCodegen.java index ae4c220d7d26..8ae19362557d 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PythonClientExperimentalCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PythonClientExperimentalCodegen.java @@ -718,4 +718,72 @@ protected void addAdditionPropertiesToCodeGenModel(CodegenModel codegenModel, Sc addParentContainer(codegenModel, codegenModel.name, schema); } } + + @Override + public void setParameterExampleValue(CodegenParameter p) { + // we have a custom version of this function so we can set the file + // type example value + String example; + + if (p.defaultValue == null) { + example = p.example; + } else { + p.example = p.defaultValue; + return; + } + + String type = p.baseType; + if (type == null) { + type = p.dataType; + } + + if ("String".equalsIgnoreCase(type) || "str".equalsIgnoreCase(type)) { + if (example == null) { + example = p.paramName + "_example"; + } + example = "'" + escapeText(example) + "'"; + } else if ("Integer".equals(type) || "int".equals(type)) { + if (example == null) { + example = "56"; + } + } else if ("Float".equalsIgnoreCase(type) || "Double".equalsIgnoreCase(type)) { + if (example == null) { + example = "3.4"; + } + } else if ("BOOLEAN".equalsIgnoreCase(type) || "bool".equalsIgnoreCase(type)) { + if (example == null) { + example = "True"; + } + } else if ("file".equalsIgnoreCase(type)) { + if (example == null) { + example = "/path/to/file"; + } + example = "open('"+example+"', 'rb')"; + } else if ("Date".equalsIgnoreCase(type)) { + if (example == null) { + example = "2013-10-20"; + } + example = "'" + escapeText(example) + "'"; + } else if ("DateTime".equalsIgnoreCase(type)) { + if (example == null) { + example = "2013-10-20T19:20:30+01:00"; + } + example = "'" + escapeText(example) + "'"; + } else if (!languageSpecificPrimitives.contains(type)) { + // type is a model class, e.g. User + example = this.packageName + "." + type + "()"; + } else { + LOGGER.warn("Type " + type + " not handled properly in setParameterExampleValue"); + } + + if (example == null) { + example = "None"; + } else if (Boolean.TRUE.equals(p.isListContainer)) { + example = "[" + example + "]"; + } else if (Boolean.TRUE.equals(p.isMapContainer)) { + example = "{'key': " + example + "}"; + } + + p.example = example; + } } diff --git a/samples/client/petstore/python-experimental/docs/FakeApi.md b/samples/client/petstore/python-experimental/docs/FakeApi.md index 368f9ec306eb..0677687d5927 100644 --- a/samples/client/petstore/python-experimental/docs/FakeApi.md +++ b/samples/client/petstore/python-experimental/docs/FakeApi.md @@ -591,7 +591,7 @@ int32 = 56 # int | None (optional) int64 = 56 # int | None (optional) float = 3.4 # float | None (optional) string = 'string_example' # str | None (optional) -binary = '/path/to/file' # file_type | None (optional) +binary = open('/path/to/file', 'rb') # file_type | None (optional) date = '2013-10-20' # date | None (optional) date_time = '2013-10-20T19:20:30+01:00' # datetime | None (optional) password = 'password_example' # str | None (optional) diff --git a/samples/client/petstore/python-experimental/docs/PetApi.md b/samples/client/petstore/python-experimental/docs/PetApi.md index 048a0af56ffc..3387e1223a96 100644 --- a/samples/client/petstore/python-experimental/docs/PetApi.md +++ b/samples/client/petstore/python-experimental/docs/PetApi.md @@ -464,7 +464,7 @@ configuration.host = "http://petstore.swagger.io:80/v2" api_instance = petstore_api.PetApi(petstore_api.ApiClient(configuration)) pet_id = 56 # int | ID of pet to update additional_metadata = 'additional_metadata_example' # str | Additional data to pass to server (optional) -file = '/path/to/file' # file_type | file to upload (optional) +file = open('/path/to/file', 'rb') # file_type | file to upload (optional) try: # uploads an image @@ -525,7 +525,7 @@ configuration.host = "http://petstore.swagger.io:80/v2" # Create an instance of the API class api_instance = petstore_api.PetApi(petstore_api.ApiClient(configuration)) pet_id = 56 # int | ID of pet to update -required_file = '/path/to/file' # file_type | file to upload +required_file = open('/path/to/file', 'rb') # file_type | file to upload additional_metadata = 'additional_metadata_example' # str | Additional data to pass to server (optional) try: From 9ce5a7f5bbd96db23db6f2e32cd0dbaefcd3e510 Mon Sep 17 00:00:00 2001 From: Justin Black Date: Wed, 16 Oct 2019 11:36:52 -0700 Subject: [PATCH 08/13] Silences line too long error for python models so CI tests pass --- .../src/main/resources/python/model.mustache | 4 ++-- .../python-asyncio/petstore_api/models/enum_arrays.py | 2 +- .../petstore/python-asyncio/petstore_api/models/map_test.py | 2 +- samples/client/petstore/python-asyncio/requirements.txt | 1 + .../python-tornado/petstore_api/models/enum_arrays.py | 2 +- .../petstore/python-tornado/petstore_api/models/map_test.py | 2 +- samples/client/petstore/python-tornado/requirements.txt | 1 + .../client/petstore/python/petstore_api/models/enum_arrays.py | 2 +- .../client/petstore/python/petstore_api/models/map_test.py | 2 +- samples/client/petstore/python/requirements.txt | 1 + .../client/petstore/python/petstore_api/models/enum_arrays.py | 2 +- .../petstore/python/petstore_api/models/inline_object2.py | 2 +- .../client/petstore/python/petstore_api/models/map_test.py | 2 +- samples/openapi3/client/petstore/python/requirements.txt | 1 + 14 files changed, 15 insertions(+), 11 deletions(-) diff --git a/modules/openapi-generator/src/main/resources/python/model.mustache b/modules/openapi-generator/src/main/resources/python/model.mustache index e2c39f3d6b3b..17264bb46b0d 100644 --- a/modules/openapi-generator/src/main/resources/python/model.mustache +++ b/modules/openapi-generator/src/main/resources/python/model.mustache @@ -115,7 +115,7 @@ class {{classname}}(object): allowed_values = [{{#isNullable}}None,{{/isNullable}}{{#allowableValues}}{{#values}}{{#items.isString}}"{{/items.isString}}{{{this}}}{{#items.isString}}"{{/items.isString}}{{^-last}}, {{/-last}}{{/values}}{{/allowableValues}}] # noqa: E501 {{#isListContainer}} if (self.local_vars_configuration.client_side_validation and - not set({{{name}}}).issubset(set(allowed_values))): + not set({{{name}}}).issubset(set(allowed_values))): # noqa: E501 raise ValueError( "Invalid values for `{{{name}}}` [{0}], must be a subset of [{1}]" # noqa: E501 .format(", ".join(map(str, set({{{name}}}) - set(allowed_values))), # noqa: E501 @@ -124,7 +124,7 @@ class {{classname}}(object): {{/isListContainer}} {{#isMapContainer}} if (self.local_vars_configuration.client_side_validation and - not set({{{name}}}.keys()).issubset(set(allowed_values))): + not set({{{name}}}.keys()).issubset(set(allowed_values))): # noqa: E501 raise ValueError( "Invalid keys in `{{{name}}}` [{0}], must be a subset of [{1}]" # noqa: E501 .format(", ".join(map(str, set({{{name}}}.keys()) - set(allowed_values))), # noqa: E501 diff --git a/samples/client/petstore/python-asyncio/petstore_api/models/enum_arrays.py b/samples/client/petstore/python-asyncio/petstore_api/models/enum_arrays.py index 481283a05c32..819ff322157d 100644 --- a/samples/client/petstore/python-asyncio/petstore_api/models/enum_arrays.py +++ b/samples/client/petstore/python-asyncio/petstore_api/models/enum_arrays.py @@ -104,7 +104,7 @@ def array_enum(self, array_enum): """ allowed_values = ["fish", "crab"] # noqa: E501 if (self.local_vars_configuration.client_side_validation and - not set(array_enum).issubset(set(allowed_values))): + not set(array_enum).issubset(set(allowed_values))): # noqa: E501 raise ValueError( "Invalid values for `array_enum` [{0}], must be a subset of [{1}]" # noqa: E501 .format(", ".join(map(str, set(array_enum) - set(allowed_values))), # noqa: E501 diff --git a/samples/client/petstore/python-asyncio/petstore_api/models/map_test.py b/samples/client/petstore/python-asyncio/petstore_api/models/map_test.py index b170dce412c7..f0cfba5073b0 100644 --- a/samples/client/petstore/python-asyncio/petstore_api/models/map_test.py +++ b/samples/client/petstore/python-asyncio/petstore_api/models/map_test.py @@ -108,7 +108,7 @@ def map_of_enum_string(self, map_of_enum_string): """ allowed_values = ["UPPER", "lower"] # noqa: E501 if (self.local_vars_configuration.client_side_validation and - not set(map_of_enum_string.keys()).issubset(set(allowed_values))): + not set(map_of_enum_string.keys()).issubset(set(allowed_values))): # noqa: E501 raise ValueError( "Invalid keys in `map_of_enum_string` [{0}], must be a subset of [{1}]" # noqa: E501 .format(", ".join(map(str, set(map_of_enum_string.keys()) - set(allowed_values))), # noqa: E501 diff --git a/samples/client/petstore/python-asyncio/requirements.txt b/samples/client/petstore/python-asyncio/requirements.txt index bafdc07532f5..eb358efd5bd3 100644 --- a/samples/client/petstore/python-asyncio/requirements.txt +++ b/samples/client/petstore/python-asyncio/requirements.txt @@ -1,4 +1,5 @@ certifi >= 14.05.14 +future; python_version<="2.7" six >= 1.10 python_dateutil >= 2.5.3 setuptools >= 21.0.0 diff --git a/samples/client/petstore/python-tornado/petstore_api/models/enum_arrays.py b/samples/client/petstore/python-tornado/petstore_api/models/enum_arrays.py index 481283a05c32..819ff322157d 100644 --- a/samples/client/petstore/python-tornado/petstore_api/models/enum_arrays.py +++ b/samples/client/petstore/python-tornado/petstore_api/models/enum_arrays.py @@ -104,7 +104,7 @@ def array_enum(self, array_enum): """ allowed_values = ["fish", "crab"] # noqa: E501 if (self.local_vars_configuration.client_side_validation and - not set(array_enum).issubset(set(allowed_values))): + not set(array_enum).issubset(set(allowed_values))): # noqa: E501 raise ValueError( "Invalid values for `array_enum` [{0}], must be a subset of [{1}]" # noqa: E501 .format(", ".join(map(str, set(array_enum) - set(allowed_values))), # noqa: E501 diff --git a/samples/client/petstore/python-tornado/petstore_api/models/map_test.py b/samples/client/petstore/python-tornado/petstore_api/models/map_test.py index b170dce412c7..f0cfba5073b0 100644 --- a/samples/client/petstore/python-tornado/petstore_api/models/map_test.py +++ b/samples/client/petstore/python-tornado/petstore_api/models/map_test.py @@ -108,7 +108,7 @@ def map_of_enum_string(self, map_of_enum_string): """ allowed_values = ["UPPER", "lower"] # noqa: E501 if (self.local_vars_configuration.client_side_validation and - not set(map_of_enum_string.keys()).issubset(set(allowed_values))): + not set(map_of_enum_string.keys()).issubset(set(allowed_values))): # noqa: E501 raise ValueError( "Invalid keys in `map_of_enum_string` [{0}], must be a subset of [{1}]" # noqa: E501 .format(", ".join(map(str, set(map_of_enum_string.keys()) - set(allowed_values))), # noqa: E501 diff --git a/samples/client/petstore/python-tornado/requirements.txt b/samples/client/petstore/python-tornado/requirements.txt index bafdc07532f5..eb358efd5bd3 100644 --- a/samples/client/petstore/python-tornado/requirements.txt +++ b/samples/client/petstore/python-tornado/requirements.txt @@ -1,4 +1,5 @@ certifi >= 14.05.14 +future; python_version<="2.7" six >= 1.10 python_dateutil >= 2.5.3 setuptools >= 21.0.0 diff --git a/samples/client/petstore/python/petstore_api/models/enum_arrays.py b/samples/client/petstore/python/petstore_api/models/enum_arrays.py index 481283a05c32..819ff322157d 100644 --- a/samples/client/petstore/python/petstore_api/models/enum_arrays.py +++ b/samples/client/petstore/python/petstore_api/models/enum_arrays.py @@ -104,7 +104,7 @@ def array_enum(self, array_enum): """ allowed_values = ["fish", "crab"] # noqa: E501 if (self.local_vars_configuration.client_side_validation and - not set(array_enum).issubset(set(allowed_values))): + not set(array_enum).issubset(set(allowed_values))): # noqa: E501 raise ValueError( "Invalid values for `array_enum` [{0}], must be a subset of [{1}]" # noqa: E501 .format(", ".join(map(str, set(array_enum) - set(allowed_values))), # noqa: E501 diff --git a/samples/client/petstore/python/petstore_api/models/map_test.py b/samples/client/petstore/python/petstore_api/models/map_test.py index b170dce412c7..f0cfba5073b0 100644 --- a/samples/client/petstore/python/petstore_api/models/map_test.py +++ b/samples/client/petstore/python/petstore_api/models/map_test.py @@ -108,7 +108,7 @@ def map_of_enum_string(self, map_of_enum_string): """ allowed_values = ["UPPER", "lower"] # noqa: E501 if (self.local_vars_configuration.client_side_validation and - not set(map_of_enum_string.keys()).issubset(set(allowed_values))): + not set(map_of_enum_string.keys()).issubset(set(allowed_values))): # noqa: E501 raise ValueError( "Invalid keys in `map_of_enum_string` [{0}], must be a subset of [{1}]" # noqa: E501 .format(", ".join(map(str, set(map_of_enum_string.keys()) - set(allowed_values))), # noqa: E501 diff --git a/samples/client/petstore/python/requirements.txt b/samples/client/petstore/python/requirements.txt index bafdc07532f5..eb358efd5bd3 100644 --- a/samples/client/petstore/python/requirements.txt +++ b/samples/client/petstore/python/requirements.txt @@ -1,4 +1,5 @@ certifi >= 14.05.14 +future; python_version<="2.7" six >= 1.10 python_dateutil >= 2.5.3 setuptools >= 21.0.0 diff --git a/samples/openapi3/client/petstore/python/petstore_api/models/enum_arrays.py b/samples/openapi3/client/petstore/python/petstore_api/models/enum_arrays.py index 481283a05c32..819ff322157d 100644 --- a/samples/openapi3/client/petstore/python/petstore_api/models/enum_arrays.py +++ b/samples/openapi3/client/petstore/python/petstore_api/models/enum_arrays.py @@ -104,7 +104,7 @@ def array_enum(self, array_enum): """ allowed_values = ["fish", "crab"] # noqa: E501 if (self.local_vars_configuration.client_side_validation and - not set(array_enum).issubset(set(allowed_values))): + not set(array_enum).issubset(set(allowed_values))): # noqa: E501 raise ValueError( "Invalid values for `array_enum` [{0}], must be a subset of [{1}]" # noqa: E501 .format(", ".join(map(str, set(array_enum) - set(allowed_values))), # noqa: E501 diff --git a/samples/openapi3/client/petstore/python/petstore_api/models/inline_object2.py b/samples/openapi3/client/petstore/python/petstore_api/models/inline_object2.py index 4e30b86dc22e..f904d0a24d5d 100644 --- a/samples/openapi3/client/petstore/python/petstore_api/models/inline_object2.py +++ b/samples/openapi3/client/petstore/python/petstore_api/models/inline_object2.py @@ -79,7 +79,7 @@ def enum_form_string_array(self, enum_form_string_array): """ allowed_values = [">", "$"] # noqa: E501 if (self.local_vars_configuration.client_side_validation and - not set(enum_form_string_array).issubset(set(allowed_values))): + not set(enum_form_string_array).issubset(set(allowed_values))): # noqa: E501 raise ValueError( "Invalid values for `enum_form_string_array` [{0}], must be a subset of [{1}]" # noqa: E501 .format(", ".join(map(str, set(enum_form_string_array) - set(allowed_values))), # noqa: E501 diff --git a/samples/openapi3/client/petstore/python/petstore_api/models/map_test.py b/samples/openapi3/client/petstore/python/petstore_api/models/map_test.py index b170dce412c7..f0cfba5073b0 100644 --- a/samples/openapi3/client/petstore/python/petstore_api/models/map_test.py +++ b/samples/openapi3/client/petstore/python/petstore_api/models/map_test.py @@ -108,7 +108,7 @@ def map_of_enum_string(self, map_of_enum_string): """ allowed_values = ["UPPER", "lower"] # noqa: E501 if (self.local_vars_configuration.client_side_validation and - not set(map_of_enum_string.keys()).issubset(set(allowed_values))): + not set(map_of_enum_string.keys()).issubset(set(allowed_values))): # noqa: E501 raise ValueError( "Invalid keys in `map_of_enum_string` [{0}], must be a subset of [{1}]" # noqa: E501 .format(", ".join(map(str, set(map_of_enum_string.keys()) - set(allowed_values))), # noqa: E501 diff --git a/samples/openapi3/client/petstore/python/requirements.txt b/samples/openapi3/client/petstore/python/requirements.txt index bafdc07532f5..eb358efd5bd3 100644 --- a/samples/openapi3/client/petstore/python/requirements.txt +++ b/samples/openapi3/client/petstore/python/requirements.txt @@ -1,4 +1,5 @@ certifi >= 14.05.14 +future; python_version<="2.7" six >= 1.10 python_dateutil >= 2.5.3 setuptools >= 21.0.0 From b90130556bfc4ec852b24cc70d1fa663d1ee1f30 Mon Sep 17 00:00:00 2001 From: Justin Black Date: Mon, 21 Oct 2019 20:55:56 -0700 Subject: [PATCH 09/13] Fixes handling of file uploads, adds tests for uploading files --- .../python/python-experimental/api.mustache | 9 +- .../python-experimental/api_client.mustache | 39 ++++--- ...ith-fake-endpoints-models-for-testing.yaml | 7 ++ .../python-experimental/docs/PetApi.md | 4 +- .../petstore_api/api/another_fake_api.py | 9 +- .../petstore_api/api/fake_api.py | 9 +- .../api/fake_classname_tags_123_api.py | 9 +- .../petstore_api/api/pet_api.py | 15 ++- .../petstore_api/api/store_api.py | 9 +- .../petstore_api/api/user_api.py | 9 +- .../petstore_api/api_client.py | 39 ++++--- .../petstore_api/configuration.py | 2 + .../testfiles/1px_pic1.png | Bin 0 -> 67 bytes .../testfiles/1px_pic2.png | Bin 0 -> 67 bytes .../python-experimental/tests/test_pet_api.py | 100 ++++++++++++++++-- 15 files changed, 204 insertions(+), 56 deletions(-) create mode 100644 samples/client/petstore/python-experimental/testfiles/1px_pic1.png create mode 100644 samples/client/petstore/python-experimental/testfiles/1px_pic2.png diff --git a/modules/openapi-generator/src/main/resources/python/python-experimental/api.mustache b/modules/openapi-generator/src/main/resources/python/python-experimental/api.mustache index 98f8be8f0eab..651559cf4ff3 100644 --- a/modules/openapi-generator/src/main/resources/python/python-experimental/api.mustache +++ b/modules/openapi-generator/src/main/resources/python/python-experimental/api.mustache @@ -379,6 +379,8 @@ class Endpoint(object): for param_name, param_value in six.iteritems(kwargs): param_location = self.location_map.get(param_name) + if param_location is None: + continue if param_location: if param_location == 'body': params['body'] = param_value @@ -386,8 +388,11 @@ class Endpoint(object): base_name = self.attribute_map[param_name] if (param_location == 'form' and self.openapi_types[param_name] == (file_type,)): - param_location = 'file' - params[param_location][param_name] = param_value + params['file'][param_name] = [param_value] + elif (param_location == 'form' and + self.openapi_types[param_name] == ([file_type],)): + # param_value is already a list + params['file'][param_name] = param_value elif param_location in {'form', 'query'}: param_value_full = (base_name, param_value) params[param_location].append(param_value_full) diff --git a/modules/openapi-generator/src/main/resources/python/python-experimental/api_client.mustache b/modules/openapi-generator/src/main/resources/python/python-experimental/api_client.mustache index 179ce3c37210..aec1ef375366 100644 --- a/modules/openapi-generator/src/main/resources/python/python-experimental/api_client.mustache +++ b/modules/openapi-generator/src/main/resources/python/python-experimental/api_client.mustache @@ -315,8 +315,8 @@ class ApiClient(object): (float, none_type) ([int, none_type],) ({str: (bool, str, int, float, date, datetime, str, none_type)},) - :param files dict: key -> filename, value -> filepath, - for `multipart/form-data`. + :param files dict: key -> field name, value -> a list of open file + objects for `multipart/form-data`. :param async_req bool: execute request asynchronously :param _return_http_data_only: response data without head status code and headers @@ -453,29 +453,34 @@ class ApiClient(object): def files_parameters(self, files=None): """Builds form parameters. - :param files: None or a dict with key=param_name and value=file_object + :param files: None or a dict with key=param_name and + value is a list of open file objects :return: List of tuples of form parameters with file data """ if files is None: return [] params = [] - for param_name, file_instance in six.iteritems(files): - if file_instance is None: + for param_name, file_instances in six.iteritems(files): + if file_instances is None: # if the file field is nullable, skip None values continue - if file_instance.closed is True: - raise ApiValueError( - "Cannot read a closed file. The passed in file_type for " - "%s must be open." % param_name - ) - filename = os.path.basename(file_instance.name) - filedata = file_instance.read() - mimetype = (mimetypes.guess_type(filename)[0] or - 'application/octet-stream') - params.append( - tuple([param_name, tuple([filename, filedata, mimetype])])) - file_instance.close() + for file_instance in file_instances: + if file_instance is None: + # if the file field is nullable, skip None values + continue + if file_instance.closed is True: + raise ApiValueError( + "Cannot read a closed file. The passed in file_type " + "for %s must be open." % param_name + ) + filename = os.path.basename(file_instance.name) + filedata = file_instance.read() + mimetype = (mimetypes.guess_type(filename)[0] or + 'application/octet-stream') + params.append( + tuple([param_name, tuple([filename, filedata, mimetype])])) + file_instance.close() return params diff --git a/modules/openapi-generator/src/test/resources/2_0/python-client-experimental/petstore-with-fake-endpoints-models-for-testing.yaml b/modules/openapi-generator/src/test/resources/2_0/python-client-experimental/petstore-with-fake-endpoints-models-for-testing.yaml index fea5233ee269..a443f059b7ef 100644 --- a/modules/openapi-generator/src/test/resources/2_0/python-client-experimental/petstore-with-fake-endpoints-models-for-testing.yaml +++ b/modules/openapi-generator/src/test/resources/2_0/python-client-experimental/petstore-with-fake-endpoints-models-for-testing.yaml @@ -269,6 +269,13 @@ paths: description: file to upload required: false type: file + - name: files + in: formData + description: files to upload + required: false + type: array + items: + type: file responses: '200': description: successful operation diff --git a/samples/client/petstore/python-experimental/docs/PetApi.md b/samples/client/petstore/python-experimental/docs/PetApi.md index 3387e1223a96..8364f8fa8fc8 100644 --- a/samples/client/petstore/python-experimental/docs/PetApi.md +++ b/samples/client/petstore/python-experimental/docs/PetApi.md @@ -465,10 +465,11 @@ api_instance = petstore_api.PetApi(petstore_api.ApiClient(configuration)) pet_id = 56 # int | ID of pet to update additional_metadata = 'additional_metadata_example' # str | Additional data to pass to server (optional) file = open('/path/to/file', 'rb') # file_type | file to upload (optional) +files = open('/path/to/file', 'rb') # [file_type] | files to upload (optional) try: # uploads an image - api_response = api_instance.upload_file(pet_id, additional_metadata=additional_metadata, file=file) + api_response = api_instance.upload_file(pet_id, additional_metadata=additional_metadata, file=file, files=files) pprint(api_response) except ApiException as e: print("Exception when calling PetApi->upload_file: %s\n" % e) @@ -481,6 +482,7 @@ Name | Type | Description | Notes **pet_id** | **int**| ID of pet to update | **additional_metadata** | **str**| Additional data to pass to server | [optional] **file** | **file_type**| file to upload | [optional] + **files** | [**[file_type]**](file_type.md)| files to upload | [optional] ### Return type diff --git a/samples/client/petstore/python-experimental/petstore_api/api/another_fake_api.py b/samples/client/petstore/python-experimental/petstore_api/api/another_fake_api.py index 2ba53120ee8a..2a875ae78764 100644 --- a/samples/client/petstore/python-experimental/petstore_api/api/another_fake_api.py +++ b/samples/client/petstore/python-experimental/petstore_api/api/another_fake_api.py @@ -268,6 +268,8 @@ def __gather_params(self, kwargs): for param_name, param_value in six.iteritems(kwargs): param_location = self.location_map.get(param_name) + if param_location is None: + continue if param_location: if param_location == 'body': params['body'] = param_value @@ -275,8 +277,11 @@ def __gather_params(self, kwargs): base_name = self.attribute_map[param_name] if (param_location == 'form' and self.openapi_types[param_name] == (file_type,)): - param_location = 'file' - params[param_location][param_name] = param_value + params['file'][param_name] = [param_value] + elif (param_location == 'form' and + self.openapi_types[param_name] == ([file_type],)): + # param_value is already a list + params['file'][param_name] = param_value elif param_location in {'form', 'query'}: param_value_full = (base_name, param_value) params[param_location].append(param_value_full) diff --git a/samples/client/petstore/python-experimental/petstore_api/api/fake_api.py b/samples/client/petstore/python-experimental/petstore_api/api/fake_api.py index cb839e5817b5..c38dac0a5b0d 100644 --- a/samples/client/petstore/python-experimental/petstore_api/api/fake_api.py +++ b/samples/client/petstore/python-experimental/petstore_api/api/fake_api.py @@ -2036,6 +2036,8 @@ def __gather_params(self, kwargs): for param_name, param_value in six.iteritems(kwargs): param_location = self.location_map.get(param_name) + if param_location is None: + continue if param_location: if param_location == 'body': params['body'] = param_value @@ -2043,8 +2045,11 @@ def __gather_params(self, kwargs): base_name = self.attribute_map[param_name] if (param_location == 'form' and self.openapi_types[param_name] == (file_type,)): - param_location = 'file' - params[param_location][param_name] = param_value + params['file'][param_name] = [param_value] + elif (param_location == 'form' and + self.openapi_types[param_name] == ([file_type],)): + # param_value is already a list + params['file'][param_name] = param_value elif param_location in {'form', 'query'}: param_value_full = (base_name, param_value) params[param_location].append(param_value_full) diff --git a/samples/client/petstore/python-experimental/petstore_api/api/fake_classname_tags_123_api.py b/samples/client/petstore/python-experimental/petstore_api/api/fake_classname_tags_123_api.py index 8bb447b34edc..459318014230 100644 --- a/samples/client/petstore/python-experimental/petstore_api/api/fake_classname_tags_123_api.py +++ b/samples/client/petstore/python-experimental/petstore_api/api/fake_classname_tags_123_api.py @@ -270,6 +270,8 @@ def __gather_params(self, kwargs): for param_name, param_value in six.iteritems(kwargs): param_location = self.location_map.get(param_name) + if param_location is None: + continue if param_location: if param_location == 'body': params['body'] = param_value @@ -277,8 +279,11 @@ def __gather_params(self, kwargs): base_name = self.attribute_map[param_name] if (param_location == 'form' and self.openapi_types[param_name] == (file_type,)): - param_location = 'file' - params[param_location][param_name] = param_value + params['file'][param_name] = [param_value] + elif (param_location == 'form' and + self.openapi_types[param_name] == ([file_type],)): + # param_value is already a list + params['file'][param_name] = param_value elif param_location in {'form', 'query'}: param_value_full = (base_name, param_value) params[param_location].append(param_value_full) diff --git a/samples/client/petstore/python-experimental/petstore_api/api/pet_api.py b/samples/client/petstore/python-experimental/petstore_api/api/pet_api.py index 41a0a329ea9a..ba58ba92a814 100644 --- a/samples/client/petstore/python-experimental/petstore_api/api/pet_api.py +++ b/samples/client/petstore/python-experimental/petstore_api/api/pet_api.py @@ -839,6 +839,7 @@ def __upload_file(self, pet_id, **kwargs): # noqa: E501 :param int pet_id: ID of pet to update (required) :param str additional_metadata: Additional data to pass to server :param file_type file: file to upload + :param [file_type] files: files to upload :param _return_http_data_only: response data without head status code and headers. Default is True. :param _preload_content: if False, the urllib3.HTTPResponse object @@ -899,6 +900,7 @@ def __upload_file(self, pet_id, **kwargs): # noqa: E501 'pet_id', 'additional_metadata', 'file', + 'files', ], 'required': [ 'pet_id', @@ -919,18 +921,22 @@ def __upload_file(self, pet_id, **kwargs): # noqa: E501 'pet_id': (int,), 'additional_metadata': (str,), 'file': (file_type,), + 'files': ([file_type],), }, 'attribute_map': { 'pet_id': 'petId', 'additional_metadata': 'additionalMetadata', 'file': 'file', + 'files': 'files', }, 'location_map': { 'pet_id': 'path', 'additional_metadata': 'form', 'file': 'form', + 'files': 'form', }, 'collection_format_map': { + 'files': 'csv', } }, headers_map={ @@ -1179,6 +1185,8 @@ def __gather_params(self, kwargs): for param_name, param_value in six.iteritems(kwargs): param_location = self.location_map.get(param_name) + if param_location is None: + continue if param_location: if param_location == 'body': params['body'] = param_value @@ -1186,8 +1194,11 @@ def __gather_params(self, kwargs): base_name = self.attribute_map[param_name] if (param_location == 'form' and self.openapi_types[param_name] == (file_type,)): - param_location = 'file' - params[param_location][param_name] = param_value + params['file'][param_name] = [param_value] + elif (param_location == 'form' and + self.openapi_types[param_name] == ([file_type],)): + # param_value is already a list + params['file'][param_name] = param_value elif param_location in {'form', 'query'}: param_value_full = (base_name, param_value) params[param_location].append(param_value_full) diff --git a/samples/client/petstore/python-experimental/petstore_api/api/store_api.py b/samples/client/petstore/python-experimental/petstore_api/api/store_api.py index 18cc23735e1c..cdeebcce432c 100644 --- a/samples/client/petstore/python-experimental/petstore_api/api/store_api.py +++ b/samples/client/petstore/python-experimental/petstore_api/api/store_api.py @@ -583,6 +583,8 @@ def __gather_params(self, kwargs): for param_name, param_value in six.iteritems(kwargs): param_location = self.location_map.get(param_name) + if param_location is None: + continue if param_location: if param_location == 'body': params['body'] = param_value @@ -590,8 +592,11 @@ def __gather_params(self, kwargs): base_name = self.attribute_map[param_name] if (param_location == 'form' and self.openapi_types[param_name] == (file_type,)): - param_location = 'file' - params[param_location][param_name] = param_value + params['file'][param_name] = [param_value] + elif (param_location == 'form' and + self.openapi_types[param_name] == ([file_type],)): + # param_value is already a list + params['file'][param_name] = param_value elif param_location in {'form', 'query'}: param_value_full = (base_name, param_value) params[param_location].append(param_value_full) diff --git a/samples/client/petstore/python-experimental/petstore_api/api/user_api.py b/samples/client/petstore/python-experimental/petstore_api/api/user_api.py index 8826867d5f0e..3e668cf374b5 100644 --- a/samples/client/petstore/python-experimental/petstore_api/api/user_api.py +++ b/samples/client/petstore/python-experimental/petstore_api/api/user_api.py @@ -996,6 +996,8 @@ def __gather_params(self, kwargs): for param_name, param_value in six.iteritems(kwargs): param_location = self.location_map.get(param_name) + if param_location is None: + continue if param_location: if param_location == 'body': params['body'] = param_value @@ -1003,8 +1005,11 @@ def __gather_params(self, kwargs): base_name = self.attribute_map[param_name] if (param_location == 'form' and self.openapi_types[param_name] == (file_type,)): - param_location = 'file' - params[param_location][param_name] = param_value + params['file'][param_name] = [param_value] + elif (param_location == 'form' and + self.openapi_types[param_name] == ([file_type],)): + # param_value is already a list + params['file'][param_name] = param_value elif param_location in {'form', 'query'}: param_value_full = (base_name, param_value) params[param_location].append(param_value_full) diff --git a/samples/client/petstore/python-experimental/petstore_api/api_client.py b/samples/client/petstore/python-experimental/petstore_api/api_client.py index bcf83024ce47..3cfe1c3ecc85 100644 --- a/samples/client/petstore/python-experimental/petstore_api/api_client.py +++ b/samples/client/petstore/python-experimental/petstore_api/api_client.py @@ -308,8 +308,8 @@ def call_api(self, resource_path, method, (float, none_type) ([int, none_type],) ({str: (bool, str, int, float, date, datetime, str, none_type)},) - :param files dict: key -> filename, value -> filepath, - for `multipart/form-data`. + :param files dict: key -> field name, value -> a list of open file + objects for `multipart/form-data`. :param async_req bool: execute request asynchronously :param _return_http_data_only: response data without head status code and headers @@ -446,29 +446,34 @@ def parameters_to_tuples(self, params, collection_formats): def files_parameters(self, files=None): """Builds form parameters. - :param files: None or a dict with key=param_name and value=file_object + :param files: None or a dict with key=param_name and + value is a list of open file objects :return: List of tuples of form parameters with file data """ if files is None: return [] params = [] - for param_name, file_instance in six.iteritems(files): - if file_instance is None: + for param_name, file_instances in six.iteritems(files): + if file_instances is None: # if the file field is nullable, skip None values continue - if file_instance.closed is True: - raise ApiValueError( - "Cannot read a closed file. The passed in file_type for " - "%s must be open." % param_name - ) - filename = os.path.basename(file_instance.name) - filedata = file_instance.read() - mimetype = (mimetypes.guess_type(filename)[0] or - 'application/octet-stream') - params.append( - tuple([param_name, tuple([filename, filedata, mimetype])])) - file_instance.close() + for file_instance in file_instances: + if file_instance is None: + # if the file field is nullable, skip None values + continue + if file_instance.closed is True: + raise ApiValueError( + "Cannot read a closed file. The passed in file_type " + "for %s must be open." % param_name + ) + filename = os.path.basename(file_instance.name) + filedata = file_instance.read() + mimetype = (mimetypes.guess_type(filename)[0] or + 'application/octet-stream') + params.append( + tuple([param_name, tuple([filename, filedata, mimetype])])) + file_instance.close() return params diff --git a/samples/client/petstore/python-experimental/petstore_api/configuration.py b/samples/client/petstore/python-experimental/petstore_api/configuration.py index 459ff6a3ca25..5e9d7b5d41d3 100644 --- a/samples/client/petstore/python-experimental/petstore_api/configuration.py +++ b/samples/client/petstore/python-experimental/petstore_api/configuration.py @@ -138,6 +138,8 @@ def __init__(self, host="http://petstore.swagger.io:80/v2", self.retries = None """Adding retries to override urllib3 default value 3 """ + # Disable client side validation + self.client_side_validation = True @property def logger_file(self): diff --git a/samples/client/petstore/python-experimental/testfiles/1px_pic1.png b/samples/client/petstore/python-experimental/testfiles/1px_pic1.png new file mode 100644 index 0000000000000000000000000000000000000000..7d3a386a21026f9b15b2c303a81f5c69333e9056 GIT binary patch literal 67 zcmeAS@N?(olHy`uVBq!ia0vp^j3CSbBp9sfW`_bPE>9Q7kcv6UzxWv#Ss9tmFVH&+ OlJ#`;b6Mw<&;$T@!wsPT literal 0 HcmV?d00001 diff --git a/samples/client/petstore/python-experimental/testfiles/1px_pic2.png b/samples/client/petstore/python-experimental/testfiles/1px_pic2.png new file mode 100644 index 0000000000000000000000000000000000000000..7d3a386a21026f9b15b2c303a81f5c69333e9056 GIT binary patch literal 67 zcmeAS@N?(olHy`uVBq!ia0vp^j3CSbBp9sfW`_bPE>9Q7kcv6UzxWv#Ss9tmFVH&+ OlJ#`;b6Mw<&;$T@!wsPT literal 0 HcmV?d00001 diff --git a/samples/client/petstore/python-experimental/tests/test_pet_api.py b/samples/client/petstore/python-experimental/tests/test_pet_api.py index 401cf76eef4c..8ceae8a7ee04 100644 --- a/samples/client/petstore/python-experimental/tests/test_pet_api.py +++ b/samples/client/petstore/python-experimental/tests/test_pet_api.py @@ -11,23 +11,35 @@ $ nosetests -v """ +from collections import namedtuple +import json import os import unittest import petstore_api from petstore_api import Configuration +from petstore_api.rest import ( + RESTClientObject, + RESTResponse +) + +import six from petstore_api.exceptions import ( ApiException, ApiValueError, + ApiTypeError, ) from .util import id_gen -import json - import urllib3 +if six.PY3: + from unittest.mock import patch +else: + from mock import patch + HOST = 'http://localhost/v2' @@ -249,9 +261,10 @@ def test_update_pet_with_form(self): def test_upload_file(self): # upload file with form parameter - file_path = os.path.join(self.test_file_dir, "foo.png") + file_path1 = os.path.join(self.test_file_dir, "1px_pic1.png") + file_path2 = os.path.join(self.test_file_dir, "1px_pic2.png") try: - file = open(file_path, "rb") + file = open(file_path1, "rb") additional_metadata = "special" self.pet_api.upload_file( pet_id=self.pet.id, @@ -263,18 +276,91 @@ def test_upload_file(self): finally: file.close() - # upload only file + # upload only one file try: - file = open(file_path, "rb") + file = open(file_path1, "rb") self.pet_api.upload_file(pet_id=self.pet.id, file=file) except ApiException as e: self.fail("upload_file() raised {0} unexpectedly".format(type(e))) finally: file.close() + # upload multiple files + HTTPResponse = namedtuple( + 'urllib3_response_HTTPResponse', + ['status', 'reason', 'data', 'getheaders', 'getheader'] + ) + headers = {} + def get_headers(): + return headers + def get_header(name, default=None): + return headers.get(name, default) + api_respponse = { + 'code': 200, + 'type': 'blah', + 'message': 'file upload succeeded' + } + http_response = HTTPResponse( + status=200, + reason='OK', + data=json.dumps(api_respponse), + getheaders=get_headers, + getheader=get_header + ) + # response which is deserialized to a file + mock_response = RESTResponse(http_response) + try: + file1 = open(file_path1, "rb") + file2 = open(file_path2, "rb") + with patch.object(RESTClientObject, 'request') as mock_method: + mock_method.return_value = mock_response + res = self.pet_api.upload_file( + pet_id=684696917, files=[file1, file2]) + mock_method.assert_called_with( + 'POST', + 'http://localhost/v2/pet/684696917/uploadImage', + _preload_content=True, + _request_timeout=None, + body=None, + headers={ + 'Accept': 'application/json', + 'Content-Type': 'multipart/form-data', + 'User-Agent': 'OpenAPI-Generator/1.0.0/python', + 'Authorization': 'Bearer ' + }, + post_params=[ + ('files', ('1px_pic1.png', b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x01\x00\x00\x00\x01\x08\x00\x00\x00\x00:~\x9bU\x00\x00\x00\nIDATx\x9cc\xfa\x0f\x00\x01\x05\x01\x02\xcf\xa0.\xcd\x00\x00\x00\x00IEND\xaeB`\x82', 'image/png')), + ('files', ('1px_pic2.png', b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x01\x00\x00\x00\x01\x08\x00\x00\x00\x00:~\x9bU\x00\x00\x00\nIDATx\x9cc\xfa\x0f\x00\x01\x05\x01\x02\xcf\xa0.\xcd\x00\x00\x00\x00IEND\xaeB`\x82', 'image/png')) + ], + query_params=[] + ) + except ApiException as e: + self.fail("upload_file() raised {0} unexpectedly".format(type(e))) + finally: + file1.close() + file2.close() + + # passing in an array of files to when file only allows one + # raises an exceptions + try: + file = open(file_path1, "rb") + with self.assertRaises(ApiTypeError) as exc: + self.pet_api.upload_file(pet_id=self.pet.id, file=[file]) + finally: + file.close() + + # passing in a single file when an array of file is required + # raises an exception + try: + file = open(file_path1, "rb") + with self.assertRaises(ApiTypeError) as exc: + self.pet_api.upload_file(pet_id=self.pet.id, files=file) + finally: + file.close() + # passing in a closed file raises an exception with self.assertRaises(ApiValueError) as exc: - file = open(file_path, "rb") + file = open(file_path1, "rb") file.close() self.pet_api.upload_file(pet_id=self.pet.id, file=file) From 0c10c0b82f4fcb55d1c727365f62004dc6a376c7 Mon Sep 17 00:00:00 2001 From: Justin Black Date: Mon, 21 Oct 2019 23:54:20 -0700 Subject: [PATCH 10/13] Removes comment --- .../client/petstore/python-experimental/tests/test_pet_api.py | 1 - 1 file changed, 1 deletion(-) diff --git a/samples/client/petstore/python-experimental/tests/test_pet_api.py b/samples/client/petstore/python-experimental/tests/test_pet_api.py index 8ceae8a7ee04..5e1dd8528c9c 100644 --- a/samples/client/petstore/python-experimental/tests/test_pet_api.py +++ b/samples/client/petstore/python-experimental/tests/test_pet_api.py @@ -307,7 +307,6 @@ def get_header(name, default=None): getheaders=get_headers, getheader=get_header ) - # response which is deserialized to a file mock_response = RESTResponse(http_response) try: file1 = open(file_path1, "rb") From 87788c6f079c71bc255392ffbb296eee3e0d406a Mon Sep 17 00:00:00 2001 From: Justin Black Date: Tue, 22 Oct 2019 00:36:40 -0700 Subject: [PATCH 11/13] Fixes mock installation in python2 --- .../src/main/resources/python/test-requirements.mustache | 2 ++ .../client/petstore/python-experimental/test-requirements.txt | 2 ++ 2 files changed, 4 insertions(+) diff --git a/modules/openapi-generator/src/main/resources/python/test-requirements.mustache b/modules/openapi-generator/src/main/resources/python/test-requirements.mustache index d9e3f20b5369..023ff960788a 100644 --- a/modules/openapi-generator/src/main/resources/python/test-requirements.mustache +++ b/modules/openapi-generator/src/main/resources/python/test-requirements.mustache @@ -9,3 +9,5 @@ pytest-cov>=2.6.1 pluggy>=0.3.1 py>=1.4.31 randomize>=0.13 +mock; python_version<="2.7" + diff --git a/samples/client/petstore/python-experimental/test-requirements.txt b/samples/client/petstore/python-experimental/test-requirements.txt index 2702246c0e6f..5816b8749532 100644 --- a/samples/client/petstore/python-experimental/test-requirements.txt +++ b/samples/client/petstore/python-experimental/test-requirements.txt @@ -3,3 +3,5 @@ nose>=1.3.7 pluggy>=0.3.1 py>=1.4.31 randomize>=0.13 +mock; python_version<="2.7" + From 43062b77fa9038fce60b8c9b1779af4d46931c05 Mon Sep 17 00:00:00 2001 From: Justin Black Date: Tue, 22 Oct 2019 08:46:13 -0700 Subject: [PATCH 12/13] Limit mock addition to python-experimental test requirements only --- .../languages/PythonClientExperimentalCodegen.java | 2 ++ .../python-experimental/test-requirements.mustache | 13 +++++++++++++ .../resources/python/test-requirements.mustache | 2 -- 3 files changed, 15 insertions(+), 2 deletions(-) create mode 100644 modules/openapi-generator/src/main/resources/python/python-experimental/test-requirements.mustache diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PythonClientExperimentalCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PythonClientExperimentalCodegen.java index 8ae19362557d..13cbb443aab4 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PythonClientExperimentalCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PythonClientExperimentalCodegen.java @@ -89,6 +89,8 @@ public void processOpts() { supportingFiles.add(new SupportingFile("python-experimental/setup.mustache", "", "setup.py")); supportingFiles.remove(new SupportingFile("requirements.mustache", "", "requirements.txt")); supportingFiles.add(new SupportingFile("python-experimental/requirements.mustache", "", "requirements.txt")); + supportingFiles.remove(new SupportingFile("test-requirements.mustache", "", "test-requirements.txt")); + supportingFiles.add(new SupportingFile("python-experimental/test-requirements.mustache", "", "test-requirements.txt")); } // default this to true so the python ModelSimple models will be generated diff --git a/modules/openapi-generator/src/main/resources/python/python-experimental/test-requirements.mustache b/modules/openapi-generator/src/main/resources/python/python-experimental/test-requirements.mustache new file mode 100644 index 000000000000..023ff960788a --- /dev/null +++ b/modules/openapi-generator/src/main/resources/python/python-experimental/test-requirements.mustache @@ -0,0 +1,13 @@ +{{^asyncio}} +coverage>=4.0.3 +nose>=1.3.7 +{{/asyncio}} +{{#asyncio}} +pytest>=3.6.0 +pytest-cov>=2.6.1 +{{/asyncio}} +pluggy>=0.3.1 +py>=1.4.31 +randomize>=0.13 +mock; python_version<="2.7" + diff --git a/modules/openapi-generator/src/main/resources/python/test-requirements.mustache b/modules/openapi-generator/src/main/resources/python/test-requirements.mustache index 023ff960788a..d9e3f20b5369 100644 --- a/modules/openapi-generator/src/main/resources/python/test-requirements.mustache +++ b/modules/openapi-generator/src/main/resources/python/test-requirements.mustache @@ -9,5 +9,3 @@ pytest-cov>=2.6.1 pluggy>=0.3.1 py>=1.4.31 randomize>=0.13 -mock; python_version<="2.7" - From 8e4e58bdf820cb683e5579c240a54ac1e97f069f Mon Sep 17 00:00:00 2001 From: Justin Black Date: Wed, 23 Oct 2019 10:50:06 -0700 Subject: [PATCH 13/13] Removes SmartBear copyright line --- .../codegen/python/PythonClientExperimentalTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/python/PythonClientExperimentalTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/python/PythonClientExperimentalTest.java index 6ddfe891d2f7..d85652ee4b2f 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/python/PythonClientExperimentalTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/python/PythonClientExperimentalTest.java @@ -1,6 +1,5 @@ /* * Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech) - * Copyright 2018 SmartBear Software * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License.