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% 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/PythonClientExperimentalCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PythonClientExperimentalCodegen.java index 71dd5d61133e..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 @@ -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,20 @@ 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")); + 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 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 +213,20 @@ 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); + 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"); + // 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 +240,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 +553,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 +616,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 +628,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 +645,147 @@ 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); + } + } + + @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/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/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..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 @@ -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, @@ -316,14 +379,20 @@ 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 continue base_name = self.attribute_map[param_name] if (param_location == 'form' and - self.openapi_types[param_name] == 'file'): - param_location = 'file' + self.openapi_types[param_name] == (file_type,)): + 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) @@ -348,20 +417,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 +434,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 +477,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..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 @@ -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,9 +305,18 @@ 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 files dict: key -> filename, value -> filepath, - for `multipart/form-data`. + :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 -> 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 @@ -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,34 @@ 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 is a list of open file objects + :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: + params = [] + for param_name, file_instances in six.iteritems(files): + if file_instances is None: + # if the file field is nullable, skip None values + continue + for file_instance in file_instances: + if file_instance is None: + # if the file field is nullable, skip None values 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])])) + 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 +541,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/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/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..d85652ee4b2f --- /dev/null +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/python/PythonClientExperimentalTest.java @@ -0,0 +1,296 @@ +/* + * Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech) + * + * 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/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-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-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/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..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 | 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) @@ -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/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/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/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/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..8364f8fa8fc8 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,11 +464,12 @@ 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 = 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) @@ -480,7 +481,8 @@ 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] + **files** | [**[file_type]**](file_type.md)| files to upload | [optional] ### Return type @@ -525,7 +527,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 = open('/path/to/file', 'rb') # file_type | file to upload additional_metadata = 'additional_metadata_example' # str | Additional data to pass to server (optional) try: @@ -541,7 +543,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/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) 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..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 @@ -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, @@ -207,14 +268,20 @@ 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 continue base_name = self.attribute_map[param_name] if (param_location == 'form' and - self.openapi_types[param_name] == 'file'): - param_location = 'file' + self.openapi_types[param_name] == (file_type,)): + 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) @@ -239,20 +306,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 +323,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 +366,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..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 @@ -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, @@ -1591,14 +2036,20 @@ 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 continue base_name = self.attribute_map[param_name] if (param_location == 'form' and - self.openapi_types[param_name] == 'file'): - param_location = 'file' + self.openapi_types[param_name] == (file_type,)): + 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) @@ -1623,20 +2074,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 +2091,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 +2134,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..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 @@ -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, @@ -209,14 +270,20 @@ 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 continue base_name = self.attribute_map[param_name] if (param_location == 'form' and - self.openapi_types[param_name] == 'file'): - param_location = 'file' + self.openapi_types[param_name] == (file_type,)): + 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) @@ -241,20 +308,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 +325,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 +368,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..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 @@ -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,58 @@ 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 [file_type] files: files 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' ], @@ -674,6 +900,7 @@ def __upload_file(self, pet_id, **kwargs): # noqa: E501 'pet_id', 'additional_metadata', 'file', + 'files', ], 'required': [ 'pet_id', @@ -691,21 +918,25 @@ 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,), + '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={ @@ -729,31 +960,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 +1043,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 +1080,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 +1116,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 +1147,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 +1158,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, @@ -901,14 +1185,20 @@ 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 continue base_name = self.attribute_map[param_name] if (param_location == 'form' and - self.openapi_types[param_name] == 'file'): - param_location = 'file' + self.openapi_types[param_name] == (file_type,)): + 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) @@ -933,20 +1223,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 +1240,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 +1283,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..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 @@ -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, @@ -441,14 +583,20 @@ 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 continue base_name = self.attribute_map[param_name] if (param_location == 'form' and - self.openapi_types[param_name] == 'file'): - param_location = 'file' + self.openapi_types[param_name] == (file_type,)): + 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) @@ -473,20 +621,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 +638,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 +681,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..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 @@ -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, @@ -746,14 +996,20 @@ 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 continue base_name = self.attribute_map[param_name] if (param_location == 'form' and - self.openapi_types[param_name] == 'file'): - param_location = 'file' + self.openapi_types[param_name] == (file_type,)): + 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) @@ -778,20 +1034,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 +1051,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 +1094,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..3cfe1c3ecc85 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,9 +298,18 @@ 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 files dict: key -> filename, value -> filepath, - for `multipart/form-data`. + :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 -> 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 @@ -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,34 @@ 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 is a list of open file objects + :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: + params = [] + for param_name, file_instances in six.iteritems(files): + if file_instances is None: + # if the file field is nullable, skip None values + continue + for file_instance in file_instances: + if file_instance is None: + # if the file field is nullable, skip None values 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])])) + 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 +534,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/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/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-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" + 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/testfiles/1px_pic1.png b/samples/client/petstore/python-experimental/testfiles/1px_pic1.png new file mode 100644 index 000000000000..7d3a386a2102 Binary files /dev/null and b/samples/client/petstore/python-experimental/testfiles/1px_pic1.png differ 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 000000000000..7d3a386a2102 Binary files /dev/null and b/samples/client/petstore/python-experimental/testfiles/1px_pic2.png differ 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..5e1dd8528c9c 100644 --- a/samples/client/petstore/python-experimental/tests/test_pet_api.py +++ b/samples/client/petstore/python-experimental/tests/test_pet_api.py @@ -11,19 +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 ApiException +from petstore_api.rest import ( + RESTClientObject, + RESTResponse +) -from .util import id_gen +import six -import json +from petstore_api.exceptions import ( + ApiException, + ApiValueError, + ApiTypeError, +) + +from .util import id_gen import urllib3 +if six.PY3: + from unittest.mock import patch +else: + from mock import patch + HOST = 'http://localhost/v2' @@ -78,7 +94,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 +188,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 +261,108 @@ def test_update_pet_with_form(self): def test_upload_file(self): # upload file with form parameter + 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_path1, "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 one file + try: + 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 only file + # 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 + ) + mock_response = RESTResponse(http_response) try: - self.pet_api.upload_file(pet_id=self.pet.id, file=self.foo) + 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_path1, "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): 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