Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 13 additions & 13 deletions modules/openapi-generator/src/main/resources/python/api.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,8 @@ class {{classname}}(object):
{{^isNullable}}
{{#required}}
# verify the required parameter '{{paramName}}' is set
if ('{{paramName}}' not in local_var_params or
local_var_params['{{paramName}}'] is None):
if self.api_client.client_side_validation and ('{{paramName}}' not in local_var_params or # noqa: E501
local_var_params['{{paramName}}'] is None): # noqa: E501
raise ApiValueError("Missing the required parameter `{{paramName}}` when calling `{{operationId}}`") # noqa: E501
{{/required}}
{{/isNullable}}
Expand All @@ -136,35 +136,35 @@ class {{classname}}(object):
{{#allParams}}
{{#hasValidation}}
{{#maxLength}}
if ('{{paramName}}' in local_var_params and
len(local_var_params['{{paramName}}']) > {{maxLength}}):
if self.api_client.client_side_validation and ('{{paramName}}' in local_var_params and # noqa: E501
len(local_var_params['{{paramName}}']) > {{maxLength}}): # noqa: E501
raise ApiValueError("Invalid value for parameter `{{paramName}}` when calling `{{operationId}}`, length must be less than or equal to `{{maxLength}}`") # noqa: E501
{{/maxLength}}
{{#minLength}}
if ('{{paramName}}' in local_var_params and
len(local_var_params['{{paramName}}']) < {{minLength}}):
if self.api_client.client_side_validation and ('{{paramName}}' in local_var_params and # noqa: E501
len(local_var_params['{{paramName}}']) < {{minLength}}): # noqa: E501
raise ApiValueError("Invalid value for parameter `{{paramName}}` when calling `{{operationId}}`, length must be greater than or equal to `{{minLength}}`") # noqa: E501
{{/minLength}}
{{#maximum}}
if '{{paramName}}' in local_var_params and local_var_params['{{paramName}}'] >{{#exclusiveMaximum}}={{/exclusiveMaximum}} {{maximum}}: # noqa: E501
if self.api_client.client_side_validation and '{{paramName}}' in local_var_params and local_var_params['{{paramName}}'] >{{#exclusiveMaximum}}={{/exclusiveMaximum}} {{maximum}}: # noqa: E501
raise ApiValueError("Invalid value for parameter `{{paramName}}` when calling `{{operationId}}`, must be a value less than {{^exclusiveMaximum}}or equal to {{/exclusiveMaximum}}`{{maximum}}`") # noqa: E501
{{/maximum}}
{{#minimum}}
if '{{paramName}}' in local_var_params and local_var_params['{{paramName}}'] <{{#exclusiveMinimum}}={{/exclusiveMinimum}} {{minimum}}: # noqa: E501
if self.api_client.client_side_validation and '{{paramName}}' in local_var_params and local_var_params['{{paramName}}'] <{{#exclusiveMinimum}}={{/exclusiveMinimum}} {{minimum}}: # noqa: E501
raise ApiValueError("Invalid value for parameter `{{paramName}}` when calling `{{operationId}}`, must be a value greater than {{^exclusiveMinimum}}or equal to {{/exclusiveMinimum}}`{{minimum}}`") # noqa: E501
{{/minimum}}
{{#pattern}}
if '{{paramName}}' in local_var_params and not re.search(r'{{{vendorExtensions.x-regex}}}', local_var_params['{{paramName}}']{{#vendorExtensions.x-modifiers}}{{#-first}}, flags={{/-first}}re.{{.}}{{^-last}} | {{/-last}}{{/vendorExtensions.x-modifiers}}): # noqa: E501
if self.api_client.client_side_validation and '{{paramName}}' in local_var_params and not re.search(r'{{{vendorExtensions.x-regex}}}', local_var_params['{{paramName}}']{{#vendorExtensions.x-modifiers}}{{#-first}}, flags={{/-first}}re.{{.}}{{^-last}} | {{/-last}}{{/vendorExtensions.x-modifiers}}): # noqa: E501
raise ApiValueError("Invalid value for parameter `{{paramName}}` when calling `{{operationId}}`, must conform to the pattern `{{{pattern}}}`") # noqa: E501
{{/pattern}}
{{#maxItems}}
if ('{{paramName}}' in local_var_params and
len(local_var_params['{{paramName}}']) > {{maxItems}}):
if self.api_client.client_side_validation and ('{{paramName}}' in local_var_params and # noqa: E501
len(local_var_params['{{paramName}}']) > {{maxItems}}): # noqa: E501
raise ApiValueError("Invalid value for parameter `{{paramName}}` when calling `{{operationId}}`, number of items must be less than or equal to `{{maxItems}}`") # noqa: E501
{{/maxItems}}
{{#minItems}}
if ('{{paramName}}' in local_var_params and
len(local_var_params['{{paramName}}']) < {{minItems}}):
if self.api_client.client_side_validation and ('{{paramName}}' in local_var_params and # noqa: E501
len(local_var_params['{{paramName}}']) < {{minItems}}): # noqa: E501
raise ApiValueError("Invalid value for parameter `{{paramName}}` when calling `{{operationId}}`, number of items must be greater than or equal to `{{minItems}}`") # noqa: E501
{{/minItems}}
{{/hasValidation}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ class ApiClient(object):
self.cookie = cookie
# Set default User-Agent.
self.user_agent = '{{#httpUserAgent}}{{{.}}}{{/httpUserAgent}}{{^httpUserAgent}}OpenAPI-Generator/{{{packageVersion}}}/python{{/httpUserAgent}}'
self.client_side_validation = configuration.client_side_validation

def __del__(self):
if self._pool:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,8 @@ class Configuration(six.with_metaclass(TypeWithDefault, object)):
self.retries = None
"""Adding retries to override urllib3 default value 3
"""
# Disable client side validation
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@wing328 typo? Shouldn't this be "Enable"

self.client_side_validation = True

@property
def logger_file(self):
Expand Down
45 changes: 31 additions & 14 deletions modules/openapi-generator/src/main/resources/python/model.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import re # noqa: F401

import six

from {{packageName}}.configuration import Configuration


{{#models}}
{{#model}}
Expand Down Expand Up @@ -51,8 +53,11 @@ class {{classname}}(object):
}
{{/discriminator}}

def __init__(self{{#vars}}, {{name}}={{#defaultValue}}{{{defaultValue}}}{{/defaultValue}}{{^defaultValue}}None{{/defaultValue}}{{/vars}}): # noqa: E501
def __init__(self{{#vars}}, {{name}}={{#defaultValue}}{{{defaultValue}}}{{/defaultValue}}{{^defaultValue}}None{{/defaultValue}}{{/vars}}, local_vars_configuration=None): # noqa: E501
"""{{classname}} - a model defined in OpenAPI""" # noqa: E501
if local_vars_configuration is None:
local_vars_configuration = Configuration()
self.local_vars_configuration = local_vars_configuration
{{#vars}}{{#-first}}
{{/-first}}
self._{{name}} = None
Expand Down Expand Up @@ -101,23 +106,25 @@ class {{classname}}(object):
"""
{{^isNullable}}
{{#required}}
if {{name}} is None:
if self.local_vars_configuration.client_side_validation and {{name}} is None: # noqa: E501
raise ValueError("Invalid value for `{{name}}`, must not be `None`") # noqa: E501
{{/required}}
{{/isNullable}}
{{#isEnum}}
{{#isContainer}}
allowed_values = [{{#isNullable}}None,{{/isNullable}}{{#allowableValues}}{{#values}}{{#items.isString}}"{{/items.isString}}{{{this}}}{{#items.isString}}"{{/items.isString}}{{^-last}}, {{/-last}}{{/values}}{{/allowableValues}}] # noqa: E501
{{#isListContainer}}
if not set({{{name}}}).issubset(set(allowed_values)):
if (self.local_vars_configuration.client_side_validation and
not set({{{name}}}).issubset(set(allowed_values))):
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
", ".join(map(str, allowed_values)))
)
{{/isListContainer}}
{{#isMapContainer}}
if not set({{{name}}}.keys()).issubset(set(allowed_values)):
if (self.local_vars_configuration.client_side_validation and
not set({{{name}}}.keys()).issubset(set(allowed_values))):
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
Expand All @@ -127,7 +134,7 @@ class {{classname}}(object):
{{/isContainer}}
{{^isContainer}}
allowed_values = [{{#isNullable}}None,{{/isNullable}}{{#allowableValues}}{{#values}}{{#isString}}"{{/isString}}{{{this}}}{{#isString}}"{{/isString}}{{^-last}}, {{/-last}}{{/values}}{{/allowableValues}}] # noqa: E501
if {{{name}}} not in allowed_values:
if self.local_vars_configuration.client_side_validation and {{{name}}} not in allowed_values: # noqa: E501
raise ValueError(
"Invalid value for `{{{name}}}` ({0}), must be one of {1}" # noqa: E501
.format({{{name}}}, allowed_values)
Expand All @@ -137,31 +144,38 @@ class {{classname}}(object):
{{^isEnum}}
{{#hasValidation}}
{{#maxLength}}
if {{name}} is not None and len({{name}}) > {{maxLength}}:
if (self.local_vars_configuration.client_side_validation and
{{name}} is not None and len({{name}}) > {{maxLength}}):
raise ValueError("Invalid value for `{{name}}`, length must be less than or equal to `{{maxLength}}`") # noqa: E501
{{/maxLength}}
{{#minLength}}
if {{name}} is not None and len({{name}}) < {{minLength}}:
if (self.local_vars_configuration.client_side_validation and
{{name}} is not None and len({{name}}) < {{minLength}}):
raise ValueError("Invalid value for `{{name}}`, length must be greater than or equal to `{{minLength}}`") # noqa: E501
{{/minLength}}
{{#maximum}}
if {{name}} is not None and {{name}} >{{#exclusiveMaximum}}={{/exclusiveMaximum}} {{maximum}}: # noqa: E501
if (self.local_vars_configuration.client_side_validation and
{{name}} is not None and {{name}} >{{#exclusiveMaximum}}={{/exclusiveMaximum}} {{maximum}}): # noqa: E501
raise ValueError("Invalid value for `{{name}}`, must be a value less than {{^exclusiveMaximum}}or equal to {{/exclusiveMaximum}}`{{maximum}}`") # noqa: E501
{{/maximum}}
{{#minimum}}
if {{name}} is not None and {{name}} <{{#exclusiveMinimum}}={{/exclusiveMinimum}} {{minimum}}: # noqa: E501
if (self.local_vars_configuration.client_side_validation and
{{name}} is not None and {{name}} <{{#exclusiveMinimum}}={{/exclusiveMinimum}} {{minimum}}): # noqa: E501
raise ValueError("Invalid value for `{{name}}`, must be a value greater than {{^exclusiveMinimum}}or equal to {{/exclusiveMinimum}}`{{minimum}}`") # noqa: E501
{{/minimum}}
{{#pattern}}
if {{name}} is not None and not re.search(r'{{{vendorExtensions.x-regex}}}', {{name}}{{#vendorExtensions.x-modifiers}}{{#-first}}, flags={{/-first}}re.{{.}}{{^-last}} | {{/-last}}{{/vendorExtensions.x-modifiers}}): # noqa: E501
if (self.local_vars_configuration.client_side_validation and
{{name}} is not None and not re.search(r'{{{vendorExtensions.x-regex}}}', {{name}}{{#vendorExtensions.x-modifiers}}{{#-first}}, flags={{/-first}}re.{{.}}{{^-last}} | {{/-last}}{{/vendorExtensions.x-modifiers}})): # noqa: E501
raise ValueError(r"Invalid value for `{{name}}`, must be a follow pattern or equal to `{{{pattern}}}`") # noqa: E501
{{/pattern}}
{{#maxItems}}
if {{name}} is not None and len({{name}}) > {{maxItems}}:
if (self.local_vars_configuration.client_side_validation and
{{name}} is not None and len({{name}}) > {{maxItems}}):
raise ValueError("Invalid value for `{{name}}`, number of items must be less than or equal to `{{maxItems}}`") # noqa: E501
{{/maxItems}}
{{#minItems}}
if {{name}} is not None and len({{name}}) < {{minItems}}:
if (self.local_vars_configuration.client_side_validation and
{{name}} is not None and len({{name}}) < {{minItems}}):
raise ValueError("Invalid value for `{{name}}`, number of items must be greater than or equal to `{{minItems}}`") # noqa: E501
{{/minItems}}
{{/hasValidation}}
Expand Down Expand Up @@ -215,10 +229,13 @@ class {{classname}}(object):
if not isinstance(other, {{classname}}):
return False

return self.__dict__ == other.__dict__
return self.to_dict() == other.to_dict()
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the reason to use to_dict() instead of __dict__?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So far configuration was not part of the model, now configuration is. So if the user does not provide configuration. The configuration is initialized since two objects have different configuration self.dict == other.dict will return false even though its the same object.

Test("abc") will not be equal to Test("abc") since configuration objects inside both are different. This change is required to prevent this behaviour

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@slash-arun thanks for the explanation. I wonder if you can add test cases to https://github.com/OpenAPITools/openapi-generator/tree/master/samples/client/petstore/python/tests to cover the issue moving forward.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, will work on the test cases


def __ne__(self, other):
"""Returns true if both objects are not equal"""
return not self == other
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Performance would not self == other be better?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This again relates to the configuration object. Since Test("abc") will not be equal to Test("abc") because config is initialized separately for both the objects.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@slash-arun thanks for the explanation. I wonder if you can add test cases to https://github.com/OpenAPITools/openapi-generator/tree/master/samples/client/petstore/python/tests to cover the issue moving forward.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, will work on the test cases

if not isinstance(other, {{classname}}):
return True

return self.to_dict() != other.to_dict()
{{/model}}
{{/models}}
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,8 @@ def call_123_test_special_tags_with_http_info(self, body, **kwargs): # noqa: E5
local_var_params[key] = val
del local_var_params['kwargs']
# verify the required parameter 'body' is set
if ('body' not in local_var_params or
local_var_params['body'] is None):
if self.api_client.client_side_validation and ('body' not in local_var_params or # noqa: E501
local_var_params['body'] is None): # noqa: E501
raise ApiValueError("Missing the required parameter `body` when calling `call_123_test_special_tags`") # noqa: E501

collection_formats = {}
Expand Down
Loading