forked from loafle/openapi-generator-original
[Python-experimental] Documentation enhancement for oneOf schema and minor err msg improvement (#5791)
* Add documentation to generated code * Improve error message * Improve documentation * Improve documentation * Improve documentation * Improve documentation * Improve documentation * Improve documentation * Run sample scripts * Address review comments * Address review comments * Fix problem in python error message
This commit is contained in:
parent
acae76b38f
commit
242c2e8544
@ -464,7 +464,11 @@ def get_required_type_classes(required_types_mixed):
|
|||||||
def change_keys_js_to_python(input_dict, model_class):
|
def change_keys_js_to_python(input_dict, model_class):
|
||||||
"""
|
"""
|
||||||
Converts from javascript_key keys in the input_dict to python_keys in
|
Converts from javascript_key keys in the input_dict to python_keys in
|
||||||
the output dict using the mapping in model_class
|
the output dict using the mapping in model_class.
|
||||||
|
If the input_dict contains a key which does not declared in the model_class,
|
||||||
|
the key is added to the output dict as is. The assumption is the model_class
|
||||||
|
may have undeclared properties (additionalProperties attribute in the OAS
|
||||||
|
document).
|
||||||
"""
|
"""
|
||||||
|
|
||||||
output_dict = {}
|
output_dict = {}
|
||||||
@ -936,19 +940,39 @@ def get_allof_instances(self, model_args, constant_args):
|
|||||||
|
|
||||||
# and use it to make the instance
|
# and use it to make the instance
|
||||||
kwargs.update(constant_args)
|
kwargs.update(constant_args)
|
||||||
|
try:
|
||||||
allof_instance = allof_class(**kwargs)
|
allof_instance = allof_class(**kwargs)
|
||||||
composed_instances.append(allof_instance)
|
composed_instances.append(allof_instance)
|
||||||
|
except Exception as ex:
|
||||||
|
raise ApiValueError(
|
||||||
|
"Invalid inputs given to generate an instance of '%s'. The "
|
||||||
|
"input data was invalid for the allOf schema '%s' in the composed "
|
||||||
|
"schema '%s'. Error=%s" % (
|
||||||
|
allof_class.__class__.__name__,
|
||||||
|
allof_class.__class__.__name__,
|
||||||
|
self.__class__.__name__,
|
||||||
|
str(ex)
|
||||||
|
)
|
||||||
|
)
|
||||||
return composed_instances
|
return composed_instances
|
||||||
|
|
||||||
|
|
||||||
def get_oneof_instance(self, model_args, constant_args):
|
def get_oneof_instance(self, model_args, constant_args):
|
||||||
"""
|
"""
|
||||||
|
Find the oneOf schema that matches the input data (e.g. payload).
|
||||||
|
If exactly one schema matches the input data, an instance of that schema
|
||||||
|
is returned.
|
||||||
|
If zero or more than one schema match the input data, an exception is raised.
|
||||||
|
In OAS 3.x, the payload MUST, by validation, match exactly one of the
|
||||||
|
schemas described by oneOf.
|
||||||
Args:
|
Args:
|
||||||
self: the class we are handling
|
self: the class we are handling
|
||||||
model_args (dict): var_name to var_value
|
model_args (dict): var_name to var_value
|
||||||
used to make instances
|
The input data, e.g. the payload that must match a oneOf schema
|
||||||
|
in the OpenAPI document.
|
||||||
constant_args (dict): var_name to var_value
|
constant_args (dict): var_name to var_value
|
||||||
used to make instances
|
args that every model requires, including configuration, server
|
||||||
|
and path to item.
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
oneof_instance (instance/None)
|
oneof_instance (instance/None)
|
||||||
@ -957,12 +981,17 @@ def get_oneof_instance(self, model_args, constant_args):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
oneof_instances = []
|
oneof_instances = []
|
||||||
|
# Iterate over each oneOf schema and determine if the input data
|
||||||
|
# matches the oneOf schemas.
|
||||||
for oneof_class in self._composed_schemas()['oneOf']:
|
for oneof_class in self._composed_schemas()['oneOf']:
|
||||||
# transform js keys to python keys in fixed_model_args
|
# transform js keys from input data to python keys in fixed_model_args
|
||||||
fixed_model_args = change_keys_js_to_python(
|
fixed_model_args = change_keys_js_to_python(
|
||||||
model_args, oneof_class)
|
model_args, oneof_class)
|
||||||
|
|
||||||
# extract a dict of only required keys from fixed_model_args
|
# Extract a dict with the properties that are declared in the oneOf schema.
|
||||||
|
# Undeclared properties (e.g. properties that are allowed because of the
|
||||||
|
# additionalProperties attribute in the OAS document) are not added to
|
||||||
|
# the dict.
|
||||||
kwargs = {}
|
kwargs = {}
|
||||||
var_names = set(oneof_class.openapi_types().keys())
|
var_names = set(oneof_class.openapi_types().keys())
|
||||||
for var_name in var_names:
|
for var_name in var_names:
|
||||||
@ -982,14 +1011,14 @@ def get_oneof_instance(self, model_args, constant_args):
|
|||||||
pass
|
pass
|
||||||
if len(oneof_instances) == 0:
|
if len(oneof_instances) == 0:
|
||||||
raise ApiValueError(
|
raise ApiValueError(
|
||||||
"Invalid inputs given to generate an instance of %s. Unable to "
|
"Invalid inputs given to generate an instance of %s. None "
|
||||||
"make any instances of the classes in oneOf definition." %
|
"of the oneOf schemas matched the input data." %
|
||||||
self.__class__.__name__
|
self.__class__.__name__
|
||||||
)
|
)
|
||||||
elif len(oneof_instances) > 1:
|
elif len(oneof_instances) > 1:
|
||||||
raise ApiValueError(
|
raise ApiValueError(
|
||||||
"Invalid inputs given to generate an instance of %s. Multiple "
|
"Invalid inputs given to generate an instance of %s. Multiple "
|
||||||
"oneOf instances were generated when a max of one is allowed." %
|
"oneOf schemas matched the inputs, but a max of one is allowed." %
|
||||||
self.__class__.__name__
|
self.__class__.__name__
|
||||||
)
|
)
|
||||||
return oneof_instances[0]
|
return oneof_instances[0]
|
||||||
@ -1035,8 +1064,8 @@ def get_anyof_instances(self, model_args, constant_args):
|
|||||||
pass
|
pass
|
||||||
if len(anyof_instances) == 0:
|
if len(anyof_instances) == 0:
|
||||||
raise ApiValueError(
|
raise ApiValueError(
|
||||||
"Invalid inputs given to generate an instance of %s. Unable to "
|
"Invalid inputs given to generate an instance of %s. None of the "
|
||||||
"make any instances of the classes in anyOf definition." %
|
"anyOf schemas matched the inputs." %
|
||||||
self.__class__.__name__
|
self.__class__.__name__
|
||||||
)
|
)
|
||||||
return anyof_instances
|
return anyof_instances
|
||||||
@ -1087,10 +1116,18 @@ def get_unused_args(self, composed_instances, model_args):
|
|||||||
|
|
||||||
def validate_get_composed_info(constant_args, model_args, self):
|
def validate_get_composed_info(constant_args, model_args, self):
|
||||||
"""
|
"""
|
||||||
For composed schemas/classes, validates the classes to make sure that
|
For composed schemas, generate schema instances for
|
||||||
they do not share any of the same parameters. If there is no collision
|
all schemas in the oneOf/anyOf/allOf definition. If additional
|
||||||
then composed model instances are created and returned tot the calling
|
properties are allowed, also assign those properties on
|
||||||
self model
|
all matched schemas that contain additionalProperties.
|
||||||
|
Openapi schemas are python classes.
|
||||||
|
|
||||||
|
Exceptions are raised if:
|
||||||
|
- no oneOf schema matches the model_args input data
|
||||||
|
- > 1 oneOf schema matches the model_args input data
|
||||||
|
- > 1 oneOf schema matches the model_args input data
|
||||||
|
- no anyOf schema matches the model_args input data
|
||||||
|
- any of the allOf schemas do not match the model_args input data
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
constant_args (dict): these are the args that every model requires
|
constant_args (dict): these are the args that every model requires
|
||||||
|
@ -720,7 +720,11 @@ def get_required_type_classes(required_types_mixed):
|
|||||||
def change_keys_js_to_python(input_dict, model_class):
|
def change_keys_js_to_python(input_dict, model_class):
|
||||||
"""
|
"""
|
||||||
Converts from javascript_key keys in the input_dict to python_keys in
|
Converts from javascript_key keys in the input_dict to python_keys in
|
||||||
the output dict using the mapping in model_class
|
the output dict using the mapping in model_class.
|
||||||
|
If the input_dict contains a key which does not declared in the model_class,
|
||||||
|
the key is added to the output dict as is. The assumption is the model_class
|
||||||
|
may have undeclared properties (additionalProperties attribute in the OAS
|
||||||
|
document).
|
||||||
"""
|
"""
|
||||||
|
|
||||||
output_dict = {}
|
output_dict = {}
|
||||||
@ -1192,19 +1196,39 @@ def get_allof_instances(self, model_args, constant_args):
|
|||||||
|
|
||||||
# and use it to make the instance
|
# and use it to make the instance
|
||||||
kwargs.update(constant_args)
|
kwargs.update(constant_args)
|
||||||
|
try:
|
||||||
allof_instance = allof_class(**kwargs)
|
allof_instance = allof_class(**kwargs)
|
||||||
composed_instances.append(allof_instance)
|
composed_instances.append(allof_instance)
|
||||||
|
except Exception as ex:
|
||||||
|
raise ApiValueError(
|
||||||
|
"Invalid inputs given to generate an instance of '%s'. The "
|
||||||
|
"input data was invalid for the allOf schema '%s' in the composed "
|
||||||
|
"schema '%s'. Error=%s" % (
|
||||||
|
allof_class.__class__.__name__,
|
||||||
|
allof_class.__class__.__name__,
|
||||||
|
self.__class__.__name__,
|
||||||
|
str(ex)
|
||||||
|
)
|
||||||
|
)
|
||||||
return composed_instances
|
return composed_instances
|
||||||
|
|
||||||
|
|
||||||
def get_oneof_instance(self, model_args, constant_args):
|
def get_oneof_instance(self, model_args, constant_args):
|
||||||
"""
|
"""
|
||||||
|
Find the oneOf schema that matches the input data (e.g. payload).
|
||||||
|
If exactly one schema matches the input data, an instance of that schema
|
||||||
|
is returned.
|
||||||
|
If zero or more than one schema match the input data, an exception is raised.
|
||||||
|
In OAS 3.x, the payload MUST, by validation, match exactly one of the
|
||||||
|
schemas described by oneOf.
|
||||||
Args:
|
Args:
|
||||||
self: the class we are handling
|
self: the class we are handling
|
||||||
model_args (dict): var_name to var_value
|
model_args (dict): var_name to var_value
|
||||||
used to make instances
|
The input data, e.g. the payload that must match a oneOf schema
|
||||||
|
in the OpenAPI document.
|
||||||
constant_args (dict): var_name to var_value
|
constant_args (dict): var_name to var_value
|
||||||
used to make instances
|
args that every model requires, including configuration, server
|
||||||
|
and path to item.
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
oneof_instance (instance/None)
|
oneof_instance (instance/None)
|
||||||
@ -1213,12 +1237,17 @@ def get_oneof_instance(self, model_args, constant_args):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
oneof_instances = []
|
oneof_instances = []
|
||||||
|
# Iterate over each oneOf schema and determine if the input data
|
||||||
|
# matches the oneOf schemas.
|
||||||
for oneof_class in self._composed_schemas()['oneOf']:
|
for oneof_class in self._composed_schemas()['oneOf']:
|
||||||
# transform js keys to python keys in fixed_model_args
|
# transform js keys from input data to python keys in fixed_model_args
|
||||||
fixed_model_args = change_keys_js_to_python(
|
fixed_model_args = change_keys_js_to_python(
|
||||||
model_args, oneof_class)
|
model_args, oneof_class)
|
||||||
|
|
||||||
# extract a dict of only required keys from fixed_model_args
|
# Extract a dict with the properties that are declared in the oneOf schema.
|
||||||
|
# Undeclared properties (e.g. properties that are allowed because of the
|
||||||
|
# additionalProperties attribute in the OAS document) are not added to
|
||||||
|
# the dict.
|
||||||
kwargs = {}
|
kwargs = {}
|
||||||
var_names = set(oneof_class.openapi_types().keys())
|
var_names = set(oneof_class.openapi_types().keys())
|
||||||
for var_name in var_names:
|
for var_name in var_names:
|
||||||
@ -1238,14 +1267,14 @@ def get_oneof_instance(self, model_args, constant_args):
|
|||||||
pass
|
pass
|
||||||
if len(oneof_instances) == 0:
|
if len(oneof_instances) == 0:
|
||||||
raise ApiValueError(
|
raise ApiValueError(
|
||||||
"Invalid inputs given to generate an instance of %s. Unable to "
|
"Invalid inputs given to generate an instance of %s. None "
|
||||||
"make any instances of the classes in oneOf definition." %
|
"of the oneOf schemas matched the input data." %
|
||||||
self.__class__.__name__
|
self.__class__.__name__
|
||||||
)
|
)
|
||||||
elif len(oneof_instances) > 1:
|
elif len(oneof_instances) > 1:
|
||||||
raise ApiValueError(
|
raise ApiValueError(
|
||||||
"Invalid inputs given to generate an instance of %s. Multiple "
|
"Invalid inputs given to generate an instance of %s. Multiple "
|
||||||
"oneOf instances were generated when a max of one is allowed." %
|
"oneOf schemas matched the inputs, but a max of one is allowed." %
|
||||||
self.__class__.__name__
|
self.__class__.__name__
|
||||||
)
|
)
|
||||||
return oneof_instances[0]
|
return oneof_instances[0]
|
||||||
@ -1291,8 +1320,8 @@ def get_anyof_instances(self, model_args, constant_args):
|
|||||||
pass
|
pass
|
||||||
if len(anyof_instances) == 0:
|
if len(anyof_instances) == 0:
|
||||||
raise ApiValueError(
|
raise ApiValueError(
|
||||||
"Invalid inputs given to generate an instance of %s. Unable to "
|
"Invalid inputs given to generate an instance of %s. None of the "
|
||||||
"make any instances of the classes in anyOf definition." %
|
"anyOf schemas matched the inputs." %
|
||||||
self.__class__.__name__
|
self.__class__.__name__
|
||||||
)
|
)
|
||||||
return anyof_instances
|
return anyof_instances
|
||||||
@ -1343,10 +1372,18 @@ def get_unused_args(self, composed_instances, model_args):
|
|||||||
|
|
||||||
def validate_get_composed_info(constant_args, model_args, self):
|
def validate_get_composed_info(constant_args, model_args, self):
|
||||||
"""
|
"""
|
||||||
For composed schemas/classes, validates the classes to make sure that
|
For composed schemas, generate schema instances for
|
||||||
they do not share any of the same parameters. If there is no collision
|
all schemas in the oneOf/anyOf/allOf definition. If additional
|
||||||
then composed model instances are created and returned tot the calling
|
properties are allowed, also assign those properties on
|
||||||
self model
|
all matched schemas that contain additionalProperties.
|
||||||
|
Openapi schemas are python classes.
|
||||||
|
|
||||||
|
Exceptions are raised if:
|
||||||
|
- no oneOf schema matches the model_args input data
|
||||||
|
- > 1 oneOf schema matches the model_args input data
|
||||||
|
- > 1 oneOf schema matches the model_args input data
|
||||||
|
- no anyOf schema matches the model_args input data
|
||||||
|
- any of the allOf schemas do not match the model_args input data
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
constant_args (dict): these are the args that every model requires
|
constant_args (dict): these are the args that every model requires
|
||||||
|
@ -720,7 +720,11 @@ def get_required_type_classes(required_types_mixed):
|
|||||||
def change_keys_js_to_python(input_dict, model_class):
|
def change_keys_js_to_python(input_dict, model_class):
|
||||||
"""
|
"""
|
||||||
Converts from javascript_key keys in the input_dict to python_keys in
|
Converts from javascript_key keys in the input_dict to python_keys in
|
||||||
the output dict using the mapping in model_class
|
the output dict using the mapping in model_class.
|
||||||
|
If the input_dict contains a key which does not declared in the model_class,
|
||||||
|
the key is added to the output dict as is. The assumption is the model_class
|
||||||
|
may have undeclared properties (additionalProperties attribute in the OAS
|
||||||
|
document).
|
||||||
"""
|
"""
|
||||||
|
|
||||||
output_dict = {}
|
output_dict = {}
|
||||||
@ -1192,19 +1196,39 @@ def get_allof_instances(self, model_args, constant_args):
|
|||||||
|
|
||||||
# and use it to make the instance
|
# and use it to make the instance
|
||||||
kwargs.update(constant_args)
|
kwargs.update(constant_args)
|
||||||
|
try:
|
||||||
allof_instance = allof_class(**kwargs)
|
allof_instance = allof_class(**kwargs)
|
||||||
composed_instances.append(allof_instance)
|
composed_instances.append(allof_instance)
|
||||||
|
except Exception as ex:
|
||||||
|
raise ApiValueError(
|
||||||
|
"Invalid inputs given to generate an instance of '%s'. The "
|
||||||
|
"input data was invalid for the allOf schema '%s' in the composed "
|
||||||
|
"schema '%s'. Error=%s" % (
|
||||||
|
allof_class.__class__.__name__,
|
||||||
|
allof_class.__class__.__name__,
|
||||||
|
self.__class__.__name__,
|
||||||
|
str(ex)
|
||||||
|
)
|
||||||
|
)
|
||||||
return composed_instances
|
return composed_instances
|
||||||
|
|
||||||
|
|
||||||
def get_oneof_instance(self, model_args, constant_args):
|
def get_oneof_instance(self, model_args, constant_args):
|
||||||
"""
|
"""
|
||||||
|
Find the oneOf schema that matches the input data (e.g. payload).
|
||||||
|
If exactly one schema matches the input data, an instance of that schema
|
||||||
|
is returned.
|
||||||
|
If zero or more than one schema match the input data, an exception is raised.
|
||||||
|
In OAS 3.x, the payload MUST, by validation, match exactly one of the
|
||||||
|
schemas described by oneOf.
|
||||||
Args:
|
Args:
|
||||||
self: the class we are handling
|
self: the class we are handling
|
||||||
model_args (dict): var_name to var_value
|
model_args (dict): var_name to var_value
|
||||||
used to make instances
|
The input data, e.g. the payload that must match a oneOf schema
|
||||||
|
in the OpenAPI document.
|
||||||
constant_args (dict): var_name to var_value
|
constant_args (dict): var_name to var_value
|
||||||
used to make instances
|
args that every model requires, including configuration, server
|
||||||
|
and path to item.
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
oneof_instance (instance/None)
|
oneof_instance (instance/None)
|
||||||
@ -1213,12 +1237,17 @@ def get_oneof_instance(self, model_args, constant_args):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
oneof_instances = []
|
oneof_instances = []
|
||||||
|
# Iterate over each oneOf schema and determine if the input data
|
||||||
|
# matches the oneOf schemas.
|
||||||
for oneof_class in self._composed_schemas()['oneOf']:
|
for oneof_class in self._composed_schemas()['oneOf']:
|
||||||
# transform js keys to python keys in fixed_model_args
|
# transform js keys from input data to python keys in fixed_model_args
|
||||||
fixed_model_args = change_keys_js_to_python(
|
fixed_model_args = change_keys_js_to_python(
|
||||||
model_args, oneof_class)
|
model_args, oneof_class)
|
||||||
|
|
||||||
# extract a dict of only required keys from fixed_model_args
|
# Extract a dict with the properties that are declared in the oneOf schema.
|
||||||
|
# Undeclared properties (e.g. properties that are allowed because of the
|
||||||
|
# additionalProperties attribute in the OAS document) are not added to
|
||||||
|
# the dict.
|
||||||
kwargs = {}
|
kwargs = {}
|
||||||
var_names = set(oneof_class.openapi_types().keys())
|
var_names = set(oneof_class.openapi_types().keys())
|
||||||
for var_name in var_names:
|
for var_name in var_names:
|
||||||
@ -1238,14 +1267,14 @@ def get_oneof_instance(self, model_args, constant_args):
|
|||||||
pass
|
pass
|
||||||
if len(oneof_instances) == 0:
|
if len(oneof_instances) == 0:
|
||||||
raise ApiValueError(
|
raise ApiValueError(
|
||||||
"Invalid inputs given to generate an instance of %s. Unable to "
|
"Invalid inputs given to generate an instance of %s. None "
|
||||||
"make any instances of the classes in oneOf definition." %
|
"of the oneOf schemas matched the input data." %
|
||||||
self.__class__.__name__
|
self.__class__.__name__
|
||||||
)
|
)
|
||||||
elif len(oneof_instances) > 1:
|
elif len(oneof_instances) > 1:
|
||||||
raise ApiValueError(
|
raise ApiValueError(
|
||||||
"Invalid inputs given to generate an instance of %s. Multiple "
|
"Invalid inputs given to generate an instance of %s. Multiple "
|
||||||
"oneOf instances were generated when a max of one is allowed." %
|
"oneOf schemas matched the inputs, but a max of one is allowed." %
|
||||||
self.__class__.__name__
|
self.__class__.__name__
|
||||||
)
|
)
|
||||||
return oneof_instances[0]
|
return oneof_instances[0]
|
||||||
@ -1291,8 +1320,8 @@ def get_anyof_instances(self, model_args, constant_args):
|
|||||||
pass
|
pass
|
||||||
if len(anyof_instances) == 0:
|
if len(anyof_instances) == 0:
|
||||||
raise ApiValueError(
|
raise ApiValueError(
|
||||||
"Invalid inputs given to generate an instance of %s. Unable to "
|
"Invalid inputs given to generate an instance of %s. None of the "
|
||||||
"make any instances of the classes in anyOf definition." %
|
"anyOf schemas matched the inputs." %
|
||||||
self.__class__.__name__
|
self.__class__.__name__
|
||||||
)
|
)
|
||||||
return anyof_instances
|
return anyof_instances
|
||||||
@ -1343,10 +1372,18 @@ def get_unused_args(self, composed_instances, model_args):
|
|||||||
|
|
||||||
def validate_get_composed_info(constant_args, model_args, self):
|
def validate_get_composed_info(constant_args, model_args, self):
|
||||||
"""
|
"""
|
||||||
For composed schemas/classes, validates the classes to make sure that
|
For composed schemas, generate schema instances for
|
||||||
they do not share any of the same parameters. If there is no collision
|
all schemas in the oneOf/anyOf/allOf definition. If additional
|
||||||
then composed model instances are created and returned tot the calling
|
properties are allowed, also assign those properties on
|
||||||
self model
|
all matched schemas that contain additionalProperties.
|
||||||
|
Openapi schemas are python classes.
|
||||||
|
|
||||||
|
Exceptions are raised if:
|
||||||
|
- no oneOf schema matches the model_args input data
|
||||||
|
- > 1 oneOf schema matches the model_args input data
|
||||||
|
- > 1 oneOf schema matches the model_args input data
|
||||||
|
- no anyOf schema matches the model_args input data
|
||||||
|
- any of the allOf schemas do not match the model_args input data
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
constant_args (dict): these are the args that every model requires
|
constant_args (dict): these are the args that every model requires
|
||||||
|
Loading…
x
Reference in New Issue
Block a user