From 1fa71ad65ed0f778b3e39152c7a5c2e70d8e4c6c Mon Sep 17 00:00:00 2001
From: "Sebastien Rosset (serosset)" <serosset@cisco.com>
Date: Fri, 8 May 2020 16:32:17 -0700
Subject: [PATCH 01/11] Add knob to disable JSON schema structural validation

---
 .../main/resources/python/configuration.mustache   | 14 ++++++++++++++
 .../python/python-experimental/api.mustache        |  3 ++-
 .../model_templates/method_set_attribute.mustache  |  3 ++-
 .../python-experimental/model_utils.mustache       | 14 ++++++++++----
 4 files changed, 28 insertions(+), 6 deletions(-)

diff --git a/modules/openapi-generator/src/main/resources/python/configuration.mustache b/modules/openapi-generator/src/main/resources/python/configuration.mustache
index dceab63e67b..277e3f197d4 100644
--- a/modules/openapi-generator/src/main/resources/python/configuration.mustache
+++ b/modules/openapi-generator/src/main/resources/python/configuration.mustache
@@ -43,6 +43,18 @@ class Configuration(object):
       then all undeclared properties received by the server are injected into the
       additional properties map. In that case, there are undeclared properties, and
       nothing to discard.
+    :param disable_validation: Boolean value indicating whether to disable the JSON
+      schema structural validation rules specified in the OpenAPI document.
+      This includes multipleOf, maximum, exclusiveMaximum, minimum, exclusiveMinimum,
+      maxLength, minLength, pattern...
+      By default, the validation is performed for data generated locally by the client
+      and data received from the server, independent of any validation performed by
+      the server side.
+      If the input data does not satisfy the JSON schema validation rules specified
+      in the OpenAPI document, an exception is raised.
+      If disable_validation is set to true, structural validation is disabled. This
+      can be useful to troubleshoot data validation problem, such as when the OpenAPI
+      document validation rules do not match the actual API data received by the server.
 {{#hasHttpSignatureMethods}}
     :param signing_info: Configuration parameters for the HTTP signature security scheme.
         Must be an instance of {{{packageName}}}.signing.HttpSigningConfiguration
@@ -139,6 +151,7 @@ conf = {{{packageName}}}.Configuration(
                  api_key=None, api_key_prefix=None,
                  username=None, password=None,
                  discard_unknown_keys=False,
+                 disable_validation=False,
 {{#hasHttpSignatureMethods}}
                  signing_info=None,
 {{/hasHttpSignatureMethods}}
@@ -172,6 +185,7 @@ conf = {{{packageName}}}.Configuration(
         """Password for HTTP basic authentication
         """
         self.discard_unknown_keys = discard_unknown_keys
+        self.disable_validation = disable_validation
 {{#hasHttpSignatureMethods}}
         if signing_info is not None:
             signing_info.host = host
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 4cf1d423e83..44fc3a89970 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
@@ -376,7 +376,8 @@ class Endpoint(object):
                 check_validations(
                     self.validations,
                     (param,),
-                    kwargs[param]
+                    kwargs[param],
+                    configuration=self.api_client.configuration
                 )
 
         if kwargs['_check_input_type'] is False:
diff --git a/modules/openapi-generator/src/main/resources/python/python-experimental/model_templates/method_set_attribute.mustache b/modules/openapi-generator/src/main/resources/python/python-experimental/model_templates/method_set_attribute.mustache
index f4a36e42f25..e52d9ea6941 100644
--- a/modules/openapi-generator/src/main/resources/python/python-experimental/model_templates/method_set_attribute.mustache
+++ b/modules/openapi-generator/src/main/resources/python/python-experimental/model_templates/method_set_attribute.mustache
@@ -44,6 +44,7 @@
             check_validations(
                 self.validations,
                 (name,),
-                value
+                value,
+                self._configuration
             )
         self.__dict__['_data_store'][name] = value
\ No newline at end of file
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 e6b1df6b0e9..1d9b346b812 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
@@ -299,15 +299,21 @@ def check_allowed_values(allowed_values, input_variable_path, input_values):
         )
 
 
-def check_validations(validations, input_variable_path, input_values):
+def check_validations(validations, input_variable_path, input_values,
+                        configuration=None):
     """Raises an exception if the input_values are invalid
 
     Args:
-        validations (dict): the validation dictionary
-        input_variable_path (tuple): the path to the input variable
+        validations (dict): the validation dictionary.
+        input_variable_path (tuple): the path to the input variable.
         input_values (list/str/int/float/date/datetime): the values that we
-            are checking
+            are checking.
+        configuration (Configuration): the configuration class.
     """
+    if configuration is not None and configuration.disable_validation:
+        # Skip JSON schema structural validation.
+        return
+
     current_validations = validations[input_variable_path]
     if ('max_length' in current_validations and
             len(input_values) > current_validations['max_length']):
-- 
GitLab


From 8c8ff6a2c572cbdf9466a1b1a3206ebc4a06383a Mon Sep 17 00:00:00 2001
From: "Sebastien Rosset (serosset)" <serosset@cisco.com>
Date: Fri, 8 May 2020 16:33:23 -0700
Subject: [PATCH 02/11] Add knob to disable JSON schema structural validation

---
 .../petstore_api/api/another_fake_api.py        |  3 ++-
 .../petstore_api/api/fake_api.py                |  3 ++-
 .../api/fake_classname_tags_123_api.py          |  3 ++-
 .../petstore_api/api/pet_api.py                 |  3 ++-
 .../petstore_api/api/store_api.py               |  3 ++-
 .../petstore_api/api/user_api.py                |  3 ++-
 .../petstore_api/configuration.py               | 14 ++++++++++++++
 .../petstore_api/model_utils.py                 | 17 ++++++++++++-----
 .../petstore_api/api/another_fake_api.py        |  3 ++-
 .../petstore_api/api/default_api.py             |  3 ++-
 .../petstore_api/api/fake_api.py                |  3 ++-
 .../api/fake_classname_tags_123_api.py          |  3 ++-
 .../petstore_api/api/pet_api.py                 |  3 ++-
 .../petstore_api/api/store_api.py               |  3 ++-
 .../petstore_api/api/user_api.py                |  3 ++-
 .../petstore_api/configuration.py               | 14 ++++++++++++++
 .../petstore_api/model_utils.py                 | 17 ++++++++++++-----
 17 files changed, 78 insertions(+), 23 deletions(-)

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 2db9b6de925..b7ea5e54932 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
@@ -249,7 +249,8 @@ class Endpoint(object):
                 check_validations(
                     self.validations,
                     (param,),
-                    kwargs[param]
+                    kwargs[param],
+                    configuration=self.api_client.configuration
                 )
 
         if kwargs['_check_input_type'] is False:
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 8c50f5e15d5..e97902bb9a2 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
@@ -2192,7 +2192,8 @@ class Endpoint(object):
                 check_validations(
                     self.validations,
                     (param,),
-                    kwargs[param]
+                    kwargs[param],
+                    configuration=self.api_client.configuration
                 )
 
         if kwargs['_check_input_type'] is False:
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 ab817996b0e..863e64beb0b 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
@@ -251,7 +251,8 @@ class Endpoint(object):
                 check_validations(
                     self.validations,
                     (param,),
-                    kwargs[param]
+                    kwargs[param],
+                    configuration=self.api_client.configuration
                 )
 
         if kwargs['_check_input_type'] is False:
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 829534ed790..3d289a66988 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
@@ -1256,7 +1256,8 @@ class Endpoint(object):
                 check_validations(
                     self.validations,
                     (param,),
-                    kwargs[param]
+                    kwargs[param],
+                    configuration=self.api_client.configuration
                 )
 
         if kwargs['_check_input_type'] is False:
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 890474acc03..bcae5aab2a6 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
@@ -590,7 +590,8 @@ class Endpoint(object):
                 check_validations(
                     self.validations,
                     (param,),
-                    kwargs[param]
+                    kwargs[param],
+                    configuration=self.api_client.configuration
                 )
 
         if kwargs['_check_input_type'] is False:
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 74389cbf242..1362c5e3110 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
@@ -1049,7 +1049,8 @@ class Endpoint(object):
                 check_validations(
                     self.validations,
                     (param,),
-                    kwargs[param]
+                    kwargs[param],
+                    configuration=self.api_client.configuration
                 )
 
         if kwargs['_check_input_type'] is False:
diff --git a/samples/client/petstore/python-experimental/petstore_api/configuration.py b/samples/client/petstore/python-experimental/petstore_api/configuration.py
index 32406df02f5..f54f947ba1a 100644
--- a/samples/client/petstore/python-experimental/petstore_api/configuration.py
+++ b/samples/client/petstore/python-experimental/petstore_api/configuration.py
@@ -49,6 +49,18 @@ class Configuration(object):
       then all undeclared properties received by the server are injected into the
       additional properties map. In that case, there are undeclared properties, and
       nothing to discard.
+    :param disable_validation: Boolean value indicating whether to disable the JSON
+      schema structural validation rules specified in the OpenAPI document.
+      This includes multipleOf, maximum, exclusiveMaximum, minimum, exclusiveMinimum,
+      maxLength, minLength, pattern...
+      By default, the validation is performed for data generated locally by the client
+      and data received from the server, independent of any validation performed by
+      the server side.
+      If the input data does not satisfy the JSON schema validation rules specified
+      in the OpenAPI document, an exception is raised.
+      If disable_validation is set to true, structural validation is disabled. This
+      can be useful to troubleshoot data validation problem, such as when the OpenAPI
+      document validation rules do not match the actual API data received by the server.
 
     :Example:
 
@@ -94,6 +106,7 @@ conf = petstore_api.Configuration(
                  api_key=None, api_key_prefix=None,
                  username=None, password=None,
                  discard_unknown_keys=False,
+                 disable_validation=False,
                  ):
         """Constructor
         """
@@ -124,6 +137,7 @@ conf = petstore_api.Configuration(
         """Password for HTTP basic authentication
         """
         self.discard_unknown_keys = discard_unknown_keys
+        self.disable_validation = disable_validation
         self.access_token = None
         """access token for OAuth/Bearer
         """
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 519b5f7a5ed..db0e440563d 100644
--- a/samples/client/petstore/python-experimental/petstore_api/model_utils.py
+++ b/samples/client/petstore/python-experimental/petstore_api/model_utils.py
@@ -110,7 +110,8 @@ class OpenApiModel(object):
             check_validations(
                 self.validations,
                 (name,),
-                value
+                value,
+                self._configuration
             )
         self.__dict__['_data_store'][name] = value
 
@@ -560,15 +561,21 @@ def check_allowed_values(allowed_values, input_variable_path, input_values):
         )
 
 
-def check_validations(validations, input_variable_path, input_values):
+def check_validations(validations, input_variable_path, input_values,
+                        configuration=None):
     """Raises an exception if the input_values are invalid
 
     Args:
-        validations (dict): the validation dictionary
-        input_variable_path (tuple): the path to the input variable
+        validations (dict): the validation dictionary.
+        input_variable_path (tuple): the path to the input variable.
         input_values (list/str/int/float/date/datetime): the values that we
-            are checking
+            are checking.
+        configuration (Configuration): the configuration class.
     """
+    if configuration is not None and configuration.disable_validation:
+        # Skip JSON schema structural validation.
+        return
+
     current_validations = validations[input_variable_path]
     if ('max_length' in current_validations and
             len(input_values) > current_validations['max_length']):
diff --git a/samples/openapi3/client/petstore/python-experimental/petstore_api/api/another_fake_api.py b/samples/openapi3/client/petstore/python-experimental/petstore_api/api/another_fake_api.py
index fbf98194fcd..6c7e40c2482 100644
--- a/samples/openapi3/client/petstore/python-experimental/petstore_api/api/another_fake_api.py
+++ b/samples/openapi3/client/petstore/python-experimental/petstore_api/api/another_fake_api.py
@@ -249,7 +249,8 @@ class Endpoint(object):
                 check_validations(
                     self.validations,
                     (param,),
-                    kwargs[param]
+                    kwargs[param],
+                    configuration=self.api_client.configuration
                 )
 
         if kwargs['_check_input_type'] is False:
diff --git a/samples/openapi3/client/petstore/python-experimental/petstore_api/api/default_api.py b/samples/openapi3/client/petstore/python-experimental/petstore_api/api/default_api.py
index 3369688cb88..3e46d7928cb 100644
--- a/samples/openapi3/client/petstore/python-experimental/petstore_api/api/default_api.py
+++ b/samples/openapi3/client/petstore/python-experimental/petstore_api/api/default_api.py
@@ -235,7 +235,8 @@ class Endpoint(object):
                 check_validations(
                     self.validations,
                     (param,),
-                    kwargs[param]
+                    kwargs[param],
+                    configuration=self.api_client.configuration
                 )
 
         if kwargs['_check_input_type'] is False:
diff --git a/samples/openapi3/client/petstore/python-experimental/petstore_api/api/fake_api.py b/samples/openapi3/client/petstore/python-experimental/petstore_api/api/fake_api.py
index ad882a19c66..fd5096ba6de 100644
--- a/samples/openapi3/client/petstore/python-experimental/petstore_api/api/fake_api.py
+++ b/samples/openapi3/client/petstore/python-experimental/petstore_api/api/fake_api.py
@@ -2054,7 +2054,8 @@ class Endpoint(object):
                 check_validations(
                     self.validations,
                     (param,),
-                    kwargs[param]
+                    kwargs[param],
+                    configuration=self.api_client.configuration
                 )
 
         if kwargs['_check_input_type'] is False:
diff --git a/samples/openapi3/client/petstore/python-experimental/petstore_api/api/fake_classname_tags_123_api.py b/samples/openapi3/client/petstore/python-experimental/petstore_api/api/fake_classname_tags_123_api.py
index ec0225f1d1c..f2a13a0b92f 100644
--- a/samples/openapi3/client/petstore/python-experimental/petstore_api/api/fake_classname_tags_123_api.py
+++ b/samples/openapi3/client/petstore/python-experimental/petstore_api/api/fake_classname_tags_123_api.py
@@ -251,7 +251,8 @@ class Endpoint(object):
                 check_validations(
                     self.validations,
                     (param,),
-                    kwargs[param]
+                    kwargs[param],
+                    configuration=self.api_client.configuration
                 )
 
         if kwargs['_check_input_type'] is False:
diff --git a/samples/openapi3/client/petstore/python-experimental/petstore_api/api/pet_api.py b/samples/openapi3/client/petstore/python-experimental/petstore_api/api/pet_api.py
index 0a0849dfb95..1a0fdb48bf4 100644
--- a/samples/openapi3/client/petstore/python-experimental/petstore_api/api/pet_api.py
+++ b/samples/openapi3/client/petstore/python-experimental/petstore_api/api/pet_api.py
@@ -1259,7 +1259,8 @@ class Endpoint(object):
                 check_validations(
                     self.validations,
                     (param,),
-                    kwargs[param]
+                    kwargs[param],
+                    configuration=self.api_client.configuration
                 )
 
         if kwargs['_check_input_type'] is False:
diff --git a/samples/openapi3/client/petstore/python-experimental/petstore_api/api/store_api.py b/samples/openapi3/client/petstore/python-experimental/petstore_api/api/store_api.py
index 36fd9bd722c..46fce50d29d 100644
--- a/samples/openapi3/client/petstore/python-experimental/petstore_api/api/store_api.py
+++ b/samples/openapi3/client/petstore/python-experimental/petstore_api/api/store_api.py
@@ -592,7 +592,8 @@ class Endpoint(object):
                 check_validations(
                     self.validations,
                     (param,),
-                    kwargs[param]
+                    kwargs[param],
+                    configuration=self.api_client.configuration
                 )
 
         if kwargs['_check_input_type'] is False:
diff --git a/samples/openapi3/client/petstore/python-experimental/petstore_api/api/user_api.py b/samples/openapi3/client/petstore/python-experimental/petstore_api/api/user_api.py
index aeac9949361..e354babbfe5 100644
--- a/samples/openapi3/client/petstore/python-experimental/petstore_api/api/user_api.py
+++ b/samples/openapi3/client/petstore/python-experimental/petstore_api/api/user_api.py
@@ -1057,7 +1057,8 @@ class Endpoint(object):
                 check_validations(
                     self.validations,
                     (param,),
-                    kwargs[param]
+                    kwargs[param],
+                    configuration=self.api_client.configuration
                 )
 
         if kwargs['_check_input_type'] is False:
diff --git a/samples/openapi3/client/petstore/python-experimental/petstore_api/configuration.py b/samples/openapi3/client/petstore/python-experimental/petstore_api/configuration.py
index 92c53fb54ec..cef6c45f95d 100644
--- a/samples/openapi3/client/petstore/python-experimental/petstore_api/configuration.py
+++ b/samples/openapi3/client/petstore/python-experimental/petstore_api/configuration.py
@@ -49,6 +49,18 @@ class Configuration(object):
       then all undeclared properties received by the server are injected into the
       additional properties map. In that case, there are undeclared properties, and
       nothing to discard.
+    :param disable_validation: Boolean value indicating whether to disable the JSON
+      schema structural validation rules specified in the OpenAPI document.
+      This includes multipleOf, maximum, exclusiveMaximum, minimum, exclusiveMinimum,
+      maxLength, minLength, pattern...
+      By default, the validation is performed for data generated locally by the client
+      and data received from the server, independent of any validation performed by
+      the server side.
+      If the input data does not satisfy the JSON schema validation rules specified
+      in the OpenAPI document, an exception is raised.
+      If disable_validation is set to true, structural validation is disabled. This
+      can be useful to troubleshoot data validation problem, such as when the OpenAPI
+      document validation rules do not match the actual API data received by the server.
     :param signing_info: Configuration parameters for the HTTP signature security scheme.
         Must be an instance of petstore_api.signing.HttpSigningConfiguration
 
@@ -135,6 +147,7 @@ conf = petstore_api.Configuration(
                  api_key=None, api_key_prefix=None,
                  username=None, password=None,
                  discard_unknown_keys=False,
+                 disable_validation=False,
                  signing_info=None,
                  ):
         """Constructor
@@ -166,6 +179,7 @@ conf = petstore_api.Configuration(
         """Password for HTTP basic authentication
         """
         self.discard_unknown_keys = discard_unknown_keys
+        self.disable_validation = disable_validation
         if signing_info is not None:
             signing_info.host = host
         self.signing_info = signing_info
diff --git a/samples/openapi3/client/petstore/python-experimental/petstore_api/model_utils.py b/samples/openapi3/client/petstore/python-experimental/petstore_api/model_utils.py
index 519b5f7a5ed..db0e440563d 100644
--- a/samples/openapi3/client/petstore/python-experimental/petstore_api/model_utils.py
+++ b/samples/openapi3/client/petstore/python-experimental/petstore_api/model_utils.py
@@ -110,7 +110,8 @@ class OpenApiModel(object):
             check_validations(
                 self.validations,
                 (name,),
-                value
+                value,
+                self._configuration
             )
         self.__dict__['_data_store'][name] = value
 
@@ -560,15 +561,21 @@ def check_allowed_values(allowed_values, input_variable_path, input_values):
         )
 
 
-def check_validations(validations, input_variable_path, input_values):
+def check_validations(validations, input_variable_path, input_values,
+                        configuration=None):
     """Raises an exception if the input_values are invalid
 
     Args:
-        validations (dict): the validation dictionary
-        input_variable_path (tuple): the path to the input variable
+        validations (dict): the validation dictionary.
+        input_variable_path (tuple): the path to the input variable.
         input_values (list/str/int/float/date/datetime): the values that we
-            are checking
+            are checking.
+        configuration (Configuration): the configuration class.
     """
+    if configuration is not None and configuration.disable_validation:
+        # Skip JSON schema structural validation.
+        return
+
     current_validations = validations[input_variable_path]
     if ('max_length' in current_validations and
             len(input_values) > current_validations['max_length']):
-- 
GitLab


From c8d05f2ac19333b40d877f1d46d1c6cdc9bd2bc1 Mon Sep 17 00:00:00 2001
From: "Sebastien Rosset (serosset)" <serosset@cisco.com>
Date: Fri, 8 May 2020 17:02:32 -0700
Subject: [PATCH 03/11] Fix formatting issues

---
 .../main/resources/python/configuration.mustache  | 15 ++++++++-------
 .../python-experimental/model_utils.mustache      | 10 ++++++----
 .../petstore_api/configuration.py                 | 15 ++++++++-------
 .../petstore_api/model_utils.py                   | 10 ++++++----
 .../petstore_api/configuration.py                 | 15 ++++++++-------
 .../petstore_api/model_utils.py                   | 10 ++++++----
 6 files changed, 42 insertions(+), 33 deletions(-)

diff --git a/modules/openapi-generator/src/main/resources/python/configuration.mustache b/modules/openapi-generator/src/main/resources/python/configuration.mustache
index 277e3f197d4..345eb007fcd 100644
--- a/modules/openapi-generator/src/main/resources/python/configuration.mustache
+++ b/modules/openapi-generator/src/main/resources/python/configuration.mustache
@@ -43,8 +43,8 @@ class Configuration(object):
       then all undeclared properties received by the server are injected into the
       additional properties map. In that case, there are undeclared properties, and
       nothing to discard.
-    :param disable_validation: Boolean value indicating whether to disable the JSON
-      schema structural validation rules specified in the OpenAPI document.
+    :param disable_client_side_validation: Boolean value indicating whether to disable
+      the JSON schema structural validation rules specified in the OpenAPI document.
       This includes multipleOf, maximum, exclusiveMaximum, minimum, exclusiveMinimum,
       maxLength, minLength, pattern...
       By default, the validation is performed for data generated locally by the client
@@ -52,9 +52,10 @@ class Configuration(object):
       the server side.
       If the input data does not satisfy the JSON schema validation rules specified
       in the OpenAPI document, an exception is raised.
-      If disable_validation is set to true, structural validation is disabled. This
-      can be useful to troubleshoot data validation problem, such as when the OpenAPI
-      document validation rules do not match the actual API data received by the server.
+      If disable_client_side_validation is set to true, structural validation is
+      disabled. This can be useful to troubleshoot data validation problem, such as
+      when the OpenAPI document validation rules do not match the actual API data
+      received by the server.
 {{#hasHttpSignatureMethods}}
     :param signing_info: Configuration parameters for the HTTP signature security scheme.
         Must be an instance of {{{packageName}}}.signing.HttpSigningConfiguration
@@ -151,7 +152,7 @@ conf = {{{packageName}}}.Configuration(
                  api_key=None, api_key_prefix=None,
                  username=None, password=None,
                  discard_unknown_keys=False,
-                 disable_validation=False,
+                 disable_client_side_validation=False,
 {{#hasHttpSignatureMethods}}
                  signing_info=None,
 {{/hasHttpSignatureMethods}}
@@ -185,7 +186,7 @@ conf = {{{packageName}}}.Configuration(
         """Password for HTTP basic authentication
         """
         self.discard_unknown_keys = discard_unknown_keys
-        self.disable_validation = disable_validation
+        self.disable_client_side_validation = disable_client_side_validation
 {{#hasHttpSignatureMethods}}
         if signing_info is not None:
             signing_info.host = host
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 1d9b346b812..cdb7d404845 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
@@ -299,8 +299,9 @@ def check_allowed_values(allowed_values, input_variable_path, input_values):
         )
 
 
-def check_validations(validations, input_variable_path, input_values,
-                        configuration=None):
+def check_validations(
+        validations, input_variable_path, input_values,
+        configuration=None):
     """Raises an exception if the input_values are invalid
 
     Args:
@@ -310,8 +311,9 @@ def check_validations(validations, input_variable_path, input_values,
             are checking.
         configuration (Configuration): the configuration class.
     """
-    if configuration is not None and configuration.disable_validation:
-        # Skip JSON schema structural validation.
+    if configuration is not None and configuration.disable_client_side_validation:
+        # Skip JSON schema structural validation as requested in the configuration.
+        # By default, JSON schema validation is enabled.
         return
 
     current_validations = validations[input_variable_path]
diff --git a/samples/client/petstore/python-experimental/petstore_api/configuration.py b/samples/client/petstore/python-experimental/petstore_api/configuration.py
index f54f947ba1a..0a66048c3da 100644
--- a/samples/client/petstore/python-experimental/petstore_api/configuration.py
+++ b/samples/client/petstore/python-experimental/petstore_api/configuration.py
@@ -49,8 +49,8 @@ class Configuration(object):
       then all undeclared properties received by the server are injected into the
       additional properties map. In that case, there are undeclared properties, and
       nothing to discard.
-    :param disable_validation: Boolean value indicating whether to disable the JSON
-      schema structural validation rules specified in the OpenAPI document.
+    :param disable_client_side_validation: Boolean value indicating whether to disable
+      the JSON schema structural validation rules specified in the OpenAPI document.
       This includes multipleOf, maximum, exclusiveMaximum, minimum, exclusiveMinimum,
       maxLength, minLength, pattern...
       By default, the validation is performed for data generated locally by the client
@@ -58,9 +58,10 @@ class Configuration(object):
       the server side.
       If the input data does not satisfy the JSON schema validation rules specified
       in the OpenAPI document, an exception is raised.
-      If disable_validation is set to true, structural validation is disabled. This
-      can be useful to troubleshoot data validation problem, such as when the OpenAPI
-      document validation rules do not match the actual API data received by the server.
+      If disable_client_side_validation is set to true, structural validation is
+      disabled. This can be useful to troubleshoot data validation problem, such as
+      when the OpenAPI document validation rules do not match the actual API data
+      received by the server.
 
     :Example:
 
@@ -106,7 +107,7 @@ conf = petstore_api.Configuration(
                  api_key=None, api_key_prefix=None,
                  username=None, password=None,
                  discard_unknown_keys=False,
-                 disable_validation=False,
+                 disable_client_side_validation=False,
                  ):
         """Constructor
         """
@@ -137,7 +138,7 @@ conf = petstore_api.Configuration(
         """Password for HTTP basic authentication
         """
         self.discard_unknown_keys = discard_unknown_keys
-        self.disable_validation = disable_validation
+        self.disable_client_side_validation = disable_client_side_validation
         self.access_token = None
         """access token for OAuth/Bearer
         """
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 db0e440563d..d135d5a4ecf 100644
--- a/samples/client/petstore/python-experimental/petstore_api/model_utils.py
+++ b/samples/client/petstore/python-experimental/petstore_api/model_utils.py
@@ -561,8 +561,9 @@ def check_allowed_values(allowed_values, input_variable_path, input_values):
         )
 
 
-def check_validations(validations, input_variable_path, input_values,
-                        configuration=None):
+def check_validations(
+        validations, input_variable_path, input_values,
+        configuration=None):
     """Raises an exception if the input_values are invalid
 
     Args:
@@ -572,8 +573,9 @@ def check_validations(validations, input_variable_path, input_values,
             are checking.
         configuration (Configuration): the configuration class.
     """
-    if configuration is not None and configuration.disable_validation:
-        # Skip JSON schema structural validation.
+    if configuration is not None and configuration.disable_client_side_validation:
+        # Skip JSON schema structural validation as requested in the configuration.
+        # By default, JSON schema validation is enabled.
         return
 
     current_validations = validations[input_variable_path]
diff --git a/samples/openapi3/client/petstore/python-experimental/petstore_api/configuration.py b/samples/openapi3/client/petstore/python-experimental/petstore_api/configuration.py
index cef6c45f95d..0d19da6dfc4 100644
--- a/samples/openapi3/client/petstore/python-experimental/petstore_api/configuration.py
+++ b/samples/openapi3/client/petstore/python-experimental/petstore_api/configuration.py
@@ -49,8 +49,8 @@ class Configuration(object):
       then all undeclared properties received by the server are injected into the
       additional properties map. In that case, there are undeclared properties, and
       nothing to discard.
-    :param disable_validation: Boolean value indicating whether to disable the JSON
-      schema structural validation rules specified in the OpenAPI document.
+    :param disable_client_side_validation: Boolean value indicating whether to disable
+      the JSON schema structural validation rules specified in the OpenAPI document.
       This includes multipleOf, maximum, exclusiveMaximum, minimum, exclusiveMinimum,
       maxLength, minLength, pattern...
       By default, the validation is performed for data generated locally by the client
@@ -58,9 +58,10 @@ class Configuration(object):
       the server side.
       If the input data does not satisfy the JSON schema validation rules specified
       in the OpenAPI document, an exception is raised.
-      If disable_validation is set to true, structural validation is disabled. This
-      can be useful to troubleshoot data validation problem, such as when the OpenAPI
-      document validation rules do not match the actual API data received by the server.
+      If disable_client_side_validation is set to true, structural validation is
+      disabled. This can be useful to troubleshoot data validation problem, such as
+      when the OpenAPI document validation rules do not match the actual API data
+      received by the server.
     :param signing_info: Configuration parameters for the HTTP signature security scheme.
         Must be an instance of petstore_api.signing.HttpSigningConfiguration
 
@@ -147,7 +148,7 @@ conf = petstore_api.Configuration(
                  api_key=None, api_key_prefix=None,
                  username=None, password=None,
                  discard_unknown_keys=False,
-                 disable_validation=False,
+                 disable_client_side_validation=False,
                  signing_info=None,
                  ):
         """Constructor
@@ -179,7 +180,7 @@ conf = petstore_api.Configuration(
         """Password for HTTP basic authentication
         """
         self.discard_unknown_keys = discard_unknown_keys
-        self.disable_validation = disable_validation
+        self.disable_client_side_validation = disable_client_side_validation
         if signing_info is not None:
             signing_info.host = host
         self.signing_info = signing_info
diff --git a/samples/openapi3/client/petstore/python-experimental/petstore_api/model_utils.py b/samples/openapi3/client/petstore/python-experimental/petstore_api/model_utils.py
index db0e440563d..d135d5a4ecf 100644
--- a/samples/openapi3/client/petstore/python-experimental/petstore_api/model_utils.py
+++ b/samples/openapi3/client/petstore/python-experimental/petstore_api/model_utils.py
@@ -561,8 +561,9 @@ def check_allowed_values(allowed_values, input_variable_path, input_values):
         )
 
 
-def check_validations(validations, input_variable_path, input_values,
-                        configuration=None):
+def check_validations(
+        validations, input_variable_path, input_values,
+        configuration=None):
     """Raises an exception if the input_values are invalid
 
     Args:
@@ -572,8 +573,9 @@ def check_validations(validations, input_variable_path, input_values,
             are checking.
         configuration (Configuration): the configuration class.
     """
-    if configuration is not None and configuration.disable_validation:
-        # Skip JSON schema structural validation.
+    if configuration is not None and configuration.disable_client_side_validation:
+        # Skip JSON schema structural validation as requested in the configuration.
+        # By default, JSON schema validation is enabled.
         return
 
     current_validations = validations[input_variable_path]
-- 
GitLab


From 8f1860d661ba9ed4a33ae816737b9baa9f1d03ca Mon Sep 17 00:00:00 2001
From: "Sebastien Rosset (serosset)" <serosset@cisco.com>
Date: Fri, 8 May 2020 18:27:57 -0700
Subject: [PATCH 04/11] execute sample scripts

---
 .../python-asyncio/petstore_api/configuration.py  | 15 +++++++++++++++
 .../python-tornado/petstore_api/configuration.py  | 15 +++++++++++++++
 .../petstore/python/petstore_api/configuration.py | 15 +++++++++++++++
 3 files changed, 45 insertions(+)

diff --git a/samples/client/petstore/python-asyncio/petstore_api/configuration.py b/samples/client/petstore/python-asyncio/petstore_api/configuration.py
index a93073e8142..d3aa29792af 100644
--- a/samples/client/petstore/python-asyncio/petstore_api/configuration.py
+++ b/samples/client/petstore/python-asyncio/petstore_api/configuration.py
@@ -48,6 +48,19 @@ class Configuration(object):
       then all undeclared properties received by the server are injected into the
       additional properties map. In that case, there are undeclared properties, and
       nothing to discard.
+    :param disable_client_side_validation: Boolean value indicating whether to disable
+      the JSON schema structural validation rules specified in the OpenAPI document.
+      This includes multipleOf, maximum, exclusiveMaximum, minimum, exclusiveMinimum,
+      maxLength, minLength, pattern...
+      By default, the validation is performed for data generated locally by the client
+      and data received from the server, independent of any validation performed by
+      the server side.
+      If the input data does not satisfy the JSON schema validation rules specified
+      in the OpenAPI document, an exception is raised.
+      If disable_client_side_validation is set to true, structural validation is
+      disabled. This can be useful to troubleshoot data validation problem, such as
+      when the OpenAPI document validation rules do not match the actual API data
+      received by the server.
 
     :Example:
 
@@ -93,6 +106,7 @@ conf = petstore_api.Configuration(
                  api_key=None, api_key_prefix=None,
                  username=None, password=None,
                  discard_unknown_keys=False,
+                 disable_client_side_validation=False,
                  ):
         """Constructor
         """
@@ -123,6 +137,7 @@ conf = petstore_api.Configuration(
         """Password for HTTP basic authentication
         """
         self.discard_unknown_keys = discard_unknown_keys
+        self.disable_client_side_validation = disable_client_side_validation
         self.access_token = None
         """access token for OAuth/Bearer
         """
diff --git a/samples/client/petstore/python-tornado/petstore_api/configuration.py b/samples/client/petstore/python-tornado/petstore_api/configuration.py
index 32406df02f5..0a66048c3da 100644
--- a/samples/client/petstore/python-tornado/petstore_api/configuration.py
+++ b/samples/client/petstore/python-tornado/petstore_api/configuration.py
@@ -49,6 +49,19 @@ class Configuration(object):
       then all undeclared properties received by the server are injected into the
       additional properties map. In that case, there are undeclared properties, and
       nothing to discard.
+    :param disable_client_side_validation: Boolean value indicating whether to disable
+      the JSON schema structural validation rules specified in the OpenAPI document.
+      This includes multipleOf, maximum, exclusiveMaximum, minimum, exclusiveMinimum,
+      maxLength, minLength, pattern...
+      By default, the validation is performed for data generated locally by the client
+      and data received from the server, independent of any validation performed by
+      the server side.
+      If the input data does not satisfy the JSON schema validation rules specified
+      in the OpenAPI document, an exception is raised.
+      If disable_client_side_validation is set to true, structural validation is
+      disabled. This can be useful to troubleshoot data validation problem, such as
+      when the OpenAPI document validation rules do not match the actual API data
+      received by the server.
 
     :Example:
 
@@ -94,6 +107,7 @@ conf = petstore_api.Configuration(
                  api_key=None, api_key_prefix=None,
                  username=None, password=None,
                  discard_unknown_keys=False,
+                 disable_client_side_validation=False,
                  ):
         """Constructor
         """
@@ -124,6 +138,7 @@ conf = petstore_api.Configuration(
         """Password for HTTP basic authentication
         """
         self.discard_unknown_keys = discard_unknown_keys
+        self.disable_client_side_validation = disable_client_side_validation
         self.access_token = None
         """access token for OAuth/Bearer
         """
diff --git a/samples/client/petstore/python/petstore_api/configuration.py b/samples/client/petstore/python/petstore_api/configuration.py
index 32406df02f5..0a66048c3da 100644
--- a/samples/client/petstore/python/petstore_api/configuration.py
+++ b/samples/client/petstore/python/petstore_api/configuration.py
@@ -49,6 +49,19 @@ class Configuration(object):
       then all undeclared properties received by the server are injected into the
       additional properties map. In that case, there are undeclared properties, and
       nothing to discard.
+    :param disable_client_side_validation: Boolean value indicating whether to disable
+      the JSON schema structural validation rules specified in the OpenAPI document.
+      This includes multipleOf, maximum, exclusiveMaximum, minimum, exclusiveMinimum,
+      maxLength, minLength, pattern...
+      By default, the validation is performed for data generated locally by the client
+      and data received from the server, independent of any validation performed by
+      the server side.
+      If the input data does not satisfy the JSON schema validation rules specified
+      in the OpenAPI document, an exception is raised.
+      If disable_client_side_validation is set to true, structural validation is
+      disabled. This can be useful to troubleshoot data validation problem, such as
+      when the OpenAPI document validation rules do not match the actual API data
+      received by the server.
 
     :Example:
 
@@ -94,6 +107,7 @@ conf = petstore_api.Configuration(
                  api_key=None, api_key_prefix=None,
                  username=None, password=None,
                  discard_unknown_keys=False,
+                 disable_client_side_validation=False,
                  ):
         """Constructor
         """
@@ -124,6 +138,7 @@ conf = petstore_api.Configuration(
         """Password for HTTP basic authentication
         """
         self.discard_unknown_keys = discard_unknown_keys
+        self.disable_client_side_validation = disable_client_side_validation
         self.access_token = None
         """access token for OAuth/Bearer
         """
-- 
GitLab


From fc06890e6b9508b0294210de1e5cac1a539afd11 Mon Sep 17 00:00:00 2001
From: "Sebastien Rosset (serosset)" <serosset@cisco.com>
Date: Fri, 8 May 2020 18:33:44 -0700
Subject: [PATCH 05/11] execute sample scripts

---
 .../petstore/python/petstore_api/configuration.py | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/samples/openapi3/client/petstore/python/petstore_api/configuration.py b/samples/openapi3/client/petstore/python/petstore_api/configuration.py
index 92c53fb54ec..0d19da6dfc4 100644
--- a/samples/openapi3/client/petstore/python/petstore_api/configuration.py
+++ b/samples/openapi3/client/petstore/python/petstore_api/configuration.py
@@ -49,6 +49,19 @@ class Configuration(object):
       then all undeclared properties received by the server are injected into the
       additional properties map. In that case, there are undeclared properties, and
       nothing to discard.
+    :param disable_client_side_validation: Boolean value indicating whether to disable
+      the JSON schema structural validation rules specified in the OpenAPI document.
+      This includes multipleOf, maximum, exclusiveMaximum, minimum, exclusiveMinimum,
+      maxLength, minLength, pattern...
+      By default, the validation is performed for data generated locally by the client
+      and data received from the server, independent of any validation performed by
+      the server side.
+      If the input data does not satisfy the JSON schema validation rules specified
+      in the OpenAPI document, an exception is raised.
+      If disable_client_side_validation is set to true, structural validation is
+      disabled. This can be useful to troubleshoot data validation problem, such as
+      when the OpenAPI document validation rules do not match the actual API data
+      received by the server.
     :param signing_info: Configuration parameters for the HTTP signature security scheme.
         Must be an instance of petstore_api.signing.HttpSigningConfiguration
 
@@ -135,6 +148,7 @@ conf = petstore_api.Configuration(
                  api_key=None, api_key_prefix=None,
                  username=None, password=None,
                  discard_unknown_keys=False,
+                 disable_client_side_validation=False,
                  signing_info=None,
                  ):
         """Constructor
@@ -166,6 +180,7 @@ conf = petstore_api.Configuration(
         """Password for HTTP basic authentication
         """
         self.discard_unknown_keys = discard_unknown_keys
+        self.disable_client_side_validation = disable_client_side_validation
         if signing_info is not None:
             signing_info.host = host
         self.signing_info = signing_info
-- 
GitLab


From f46d0c5539ba593e4d96e576fc143e1aea8a1fb4 Mon Sep 17 00:00:00 2001
From: "Sebastien Rosset (serosset)" <serosset@cisco.com>
Date: Tue, 12 May 2020 10:00:36 -0700
Subject: [PATCH 06/11] fix multipleOf validation issue

---
 .../org/openapitools/codegen/DefaultCodegen.java     | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

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 68919c695a0..ee490539939 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
@@ -2949,10 +2949,13 @@ public class DefaultCodegen implements CodegenConfig {
             if (p.getExclusiveMaximum() != null) {
                 property.exclusiveMaximum = p.getExclusiveMaximum();
             }
+            if (p.getMultipleOf() != null) {
+                property.multipleOf = p.getMultipleOf();
+            }
 
             // check if any validation rule defined
             // exclusive* are noop without corresponding min/max
-            if (property.minimum != null || property.maximum != null)
+            if (property.minimum != null || property.maximum != null || p.getMultipleOf() != null)
                 property.hasValidation = true;
 
         } else if (ModelUtils.isBooleanSchema(p)) { // boolean type
@@ -3024,8 +3027,9 @@ public class DefaultCodegen implements CodegenConfig {
 
             // check if any validation rule defined
             // exclusive* are noop without corresponding min/max
-            if (property.minimum != null || property.maximum != null)
+            if (property.minimum != null || property.maximum != null || p.getMultipleOf() != null) {
                 property.hasValidation = true;
+            }
 
         } else if (ModelUtils.isFreeFormObject(p)) {
             property.isFreeFormObject = true;
@@ -4138,7 +4142,7 @@ public class DefaultCodegen implements CodegenConfig {
             if (codegenParameter.maximum != null || codegenParameter.minimum != null ||
                     codegenParameter.maxLength != null || codegenParameter.minLength != null ||
                     codegenParameter.maxItems != null || codegenParameter.minItems != null ||
-                    codegenParameter.pattern != null) {
+                    codegenParameter.pattern != null || codegenParameter.multipleOf != null) {
                 codegenParameter.hasValidation = true;
             }
 
@@ -5616,7 +5620,7 @@ public class DefaultCodegen implements CodegenConfig {
         if (codegenParameter.maximum != null || codegenParameter.minimum != null ||
                 codegenParameter.maxLength != null || codegenParameter.minLength != null ||
                 codegenParameter.maxItems != null || codegenParameter.minItems != null ||
-                codegenParameter.pattern != null) {
+                codegenParameter.pattern != null || codegenParameter.multipleOf != null) {
             codegenParameter.hasValidation = true;
         }
 
-- 
GitLab


From b14e93e1b091bed4acc4d4fabdf41d6e04c1a14c Mon Sep 17 00:00:00 2001
From: "Sebastien Rosset (serosset)" <serosset@cisco.com>
Date: Tue, 12 May 2020 10:02:01 -0700
Subject: [PATCH 07/11] Add validation log for multipleOf. Add customizable
 validation checks. add unit tests for JSON schema validation

---
 .../resources/python/configuration.mustache   |  31 +++--
 .../model_templates/classvars.mustache        |   6 +
 .../python-experimental/model_utils.mustache  |  58 ++++++--
 ...odels-for-testing-with-http-signature.yaml |   2 +
 .../petstore_api/configuration.py             |  31 +++--
 .../petstore_api/model_utils.py               |  45 ++++--
 .../petstore_api/configuration.py             |  31 +++--
 .../petstore_api/model_utils.py               |  58 ++++++--
 .../petstore_api/models/format_test.py        |   2 +
 .../tests/test_api_validation.py              | 130 ++++++++++++++++++
 10 files changed, 328 insertions(+), 66 deletions(-)
 create mode 100644 samples/openapi3/client/petstore/python-experimental/tests/test_api_validation.py

diff --git a/modules/openapi-generator/src/main/resources/python/configuration.mustache b/modules/openapi-generator/src/main/resources/python/configuration.mustache
index 345eb007fcd..b559bc75616 100644
--- a/modules/openapi-generator/src/main/resources/python/configuration.mustache
+++ b/modules/openapi-generator/src/main/resources/python/configuration.mustache
@@ -16,6 +16,12 @@ import six
 from six.moves import http_client as httplib
 
 
+JSON_SCHEMA_VALIDATION_KEYWORDS = {
+    'multipleOf', 'maximum', 'exclusiveMaximum',
+    'minimum', 'exclusiveMinimum', 'maxLength',
+    'minLength', 'pattern', 'maxItems', 'minItems'
+}
+
 class Configuration(object):
     """NOTE: This class is auto generated by OpenAPI Generator
 
@@ -43,16 +49,16 @@ class Configuration(object):
       then all undeclared properties received by the server are injected into the
       additional properties map. In that case, there are undeclared properties, and
       nothing to discard.
-    :param disable_client_side_validation: Boolean value indicating whether to disable
-      the JSON schema structural validation rules specified in the OpenAPI document.
-      This includes multipleOf, maximum, exclusiveMaximum, minimum, exclusiveMinimum,
-      maxLength, minLength, pattern...
+    :param disable_client_side_validation (string/None): Comma-separated list of
+      JSON schema validation keywords to disable JSON schema structural validation
+      rules. The following keywords may be specified: multipleOf, maximum,
+      exclusiveMaximum, minimum, exclusiveMinimum, maxLength, minLength, pattern,
+      maxItems, minItems.
       By default, the validation is performed for data generated locally by the client
       and data received from the server, independent of any validation performed by
-      the server side.
-      If the input data does not satisfy the JSON schema validation rules specified
-      in the OpenAPI document, an exception is raised.
-      If disable_client_side_validation is set to true, structural validation is
+      the server side. If the input data does not satisfy the JSON schema validation
+      rules specified in the OpenAPI document, an exception is raised.
+      If disable_client_side_validation is set, structural validation is
       disabled. This can be useful to troubleshoot data validation problem, such as
       when the OpenAPI document validation rules do not match the actual API data
       received by the server.
@@ -152,7 +158,7 @@ conf = {{{packageName}}}.Configuration(
                  api_key=None, api_key_prefix=None,
                  username=None, password=None,
                  discard_unknown_keys=False,
-                 disable_client_side_validation=False,
+                 disable_client_side_validation=None,
 {{#hasHttpSignatureMethods}}
                  signing_info=None,
 {{/hasHttpSignatureMethods}}
@@ -292,6 +298,13 @@ conf = {{{packageName}}}.Configuration(
 
     def __setattr__(self, name, value):
         object.__setattr__(self, name, value)
+        if name == 'disable_client_side_validation' and value is not None:
+            s = set(value.split(','))
+            for v in s:
+                if v not in JSON_SCHEMA_VALIDATION_KEYWORDS:
+                    raise ValueError(
+                        "Invalid keyword: '{0}''".format(v))
+            self._disable_client_side_validation = s
 {{#hasHttpSignatureMethods}}
         if name == "signing_info" and value is not None:
             # Ensure the host paramater from signing info is the same as
diff --git a/modules/openapi-generator/src/main/resources/python/python-experimental/model_templates/classvars.mustache b/modules/openapi-generator/src/main/resources/python/python-experimental/model_templates/classvars.mustache
index fe54e34f5bb..471c16c10a9 100644
--- a/modules/openapi-generator/src/main/resources/python/python-experimental/model_templates/classvars.mustache
+++ b/modules/openapi-generator/src/main/resources/python/python-experimental/model_templates/classvars.mustache
@@ -57,6 +57,9 @@
                 {{#-first}}'flags': (re.{{.}}{{/-first}}{{^-first}}          re.{{.}}{{/-first}}{{^-last}} | {{/-last}}{{#-last}}){{/-last}}{{/vendorExtensions.x-modifiers}}
             },
 {{/pattern}}
+{{#multipleOf}}
+            'multiple_of': {{multipleOf}},
+{{/multipleOf}}
         },
 {{/hasValidation}}
 {{/requiredVars}}
@@ -87,6 +90,9 @@
                 {{#-first}}'flags': (re.{{.}}{{/-first}}{{^-first}}          re.{{.}}{{/-first}}{{^-last}} | {{/-last}}{{#-last}}){{/-last}}{{/vendorExtensions.x-modifiers}}
             },
 {{/pattern}}
+{{#multipleOf}}
+            'multiple_of': {{multipleOf}},
+{{/multipleOf}}
         },
 {{/hasValidation}}
 {{/optionalVars}}
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 bfeaed8b512..819aac4781c 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
@@ -369,6 +369,21 @@ def check_allowed_values(allowed_values, input_variable_path, input_values):
         )
 
 
+def is_json_validation_enabled(schema_keyword, configuration=None):
+    """Returns true if JSON schema validation is enabled for the specified
+    validation keyword. This can be used to skip JSON schema structural validation
+    as requested in the configuration.
+
+    Args:
+        schema_keyword (string): the name of a JSON schema validation keyword.
+        configuration (Configuration): the configuration class.
+    """
+
+    return (configuration is None or
+        not hasattr(configuration, '_disable_client_side_validation') or
+        schema_keyword not in configuration._disable_client_side_validation)
+
+
 def check_validations(
         validations, input_variable_path, input_values,
         configuration=None):
@@ -381,13 +396,22 @@ def check_validations(
             are checking.
         configuration (Configuration): the configuration class.
     """
-    if configuration is not None and configuration.disable_client_side_validation:
-        # Skip JSON schema structural validation as requested in the configuration.
-        # By default, JSON schema validation is enabled.
-        return
 
     current_validations = validations[input_variable_path]
-    if ('max_length' in current_validations and
+    if (is_json_validation_enabled('multipleOf', configuration) and
+            'multiple_of' in current_validations and
+            not (input_values / current_validations['multiple_of']).is_integer()):
+        # Note 'multipleOf' will be as good as the floating point arithmetic.
+        raise ApiValueError(
+            "Invalid value for `%s`, value must be a multiple of "
+            "`%s`" % (
+                input_variable_path[0],
+                current_validations['multiple_of']
+            )
+        )
+
+    if (is_json_validation_enabled('maxLength', configuration) and
+            'max_length' in current_validations and
             len(input_values) > current_validations['max_length']):
         raise ApiValueError(
             "Invalid value for `%s`, length must be less than or equal to "
@@ -397,7 +421,8 @@ def check_validations(
             )
         )
 
-    if ('min_length' in current_validations and
+    if (is_json_validation_enabled('minLength', configuration) and
+            'min_length' in current_validations and
             len(input_values) < current_validations['min_length']):
         raise ApiValueError(
             "Invalid value for `%s`, length must be greater than or equal to "
@@ -407,7 +432,8 @@ def check_validations(
             )
         )
 
-    if ('max_items' in current_validations and
+    if (is_json_validation_enabled('maxItems', configuration) and
+            'max_items' in current_validations and
             len(input_values) > current_validations['max_items']):
         raise ApiValueError(
             "Invalid value for `%s`, number of items must be less than or "
@@ -417,7 +443,8 @@ def check_validations(
             )
         )
 
-    if ('min_items' in current_validations and
+    if (is_json_validation_enabled('minItems', configuration) and
+            'min_items' in current_validations and
             len(input_values) < current_validations['min_items']):
         raise ValueError(
             "Invalid value for `%s`, number of items must be greater than or "
@@ -440,7 +467,8 @@ def check_validations(
             max_val = input_values
             min_val = input_values
 
-    if ('exclusive_maximum' in current_validations and
+    if (is_json_validation_enabled('exclusiveMaximum', configuration) and
+            'exclusive_maximum' in current_validations and
             max_val >= current_validations['exclusive_maximum']):
         raise ApiValueError(
             "Invalid value for `%s`, must be a value less than `%s`" % (
@@ -449,7 +477,8 @@ def check_validations(
             )
         )
 
-    if ('inclusive_maximum' in current_validations and
+    if (is_json_validation_enabled('maximum', configuration) and
+            'inclusive_maximum' in current_validations and
             max_val > current_validations['inclusive_maximum']):
         raise ApiValueError(
             "Invalid value for `%s`, must be a value less than or equal to "
@@ -459,7 +488,8 @@ def check_validations(
             )
         )
 
-    if ('exclusive_minimum' in current_validations and
+    if (is_json_validation_enabled('exclusiveMinimum', configuration) and
+            'exclusive_minimum' in current_validations and
             min_val <= current_validations['exclusive_minimum']):
         raise ApiValueError(
             "Invalid value for `%s`, must be a value greater than `%s`" %
@@ -469,7 +499,8 @@ def check_validations(
             )
         )
 
-    if ('inclusive_minimum' in current_validations and
+    if (is_json_validation_enabled('minimum', configuration) and
+            'inclusive_minimum' in current_validations and
             min_val < current_validations['inclusive_minimum']):
         raise ApiValueError(
             "Invalid value for `%s`, must be a value greater than or equal "
@@ -479,7 +510,8 @@ def check_validations(
             )
         )
     flags = current_validations.get('regex', {}).get('flags', 0)
-    if ('regex' in current_validations and
+    if (is_json_validation_enabled('pattern', configuration) and
+            'regex' in current_validations and
             not re.search(current_validations['regex']['pattern'],
                           input_values, flags=flags)):
         err_msg = r"Invalid value for `%s`, must match regular expression `%s`" % (
diff --git a/modules/openapi-generator/src/test/resources/3_0/python-experimental/petstore-with-fake-endpoints-models-for-testing-with-http-signature.yaml b/modules/openapi-generator/src/test/resources/3_0/python-experimental/petstore-with-fake-endpoints-models-for-testing-with-http-signature.yaml
index 919bcc7445e..fe50435315e 100644
--- a/modules/openapi-generator/src/test/resources/3_0/python-experimental/petstore-with-fake-endpoints-models-for-testing-with-http-signature.yaml
+++ b/modules/openapi-generator/src/test/resources/3_0/python-experimental/petstore-with-fake-endpoints-models-for-testing-with-http-signature.yaml
@@ -1416,6 +1416,7 @@ components:
           type: integer
           maximum: 100
           minimum: 10
+          multipleOf: 2
         int32:
           type: integer
           format: int32
@@ -1428,6 +1429,7 @@ components:
           maximum: 543.2
           minimum: 32.1
           type: number
+          multipleOf: 32.5 
         float:
           type: number
           format: float
diff --git a/samples/client/petstore/python-experimental/petstore_api/configuration.py b/samples/client/petstore/python-experimental/petstore_api/configuration.py
index 0a66048c3da..c289a675a59 100644
--- a/samples/client/petstore/python-experimental/petstore_api/configuration.py
+++ b/samples/client/petstore/python-experimental/petstore_api/configuration.py
@@ -22,6 +22,12 @@ import six
 from six.moves import http_client as httplib
 
 
+JSON_SCHEMA_VALIDATION_KEYWORDS = {
+    'multipleOf', 'maximum', 'exclusiveMaximum',
+    'minimum', 'exclusiveMinimum', 'maxLength',
+    'minLength', 'pattern', 'maxItems', 'minItems'
+}
+
 class Configuration(object):
     """NOTE: This class is auto generated by OpenAPI Generator
 
@@ -49,16 +55,16 @@ class Configuration(object):
       then all undeclared properties received by the server are injected into the
       additional properties map. In that case, there are undeclared properties, and
       nothing to discard.
-    :param disable_client_side_validation: Boolean value indicating whether to disable
-      the JSON schema structural validation rules specified in the OpenAPI document.
-      This includes multipleOf, maximum, exclusiveMaximum, minimum, exclusiveMinimum,
-      maxLength, minLength, pattern...
+    :param disable_client_side_validation (string/None): Comma-separated list of
+      JSON schema validation keywords to disable JSON schema structural validation
+      rules. The following keywords may be specified: multipleOf, maximum,
+      exclusiveMaximum, minimum, exclusiveMinimum, maxLength, minLength, pattern,
+      maxItems, minItems.
       By default, the validation is performed for data generated locally by the client
       and data received from the server, independent of any validation performed by
-      the server side.
-      If the input data does not satisfy the JSON schema validation rules specified
-      in the OpenAPI document, an exception is raised.
-      If disable_client_side_validation is set to true, structural validation is
+      the server side. If the input data does not satisfy the JSON schema validation
+      rules specified in the OpenAPI document, an exception is raised.
+      If disable_client_side_validation is set, structural validation is
       disabled. This can be useful to troubleshoot data validation problem, such as
       when the OpenAPI document validation rules do not match the actual API data
       received by the server.
@@ -107,7 +113,7 @@ conf = petstore_api.Configuration(
                  api_key=None, api_key_prefix=None,
                  username=None, password=None,
                  discard_unknown_keys=False,
-                 disable_client_side_validation=False,
+                 disable_client_side_validation=None,
                  ):
         """Constructor
         """
@@ -220,6 +226,13 @@ conf = petstore_api.Configuration(
 
     def __setattr__(self, name, value):
         object.__setattr__(self, name, value)
+        if name == 'disable_client_side_validation' and value is not None:
+            s = set(value.split(','))
+            for v in s:
+                if v not in JSON_SCHEMA_VALIDATION_KEYWORDS:
+                    raise ValueError(
+                        "Invalid keyword: '{0}''".format(v))
+            self._disable_client_side_validation = s
 
     @classmethod
     def set_default(cls, default):
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 de542673d28..26932850255 100644
--- a/samples/client/petstore/python-experimental/petstore_api/model_utils.py
+++ b/samples/client/petstore/python-experimental/petstore_api/model_utils.py
@@ -636,6 +636,20 @@ def check_allowed_values(allowed_values, input_variable_path, input_values):
         )
 
 
+def is_json_validation_enabled(schema_keyword, configuration=None):
+    """Returns true if JSON schema validation is enabled for the specified
+    validation keyword. This can be used to skip JSON schema structural validation
+    as requested in the configuration.
+
+    Args:
+        schema_keyword (string): the name of a JSON schema validation keyword.
+        configuration (Configuration): the configuration class.
+    """
+
+    return (configuration is None or
+        schema_keyword not in configuration._disable_client_side_validation)
+
+
 def check_validations(
         validations, input_variable_path, input_values,
         configuration=None):
@@ -648,13 +662,10 @@ def check_validations(
             are checking.
         configuration (Configuration): the configuration class.
     """
-    if configuration is not None and configuration.disable_client_side_validation:
-        # Skip JSON schema structural validation as requested in the configuration.
-        # By default, JSON schema validation is enabled.
-        return
 
     current_validations = validations[input_variable_path]
-    if ('max_length' in current_validations and
+    if (is_json_validation_enabled('maxLength') and
+            'max_length' in current_validations and
             len(input_values) > current_validations['max_length']):
         raise ApiValueError(
             "Invalid value for `%s`, length must be less than or equal to "
@@ -664,7 +675,8 @@ def check_validations(
             )
         )
 
-    if ('min_length' in current_validations and
+    if (is_json_validation_enabled('minLength') and
+            'min_length' in current_validations and
             len(input_values) < current_validations['min_length']):
         raise ApiValueError(
             "Invalid value for `%s`, length must be greater than or equal to "
@@ -674,7 +686,8 @@ def check_validations(
             )
         )
 
-    if ('max_items' in current_validations and
+    if (is_json_validation_enabled('maxItems') and
+            'max_items' in current_validations and
             len(input_values) > current_validations['max_items']):
         raise ApiValueError(
             "Invalid value for `%s`, number of items must be less than or "
@@ -684,7 +697,8 @@ def check_validations(
             )
         )
 
-    if ('min_items' in current_validations and
+    if (is_json_validation_enabled('minItems') and
+            'min_items' in current_validations and
             len(input_values) < current_validations['min_items']):
         raise ValueError(
             "Invalid value for `%s`, number of items must be greater than or "
@@ -707,7 +721,8 @@ def check_validations(
             max_val = input_values
             min_val = input_values
 
-    if ('exclusive_maximum' in current_validations and
+    if (is_json_validation_enabled('exclusiveMaximum') and
+            'exclusive_maximum' in current_validations and
             max_val >= current_validations['exclusive_maximum']):
         raise ApiValueError(
             "Invalid value for `%s`, must be a value less than `%s`" % (
@@ -716,7 +731,8 @@ def check_validations(
             )
         )
 
-    if ('inclusive_maximum' in current_validations and
+    if (is_json_validation_enabled('maximum') and
+            'inclusive_maximum' in current_validations and
             max_val > current_validations['inclusive_maximum']):
         raise ApiValueError(
             "Invalid value for `%s`, must be a value less than or equal to "
@@ -726,7 +742,8 @@ def check_validations(
             )
         )
 
-    if ('exclusive_minimum' in current_validations and
+    if (is_json_validation_enabled('exclusiveMinimum') and
+            'exclusive_minimum' in current_validations and
             min_val <= current_validations['exclusive_minimum']):
         raise ApiValueError(
             "Invalid value for `%s`, must be a value greater than `%s`" %
@@ -736,7 +753,8 @@ def check_validations(
             )
         )
 
-    if ('inclusive_minimum' in current_validations and
+    if (is_json_validation_enabled('minimum') and
+            'inclusive_minimum' in current_validations and
             min_val < current_validations['inclusive_minimum']):
         raise ApiValueError(
             "Invalid value for `%s`, must be a value greater than or equal "
@@ -746,7 +764,8 @@ def check_validations(
             )
         )
     flags = current_validations.get('regex', {}).get('flags', 0)
-    if ('regex' in current_validations and
+    if (is_json_validation_enabled('pattern') and
+            'regex' in current_validations and
             not re.search(current_validations['regex']['pattern'],
                           input_values, flags=flags)):
         err_msg = r"Invalid value for `%s`, must match regular expression `%s`" % (
diff --git a/samples/openapi3/client/petstore/python-experimental/petstore_api/configuration.py b/samples/openapi3/client/petstore/python-experimental/petstore_api/configuration.py
index 0d19da6dfc4..981c3c9e22e 100644
--- a/samples/openapi3/client/petstore/python-experimental/petstore_api/configuration.py
+++ b/samples/openapi3/client/petstore/python-experimental/petstore_api/configuration.py
@@ -22,6 +22,12 @@ import six
 from six.moves import http_client as httplib
 
 
+JSON_SCHEMA_VALIDATION_KEYWORDS = {
+    'multipleOf', 'maximum', 'exclusiveMaximum',
+    'minimum', 'exclusiveMinimum', 'maxLength',
+    'minLength', 'pattern', 'maxItems', 'minItems'
+}
+
 class Configuration(object):
     """NOTE: This class is auto generated by OpenAPI Generator
 
@@ -49,16 +55,16 @@ class Configuration(object):
       then all undeclared properties received by the server are injected into the
       additional properties map. In that case, there are undeclared properties, and
       nothing to discard.
-    :param disable_client_side_validation: Boolean value indicating whether to disable
-      the JSON schema structural validation rules specified in the OpenAPI document.
-      This includes multipleOf, maximum, exclusiveMaximum, minimum, exclusiveMinimum,
-      maxLength, minLength, pattern...
+    :param disable_client_side_validation (string/None): Comma-separated list of
+      JSON schema validation keywords to disable JSON schema structural validation
+      rules. The following keywords may be specified: multipleOf, maximum,
+      exclusiveMaximum, minimum, exclusiveMinimum, maxLength, minLength, pattern,
+      maxItems, minItems.
       By default, the validation is performed for data generated locally by the client
       and data received from the server, independent of any validation performed by
-      the server side.
-      If the input data does not satisfy the JSON schema validation rules specified
-      in the OpenAPI document, an exception is raised.
-      If disable_client_side_validation is set to true, structural validation is
+      the server side. If the input data does not satisfy the JSON schema validation
+      rules specified in the OpenAPI document, an exception is raised.
+      If disable_client_side_validation is set, structural validation is
       disabled. This can be useful to troubleshoot data validation problem, such as
       when the OpenAPI document validation rules do not match the actual API data
       received by the server.
@@ -148,7 +154,7 @@ conf = petstore_api.Configuration(
                  api_key=None, api_key_prefix=None,
                  username=None, password=None,
                  discard_unknown_keys=False,
-                 disable_client_side_validation=False,
+                 disable_client_side_validation=None,
                  signing_info=None,
                  ):
         """Constructor
@@ -267,6 +273,13 @@ conf = petstore_api.Configuration(
 
     def __setattr__(self, name, value):
         object.__setattr__(self, name, value)
+        if name == 'disable_client_side_validation' and value is not None:
+            s = set(value.split(','))
+            for v in s:
+                if v not in JSON_SCHEMA_VALIDATION_KEYWORDS:
+                    raise ValueError(
+                        "Invalid keyword: '{0}''".format(v))
+            self._disable_client_side_validation = s
         if name == "signing_info" and value is not None:
             # Ensure the host paramater from signing info is the same as
             # Configuration.host.
diff --git a/samples/openapi3/client/petstore/python-experimental/petstore_api/model_utils.py b/samples/openapi3/client/petstore/python-experimental/petstore_api/model_utils.py
index de542673d28..ffc6eea913f 100644
--- a/samples/openapi3/client/petstore/python-experimental/petstore_api/model_utils.py
+++ b/samples/openapi3/client/petstore/python-experimental/petstore_api/model_utils.py
@@ -636,6 +636,21 @@ def check_allowed_values(allowed_values, input_variable_path, input_values):
         )
 
 
+def is_json_validation_enabled(schema_keyword, configuration=None):
+    """Returns true if JSON schema validation is enabled for the specified
+    validation keyword. This can be used to skip JSON schema structural validation
+    as requested in the configuration.
+
+    Args:
+        schema_keyword (string): the name of a JSON schema validation keyword.
+        configuration (Configuration): the configuration class.
+    """
+
+    return (configuration is None or
+        not hasattr(configuration, '_disable_client_side_validation') or
+        schema_keyword not in configuration._disable_client_side_validation)
+
+
 def check_validations(
         validations, input_variable_path, input_values,
         configuration=None):
@@ -648,13 +663,22 @@ def check_validations(
             are checking.
         configuration (Configuration): the configuration class.
     """
-    if configuration is not None and configuration.disable_client_side_validation:
-        # Skip JSON schema structural validation as requested in the configuration.
-        # By default, JSON schema validation is enabled.
-        return
 
     current_validations = validations[input_variable_path]
-    if ('max_length' in current_validations and
+    if (is_json_validation_enabled('multipleOf', configuration) and
+            'multiple_of' in current_validations and
+            not (input_values / current_validations['multiple_of']).is_integer()):
+        # Note 'multipleOf' will be as good as the floating point arithmetic.
+        raise ApiValueError(
+            "Invalid value for `%s`, value must be a multiple of "
+            "`%s`" % (
+                input_variable_path[0],
+                current_validations['multiple_of']
+            )
+        )
+
+    if (is_json_validation_enabled('maxLength', configuration) and
+            'max_length' in current_validations and
             len(input_values) > current_validations['max_length']):
         raise ApiValueError(
             "Invalid value for `%s`, length must be less than or equal to "
@@ -664,7 +688,8 @@ def check_validations(
             )
         )
 
-    if ('min_length' in current_validations and
+    if (is_json_validation_enabled('minLength', configuration) and
+            'min_length' in current_validations and
             len(input_values) < current_validations['min_length']):
         raise ApiValueError(
             "Invalid value for `%s`, length must be greater than or equal to "
@@ -674,7 +699,8 @@ def check_validations(
             )
         )
 
-    if ('max_items' in current_validations and
+    if (is_json_validation_enabled('maxItems', configuration) and
+            'max_items' in current_validations and
             len(input_values) > current_validations['max_items']):
         raise ApiValueError(
             "Invalid value for `%s`, number of items must be less than or "
@@ -684,7 +710,8 @@ def check_validations(
             )
         )
 
-    if ('min_items' in current_validations and
+    if (is_json_validation_enabled('minItems', configuration) and
+            'min_items' in current_validations and
             len(input_values) < current_validations['min_items']):
         raise ValueError(
             "Invalid value for `%s`, number of items must be greater than or "
@@ -707,7 +734,8 @@ def check_validations(
             max_val = input_values
             min_val = input_values
 
-    if ('exclusive_maximum' in current_validations and
+    if (is_json_validation_enabled('exclusiveMaximum', configuration) and
+            'exclusive_maximum' in current_validations and
             max_val >= current_validations['exclusive_maximum']):
         raise ApiValueError(
             "Invalid value for `%s`, must be a value less than `%s`" % (
@@ -716,7 +744,8 @@ def check_validations(
             )
         )
 
-    if ('inclusive_maximum' in current_validations and
+    if (is_json_validation_enabled('maximum', configuration) and
+            'inclusive_maximum' in current_validations and
             max_val > current_validations['inclusive_maximum']):
         raise ApiValueError(
             "Invalid value for `%s`, must be a value less than or equal to "
@@ -726,7 +755,8 @@ def check_validations(
             )
         )
 
-    if ('exclusive_minimum' in current_validations and
+    if (is_json_validation_enabled('exclusiveMinimum', configuration) and
+            'exclusive_minimum' in current_validations and
             min_val <= current_validations['exclusive_minimum']):
         raise ApiValueError(
             "Invalid value for `%s`, must be a value greater than `%s`" %
@@ -736,7 +766,8 @@ def check_validations(
             )
         )
 
-    if ('inclusive_minimum' in current_validations and
+    if (is_json_validation_enabled('minimum', configuration) and
+            'inclusive_minimum' in current_validations and
             min_val < current_validations['inclusive_minimum']):
         raise ApiValueError(
             "Invalid value for `%s`, must be a value greater than or equal "
@@ -746,7 +777,8 @@ def check_validations(
             )
         )
     flags = current_validations.get('regex', {}).get('flags', 0)
-    if ('regex' in current_validations and
+    if (is_json_validation_enabled('pattern', configuration) and
+            'regex' in current_validations and
             not re.search(current_validations['regex']['pattern'],
                           input_values, flags=flags)):
         err_msg = r"Invalid value for `%s`, must match regular expression `%s`" % (
diff --git a/samples/openapi3/client/petstore/python-experimental/petstore_api/models/format_test.py b/samples/openapi3/client/petstore/python-experimental/petstore_api/models/format_test.py
index e3084b71911..24601b9499c 100644
--- a/samples/openapi3/client/petstore/python-experimental/petstore_api/models/format_test.py
+++ b/samples/openapi3/client/petstore/python-experimental/petstore_api/models/format_test.py
@@ -65,6 +65,7 @@ class FormatTest(ModelNormal):
         ('number',): {
             'inclusive_maximum': 543.2,
             'inclusive_minimum': 32.1,
+            'multiple_of': 32.5,
         },
         ('password',): {
             'max_length': 64,
@@ -73,6 +74,7 @@ class FormatTest(ModelNormal):
         ('integer',): {
             'inclusive_maximum': 100,
             'inclusive_minimum': 10,
+            'multiple_of': 2,
         },
         ('int32',): {
             'inclusive_maximum': 200,
diff --git a/samples/openapi3/client/petstore/python-experimental/tests/test_api_validation.py b/samples/openapi3/client/petstore/python-experimental/tests/test_api_validation.py
new file mode 100644
index 00000000000..725dd44cbaf
--- /dev/null
+++ b/samples/openapi3/client/petstore/python-experimental/tests/test_api_validation.py
@@ -0,0 +1,130 @@
+# coding: utf-8
+
+# flake8: noqa
+
+"""
+Run the tests.
+$ pip install nose (optional)
+$ cd OpenAPIetstore-python
+$ nosetests -v
+"""
+
+import os
+import time
+import atexit
+import datetime
+import json
+import sys
+import weakref
+import unittest
+from dateutil.parser import parse
+from collections import namedtuple
+
+import petstore_api
+import petstore_api.configuration
+
+HOST = 'http://petstore.swagger.io/v2'
+MockResponse = namedtuple('MockResponse', 'data')
+
+
+class ApiClientTests(unittest.TestCase):
+    def setUp(self):
+        self.api_client = petstore_api.ApiClient()
+
+    def test_configuration(self):
+        config = petstore_api.Configuration()
+        config.host = 'http://localhost/'
+
+        config.disable_client_side_validation = ("multipleOf,maximum,exclusiveMaximum,minimum,exclusiveMinimum,"
+            "maxLength,minLength,pattern,maxItems,minItems")
+        with self.checkRaiseRegex(ValueError, "Invalid keyword: 'foo'"):
+            config.disable_client_side_validation = 'foo'
+        config.disable_client_side_validation = None
+
+
+    def checkRaiseRegex(self, expected_exception, expected_regex):
+        if sys.version_info < (3, 0):
+            return self.assertRaisesRegexp(expected_exception, expected_regex)
+
+        return self.assertRaisesRegex(expected_exception, expected_regex)
+
+
+    def test_multiple_of(self):
+        inst = petstore_api.FormatTest(
+            byte='3',
+            date=datetime.date(2000, 1, 1),
+            password="abcdefghijkl",
+            integer=30,
+            number=65.0,
+            float=62.4
+        )
+        assert isinstance(inst, petstore_api.FormatTest)
+
+        with self.checkRaiseRegex(petstore_api.exceptions.ApiValueError, "Invalid value for `integer`, value must be a multiple of `2`"):
+          inst = petstore_api.FormatTest(
+              byte='3',
+              date=datetime.date(2000, 1, 1),
+              password="abcdefghijkl",
+              integer=31,  # Value is supposed to be multiple of '2'. An error must be raised
+              number=65.0,
+              float=62.4
+          )
+
+        data = {
+            'byte': '3',
+            'date': '1970-01-01',
+            'password': "abcdefghijkl",
+            'integer': 30,
+            'number': 65.0,
+            'float': 62.4,
+        }
+        response = MockResponse(data=json.dumps(data))
+        deserialized = self.api_client.deserialize(response, (petstore_api.FormatTest,), True)
+        self.assertTrue(isinstance(deserialized, petstore_api.FormatTest))
+
+        with self.checkRaiseRegex(petstore_api.exceptions.ApiValueError, "Invalid value for `integer`, value must be a multiple of `2`"):
+          data = {
+              'byte': '3',
+              'date': '1970-01-01',
+              'password': "abcdefghijkl",
+              'integer': 31,  # Value is supposed to be multiple of '2'. An error must be raised
+              'number': 65.0,
+              'float': 62.4,
+          }
+          response = MockResponse(data=json.dumps(data))
+          deserialized = self.api_client.deserialize(response, (petstore_api.FormatTest,), True)
+
+        # Disable JSON schema validation. No error should be raised during deserialization.
+        config = petstore_api.Configuration()
+        config.disable_client_side_validation = ("multipleOf")
+        api_client = petstore_api.ApiClient(configuration=config)
+
+        data = {
+            'byte': '3',
+            'date': '1970-01-01',
+            'password': "abcdefghijkl",
+            'integer': 31, # Value is supposed to be multiple of '2'
+            'number': 65.0,
+            'float': 62.4,
+        }
+        response = MockResponse(data=json.dumps(data))
+        deserialized = api_client.deserialize(response, (petstore_api.FormatTest,), True)
+        self.assertTrue(isinstance(deserialized, petstore_api.FormatTest))
+
+        # Disable JSON schema validation but for a different keyword.
+        # An error should be raised during deserialization.
+        config = petstore_api.Configuration()
+        config.disable_client_side_validation = ("maxItems")
+        api_client = petstore_api.ApiClient(configuration=config)
+
+        with self.checkRaiseRegex(petstore_api.exceptions.ApiValueError, "Invalid value for `integer`, value must be a multiple of `2`"):
+            data = {
+                'byte': '3',
+                'date': '1970-01-01',
+                'password': "abcdefghijkl",
+                'integer': 31, # Value is supposed to be multiple of '2'
+                'number': 65.0,
+                'float': 62.4,
+            }
+            response = MockResponse(data=json.dumps(data))
+            deserialized = api_client.deserialize(response, (petstore_api.FormatTest,), True)
-- 
GitLab


From c2db11f1950b062a40ae20df3e740a29c7807fb4 Mon Sep 17 00:00:00 2001
From: "Sebastien Rosset (serosset)" <serosset@cisco.com>
Date: Tue, 12 May 2020 10:06:00 -0700
Subject: [PATCH 08/11] Add validation log for multipleOf. Add customizable
 validation checks. add unit tests for JSON schema validation

---
 .../petstore_api/configuration.py             | 31 +++++++++++++------
 .../petstore_api/model_utils.py               | 31 +++++++++++++------
 .../petstore_api/configuration.py             | 31 +++++++++++++------
 .../python/petstore_api/configuration.py      | 31 +++++++++++++------
 .../python/petstore_api/configuration.py      | 31 +++++++++++++------
 5 files changed, 110 insertions(+), 45 deletions(-)

diff --git a/samples/client/petstore/python-asyncio/petstore_api/configuration.py b/samples/client/petstore/python-asyncio/petstore_api/configuration.py
index d3aa29792af..7587ec64da8 100644
--- a/samples/client/petstore/python-asyncio/petstore_api/configuration.py
+++ b/samples/client/petstore/python-asyncio/petstore_api/configuration.py
@@ -21,6 +21,12 @@ import six
 from six.moves import http_client as httplib
 
 
+JSON_SCHEMA_VALIDATION_KEYWORDS = {
+    'multipleOf', 'maximum', 'exclusiveMaximum',
+    'minimum', 'exclusiveMinimum', 'maxLength',
+    'minLength', 'pattern', 'maxItems', 'minItems'
+}
+
 class Configuration(object):
     """NOTE: This class is auto generated by OpenAPI Generator
 
@@ -48,16 +54,16 @@ class Configuration(object):
       then all undeclared properties received by the server are injected into the
       additional properties map. In that case, there are undeclared properties, and
       nothing to discard.
-    :param disable_client_side_validation: Boolean value indicating whether to disable
-      the JSON schema structural validation rules specified in the OpenAPI document.
-      This includes multipleOf, maximum, exclusiveMaximum, minimum, exclusiveMinimum,
-      maxLength, minLength, pattern...
+    :param disable_client_side_validation (string/None): Comma-separated list of
+      JSON schema validation keywords to disable JSON schema structural validation
+      rules. The following keywords may be specified: multipleOf, maximum,
+      exclusiveMaximum, minimum, exclusiveMinimum, maxLength, minLength, pattern,
+      maxItems, minItems.
       By default, the validation is performed for data generated locally by the client
       and data received from the server, independent of any validation performed by
-      the server side.
-      If the input data does not satisfy the JSON schema validation rules specified
-      in the OpenAPI document, an exception is raised.
-      If disable_client_side_validation is set to true, structural validation is
+      the server side. If the input data does not satisfy the JSON schema validation
+      rules specified in the OpenAPI document, an exception is raised.
+      If disable_client_side_validation is set, structural validation is
       disabled. This can be useful to troubleshoot data validation problem, such as
       when the OpenAPI document validation rules do not match the actual API data
       received by the server.
@@ -106,7 +112,7 @@ conf = petstore_api.Configuration(
                  api_key=None, api_key_prefix=None,
                  username=None, password=None,
                  discard_unknown_keys=False,
-                 disable_client_side_validation=False,
+                 disable_client_side_validation=None,
                  ):
         """Constructor
         """
@@ -216,6 +222,13 @@ conf = petstore_api.Configuration(
 
     def __setattr__(self, name, value):
         object.__setattr__(self, name, value)
+        if name == 'disable_client_side_validation' and value is not None:
+            s = set(value.split(','))
+            for v in s:
+                if v not in JSON_SCHEMA_VALIDATION_KEYWORDS:
+                    raise ValueError(
+                        "Invalid keyword: '{0}''".format(v))
+            self._disable_client_side_validation = s
 
     @classmethod
     def set_default(cls, default):
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 26932850255..ffc6eea913f 100644
--- a/samples/client/petstore/python-experimental/petstore_api/model_utils.py
+++ b/samples/client/petstore/python-experimental/petstore_api/model_utils.py
@@ -647,6 +647,7 @@ def is_json_validation_enabled(schema_keyword, configuration=None):
     """
 
     return (configuration is None or
+        not hasattr(configuration, '_disable_client_side_validation') or
         schema_keyword not in configuration._disable_client_side_validation)
 
 
@@ -664,7 +665,19 @@ def check_validations(
     """
 
     current_validations = validations[input_variable_path]
-    if (is_json_validation_enabled('maxLength') and
+    if (is_json_validation_enabled('multipleOf', configuration) and
+            'multiple_of' in current_validations and
+            not (input_values / current_validations['multiple_of']).is_integer()):
+        # Note 'multipleOf' will be as good as the floating point arithmetic.
+        raise ApiValueError(
+            "Invalid value for `%s`, value must be a multiple of "
+            "`%s`" % (
+                input_variable_path[0],
+                current_validations['multiple_of']
+            )
+        )
+
+    if (is_json_validation_enabled('maxLength', configuration) and
             'max_length' in current_validations and
             len(input_values) > current_validations['max_length']):
         raise ApiValueError(
@@ -675,7 +688,7 @@ def check_validations(
             )
         )
 
-    if (is_json_validation_enabled('minLength') and
+    if (is_json_validation_enabled('minLength', configuration) and
             'min_length' in current_validations and
             len(input_values) < current_validations['min_length']):
         raise ApiValueError(
@@ -686,7 +699,7 @@ def check_validations(
             )
         )
 
-    if (is_json_validation_enabled('maxItems') and
+    if (is_json_validation_enabled('maxItems', configuration) and
             'max_items' in current_validations and
             len(input_values) > current_validations['max_items']):
         raise ApiValueError(
@@ -697,7 +710,7 @@ def check_validations(
             )
         )
 
-    if (is_json_validation_enabled('minItems') and
+    if (is_json_validation_enabled('minItems', configuration) and
             'min_items' in current_validations and
             len(input_values) < current_validations['min_items']):
         raise ValueError(
@@ -721,7 +734,7 @@ def check_validations(
             max_val = input_values
             min_val = input_values
 
-    if (is_json_validation_enabled('exclusiveMaximum') and
+    if (is_json_validation_enabled('exclusiveMaximum', configuration) and
             'exclusive_maximum' in current_validations and
             max_val >= current_validations['exclusive_maximum']):
         raise ApiValueError(
@@ -731,7 +744,7 @@ def check_validations(
             )
         )
 
-    if (is_json_validation_enabled('maximum') and
+    if (is_json_validation_enabled('maximum', configuration) and
             'inclusive_maximum' in current_validations and
             max_val > current_validations['inclusive_maximum']):
         raise ApiValueError(
@@ -742,7 +755,7 @@ def check_validations(
             )
         )
 
-    if (is_json_validation_enabled('exclusiveMinimum') and
+    if (is_json_validation_enabled('exclusiveMinimum', configuration) and
             'exclusive_minimum' in current_validations and
             min_val <= current_validations['exclusive_minimum']):
         raise ApiValueError(
@@ -753,7 +766,7 @@ def check_validations(
             )
         )
 
-    if (is_json_validation_enabled('minimum') and
+    if (is_json_validation_enabled('minimum', configuration) and
             'inclusive_minimum' in current_validations and
             min_val < current_validations['inclusive_minimum']):
         raise ApiValueError(
@@ -764,7 +777,7 @@ def check_validations(
             )
         )
     flags = current_validations.get('regex', {}).get('flags', 0)
-    if (is_json_validation_enabled('pattern') and
+    if (is_json_validation_enabled('pattern', configuration) and
             'regex' in current_validations and
             not re.search(current_validations['regex']['pattern'],
                           input_values, flags=flags)):
diff --git a/samples/client/petstore/python-tornado/petstore_api/configuration.py b/samples/client/petstore/python-tornado/petstore_api/configuration.py
index 0a66048c3da..c289a675a59 100644
--- a/samples/client/petstore/python-tornado/petstore_api/configuration.py
+++ b/samples/client/petstore/python-tornado/petstore_api/configuration.py
@@ -22,6 +22,12 @@ import six
 from six.moves import http_client as httplib
 
 
+JSON_SCHEMA_VALIDATION_KEYWORDS = {
+    'multipleOf', 'maximum', 'exclusiveMaximum',
+    'minimum', 'exclusiveMinimum', 'maxLength',
+    'minLength', 'pattern', 'maxItems', 'minItems'
+}
+
 class Configuration(object):
     """NOTE: This class is auto generated by OpenAPI Generator
 
@@ -49,16 +55,16 @@ class Configuration(object):
       then all undeclared properties received by the server are injected into the
       additional properties map. In that case, there are undeclared properties, and
       nothing to discard.
-    :param disable_client_side_validation: Boolean value indicating whether to disable
-      the JSON schema structural validation rules specified in the OpenAPI document.
-      This includes multipleOf, maximum, exclusiveMaximum, minimum, exclusiveMinimum,
-      maxLength, minLength, pattern...
+    :param disable_client_side_validation (string/None): Comma-separated list of
+      JSON schema validation keywords to disable JSON schema structural validation
+      rules. The following keywords may be specified: multipleOf, maximum,
+      exclusiveMaximum, minimum, exclusiveMinimum, maxLength, minLength, pattern,
+      maxItems, minItems.
       By default, the validation is performed for data generated locally by the client
       and data received from the server, independent of any validation performed by
-      the server side.
-      If the input data does not satisfy the JSON schema validation rules specified
-      in the OpenAPI document, an exception is raised.
-      If disable_client_side_validation is set to true, structural validation is
+      the server side. If the input data does not satisfy the JSON schema validation
+      rules specified in the OpenAPI document, an exception is raised.
+      If disable_client_side_validation is set, structural validation is
       disabled. This can be useful to troubleshoot data validation problem, such as
       when the OpenAPI document validation rules do not match the actual API data
       received by the server.
@@ -107,7 +113,7 @@ conf = petstore_api.Configuration(
                  api_key=None, api_key_prefix=None,
                  username=None, password=None,
                  discard_unknown_keys=False,
-                 disable_client_side_validation=False,
+                 disable_client_side_validation=None,
                  ):
         """Constructor
         """
@@ -220,6 +226,13 @@ conf = petstore_api.Configuration(
 
     def __setattr__(self, name, value):
         object.__setattr__(self, name, value)
+        if name == 'disable_client_side_validation' and value is not None:
+            s = set(value.split(','))
+            for v in s:
+                if v not in JSON_SCHEMA_VALIDATION_KEYWORDS:
+                    raise ValueError(
+                        "Invalid keyword: '{0}''".format(v))
+            self._disable_client_side_validation = s
 
     @classmethod
     def set_default(cls, default):
diff --git a/samples/client/petstore/python/petstore_api/configuration.py b/samples/client/petstore/python/petstore_api/configuration.py
index 0a66048c3da..c289a675a59 100644
--- a/samples/client/petstore/python/petstore_api/configuration.py
+++ b/samples/client/petstore/python/petstore_api/configuration.py
@@ -22,6 +22,12 @@ import six
 from six.moves import http_client as httplib
 
 
+JSON_SCHEMA_VALIDATION_KEYWORDS = {
+    'multipleOf', 'maximum', 'exclusiveMaximum',
+    'minimum', 'exclusiveMinimum', 'maxLength',
+    'minLength', 'pattern', 'maxItems', 'minItems'
+}
+
 class Configuration(object):
     """NOTE: This class is auto generated by OpenAPI Generator
 
@@ -49,16 +55,16 @@ class Configuration(object):
       then all undeclared properties received by the server are injected into the
       additional properties map. In that case, there are undeclared properties, and
       nothing to discard.
-    :param disable_client_side_validation: Boolean value indicating whether to disable
-      the JSON schema structural validation rules specified in the OpenAPI document.
-      This includes multipleOf, maximum, exclusiveMaximum, minimum, exclusiveMinimum,
-      maxLength, minLength, pattern...
+    :param disable_client_side_validation (string/None): Comma-separated list of
+      JSON schema validation keywords to disable JSON schema structural validation
+      rules. The following keywords may be specified: multipleOf, maximum,
+      exclusiveMaximum, minimum, exclusiveMinimum, maxLength, minLength, pattern,
+      maxItems, minItems.
       By default, the validation is performed for data generated locally by the client
       and data received from the server, independent of any validation performed by
-      the server side.
-      If the input data does not satisfy the JSON schema validation rules specified
-      in the OpenAPI document, an exception is raised.
-      If disable_client_side_validation is set to true, structural validation is
+      the server side. If the input data does not satisfy the JSON schema validation
+      rules specified in the OpenAPI document, an exception is raised.
+      If disable_client_side_validation is set, structural validation is
       disabled. This can be useful to troubleshoot data validation problem, such as
       when the OpenAPI document validation rules do not match the actual API data
       received by the server.
@@ -107,7 +113,7 @@ conf = petstore_api.Configuration(
                  api_key=None, api_key_prefix=None,
                  username=None, password=None,
                  discard_unknown_keys=False,
-                 disable_client_side_validation=False,
+                 disable_client_side_validation=None,
                  ):
         """Constructor
         """
@@ -220,6 +226,13 @@ conf = petstore_api.Configuration(
 
     def __setattr__(self, name, value):
         object.__setattr__(self, name, value)
+        if name == 'disable_client_side_validation' and value is not None:
+            s = set(value.split(','))
+            for v in s:
+                if v not in JSON_SCHEMA_VALIDATION_KEYWORDS:
+                    raise ValueError(
+                        "Invalid keyword: '{0}''".format(v))
+            self._disable_client_side_validation = s
 
     @classmethod
     def set_default(cls, default):
diff --git a/samples/openapi3/client/petstore/python/petstore_api/configuration.py b/samples/openapi3/client/petstore/python/petstore_api/configuration.py
index 0d19da6dfc4..981c3c9e22e 100644
--- a/samples/openapi3/client/petstore/python/petstore_api/configuration.py
+++ b/samples/openapi3/client/petstore/python/petstore_api/configuration.py
@@ -22,6 +22,12 @@ import six
 from six.moves import http_client as httplib
 
 
+JSON_SCHEMA_VALIDATION_KEYWORDS = {
+    'multipleOf', 'maximum', 'exclusiveMaximum',
+    'minimum', 'exclusiveMinimum', 'maxLength',
+    'minLength', 'pattern', 'maxItems', 'minItems'
+}
+
 class Configuration(object):
     """NOTE: This class is auto generated by OpenAPI Generator
 
@@ -49,16 +55,16 @@ class Configuration(object):
       then all undeclared properties received by the server are injected into the
       additional properties map. In that case, there are undeclared properties, and
       nothing to discard.
-    :param disable_client_side_validation: Boolean value indicating whether to disable
-      the JSON schema structural validation rules specified in the OpenAPI document.
-      This includes multipleOf, maximum, exclusiveMaximum, minimum, exclusiveMinimum,
-      maxLength, minLength, pattern...
+    :param disable_client_side_validation (string/None): Comma-separated list of
+      JSON schema validation keywords to disable JSON schema structural validation
+      rules. The following keywords may be specified: multipleOf, maximum,
+      exclusiveMaximum, minimum, exclusiveMinimum, maxLength, minLength, pattern,
+      maxItems, minItems.
       By default, the validation is performed for data generated locally by the client
       and data received from the server, independent of any validation performed by
-      the server side.
-      If the input data does not satisfy the JSON schema validation rules specified
-      in the OpenAPI document, an exception is raised.
-      If disable_client_side_validation is set to true, structural validation is
+      the server side. If the input data does not satisfy the JSON schema validation
+      rules specified in the OpenAPI document, an exception is raised.
+      If disable_client_side_validation is set, structural validation is
       disabled. This can be useful to troubleshoot data validation problem, such as
       when the OpenAPI document validation rules do not match the actual API data
       received by the server.
@@ -148,7 +154,7 @@ conf = petstore_api.Configuration(
                  api_key=None, api_key_prefix=None,
                  username=None, password=None,
                  discard_unknown_keys=False,
-                 disable_client_side_validation=False,
+                 disable_client_side_validation=None,
                  signing_info=None,
                  ):
         """Constructor
@@ -267,6 +273,13 @@ conf = petstore_api.Configuration(
 
     def __setattr__(self, name, value):
         object.__setattr__(self, name, value)
+        if name == 'disable_client_side_validation' and value is not None:
+            s = set(value.split(','))
+            for v in s:
+                if v not in JSON_SCHEMA_VALIDATION_KEYWORDS:
+                    raise ValueError(
+                        "Invalid keyword: '{0}''".format(v))
+            self._disable_client_side_validation = s
         if name == "signing_info" and value is not None:
             # Ensure the host paramater from signing info is the same as
             # Configuration.host.
-- 
GitLab


From ece58e16bd5d80e3a32a3a78964848d84568972d Mon Sep 17 00:00:00 2001
From: "Sebastien Rosset (serosset)" <serosset@cisco.com>
Date: Tue, 12 May 2020 10:39:42 -0700
Subject: [PATCH 09/11] Add validation log for multipleOf. Add customizable
 validation checks. add unit tests for JSON schema validation

---
 .../resources/python/python-experimental/model_utils.mustache   | 2 +-
 .../petstore/python-experimental/petstore_api/model_utils.py    | 2 +-
 .../petstore/python-experimental/petstore_api/model_utils.py    | 2 +-
 .../petstore/python-experimental/tests/test_api_validation.py   | 1 +
 4 files changed, 4 insertions(+), 3 deletions(-)

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 819aac4781c..6cbb5df79a3 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
@@ -400,7 +400,7 @@ def check_validations(
     current_validations = validations[input_variable_path]
     if (is_json_validation_enabled('multipleOf', configuration) and
             'multiple_of' in current_validations and
-            not (input_values / current_validations['multiple_of']).is_integer()):
+            not float(input_values / current_validations['multiple_of']).is_integer()):
         # Note 'multipleOf' will be as good as the floating point arithmetic.
         raise ApiValueError(
             "Invalid value for `%s`, value must be a multiple of "
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 ffc6eea913f..0c04d65953d 100644
--- a/samples/client/petstore/python-experimental/petstore_api/model_utils.py
+++ b/samples/client/petstore/python-experimental/petstore_api/model_utils.py
@@ -667,7 +667,7 @@ def check_validations(
     current_validations = validations[input_variable_path]
     if (is_json_validation_enabled('multipleOf', configuration) and
             'multiple_of' in current_validations and
-            not (input_values / current_validations['multiple_of']).is_integer()):
+            not float(input_values / current_validations['multiple_of']).is_integer()):
         # Note 'multipleOf' will be as good as the floating point arithmetic.
         raise ApiValueError(
             "Invalid value for `%s`, value must be a multiple of "
diff --git a/samples/openapi3/client/petstore/python-experimental/petstore_api/model_utils.py b/samples/openapi3/client/petstore/python-experimental/petstore_api/model_utils.py
index ffc6eea913f..0c04d65953d 100644
--- a/samples/openapi3/client/petstore/python-experimental/petstore_api/model_utils.py
+++ b/samples/openapi3/client/petstore/python-experimental/petstore_api/model_utils.py
@@ -667,7 +667,7 @@ def check_validations(
     current_validations = validations[input_variable_path]
     if (is_json_validation_enabled('multipleOf', configuration) and
             'multiple_of' in current_validations and
-            not (input_values / current_validations['multiple_of']).is_integer()):
+            not float(input_values / current_validations['multiple_of']).is_integer()):
         # Note 'multipleOf' will be as good as the floating point arithmetic.
         raise ApiValueError(
             "Invalid value for `%s`, value must be a multiple of "
diff --git a/samples/openapi3/client/petstore/python-experimental/tests/test_api_validation.py b/samples/openapi3/client/petstore/python-experimental/tests/test_api_validation.py
index 725dd44cbaf..fb22afb067d 100644
--- a/samples/openapi3/client/petstore/python-experimental/tests/test_api_validation.py
+++ b/samples/openapi3/client/petstore/python-experimental/tests/test_api_validation.py
@@ -70,6 +70,7 @@ class ApiClientTests(unittest.TestCase):
               float=62.4
           )
 
+    def test_multiple_of_deserialization(self):
         data = {
             'byte': '3',
             'date': '1970-01-01',
-- 
GitLab


From e512302787993d7215085339671eb34670c02e2e Mon Sep 17 00:00:00 2001
From: "Sebastien Rosset (serosset)" <serosset@cisco.com>
Date: Tue, 12 May 2020 11:08:08 -0700
Subject: [PATCH 10/11] Add validation log for multipleOf. Add customizable
 validation checks. add unit tests for JSON schema validation. Fix for python
 2

---
 .../resources/python/python-experimental/model_utils.mustache  | 3 ++-
 .../petstore/python-experimental/petstore_api/model_utils.py   | 3 ++-
 .../petstore/python-experimental/petstore_api/model_utils.py   | 3 ++-
 3 files changed, 6 insertions(+), 3 deletions(-)

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 6cbb5df79a3..36b59f1027c 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
@@ -400,7 +400,8 @@ def check_validations(
     current_validations = validations[input_variable_path]
     if (is_json_validation_enabled('multipleOf', configuration) and
             'multiple_of' in current_validations and
-            not float(input_values / current_validations['multiple_of']).is_integer()):
+            isinstance(input_values, (int, float)) and
+            not (float(input_values) / current_validations['multiple_of']).is_integer()):
         # Note 'multipleOf' will be as good as the floating point arithmetic.
         raise ApiValueError(
             "Invalid value for `%s`, value must be a multiple of "
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 0c04d65953d..0a446c7b55a 100644
--- a/samples/client/petstore/python-experimental/petstore_api/model_utils.py
+++ b/samples/client/petstore/python-experimental/petstore_api/model_utils.py
@@ -667,7 +667,8 @@ def check_validations(
     current_validations = validations[input_variable_path]
     if (is_json_validation_enabled('multipleOf', configuration) and
             'multiple_of' in current_validations and
-            not float(input_values / current_validations['multiple_of']).is_integer()):
+            isinstance(input_values, (int, float)) and
+            not (float(input_values) / current_validations['multiple_of']).is_integer()):
         # Note 'multipleOf' will be as good as the floating point arithmetic.
         raise ApiValueError(
             "Invalid value for `%s`, value must be a multiple of "
diff --git a/samples/openapi3/client/petstore/python-experimental/petstore_api/model_utils.py b/samples/openapi3/client/petstore/python-experimental/petstore_api/model_utils.py
index 0c04d65953d..0a446c7b55a 100644
--- a/samples/openapi3/client/petstore/python-experimental/petstore_api/model_utils.py
+++ b/samples/openapi3/client/petstore/python-experimental/petstore_api/model_utils.py
@@ -667,7 +667,8 @@ def check_validations(
     current_validations = validations[input_variable_path]
     if (is_json_validation_enabled('multipleOf', configuration) and
             'multiple_of' in current_validations and
-            not float(input_values / current_validations['multiple_of']).is_integer()):
+            isinstance(input_values, (int, float)) and
+            not (float(input_values) / current_validations['multiple_of']).is_integer()):
         # Note 'multipleOf' will be as good as the floating point arithmetic.
         raise ApiValueError(
             "Invalid value for `%s`, value must be a multiple of "
-- 
GitLab


From ea2b170f56c59935439367cec08359fa2dcea484 Mon Sep 17 00:00:00 2001
From: "Sebastien Rosset (serosset)" <serosset@cisco.com>
Date: Tue, 12 May 2020 15:08:49 -0700
Subject: [PATCH 11/11] address review comments

---
 .../resources/python/configuration.mustache     | 17 +++++++++--------
 .../python-experimental/model_utils.mustache    |  4 ++--
 .../petstore_api/configuration.py               | 17 +++++++++--------
 .../petstore_api/configuration.py               | 17 +++++++++--------
 .../petstore_api/model_utils.py                 |  4 ++--
 .../petstore_api/configuration.py               | 17 +++++++++--------
 .../python/petstore_api/configuration.py        | 17 +++++++++--------
 .../petstore_api/configuration.py               | 17 +++++++++--------
 .../petstore_api/model_utils.py                 |  4 ++--
 .../tests/test_api_validation.py                | 10 +++++-----
 .../python/petstore_api/configuration.py        | 17 +++++++++--------
 11 files changed, 74 insertions(+), 67 deletions(-)

diff --git a/modules/openapi-generator/src/main/resources/python/configuration.mustache b/modules/openapi-generator/src/main/resources/python/configuration.mustache
index b559bc75616..d1705eed25d 100644
--- a/modules/openapi-generator/src/main/resources/python/configuration.mustache
+++ b/modules/openapi-generator/src/main/resources/python/configuration.mustache
@@ -14,6 +14,7 @@ import urllib3
 
 import six
 from six.moves import http_client as httplib
+from {{packageName}}.exceptions import ApiValueError
 
 
 JSON_SCHEMA_VALIDATION_KEYWORDS = {
@@ -49,7 +50,7 @@ class Configuration(object):
       then all undeclared properties received by the server are injected into the
       additional properties map. In that case, there are undeclared properties, and
       nothing to discard.
-    :param disable_client_side_validation (string/None): Comma-separated list of
+    :param disabled_client_side_validations (string): Comma-separated list of
       JSON schema validation keywords to disable JSON schema structural validation
       rules. The following keywords may be specified: multipleOf, maximum,
       exclusiveMaximum, minimum, exclusiveMinimum, maxLength, minLength, pattern,
@@ -58,7 +59,7 @@ class Configuration(object):
       and data received from the server, independent of any validation performed by
       the server side. If the input data does not satisfy the JSON schema validation
       rules specified in the OpenAPI document, an exception is raised.
-      If disable_client_side_validation is set, structural validation is
+      If disabled_client_side_validations is set, structural validation is
       disabled. This can be useful to troubleshoot data validation problem, such as
       when the OpenAPI document validation rules do not match the actual API data
       received by the server.
@@ -158,7 +159,7 @@ conf = {{{packageName}}}.Configuration(
                  api_key=None, api_key_prefix=None,
                  username=None, password=None,
                  discard_unknown_keys=False,
-                 disable_client_side_validation=None,
+                 disabled_client_side_validations="",
 {{#hasHttpSignatureMethods}}
                  signing_info=None,
 {{/hasHttpSignatureMethods}}
@@ -192,7 +193,7 @@ conf = {{{packageName}}}.Configuration(
         """Password for HTTP basic authentication
         """
         self.discard_unknown_keys = discard_unknown_keys
-        self.disable_client_side_validation = disable_client_side_validation
+        self.disabled_client_side_validations = disabled_client_side_validations
 {{#hasHttpSignatureMethods}}
         if signing_info is not None:
             signing_info.host = host
@@ -298,13 +299,13 @@ conf = {{{packageName}}}.Configuration(
 
     def __setattr__(self, name, value):
         object.__setattr__(self, name, value)
-        if name == 'disable_client_side_validation' and value is not None:
-            s = set(value.split(','))
+        if name == 'disabled_client_side_validations':
+            s = set(filter(None, value.split(',')))
             for v in s:
                 if v not in JSON_SCHEMA_VALIDATION_KEYWORDS:
-                    raise ValueError(
+                    raise ApiValueError(
                         "Invalid keyword: '{0}''".format(v))
-            self._disable_client_side_validation = s
+            self._disabled_client_side_validations = s
 {{#hasHttpSignatureMethods}}
         if name == "signing_info" and value is not None:
             # Ensure the host paramater from signing info is the same as
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 36b59f1027c..2a62d640e13 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
@@ -380,8 +380,8 @@ def is_json_validation_enabled(schema_keyword, configuration=None):
     """
 
     return (configuration is None or
-        not hasattr(configuration, '_disable_client_side_validation') or
-        schema_keyword not in configuration._disable_client_side_validation)
+        not hasattr(configuration, '_disabled_client_side_validations') or
+        schema_keyword not in configuration._disabled_client_side_validations)
 
 
 def check_validations(
diff --git a/samples/client/petstore/python-asyncio/petstore_api/configuration.py b/samples/client/petstore/python-asyncio/petstore_api/configuration.py
index 7587ec64da8..5c860e8c954 100644
--- a/samples/client/petstore/python-asyncio/petstore_api/configuration.py
+++ b/samples/client/petstore/python-asyncio/petstore_api/configuration.py
@@ -19,6 +19,7 @@ import urllib3
 
 import six
 from six.moves import http_client as httplib
+from petstore_api.exceptions import ApiValueError
 
 
 JSON_SCHEMA_VALIDATION_KEYWORDS = {
@@ -54,7 +55,7 @@ class Configuration(object):
       then all undeclared properties received by the server are injected into the
       additional properties map. In that case, there are undeclared properties, and
       nothing to discard.
-    :param disable_client_side_validation (string/None): Comma-separated list of
+    :param disabled_client_side_validations (string): Comma-separated list of
       JSON schema validation keywords to disable JSON schema structural validation
       rules. The following keywords may be specified: multipleOf, maximum,
       exclusiveMaximum, minimum, exclusiveMinimum, maxLength, minLength, pattern,
@@ -63,7 +64,7 @@ class Configuration(object):
       and data received from the server, independent of any validation performed by
       the server side. If the input data does not satisfy the JSON schema validation
       rules specified in the OpenAPI document, an exception is raised.
-      If disable_client_side_validation is set, structural validation is
+      If disabled_client_side_validations is set, structural validation is
       disabled. This can be useful to troubleshoot data validation problem, such as
       when the OpenAPI document validation rules do not match the actual API data
       received by the server.
@@ -112,7 +113,7 @@ conf = petstore_api.Configuration(
                  api_key=None, api_key_prefix=None,
                  username=None, password=None,
                  discard_unknown_keys=False,
-                 disable_client_side_validation=None,
+                 disabled_client_side_validations="",
                  ):
         """Constructor
         """
@@ -143,7 +144,7 @@ conf = petstore_api.Configuration(
         """Password for HTTP basic authentication
         """
         self.discard_unknown_keys = discard_unknown_keys
-        self.disable_client_side_validation = disable_client_side_validation
+        self.disabled_client_side_validations = disabled_client_side_validations
         self.access_token = None
         """access token for OAuth/Bearer
         """
@@ -222,13 +223,13 @@ conf = petstore_api.Configuration(
 
     def __setattr__(self, name, value):
         object.__setattr__(self, name, value)
-        if name == 'disable_client_side_validation' and value is not None:
-            s = set(value.split(','))
+        if name == 'disabled_client_side_validations':
+            s = set(filter(None, value.split(',')))
             for v in s:
                 if v not in JSON_SCHEMA_VALIDATION_KEYWORDS:
-                    raise ValueError(
+                    raise ApiValueError(
                         "Invalid keyword: '{0}''".format(v))
-            self._disable_client_side_validation = s
+            self._disabled_client_side_validations = s
 
     @classmethod
     def set_default(cls, default):
diff --git a/samples/client/petstore/python-experimental/petstore_api/configuration.py b/samples/client/petstore/python-experimental/petstore_api/configuration.py
index c289a675a59..18085f8b748 100644
--- a/samples/client/petstore/python-experimental/petstore_api/configuration.py
+++ b/samples/client/petstore/python-experimental/petstore_api/configuration.py
@@ -20,6 +20,7 @@ import urllib3
 
 import six
 from six.moves import http_client as httplib
+from petstore_api.exceptions import ApiValueError
 
 
 JSON_SCHEMA_VALIDATION_KEYWORDS = {
@@ -55,7 +56,7 @@ class Configuration(object):
       then all undeclared properties received by the server are injected into the
       additional properties map. In that case, there are undeclared properties, and
       nothing to discard.
-    :param disable_client_side_validation (string/None): Comma-separated list of
+    :param disabled_client_side_validations (string): Comma-separated list of
       JSON schema validation keywords to disable JSON schema structural validation
       rules. The following keywords may be specified: multipleOf, maximum,
       exclusiveMaximum, minimum, exclusiveMinimum, maxLength, minLength, pattern,
@@ -64,7 +65,7 @@ class Configuration(object):
       and data received from the server, independent of any validation performed by
       the server side. If the input data does not satisfy the JSON schema validation
       rules specified in the OpenAPI document, an exception is raised.
-      If disable_client_side_validation is set, structural validation is
+      If disabled_client_side_validations is set, structural validation is
       disabled. This can be useful to troubleshoot data validation problem, such as
       when the OpenAPI document validation rules do not match the actual API data
       received by the server.
@@ -113,7 +114,7 @@ conf = petstore_api.Configuration(
                  api_key=None, api_key_prefix=None,
                  username=None, password=None,
                  discard_unknown_keys=False,
-                 disable_client_side_validation=None,
+                 disabled_client_side_validations="",
                  ):
         """Constructor
         """
@@ -144,7 +145,7 @@ conf = petstore_api.Configuration(
         """Password for HTTP basic authentication
         """
         self.discard_unknown_keys = discard_unknown_keys
-        self.disable_client_side_validation = disable_client_side_validation
+        self.disabled_client_side_validations = disabled_client_side_validations
         self.access_token = None
         """access token for OAuth/Bearer
         """
@@ -226,13 +227,13 @@ conf = petstore_api.Configuration(
 
     def __setattr__(self, name, value):
         object.__setattr__(self, name, value)
-        if name == 'disable_client_side_validation' and value is not None:
-            s = set(value.split(','))
+        if name == 'disabled_client_side_validations':
+            s = set(filter(None, value.split(',')))
             for v in s:
                 if v not in JSON_SCHEMA_VALIDATION_KEYWORDS:
-                    raise ValueError(
+                    raise ApiValueError(
                         "Invalid keyword: '{0}''".format(v))
-            self._disable_client_side_validation = s
+            self._disabled_client_side_validations = s
 
     @classmethod
     def set_default(cls, default):
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 0a446c7b55a..724dd2bdec4 100644
--- a/samples/client/petstore/python-experimental/petstore_api/model_utils.py
+++ b/samples/client/petstore/python-experimental/petstore_api/model_utils.py
@@ -647,8 +647,8 @@ def is_json_validation_enabled(schema_keyword, configuration=None):
     """
 
     return (configuration is None or
-        not hasattr(configuration, '_disable_client_side_validation') or
-        schema_keyword not in configuration._disable_client_side_validation)
+        not hasattr(configuration, '_disabled_client_side_validations') or
+        schema_keyword not in configuration._disabled_client_side_validations)
 
 
 def check_validations(
diff --git a/samples/client/petstore/python-tornado/petstore_api/configuration.py b/samples/client/petstore/python-tornado/petstore_api/configuration.py
index c289a675a59..18085f8b748 100644
--- a/samples/client/petstore/python-tornado/petstore_api/configuration.py
+++ b/samples/client/petstore/python-tornado/petstore_api/configuration.py
@@ -20,6 +20,7 @@ import urllib3
 
 import six
 from six.moves import http_client as httplib
+from petstore_api.exceptions import ApiValueError
 
 
 JSON_SCHEMA_VALIDATION_KEYWORDS = {
@@ -55,7 +56,7 @@ class Configuration(object):
       then all undeclared properties received by the server are injected into the
       additional properties map. In that case, there are undeclared properties, and
       nothing to discard.
-    :param disable_client_side_validation (string/None): Comma-separated list of
+    :param disabled_client_side_validations (string): Comma-separated list of
       JSON schema validation keywords to disable JSON schema structural validation
       rules. The following keywords may be specified: multipleOf, maximum,
       exclusiveMaximum, minimum, exclusiveMinimum, maxLength, minLength, pattern,
@@ -64,7 +65,7 @@ class Configuration(object):
       and data received from the server, independent of any validation performed by
       the server side. If the input data does not satisfy the JSON schema validation
       rules specified in the OpenAPI document, an exception is raised.
-      If disable_client_side_validation is set, structural validation is
+      If disabled_client_side_validations is set, structural validation is
       disabled. This can be useful to troubleshoot data validation problem, such as
       when the OpenAPI document validation rules do not match the actual API data
       received by the server.
@@ -113,7 +114,7 @@ conf = petstore_api.Configuration(
                  api_key=None, api_key_prefix=None,
                  username=None, password=None,
                  discard_unknown_keys=False,
-                 disable_client_side_validation=None,
+                 disabled_client_side_validations="",
                  ):
         """Constructor
         """
@@ -144,7 +145,7 @@ conf = petstore_api.Configuration(
         """Password for HTTP basic authentication
         """
         self.discard_unknown_keys = discard_unknown_keys
-        self.disable_client_side_validation = disable_client_side_validation
+        self.disabled_client_side_validations = disabled_client_side_validations
         self.access_token = None
         """access token for OAuth/Bearer
         """
@@ -226,13 +227,13 @@ conf = petstore_api.Configuration(
 
     def __setattr__(self, name, value):
         object.__setattr__(self, name, value)
-        if name == 'disable_client_side_validation' and value is not None:
-            s = set(value.split(','))
+        if name == 'disabled_client_side_validations':
+            s = set(filter(None, value.split(',')))
             for v in s:
                 if v not in JSON_SCHEMA_VALIDATION_KEYWORDS:
-                    raise ValueError(
+                    raise ApiValueError(
                         "Invalid keyword: '{0}''".format(v))
-            self._disable_client_side_validation = s
+            self._disabled_client_side_validations = s
 
     @classmethod
     def set_default(cls, default):
diff --git a/samples/client/petstore/python/petstore_api/configuration.py b/samples/client/petstore/python/petstore_api/configuration.py
index c289a675a59..18085f8b748 100644
--- a/samples/client/petstore/python/petstore_api/configuration.py
+++ b/samples/client/petstore/python/petstore_api/configuration.py
@@ -20,6 +20,7 @@ import urllib3
 
 import six
 from six.moves import http_client as httplib
+from petstore_api.exceptions import ApiValueError
 
 
 JSON_SCHEMA_VALIDATION_KEYWORDS = {
@@ -55,7 +56,7 @@ class Configuration(object):
       then all undeclared properties received by the server are injected into the
       additional properties map. In that case, there are undeclared properties, and
       nothing to discard.
-    :param disable_client_side_validation (string/None): Comma-separated list of
+    :param disabled_client_side_validations (string): Comma-separated list of
       JSON schema validation keywords to disable JSON schema structural validation
       rules. The following keywords may be specified: multipleOf, maximum,
       exclusiveMaximum, minimum, exclusiveMinimum, maxLength, minLength, pattern,
@@ -64,7 +65,7 @@ class Configuration(object):
       and data received from the server, independent of any validation performed by
       the server side. If the input data does not satisfy the JSON schema validation
       rules specified in the OpenAPI document, an exception is raised.
-      If disable_client_side_validation is set, structural validation is
+      If disabled_client_side_validations is set, structural validation is
       disabled. This can be useful to troubleshoot data validation problem, such as
       when the OpenAPI document validation rules do not match the actual API data
       received by the server.
@@ -113,7 +114,7 @@ conf = petstore_api.Configuration(
                  api_key=None, api_key_prefix=None,
                  username=None, password=None,
                  discard_unknown_keys=False,
-                 disable_client_side_validation=None,
+                 disabled_client_side_validations="",
                  ):
         """Constructor
         """
@@ -144,7 +145,7 @@ conf = petstore_api.Configuration(
         """Password for HTTP basic authentication
         """
         self.discard_unknown_keys = discard_unknown_keys
-        self.disable_client_side_validation = disable_client_side_validation
+        self.disabled_client_side_validations = disabled_client_side_validations
         self.access_token = None
         """access token for OAuth/Bearer
         """
@@ -226,13 +227,13 @@ conf = petstore_api.Configuration(
 
     def __setattr__(self, name, value):
         object.__setattr__(self, name, value)
-        if name == 'disable_client_side_validation' and value is not None:
-            s = set(value.split(','))
+        if name == 'disabled_client_side_validations':
+            s = set(filter(None, value.split(',')))
             for v in s:
                 if v not in JSON_SCHEMA_VALIDATION_KEYWORDS:
-                    raise ValueError(
+                    raise ApiValueError(
                         "Invalid keyword: '{0}''".format(v))
-            self._disable_client_side_validation = s
+            self._disabled_client_side_validations = s
 
     @classmethod
     def set_default(cls, default):
diff --git a/samples/openapi3/client/petstore/python-experimental/petstore_api/configuration.py b/samples/openapi3/client/petstore/python-experimental/petstore_api/configuration.py
index 981c3c9e22e..850cb907b09 100644
--- a/samples/openapi3/client/petstore/python-experimental/petstore_api/configuration.py
+++ b/samples/openapi3/client/petstore/python-experimental/petstore_api/configuration.py
@@ -20,6 +20,7 @@ import urllib3
 
 import six
 from six.moves import http_client as httplib
+from petstore_api.exceptions import ApiValueError
 
 
 JSON_SCHEMA_VALIDATION_KEYWORDS = {
@@ -55,7 +56,7 @@ class Configuration(object):
       then all undeclared properties received by the server are injected into the
       additional properties map. In that case, there are undeclared properties, and
       nothing to discard.
-    :param disable_client_side_validation (string/None): Comma-separated list of
+    :param disabled_client_side_validations (string): Comma-separated list of
       JSON schema validation keywords to disable JSON schema structural validation
       rules. The following keywords may be specified: multipleOf, maximum,
       exclusiveMaximum, minimum, exclusiveMinimum, maxLength, minLength, pattern,
@@ -64,7 +65,7 @@ class Configuration(object):
       and data received from the server, independent of any validation performed by
       the server side. If the input data does not satisfy the JSON schema validation
       rules specified in the OpenAPI document, an exception is raised.
-      If disable_client_side_validation is set, structural validation is
+      If disabled_client_side_validations is set, structural validation is
       disabled. This can be useful to troubleshoot data validation problem, such as
       when the OpenAPI document validation rules do not match the actual API data
       received by the server.
@@ -154,7 +155,7 @@ conf = petstore_api.Configuration(
                  api_key=None, api_key_prefix=None,
                  username=None, password=None,
                  discard_unknown_keys=False,
-                 disable_client_side_validation=None,
+                 disabled_client_side_validations="",
                  signing_info=None,
                  ):
         """Constructor
@@ -186,7 +187,7 @@ conf = petstore_api.Configuration(
         """Password for HTTP basic authentication
         """
         self.discard_unknown_keys = discard_unknown_keys
-        self.disable_client_side_validation = disable_client_side_validation
+        self.disabled_client_side_validations = disabled_client_side_validations
         if signing_info is not None:
             signing_info.host = host
         self.signing_info = signing_info
@@ -273,13 +274,13 @@ conf = petstore_api.Configuration(
 
     def __setattr__(self, name, value):
         object.__setattr__(self, name, value)
-        if name == 'disable_client_side_validation' and value is not None:
-            s = set(value.split(','))
+        if name == 'disabled_client_side_validations':
+            s = set(filter(None, value.split(',')))
             for v in s:
                 if v not in JSON_SCHEMA_VALIDATION_KEYWORDS:
-                    raise ValueError(
+                    raise ApiValueError(
                         "Invalid keyword: '{0}''".format(v))
-            self._disable_client_side_validation = s
+            self._disabled_client_side_validations = s
         if name == "signing_info" and value is not None:
             # Ensure the host paramater from signing info is the same as
             # Configuration.host.
diff --git a/samples/openapi3/client/petstore/python-experimental/petstore_api/model_utils.py b/samples/openapi3/client/petstore/python-experimental/petstore_api/model_utils.py
index 0a446c7b55a..724dd2bdec4 100644
--- a/samples/openapi3/client/petstore/python-experimental/petstore_api/model_utils.py
+++ b/samples/openapi3/client/petstore/python-experimental/petstore_api/model_utils.py
@@ -647,8 +647,8 @@ def is_json_validation_enabled(schema_keyword, configuration=None):
     """
 
     return (configuration is None or
-        not hasattr(configuration, '_disable_client_side_validation') or
-        schema_keyword not in configuration._disable_client_side_validation)
+        not hasattr(configuration, '_disabled_client_side_validations') or
+        schema_keyword not in configuration._disabled_client_side_validations)
 
 
 def check_validations(
diff --git a/samples/openapi3/client/petstore/python-experimental/tests/test_api_validation.py b/samples/openapi3/client/petstore/python-experimental/tests/test_api_validation.py
index fb22afb067d..a8a7276142b 100644
--- a/samples/openapi3/client/petstore/python-experimental/tests/test_api_validation.py
+++ b/samples/openapi3/client/petstore/python-experimental/tests/test_api_validation.py
@@ -35,11 +35,11 @@ class ApiClientTests(unittest.TestCase):
         config = petstore_api.Configuration()
         config.host = 'http://localhost/'
 
-        config.disable_client_side_validation = ("multipleOf,maximum,exclusiveMaximum,minimum,exclusiveMinimum,"
+        config.disabled_client_side_validations = ("multipleOf,maximum,exclusiveMaximum,minimum,exclusiveMinimum,"
             "maxLength,minLength,pattern,maxItems,minItems")
         with self.checkRaiseRegex(ValueError, "Invalid keyword: 'foo'"):
-            config.disable_client_side_validation = 'foo'
-        config.disable_client_side_validation = None
+            config.disabled_client_side_validations = 'foo'
+        config.disabled_client_side_validations = ""
 
 
     def checkRaiseRegex(self, expected_exception, expected_regex):
@@ -97,7 +97,7 @@ class ApiClientTests(unittest.TestCase):
 
         # Disable JSON schema validation. No error should be raised during deserialization.
         config = petstore_api.Configuration()
-        config.disable_client_side_validation = ("multipleOf")
+        config.disabled_client_side_validations = "multipleOf"
         api_client = petstore_api.ApiClient(configuration=config)
 
         data = {
@@ -115,7 +115,7 @@ class ApiClientTests(unittest.TestCase):
         # Disable JSON schema validation but for a different keyword.
         # An error should be raised during deserialization.
         config = petstore_api.Configuration()
-        config.disable_client_side_validation = ("maxItems")
+        config.disabled_client_side_validations = "maxItems"
         api_client = petstore_api.ApiClient(configuration=config)
 
         with self.checkRaiseRegex(petstore_api.exceptions.ApiValueError, "Invalid value for `integer`, value must be a multiple of `2`"):
diff --git a/samples/openapi3/client/petstore/python/petstore_api/configuration.py b/samples/openapi3/client/petstore/python/petstore_api/configuration.py
index 981c3c9e22e..850cb907b09 100644
--- a/samples/openapi3/client/petstore/python/petstore_api/configuration.py
+++ b/samples/openapi3/client/petstore/python/petstore_api/configuration.py
@@ -20,6 +20,7 @@ import urllib3
 
 import six
 from six.moves import http_client as httplib
+from petstore_api.exceptions import ApiValueError
 
 
 JSON_SCHEMA_VALIDATION_KEYWORDS = {
@@ -55,7 +56,7 @@ class Configuration(object):
       then all undeclared properties received by the server are injected into the
       additional properties map. In that case, there are undeclared properties, and
       nothing to discard.
-    :param disable_client_side_validation (string/None): Comma-separated list of
+    :param disabled_client_side_validations (string): Comma-separated list of
       JSON schema validation keywords to disable JSON schema structural validation
       rules. The following keywords may be specified: multipleOf, maximum,
       exclusiveMaximum, minimum, exclusiveMinimum, maxLength, minLength, pattern,
@@ -64,7 +65,7 @@ class Configuration(object):
       and data received from the server, independent of any validation performed by
       the server side. If the input data does not satisfy the JSON schema validation
       rules specified in the OpenAPI document, an exception is raised.
-      If disable_client_side_validation is set, structural validation is
+      If disabled_client_side_validations is set, structural validation is
       disabled. This can be useful to troubleshoot data validation problem, such as
       when the OpenAPI document validation rules do not match the actual API data
       received by the server.
@@ -154,7 +155,7 @@ conf = petstore_api.Configuration(
                  api_key=None, api_key_prefix=None,
                  username=None, password=None,
                  discard_unknown_keys=False,
-                 disable_client_side_validation=None,
+                 disabled_client_side_validations="",
                  signing_info=None,
                  ):
         """Constructor
@@ -186,7 +187,7 @@ conf = petstore_api.Configuration(
         """Password for HTTP basic authentication
         """
         self.discard_unknown_keys = discard_unknown_keys
-        self.disable_client_side_validation = disable_client_side_validation
+        self.disabled_client_side_validations = disabled_client_side_validations
         if signing_info is not None:
             signing_info.host = host
         self.signing_info = signing_info
@@ -273,13 +274,13 @@ conf = petstore_api.Configuration(
 
     def __setattr__(self, name, value):
         object.__setattr__(self, name, value)
-        if name == 'disable_client_side_validation' and value is not None:
-            s = set(value.split(','))
+        if name == 'disabled_client_side_validations':
+            s = set(filter(None, value.split(',')))
             for v in s:
                 if v not in JSON_SCHEMA_VALIDATION_KEYWORDS:
-                    raise ValueError(
+                    raise ApiValueError(
                         "Invalid keyword: '{0}''".format(v))
-            self._disable_client_side_validation = s
+            self._disabled_client_side_validations = s
         if name == "signing_info" and value is not None:
             # Ensure the host paramater from signing info is the same as
             # Configuration.host.
-- 
GitLab