Update python-fastapi generator to support Pydantic v2 (#17369)

* update python fastapi to support pydantic v2

* add new files

* update samples

* update samples

* update starlette

* update typing extensions

* update email validator
This commit is contained in:
William Cheng
2024-02-15 14:15:51 +08:00
committed by GitHub
parent 8cd34ac963
commit 887b860007
19 changed files with 1525 additions and 214 deletions

View File

@@ -140,6 +140,18 @@ public class PythonFastAPIServerCodegen extends AbstractPythonCodegen {
cliOptions.add(new CliOption(CodegenConstants.FASTAPI_IMPLEMENTATION_PACKAGE, "python package name for the implementation code (convention: snake_case).")
.defaultValue(implPackage));
// option to change how we process + set the data in the 'additionalProperties' keyword.
CliOption disallowAdditionalPropertiesIfNotPresentOpt = CliOption.newBoolean(
CodegenConstants.DISALLOW_ADDITIONAL_PROPERTIES_IF_NOT_PRESENT,
CodegenConstants.DISALLOW_ADDITIONAL_PROPERTIES_IF_NOT_PRESENT_DESC).defaultValue(Boolean.TRUE.toString());
Map<String, String> disallowAdditionalPropertiesIfNotPresentOpts = new HashMap<>();
disallowAdditionalPropertiesIfNotPresentOpts.put("false",
"The 'additionalProperties' implementation is compliant with the OAS and JSON schema specifications.");
disallowAdditionalPropertiesIfNotPresentOpts.put("true",
"Keep the old (incorrect) behaviour that 'additionalProperties' is set to false by default.");
disallowAdditionalPropertiesIfNotPresentOpt.setEnum(disallowAdditionalPropertiesIfNotPresentOpts);
cliOptions.add(disallowAdditionalPropertiesIfNotPresentOpt);
this.setDisallowAdditionalPropertiesIfNotPresent(true);
}
@Override

View File

@@ -1,76 +1,14 @@
# coding: utf-8
from __future__ import annotations
from datetime import date, datetime # noqa: F401
import re # noqa: F401
from typing import Any, Dict, List, Optional # noqa: F401
from pydantic import AnyUrl, BaseModel, EmailStr, Field, validator # noqa: F401
{{#models}}
{{#model}}
{{#pyImports}}
{{import}}
{{/pyImports}}
{{/model}}
{{/models}}
{{>partial_header}}
{{#models}}
{{#model}}
class {{classname}}(BaseModel):
"""NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
Do not edit the class manually.
{{classname}} - a model defined in OpenAPI
{{#vars}}
{{name}}: The {{name}} of this {{classname}}{{^required}} [Optional]{{/required}}.
{{/vars}}
"""
{{#vars}}
{{name}}: {{#required}}{{>model_field_type}}{{/required}}{{^required}}Optional[{{>model_field_type}}]{{/required}} = Field(alias="{{baseName}}"{{^required}}, default=None{{/required}})
{{/vars}}
{{#vars}}
{{#maximum}}
@validator("{{name}}")
def {{name}}_max(cls, value):
assert value <= {{maximum}}
return value
{{/maximum}}
{{#minimum}}
@validator("{{name}}")
def {{name}}_min(cls, value):
assert value >= {{minimum}}
return value
{{/minimum}}
{{#minLength}}
@validator("{{name}}")
def {{name}}_min_length(cls, value):
assert len(value) >= {{minLength}}
return value
{{/minLength}}
{{#maxLength}}
@validator("{{name}}")
def {{name}}_max_length(cls, value):
assert len(value) <= {{maxLength}}
return value
{{/maxLength}}
{{#pattern}}
@validator("{{name}}")
def {{name}}_pattern(cls, value):
assert value is not None and re.match(r"{{pattern}}", value)
return value
{{/pattern}}
{{/vars}}
{{#isEnum}}
{{>model_enum}}
{{/isEnum}}
{{^isEnum}}
{{#oneOf}}{{#-first}}{{>model_oneof}}{{/-first}}{{/oneOf}}{{^oneOf}}{{#anyOf}}{{#-first}}{{>model_anyof}}{{/-first}}{{/anyOf}}{{^anyOf}}{{>model_generic}}{{/anyOf}}{{/oneOf}}
{{/isEnum}}
{{/model}}
{{/models}}
{{classname}}.update_forward_refs()

View File

@@ -0,0 +1,191 @@
from __future__ import annotations
from inspect import getfullargspec
import json
import pprint
import re # noqa: F401
{{#vendorExtensions.x-py-datetime-imports}}{{#-first}}from datetime import{{/-first}} {{{.}}}{{^-last}},{{/-last}}{{/vendorExtensions.x-py-datetime-imports}}
{{#vendorExtensions.x-py-typing-imports}}{{#-first}}from typing import{{/-first}} {{{.}}}{{^-last}},{{/-last}}{{/vendorExtensions.x-py-typing-imports}}
{{#vendorExtensions.x-py-pydantic-imports}}{{#-first}}from pydantic import{{/-first}} {{{.}}}{{^-last}},{{/-last}}{{/vendorExtensions.x-py-pydantic-imports}}
{{#vendorExtensions.x-py-other-imports}}
{{{.}}}
{{/vendorExtensions.x-py-other-imports}}
{{#vendorExtensions.x-py-model-imports}}
{{{.}}}
{{/vendorExtensions.x-py-model-imports}}
from typing import Union, Any, List, TYPE_CHECKING, Optional, Dict
from typing_extensions import Literal
from pydantic import StrictStr, Field
try:
from typing import Self
except ImportError:
from typing_extensions import Self
{{#lambda.uppercase}}{{{classname}}}{{/lambda.uppercase}}_ANY_OF_SCHEMAS = [{{#anyOf}}"{{.}}"{{^-last}}, {{/-last}}{{/anyOf}}]
class {{classname}}({{#parent}}{{{.}}}{{/parent}}{{^parent}}BaseModel{{/parent}}):
"""
{{{description}}}{{^description}}{{{classname}}}{{/description}}
"""
{{#composedSchemas.anyOf}}
# data type: {{{dataType}}}
{{vendorExtensions.x-py-name}}: {{{vendorExtensions.x-py-typing}}}
{{/composedSchemas.anyOf}}
if TYPE_CHECKING:
actual_instance: Optional[Union[{{#anyOf}}{{{.}}}{{^-last}}, {{/-last}}{{/anyOf}}]] = None
else:
actual_instance: Any = None
any_of_schemas: List[str] = Literal[{{#lambda.uppercase}}{{{classname}}}{{/lambda.uppercase}}_ANY_OF_SCHEMAS]
model_config = {
"validate_assignment": True,
"protected_namespaces": (),
}
{{#discriminator}}
discriminator_value_class_map: Dict[str, str] = {
{{#children}}
'{{^vendorExtensions.x-discriminator-value}}{{name}}{{/vendorExtensions.x-discriminator-value}}{{#vendorExtensions.x-discriminator-value}}{{{vendorExtensions.x-discriminator-value}}}{{/vendorExtensions.x-discriminator-value}}': '{{{classname}}}'{{^-last}},{{/-last}}
{{/children}}
}
{{/discriminator}}
def __init__(self, *args, **kwargs) -> None:
if args:
if len(args) > 1:
raise ValueError("If a position argument is used, only 1 is allowed to set `actual_instance`")
if kwargs:
raise ValueError("If a position argument is used, keyword arguments cannot be used.")
super().__init__(actual_instance=args[0])
else:
super().__init__(**kwargs)
@field_validator('actual_instance')
def actual_instance_must_validate_anyof(cls, v):
{{#isNullable}}
if v is None:
return v
{{/isNullable}}
instance = {{{classname}}}.model_construct()
error_messages = []
{{#composedSchemas.anyOf}}
# validate data type: {{{dataType}}}
{{#isContainer}}
try:
instance.{{vendorExtensions.x-py-name}} = v
return v
except (ValidationError, ValueError) as e:
error_messages.append(str(e))
{{/isContainer}}
{{^isContainer}}
{{#isPrimitiveType}}
try:
instance.{{vendorExtensions.x-py-name}} = v
return v
except (ValidationError, ValueError) as e:
error_messages.append(str(e))
{{/isPrimitiveType}}
{{^isPrimitiveType}}
if not isinstance(v, {{{dataType}}}):
error_messages.append(f"Error! Input type `{type(v)}` is not `{{{dataType}}}`")
else:
return v
{{/isPrimitiveType}}
{{/isContainer}}
{{/composedSchemas.anyOf}}
if error_messages:
# no match
raise ValueError("No match found when setting the actual_instance in {{{classname}}} with anyOf schemas: {{#anyOf}}{{{.}}}{{^-last}}, {{/-last}}{{/anyOf}}. Details: " + ", ".join(error_messages))
else:
return v
@classmethod
def from_dict(cls, obj: dict) -> Self:
return cls.from_json(json.dumps(obj))
@classmethod
def from_json(cls, json_str: str) -> Self:
"""Returns the object represented by the json string"""
instance = cls.model_construct()
{{#isNullable}}
if json_str is None:
return instance
{{/isNullable}}
error_messages = []
{{#composedSchemas.anyOf}}
{{#isContainer}}
# deserialize data into {{{dataType}}}
try:
# validation
instance.{{vendorExtensions.x-py-name}} = json.loads(json_str)
# assign value to actual_instance
instance.actual_instance = instance.{{vendorExtensions.x-py-name}}
return instance
except (ValidationError, ValueError) as e:
error_messages.append(str(e))
{{/isContainer}}
{{^isContainer}}
{{#isPrimitiveType}}
# deserialize data into {{{dataType}}}
try:
# validation
instance.{{vendorExtensions.x-py-name}} = json.loads(json_str)
# assign value to actual_instance
instance.actual_instance = instance.{{vendorExtensions.x-py-name}}
return instance
except (ValidationError, ValueError) as e:
error_messages.append(str(e))
{{/isPrimitiveType}}
{{^isPrimitiveType}}
# {{vendorExtensions.x-py-name}}: {{{vendorExtensions.x-py-typing}}}
try:
instance.actual_instance = {{{dataType}}}.from_json(json_str)
return instance
except (ValidationError, ValueError) as e:
error_messages.append(str(e))
{{/isPrimitiveType}}
{{/isContainer}}
{{/composedSchemas.anyOf}}
if error_messages:
# no match
raise ValueError("No match found when deserializing the JSON string into {{{classname}}} with anyOf schemas: {{#anyOf}}{{{.}}}{{^-last}}, {{/-last}}{{/anyOf}}. Details: " + ", ".join(error_messages))
else:
return instance
def to_json(self) -> str:
"""Returns the JSON representation of the actual instance"""
if self.actual_instance is None:
return "null"
to_json = getattr(self.actual_instance, "to_json", None)
if callable(to_json):
return self.actual_instance.to_json()
else:
return json.dumps(self.actual_instance)
def to_dict(self) -> Dict:
"""Returns the dict representation of the actual instance"""
if self.actual_instance is None:
return "null"
to_json = getattr(self.actual_instance, "to_json", None)
if callable(to_json):
return self.actual_instance.to_dict()
else:
return json.dumps(self.actual_instance)
def to_str(self) -> str:
"""Returns the string representation of the actual instance"""
return pprint.pformat(self.model_dump())
{{#vendorExtensions.x-py-postponed-model-imports.size}}
{{#vendorExtensions.x-py-postponed-model-imports}}
{{{.}}}
{{/vendorExtensions.x-py-postponed-model-imports}}
# TODO: Rewrite to not use raise_errors
{{classname}}.model_rebuild(raise_errors=False)
{{/vendorExtensions.x-py-postponed-model-imports.size}}

View File

@@ -0,0 +1,34 @@
{{#models}}{{#model}}# {{classname}}
{{#description}}{{&description}}
{{/description}}
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
{{#vars}}**{{name}}** | {{#isPrimitiveType}}**{{dataType}}**{{/isPrimitiveType}}{{^isPrimitiveType}}[**{{dataType}}**]({{complexType}}.md){{/isPrimitiveType}} | {{description}} | {{^required}}[optional] {{/required}}{{#isReadOnly}}[readonly] {{/isReadOnly}}{{#defaultValue}}[default to {{{.}}}]{{/defaultValue}}
{{/vars}}
{{^isEnum}}
## Example
```python
from {{modelPackage}}.{{#lambda.snakecase}}{{classname}}{{/lambda.snakecase}} import {{classname}}
# TODO update the JSON string below
json = "{}"
# create an instance of {{classname}} from a JSON string
{{#lambda.snakecase}}{{classname}}{{/lambda.snakecase}}_instance = {{classname}}.from_json(json)
# print the JSON string representation of the object
print {{classname}}.to_json()
# convert the object into a dict
{{#lambda.snakecase}}{{classname}}{{/lambda.snakecase}}_dict = {{#lambda.snakecase}}{{classname}}{{/lambda.snakecase}}_instance.to_dict()
# create an instance of {{classname}} from a dict
{{#lambda.snakecase}}{{classname}}{{/lambda.snakecase}}_form_dict = {{#lambda.snakecase}}{{classname}}{{/lambda.snakecase}}.from_dict({{#lambda.snakecase}}{{classname}}{{/lambda.snakecase}}_dict)
```
{{/isEnum}}
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
{{/model}}{{/models}}

View File

@@ -0,0 +1,41 @@
from __future__ import annotations
import json
import pprint
import re # noqa: F401
from enum import Enum
{{#vendorExtensions.x-py-datetime-imports}}{{#-first}}from datetime import{{/-first}} {{{.}}}{{^-last}},{{/-last}}{{/vendorExtensions.x-py-datetime-imports}}
{{#vendorExtensions.x-py-typing-imports}}{{#-first}}from typing import{{/-first}} {{{.}}}{{^-last}},{{/-last}}{{/vendorExtensions.x-py-typing-imports}}
{{#vendorExtensions.x-py-pydantic-imports}}{{#-first}}from pydantic import{{/-first}} {{{.}}}{{^-last}},{{/-last}}{{/vendorExtensions.x-py-pydantic-imports}}
try:
from typing import Self
except ImportError:
from typing_extensions import Self
class {{classname}}({{vendorExtensions.x-py-enum-type}}, Enum):
"""
{{{description}}}{{^description}}{{{classname}}}{{/description}}
"""
"""
allowed enum values
"""
{{#allowableValues}}
{{#enumVars}}
{{{name}}} = {{{value}}}
{{/enumVars}}
@classmethod
def from_json(cls, json_str: str) -> Self:
"""Create an instance of {{classname}} from a JSON string"""
return cls(json.loads(json_str))
{{#defaultValue}}
#
@classmethod
def _missing_value_(cls, value):
if value is no_arg:
return cls.{{{.}}}
{{/defaultValue}}
{{/allowableValues}}

View File

@@ -1 +0,0 @@
{{#isEmail}}EmailStr{{/isEmail}}{{#isUri}}AnyUrl{{/isUri}}{{#isFreeFormObject}}Dict[str, Any]{{/isFreeFormObject}}{{^isEmail}}{{^isUri}}{{^isFreeFormObject}}{{dataType}}{{/isFreeFormObject}}{{/isUri}}{{/isEmail}}

View File

@@ -0,0 +1,384 @@
from __future__ import annotations
import pprint
import re # noqa: F401
import json
{{#vendorExtensions.x-py-datetime-imports}}{{#-first}}from datetime import{{/-first}} {{{.}}}{{^-last}},{{/-last}}{{/vendorExtensions.x-py-datetime-imports}}
{{#vendorExtensions.x-py-typing-imports}}{{#-first}}from typing import{{/-first}} {{{.}}}{{^-last}},{{/-last}}{{/vendorExtensions.x-py-typing-imports}}
{{#vendorExtensions.x-py-pydantic-imports}}{{#-first}}from pydantic import{{/-first}} {{{.}}}{{^-last}},{{/-last}}{{/vendorExtensions.x-py-pydantic-imports}}
{{#vendorExtensions.x-py-other-imports}}
{{{.}}}
{{/vendorExtensions.x-py-other-imports}}
{{#vendorExtensions.x-py-model-imports}}
{{{.}}}
{{/vendorExtensions.x-py-model-imports}}
try:
from typing import Self
except ImportError:
from typing_extensions import Self
class {{classname}}({{#parent}}{{{.}}}{{/parent}}{{^parent}}BaseModel{{/parent}}):
"""
{{#description}}{{{description}}}{{/description}}{{^description}}{{{classname}}}{{/description}}
""" # noqa: E501
{{#vars}}
{{name}}: {{{vendorExtensions.x-py-typing}}}
{{/vars}}
{{#isAdditionalPropertiesTrue}}
additional_properties: Dict[str, Any] = {}
{{/isAdditionalPropertiesTrue}}
__properties: ClassVar[List[str]] = [{{#allVars}}"{{baseName}}"{{^-last}}, {{/-last}}{{/allVars}}]
{{#vars}}
{{#vendorExtensions.x-regex}}
@field_validator('{{{name}}}')
def {{{name}}}_validate_regular_expression(cls, value):
"""Validates the regular expression"""
{{^required}}
if value is None:
return value
{{/required}}
{{#required}}
{{#isNullable}}
if value is None:
return value
{{/isNullable}}
{{/required}}
if not re.match(r"{{{.}}}", value{{#vendorExtensions.x-modifiers}} ,re.{{{.}}}{{/vendorExtensions.x-modifiers}}):
raise ValueError(r"must validate the regular expression {{{vendorExtensions.x-pattern}}}")
return value
{{/vendorExtensions.x-regex}}
{{#isEnum}}
@field_validator('{{{name}}}')
def {{{name}}}_validate_enum(cls, value):
"""Validates the enum"""
{{^required}}
if value is None:
return value
{{/required}}
{{#required}}
{{#isNullable}}
if value is None:
return value
{{/isNullable}}
{{/required}}
{{#isArray}}
for i in value:
if i not in ({{#allowableValues}}{{#enumVars}}{{{value}}}{{^-last}}, {{/-last}}{{/enumVars}}{{/allowableValues}}):
raise ValueError("each list item must be one of ({{#allowableValues}}{{#enumVars}}{{{value}}}{{^-last}}, {{/-last}}{{/enumVars}}{{/allowableValues}})")
{{/isArray}}
{{^isArray}}
if value not in ({{#allowableValues}}{{#enumVars}}{{{value}}}{{^-last}}, {{/-last}}{{/enumVars}}{{/allowableValues}}):
raise ValueError("must be one of enum values ({{#allowableValues}}{{#enumVars}}{{{value}}}{{^-last}}, {{/-last}}{{/enumVars}}{{/allowableValues}})")
{{/isArray}}
return value
{{/isEnum}}
{{/vars}}
model_config = {
"populate_by_name": True,
"validate_assignment": True,
"protected_namespaces": (),
}
{{#hasChildren}}
{{#discriminator}}
# JSON field name that stores the object type
__discriminator_property_name: ClassVar[List[str]] = '{{discriminator.propertyBaseName}}'
# discriminator mappings
__discriminator_value_class_map: ClassVar[Dict[str, str]] = {
{{#mappedModels}}'{{{mappingName}}}': '{{{modelName}}}'{{^-last}},{{/-last}}{{/mappedModels}}
}
@classmethod
def get_discriminator_value(cls, obj: Dict) -> str:
"""Returns the discriminator value (object type) of the data"""
discriminator_value = obj[cls.__discriminator_property_name]
if discriminator_value:
return cls.__discriminator_value_class_map.get(discriminator_value)
else:
return None
{{/discriminator}}
{{/hasChildren}}
def to_str(self) -> str:
"""Returns the string representation of the model using alias"""
return pprint.pformat(self.model_dump(by_alias=True))
def to_json(self) -> str:
"""Returns the JSON representation of the model using alias"""
# TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
return json.dumps(self.to_dict())
@classmethod
def from_json(cls, json_str: str) -> {{^hasChildren}}Self{{/hasChildren}}{{#hasChildren}}{{#discriminator}}Union[{{#children}}Self{{^-last}}, {{/-last}}{{/children}}]{{/discriminator}}{{^discriminator}}Self{{/discriminator}}{{/hasChildren}}:
"""Create an instance of {{{classname}}} from a JSON string"""
return cls.from_dict(json.loads(json_str))
def to_dict(self) -> Dict[str, Any]:
"""Return the dictionary representation of the model using alias.
This has the following differences from calling pydantic's
`self.model_dump(by_alias=True)`:
* `None` is only added to the output dict for nullable fields that
were set at model initialization. Other fields with value `None`
are ignored.
{{#vendorExtensions.x-py-readonly}}
* OpenAPI `readOnly` fields are excluded.
{{/vendorExtensions.x-py-readonly}}
{{#isAdditionalPropertiesTrue}}
* Fields in `self.additional_properties` are added to the output dict.
{{/isAdditionalPropertiesTrue}}
"""
_dict = self.model_dump(
by_alias=True,
exclude={
{{#vendorExtensions.x-py-readonly}}
"{{{.}}}",
{{/vendorExtensions.x-py-readonly}}
{{#isAdditionalPropertiesTrue}}
"additional_properties",
{{/isAdditionalPropertiesTrue}}
},
exclude_none=True,
)
{{#allVars}}
{{#isContainer}}
{{#isArray}}
{{#items.isArray}}
{{^items.items.isPrimitiveType}}
# override the default output from pydantic by calling `to_dict()` of each item in {{{name}}} (list of list)
_items = []
if self.{{{name}}}:
for _item in self.{{{name}}}:
if _item:
_items.append(
[_inner_item.to_dict() for _inner_item in _item if _inner_item is not None]
)
_dict['{{{baseName}}}'] = _items
{{/items.items.isPrimitiveType}}
{{/items.isArray}}
{{^items.isArray}}
{{^items.isPrimitiveType}}
{{^items.isEnumOrRef}}
# override the default output from pydantic by calling `to_dict()` of each item in {{{name}}} (list)
_items = []
if self.{{{name}}}:
for _item in self.{{{name}}}:
if _item:
_items.append(_item.to_dict())
_dict['{{{baseName}}}'] = _items
{{/items.isEnumOrRef}}
{{/items.isPrimitiveType}}
{{/items.isArray}}
{{/isArray}}
{{#isMap}}
{{#items.isArray}}
{{^items.items.isPrimitiveType}}
# override the default output from pydantic by calling `to_dict()` of each value in {{{name}}} (dict of array)
_field_dict_of_array = {}
if self.{{{name}}}:
for _key in self.{{{name}}}:
if self.{{{name}}}[_key] is not None:
_field_dict_of_array[_key] = [
_item.to_dict() for _item in self.{{{name}}}[_key]
]
_dict['{{{baseName}}}'] = _field_dict_of_array
{{/items.items.isPrimitiveType}}
{{/items.isArray}}
{{^items.isArray}}
{{^items.isPrimitiveType}}
{{^items.isEnumOrRef}}
# override the default output from pydantic by calling `to_dict()` of each value in {{{name}}} (dict)
_field_dict = {}
if self.{{{name}}}:
for _key in self.{{{name}}}:
if self.{{{name}}}[_key]:
_field_dict[_key] = self.{{{name}}}[_key].to_dict()
_dict['{{{baseName}}}'] = _field_dict
{{/items.isEnumOrRef}}
{{/items.isPrimitiveType}}
{{/items.isArray}}
{{/isMap}}
{{/isContainer}}
{{^isContainer}}
{{^isPrimitiveType}}
{{^isEnumOrRef}}
# override the default output from pydantic by calling `to_dict()` of {{{name}}}
if self.{{{name}}}:
_dict['{{{baseName}}}'] = self.{{{name}}}.to_dict()
{{/isEnumOrRef}}
{{/isPrimitiveType}}
{{/isContainer}}
{{/allVars}}
{{#isAdditionalPropertiesTrue}}
# puts key-value pairs in additional_properties in the top level
if self.additional_properties is not None:
for _key, _value in self.additional_properties.items():
_dict[_key] = _value
{{/isAdditionalPropertiesTrue}}
{{#allVars}}
{{#isNullable}}
# set to None if {{{name}}} (nullable) is None
# and model_fields_set contains the field
if self.{{name}} is None and "{{{name}}}" in self.model_fields_set:
_dict['{{{baseName}}}'] = None
{{/isNullable}}
{{/allVars}}
return _dict
@classmethod
def from_dict(cls, obj: Dict) -> {{^hasChildren}}Self{{/hasChildren}}{{#hasChildren}}{{#discriminator}}Union[{{#children}}Self{{^-last}}, {{/-last}}{{/children}}]{{/discriminator}}{{^discriminator}}Self{{/discriminator}}{{/hasChildren}}:
"""Create an instance of {{{classname}}} from a dict"""
{{#hasChildren}}
{{#discriminator}}
# look up the object type based on discriminator mapping
object_type = cls.get_discriminator_value(obj)
if object_type:
klass = globals()[object_type]
return klass.from_dict(obj)
else:
raise ValueError("{{{classname}}} failed to lookup discriminator value from " +
json.dumps(obj) + ". Discriminator property name: " + cls.__discriminator_property_name +
", mapping: " + json.dumps(cls.__discriminator_value_class_map))
{{/discriminator}}
{{/hasChildren}}
{{^hasChildren}}
if obj is None:
return None
if not isinstance(obj, dict):
return cls.model_validate(obj)
{{#disallowAdditionalPropertiesIfNotPresent}}
{{^isAdditionalPropertiesTrue}}
# raise errors for additional fields in the input
for _key in obj.keys():
if _key not in cls.__properties:
raise ValueError("Error due to additional fields (not defined in {{classname}}) in the input: " + _key)
{{/isAdditionalPropertiesTrue}}
{{/disallowAdditionalPropertiesIfNotPresent}}
_obj = cls.model_validate({
{{#allVars}}
{{#isContainer}}
{{#isArray}}
{{#items.isArray}}
{{#items.items.isPrimitiveType}}
"{{{baseName}}}": obj.get("{{{baseName}}}"){{^-last}},{{/-last}}
{{/items.items.isPrimitiveType}}
{{^items.items.isPrimitiveType}}
"{{{baseName}}}": [
[{{{items.items.dataType}}}.from_dict(_inner_item) for _inner_item in _item]
for _item in obj.get("{{{baseName}}}")
] if obj.get("{{{baseName}}}") is not None else None{{^-last}},{{/-last}}
{{/items.items.isPrimitiveType}}
{{/items.isArray}}
{{^items.isArray}}
{{^items.isPrimitiveType}}
{{#items.isEnumOrRef}}
"{{{baseName}}}": obj.get("{{{baseName}}}"){{^-last}},{{/-last}}
{{/items.isEnumOrRef}}
{{^items.isEnumOrRef}}
"{{{baseName}}}": [{{{items.dataType}}}.from_dict(_item) for _item in obj.get("{{{baseName}}}")] if obj.get("{{{baseName}}}") is not None else None{{^-last}},{{/-last}}
{{/items.isEnumOrRef}}
{{/items.isPrimitiveType}}
{{#items.isPrimitiveType}}
"{{{baseName}}}": obj.get("{{{baseName}}}"){{^-last}},{{/-last}}
{{/items.isPrimitiveType}}
{{/items.isArray}}
{{/isArray}}
{{#isMap}}
{{^items.isPrimitiveType}}
{{^items.isEnumOrRef}}
{{#items.isContainer}}
{{#items.isMap}}
"{{{baseName}}}": dict(
(_k, dict(
(_ik, {{{items.items.dataType}}}.from_dict(_iv))
for _ik, _iv in _v.items()
)
if _v is not None
else None
)
for _k, _v in obj.get("{{{baseName}}}").items()
)
if obj.get("{{{baseName}}}") is not None
else None{{^-last}},{{/-last}}
{{/items.isMap}}
{{#items.isArray}}
"{{{baseName}}}": dict(
(_k,
[{{{items.items.dataType}}}.from_dict(_item) for _item in _v]
if _v is not None
else None
)
for _k, _v in obj.get("{{{baseName}}}").items()
){{^-last}},{{/-last}}
{{/items.isArray}}
{{/items.isContainer}}
{{^items.isContainer}}
"{{{baseName}}}": dict(
(_k, {{{items.dataType}}}.from_dict(_v))
for _k, _v in obj.get("{{{baseName}}}").items()
)
if obj.get("{{{baseName}}}") is not None
else None{{^-last}},{{/-last}}
{{/items.isContainer}}
{{/items.isEnumOrRef}}
{{#items.isEnumOrRef}}
"{{{baseName}}}": dict((_k, _v) for _k, _v in obj.get("{{{baseName}}}").items()){{^-last}},{{/-last}}
{{/items.isEnumOrRef}}
{{/items.isPrimitiveType}}
{{#items.isPrimitiveType}}
"{{{baseName}}}": obj.get("{{{baseName}}}"){{^-last}},{{/-last}}
{{/items.isPrimitiveType}}
{{/isMap}}
{{/isContainer}}
{{^isContainer}}
{{^isPrimitiveType}}
{{^isEnumOrRef}}
"{{{baseName}}}": {{{dataType}}}.from_dict(obj.get("{{{baseName}}}")) if obj.get("{{{baseName}}}") is not None else None{{^-last}},{{/-last}}
{{/isEnumOrRef}}
{{#isEnumOrRef}}
"{{{baseName}}}": obj.get("{{{baseName}}}"){{^-last}},{{/-last}}
{{/isEnumOrRef}}
{{/isPrimitiveType}}
{{#isPrimitiveType}}
{{#defaultValue}}
"{{{baseName}}}": obj.get("{{{baseName}}}") if obj.get("{{{baseName}}}") is not None else {{{defaultValue}}}{{^-last}},{{/-last}}
{{/defaultValue}}
{{^defaultValue}}
"{{{baseName}}}": obj.get("{{{baseName}}}"){{^-last}},{{/-last}}
{{/defaultValue}}
{{/isPrimitiveType}}
{{/isContainer}}
{{/allVars}}
})
{{#isAdditionalPropertiesTrue}}
# store additional fields in additional_properties
for _key in obj.keys():
if _key not in cls.__properties:
_obj.additional_properties[_key] = obj.get(_key)
{{/isAdditionalPropertiesTrue}}
return _obj
{{/hasChildren}}
{{#vendorExtensions.x-py-postponed-model-imports.size}}
{{#vendorExtensions.x-py-postponed-model-imports}}
{{{.}}}
{{/vendorExtensions.x-py-postponed-model-imports}}
# TODO: Rewrite to not use raise_errors
{{classname}}.model_rebuild(raise_errors=False)
{{/vendorExtensions.x-py-postponed-model-imports.size}}

View File

@@ -0,0 +1,215 @@
from __future__ import annotations
from inspect import getfullargspec
import json
import pprint
import re # noqa: F401
{{#vendorExtensions.x-py-datetime-imports}}{{#-first}}from datetime import{{/-first}} {{{.}}}{{^-last}},{{/-last}}{{/vendorExtensions.x-py-datetime-imports}}
{{#vendorExtensions.x-py-typing-imports}}{{#-first}}from typing import{{/-first}} {{{.}}}{{^-last}},{{/-last}}{{/vendorExtensions.x-py-typing-imports}}
{{#vendorExtensions.x-py-pydantic-imports}}{{#-first}}from pydantic import{{/-first}} {{{.}}}{{^-last}},{{/-last}}{{/vendorExtensions.x-py-pydantic-imports}}
{{#vendorExtensions.x-py-other-imports}}
{{{.}}}
{{/vendorExtensions.x-py-other-imports}}
{{#vendorExtensions.x-py-model-imports}}
{{{.}}}
{{/vendorExtensions.x-py-model-imports}}
from typing import Union, Any, List, TYPE_CHECKING, Optional, Dict
from typing_extensions import Literal
from pydantic import StrictStr, Field
try:
from typing import Self
except ImportError:
from typing_extensions import Self
{{#lambda.uppercase}}{{{classname}}}{{/lambda.uppercase}}_ONE_OF_SCHEMAS = [{{#oneOf}}"{{.}}"{{^-last}}, {{/-last}}{{/oneOf}}]
class {{classname}}({{#parent}}{{{.}}}{{/parent}}{{^parent}}BaseModel{{/parent}}):
"""
{{{description}}}{{^description}}{{{classname}}}{{/description}}
"""
{{#composedSchemas.oneOf}}
# data type: {{{dataType}}}
{{vendorExtensions.x-py-name}}: {{{vendorExtensions.x-py-typing}}}
{{/composedSchemas.oneOf}}
actual_instance: Optional[Union[{{#oneOf}}{{{.}}}{{^-last}}, {{/-last}}{{/oneOf}}]] = None
one_of_schemas: List[str] = Literal[{{#oneOf}}"{{.}}"{{^-last}}, {{/-last}}{{/oneOf}}]
model_config = {
"validate_assignment": True,
"protected_namespaces": (),
}
{{#discriminator}}
discriminator_value_class_map: Dict[str, str] = {
{{#children}}
'{{^vendorExtensions.x-discriminator-value}}{{name}}{{/vendorExtensions.x-discriminator-value}}{{#vendorExtensions.x-discriminator-value}}{{{vendorExtensions.x-discriminator-value}}}{{/vendorExtensions.x-discriminator-value}}': '{{{classname}}}'{{^-last}},{{/-last}}
{{/children}}
}
{{/discriminator}}
def __init__(self, *args, **kwargs) -> None:
if args:
if len(args) > 1:
raise ValueError("If a position argument is used, only 1 is allowed to set `actual_instance`")
if kwargs:
raise ValueError("If a position argument is used, keyword arguments cannot be used.")
super().__init__(actual_instance=args[0])
else:
super().__init__(**kwargs)
@field_validator('actual_instance')
def actual_instance_must_validate_oneof(cls, v):
{{#isNullable}}
if v is None:
return v
{{/isNullable}}
instance = {{{classname}}}.model_construct()
error_messages = []
match = 0
{{#composedSchemas.oneOf}}
# validate data type: {{{dataType}}}
{{#isContainer}}
try:
instance.{{vendorExtensions.x-py-name}} = v
match += 1
except (ValidationError, ValueError) as e:
error_messages.append(str(e))
{{/isContainer}}
{{^isContainer}}
{{#isPrimitiveType}}
try:
instance.{{vendorExtensions.x-py-name}} = v
match += 1
except (ValidationError, ValueError) as e:
error_messages.append(str(e))
{{/isPrimitiveType}}
{{^isPrimitiveType}}
if not isinstance(v, {{{dataType}}}):
error_messages.append(f"Error! Input type `{type(v)}` is not `{{{dataType}}}`")
else:
match += 1
{{/isPrimitiveType}}
{{/isContainer}}
{{/composedSchemas.oneOf}}
if match > 1:
# more than 1 match
raise ValueError("Multiple matches found when setting `actual_instance` in {{{classname}}} with oneOf schemas: {{#oneOf}}{{{.}}}{{^-last}}, {{/-last}}{{/oneOf}}. Details: " + ", ".join(error_messages))
elif match == 0:
# no match
raise ValueError("No match found when setting `actual_instance` in {{{classname}}} with oneOf schemas: {{#oneOf}}{{{.}}}{{^-last}}, {{/-last}}{{/oneOf}}. Details: " + ", ".join(error_messages))
else:
return v
@classmethod
def from_dict(cls, obj: dict) -> Self:
return cls.from_json(json.dumps(obj))
@classmethod
def from_json(cls, json_str: str) -> Self:
"""Returns the object represented by the json string"""
instance = cls.model_construct()
{{#isNullable}}
if json_str is None:
return instance
{{/isNullable}}
error_messages = []
match = 0
{{#useOneOfDiscriminatorLookup}}
{{#discriminator}}
{{#mappedModels}}
{{#-first}}
# use oneOf discriminator to lookup the data type
_data_type = json.loads(json_str).get("{{{propertyBaseName}}}")
if not _data_type:
raise ValueError("Failed to lookup data type from the field `{{{propertyBaseName}}}` in the input.")
{{/-first}}
# check if data type is `{{{modelName}}}`
if _data_type == "{{{mappingName}}}":
instance.actual_instance = {{{modelName}}}.from_json(json_str)
return instance
{{/mappedModels}}
{{/discriminator}}
{{/useOneOfDiscriminatorLookup}}
{{#composedSchemas.oneOf}}
{{#isContainer}}
# deserialize data into {{{dataType}}}
try:
# validation
instance.{{vendorExtensions.x-py-name}} = json.loads(json_str)
# assign value to actual_instance
instance.actual_instance = instance.{{vendorExtensions.x-py-name}}
match += 1
except (ValidationError, ValueError) as e:
error_messages.append(str(e))
{{/isContainer}}
{{^isContainer}}
{{#isPrimitiveType}}
# deserialize data into {{{dataType}}}
try:
# validation
instance.{{vendorExtensions.x-py-name}} = json.loads(json_str)
# assign value to actual_instance
instance.actual_instance = instance.{{vendorExtensions.x-py-name}}
match += 1
except (ValidationError, ValueError) as e:
error_messages.append(str(e))
{{/isPrimitiveType}}
{{^isPrimitiveType}}
# deserialize data into {{{dataType}}}
try:
instance.actual_instance = {{{dataType}}}.from_json(json_str)
match += 1
except (ValidationError, ValueError) as e:
error_messages.append(str(e))
{{/isPrimitiveType}}
{{/isContainer}}
{{/composedSchemas.oneOf}}
if match > 1:
# more than 1 match
raise ValueError("Multiple matches found when deserializing the JSON string into {{{classname}}} with oneOf schemas: {{#oneOf}}{{{.}}}{{^-last}}, {{/-last}}{{/oneOf}}. Details: " + ", ".join(error_messages))
elif match == 0:
# no match
raise ValueError("No match found when deserializing the JSON string into {{{classname}}} with oneOf schemas: {{#oneOf}}{{{.}}}{{^-last}}, {{/-last}}{{/oneOf}}. Details: " + ", ".join(error_messages))
else:
return instance
def to_json(self) -> str:
"""Returns the JSON representation of the actual instance"""
if self.actual_instance is None:
return "null"
to_json = getattr(self.actual_instance, "to_json", None)
if callable(to_json):
return self.actual_instance.to_json()
else:
return json.dumps(self.actual_instance)
def to_dict(self) -> Dict:
"""Returns the dict representation of the actual instance"""
if self.actual_instance is None:
return None
to_dict = getattr(self.actual_instance, "to_dict", None)
if callable(to_dict):
return self.actual_instance.to_dict()
else:
# primitive type
return self.actual_instance
def to_str(self) -> str:
"""Returns the string representation of the actual instance"""
return pprint.pformat(self.model_dump())
{{#vendorExtensions.x-py-postponed-model-imports.size}}
{{#vendorExtensions.x-py-postponed-model-imports}}
{{{.}}}
{{/vendorExtensions.x-py-postponed-model-imports}}
# TODO: Rewrite to not use raise_errors
{{classname}}.model_rebuild(raise_errors=False)
{{/vendorExtensions.x-py-postponed-model-imports.size}}

View File

@@ -0,0 +1,60 @@
# coding: utf-8
{{>partial_header}}
import unittest
import datetime
{{#models}}
{{#model}}
from {{modelPackage}}.{{classFilename}} import {{classname}}
class Test{{classname}}(unittest.TestCase):
"""{{classname}} unit test stubs"""
def setUp(self):
pass
def tearDown(self):
pass
{{^isEnum}}
def make_instance(self, include_optional) -> {{classname}}:
"""Test {{classname}}
include_option is a boolean, when False only required
params are included, when True both required and
optional params are included """
# uncomment below to create an instance of `{{{classname}}}`
"""
model = {{classname}}()
if include_optional:
return {{classname}}(
{{#vars}}
{{name}} = {{{example}}}{{^example}}None{{/example}}{{^-last}},{{/-last}}
{{/vars}}
)
else:
return {{classname}}(
{{#vars}}
{{#required}}
{{name}} = {{{example}}}{{^example}}None{{/example}},
{{/required}}
{{/vars}}
)
"""
{{/isEnum}}
def test{{classname}}(self):
"""Test {{classname}}"""
{{^isEnum}}
# inst_req_only = self.make_instance(include_optional=False)
# inst_req_and_optional = self.make_instance(include_optional=True)
{{/isEnum}}
{{#isEnum}}
# inst = {{{classname}}}()
{{/isEnum}}
{{/model}}
{{/models}}
if __name__ == '__main__':
unittest.main()

View File

@@ -1,17 +1,19 @@
"""
{{#appName}}
{{{.}}}
{{/appName}}
{{/appName}}
{{#appDescription}}
{{{.}}}
{{/appDescription}}
{{/appDescription}}
{{#version}}
The version of the OpenAPI document: {{{.}}}
{{/version}}
{{#infoEmail}}
Contact: {{{.}}}
{{/infoEmail}}
Generated by: https://openapi-generator.tech
"""
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
""" # noqa: E501

View File

@@ -2,12 +2,12 @@ aiofiles==23.1.0
aniso8601==7.0.0
async-exit-stack==1.0.1
async-generator==1.10
certifi==2022.12.7
certifi==2023.7.22
chardet==4.0.0
click==7.1.2
dnspython==2.1.0
email-validator==1.1.2
fastapi==0.95.2
email-validator==2.0.0
fastapi==0.109.2
graphene==2.1.8
graphql-core==2.3.2
graphql-relay==2.0.1
@@ -20,14 +20,14 @@ Jinja2==2.11.3
MarkupSafe==2.0.1
orjson==3.5.2
promise==2.3
pydantic==1.8.2
pydantic>=2
python-dotenv==0.17.1
python-multipart==0.0.5
PyYAML==5.4.1
requests==2.25.1
Rx==1.6.1
starlette==0.27.0
typing-extensions==3.10.0.0
starlette==0.36.3
typing-extensions==4.8.0
ujson==4.0.2
urllib3==1.26.5
uvicorn==0.13.4

View File

@@ -2,12 +2,12 @@ aiofiles==23.1.0
aniso8601==7.0.0
async-exit-stack==1.0.1
async-generator==1.10
certifi==2022.12.7
certifi==2023.7.22
chardet==4.0.0
click==7.1.2
dnspython==2.1.0
email-validator==1.1.2
fastapi==0.95.2
email-validator==2.0.0
fastapi==0.109.2
graphene==2.1.8
graphql-core==2.3.2
graphql-relay==2.0.1
@@ -20,14 +20,14 @@ Jinja2==2.11.3
MarkupSafe==2.0.1
orjson==3.5.2
promise==2.3
pydantic==1.8.2
pydantic>=2
python-dotenv==0.17.1
python-multipart==0.0.5
PyYAML==5.4.1
requests==2.25.1
Rx==1.6.1
starlette==0.27.0
typing-extensions==3.10.0.0
starlette==0.36.3
typing-extensions==4.8.0
ujson==4.0.2
urllib3==1.26.5
uvicorn==0.13.4

View File

@@ -6,8 +6,10 @@
This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
The version of the OpenAPI document: 1.0.0
Generated by: https://openapi-generator.tech
"""
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
""" # noqa: E501
from fastapi import FastAPI

View File

@@ -1,28 +1,94 @@
# coding: utf-8
from __future__ import annotations
from datetime import date, datetime # noqa: F401
"""
OpenAPI Petstore
import re # noqa: F401
from typing import Any, Dict, List, Optional # noqa: F401
This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
from pydantic import AnyUrl, BaseModel, EmailStr, Field, validator # noqa: F401
class ApiResponse(BaseModel):
"""NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
The version of the OpenAPI document: 1.0.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
""" # noqa: E501
ApiResponse - a model defined in OpenAPI
code: The code of this ApiResponse [Optional].
type: The type of this ApiResponse [Optional].
message: The message of this ApiResponse [Optional].
from __future__ import annotations
import pprint
import re # noqa: F401
import json
from pydantic import BaseModel, StrictInt, StrictStr
from typing import Any, ClassVar, Dict, List, Optional
try:
from typing import Self
except ImportError:
from typing_extensions import Self
class ApiResponse(BaseModel):
"""
Describes the result of uploading an image resource
""" # noqa: E501
code: Optional[StrictInt] = None
type: Optional[StrictStr] = None
message: Optional[StrictStr] = None
__properties: ClassVar[List[str]] = ["code", "type", "message"]
model_config = {
"populate_by_name": True,
"validate_assignment": True,
"protected_namespaces": (),
}
def to_str(self) -> str:
"""Returns the string representation of the model using alias"""
return pprint.pformat(self.model_dump(by_alias=True))
def to_json(self) -> str:
"""Returns the JSON representation of the model using alias"""
# TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
return json.dumps(self.to_dict())
@classmethod
def from_json(cls, json_str: str) -> Self:
"""Create an instance of ApiResponse from a JSON string"""
return cls.from_dict(json.loads(json_str))
def to_dict(self) -> Dict[str, Any]:
"""Return the dictionary representation of the model using alias.
This has the following differences from calling pydantic's
`self.model_dump(by_alias=True)`:
* `None` is only added to the output dict for nullable fields that
were set at model initialization. Other fields with value `None`
are ignored.
"""
_dict = self.model_dump(
by_alias=True,
exclude={
},
exclude_none=True,
)
return _dict
@classmethod
def from_dict(cls, obj: Dict) -> Self:
"""Create an instance of ApiResponse from a dict"""
if obj is None:
return None
if not isinstance(obj, dict):
return cls.model_validate(obj)
_obj = cls.model_validate({
"code": obj.get("code"),
"type": obj.get("type"),
"message": obj.get("message")
})
return _obj
code: Optional[int] = Field(alias="code", default=None)
type: Optional[str] = Field(alias="type", default=None)
message: Optional[str] = Field(alias="message", default=None)
ApiResponse.update_forward_refs()

View File

@@ -1,31 +1,103 @@
# coding: utf-8
from __future__ import annotations
from datetime import date, datetime # noqa: F401
"""
OpenAPI Petstore
import re # noqa: F401
from typing import Any, Dict, List, Optional # noqa: F401
This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
from pydantic import AnyUrl, BaseModel, EmailStr, Field, validator # noqa: F401
class Category(BaseModel):
"""NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
The version of the OpenAPI document: 1.0.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
""" # noqa: E501
Category - a model defined in OpenAPI
id: The id of this Category [Optional].
name: The name of this Category [Optional].
from __future__ import annotations
import pprint
import re # noqa: F401
import json
from pydantic import BaseModel, Field, StrictInt, field_validator
from typing import Any, ClassVar, Dict, List, Optional
from typing_extensions import Annotated
try:
from typing import Self
except ImportError:
from typing_extensions import Self
class Category(BaseModel):
"""
A category for a pet
""" # noqa: E501
id: Optional[StrictInt] = None
name: Optional[Annotated[str, Field(strict=True)]] = None
__properties: ClassVar[List[str]] = ["id", "name"]
id: Optional[int] = Field(alias="id", default=None)
name: Optional[str] = Field(alias="name", default=None)
@validator("name")
def name_pattern(cls, value):
assert value is not None and re.match(r"/^[a-zA-Z0-9]+[a-zA-Z0-9\.\-_]*[a-zA-Z0-9]+$/", value)
@field_validator('name')
def name_validate_regular_expression(cls, value):
"""Validates the regular expression"""
if value is None:
return value
Category.update_forward_refs()
if not re.match(r"^[a-zA-Z0-9]+[a-zA-Z0-9\.\-_]*[a-zA-Z0-9]+$", value):
raise ValueError(r"must validate the regular expression /^[a-zA-Z0-9]+[a-zA-Z0-9\.\-_]*[a-zA-Z0-9]+$/")
return value
model_config = {
"populate_by_name": True,
"validate_assignment": True,
"protected_namespaces": (),
}
def to_str(self) -> str:
"""Returns the string representation of the model using alias"""
return pprint.pformat(self.model_dump(by_alias=True))
def to_json(self) -> str:
"""Returns the JSON representation of the model using alias"""
# TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
return json.dumps(self.to_dict())
@classmethod
def from_json(cls, json_str: str) -> Self:
"""Create an instance of Category from a JSON string"""
return cls.from_dict(json.loads(json_str))
def to_dict(self) -> Dict[str, Any]:
"""Return the dictionary representation of the model using alias.
This has the following differences from calling pydantic's
`self.model_dump(by_alias=True)`:
* `None` is only added to the output dict for nullable fields that
were set at model initialization. Other fields with value `None`
are ignored.
"""
_dict = self.model_dump(
by_alias=True,
exclude={
},
exclude_none=True,
)
return _dict
@classmethod
def from_dict(cls, obj: Dict) -> Self:
"""Create an instance of Category from a dict"""
if obj is None:
return None
if not isinstance(obj, dict):
return cls.model_validate(obj)
_obj = cls.model_validate({
"id": obj.get("id"),
"name": obj.get("name")
})
return _obj

View File

@@ -1,34 +1,111 @@
# coding: utf-8
from __future__ import annotations
from datetime import date, datetime # noqa: F401
"""
OpenAPI Petstore
import re # noqa: F401
from typing import Any, Dict, List, Optional # noqa: F401
This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
from pydantic import AnyUrl, BaseModel, EmailStr, Field, validator # noqa: F401
class Order(BaseModel):
"""NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
The version of the OpenAPI document: 1.0.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
""" # noqa: E501
Order - a model defined in OpenAPI
id: The id of this Order [Optional].
pet_id: The pet_id of this Order [Optional].
quantity: The quantity of this Order [Optional].
ship_date: The ship_date of this Order [Optional].
status: The status of this Order [Optional].
complete: The complete of this Order [Optional].
from __future__ import annotations
import pprint
import re # noqa: F401
import json
from datetime import datetime
from pydantic import BaseModel, Field, StrictBool, StrictInt, StrictStr, field_validator
from typing import Any, ClassVar, Dict, List, Optional
try:
from typing import Self
except ImportError:
from typing_extensions import Self
class Order(BaseModel):
"""
An order for a pets from the pet store
""" # noqa: E501
id: Optional[StrictInt] = None
pet_id: Optional[StrictInt] = Field(default=None, alias="petId")
quantity: Optional[StrictInt] = None
ship_date: Optional[datetime] = Field(default=None, alias="shipDate")
status: Optional[StrictStr] = Field(default=None, description="Order Status")
complete: Optional[StrictBool] = False
__properties: ClassVar[List[str]] = ["id", "petId", "quantity", "shipDate", "status", "complete"]
@field_validator('status')
def status_validate_enum(cls, value):
"""Validates the enum"""
if value is None:
return value
if value not in ('placed', 'approved', 'delivered'):
raise ValueError("must be one of enum values ('placed', 'approved', 'delivered')")
return value
model_config = {
"populate_by_name": True,
"validate_assignment": True,
"protected_namespaces": (),
}
def to_str(self) -> str:
"""Returns the string representation of the model using alias"""
return pprint.pformat(self.model_dump(by_alias=True))
def to_json(self) -> str:
"""Returns the JSON representation of the model using alias"""
# TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
return json.dumps(self.to_dict())
@classmethod
def from_json(cls, json_str: str) -> Self:
"""Create an instance of Order from a JSON string"""
return cls.from_dict(json.loads(json_str))
def to_dict(self) -> Dict[str, Any]:
"""Return the dictionary representation of the model using alias.
This has the following differences from calling pydantic's
`self.model_dump(by_alias=True)`:
* `None` is only added to the output dict for nullable fields that
were set at model initialization. Other fields with value `None`
are ignored.
"""
_dict = self.model_dump(
by_alias=True,
exclude={
},
exclude_none=True,
)
return _dict
@classmethod
def from_dict(cls, obj: Dict) -> Self:
"""Create an instance of Order from a dict"""
if obj is None:
return None
if not isinstance(obj, dict):
return cls.model_validate(obj)
_obj = cls.model_validate({
"id": obj.get("id"),
"petId": obj.get("petId"),
"quantity": obj.get("quantity"),
"shipDate": obj.get("shipDate"),
"status": obj.get("status"),
"complete": obj.get("complete") if obj.get("complete") is not None else False
})
return _obj
id: Optional[int] = Field(alias="id", default=None)
pet_id: Optional[int] = Field(alias="petId", default=None)
quantity: Optional[int] = Field(alias="quantity", default=None)
ship_date: Optional[datetime] = Field(alias="shipDate", default=None)
status: Optional[str] = Field(alias="status", default=None)
complete: Optional[bool] = Field(alias="complete", default=None)
Order.update_forward_refs()

View File

@@ -1,36 +1,122 @@
# coding: utf-8
from __future__ import annotations
from datetime import date, datetime # noqa: F401
"""
OpenAPI Petstore
import re # noqa: F401
from typing import Any, Dict, List, Optional # noqa: F401
This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
from pydantic import AnyUrl, BaseModel, EmailStr, Field, validator # noqa: F401
from openapi_server.models.category import Category
from openapi_server.models.tag import Tag
class Pet(BaseModel):
"""NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
The version of the OpenAPI document: 1.0.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
""" # noqa: E501
Pet - a model defined in OpenAPI
id: The id of this Pet [Optional].
category: The category of this Pet [Optional].
name: The name of this Pet.
photo_urls: The photo_urls of this Pet.
tags: The tags of this Pet [Optional].
status: The status of this Pet [Optional].
from __future__ import annotations
import pprint
import re # noqa: F401
import json
from pydantic import BaseModel, Field, StrictInt, StrictStr, field_validator
from typing import Any, ClassVar, Dict, List, Optional
from openapi_server.models.category import Category
from openapi_server.models.tag import Tag
try:
from typing import Self
except ImportError:
from typing_extensions import Self
class Pet(BaseModel):
"""
A pet for sale in the pet store
""" # noqa: E501
id: Optional[StrictInt] = None
category: Optional[Category] = None
name: StrictStr
photo_urls: List[StrictStr] = Field(alias="photoUrls")
tags: Optional[List[Tag]] = None
status: Optional[StrictStr] = Field(default=None, description="pet status in the store")
__properties: ClassVar[List[str]] = ["id", "category", "name", "photoUrls", "tags", "status"]
@field_validator('status')
def status_validate_enum(cls, value):
"""Validates the enum"""
if value is None:
return value
if value not in ('available', 'pending', 'sold'):
raise ValueError("must be one of enum values ('available', 'pending', 'sold')")
return value
model_config = {
"populate_by_name": True,
"validate_assignment": True,
"protected_namespaces": (),
}
def to_str(self) -> str:
"""Returns the string representation of the model using alias"""
return pprint.pformat(self.model_dump(by_alias=True))
def to_json(self) -> str:
"""Returns the JSON representation of the model using alias"""
# TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
return json.dumps(self.to_dict())
@classmethod
def from_json(cls, json_str: str) -> Self:
"""Create an instance of Pet from a JSON string"""
return cls.from_dict(json.loads(json_str))
def to_dict(self) -> Dict[str, Any]:
"""Return the dictionary representation of the model using alias.
This has the following differences from calling pydantic's
`self.model_dump(by_alias=True)`:
* `None` is only added to the output dict for nullable fields that
were set at model initialization. Other fields with value `None`
are ignored.
"""
_dict = self.model_dump(
by_alias=True,
exclude={
},
exclude_none=True,
)
# override the default output from pydantic by calling `to_dict()` of category
if self.category:
_dict['category'] = self.category.to_dict()
# override the default output from pydantic by calling `to_dict()` of each item in tags (list)
_items = []
if self.tags:
for _item in self.tags:
if _item:
_items.append(_item.to_dict())
_dict['tags'] = _items
return _dict
@classmethod
def from_dict(cls, obj: Dict) -> Self:
"""Create an instance of Pet from a dict"""
if obj is None:
return None
if not isinstance(obj, dict):
return cls.model_validate(obj)
_obj = cls.model_validate({
"id": obj.get("id"),
"category": Category.from_dict(obj.get("category")) if obj.get("category") is not None else None,
"name": obj.get("name"),
"photoUrls": obj.get("photoUrls"),
"tags": [Tag.from_dict(_item) for _item in obj.get("tags")] if obj.get("tags") is not None else None,
"status": obj.get("status")
})
return _obj
id: Optional[int] = Field(alias="id", default=None)
category: Optional[Category] = Field(alias="category", default=None)
name: str = Field(alias="name")
photo_urls: List[str] = Field(alias="photoUrls")
tags: Optional[List[Tag]] = Field(alias="tags", default=None)
status: Optional[str] = Field(alias="status", default=None)
Pet.update_forward_refs()

View File

@@ -1,26 +1,92 @@
# coding: utf-8
from __future__ import annotations
from datetime import date, datetime # noqa: F401
"""
OpenAPI Petstore
import re # noqa: F401
from typing import Any, Dict, List, Optional # noqa: F401
This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
from pydantic import AnyUrl, BaseModel, EmailStr, Field, validator # noqa: F401
class Tag(BaseModel):
"""NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
The version of the OpenAPI document: 1.0.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
""" # noqa: E501
Tag - a model defined in OpenAPI
id: The id of this Tag [Optional].
name: The name of this Tag [Optional].
from __future__ import annotations
import pprint
import re # noqa: F401
import json
from pydantic import BaseModel, StrictInt, StrictStr
from typing import Any, ClassVar, Dict, List, Optional
try:
from typing import Self
except ImportError:
from typing_extensions import Self
class Tag(BaseModel):
"""
A tag for a pet
""" # noqa: E501
id: Optional[StrictInt] = None
name: Optional[StrictStr] = None
__properties: ClassVar[List[str]] = ["id", "name"]
model_config = {
"populate_by_name": True,
"validate_assignment": True,
"protected_namespaces": (),
}
def to_str(self) -> str:
"""Returns the string representation of the model using alias"""
return pprint.pformat(self.model_dump(by_alias=True))
def to_json(self) -> str:
"""Returns the JSON representation of the model using alias"""
# TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
return json.dumps(self.to_dict())
@classmethod
def from_json(cls, json_str: str) -> Self:
"""Create an instance of Tag from a JSON string"""
return cls.from_dict(json.loads(json_str))
def to_dict(self) -> Dict[str, Any]:
"""Return the dictionary representation of the model using alias.
This has the following differences from calling pydantic's
`self.model_dump(by_alias=True)`:
* `None` is only added to the output dict for nullable fields that
were set at model initialization. Other fields with value `None`
are ignored.
"""
_dict = self.model_dump(
by_alias=True,
exclude={
},
exclude_none=True,
)
return _dict
@classmethod
def from_dict(cls, obj: Dict) -> Self:
"""Create an instance of Tag from a dict"""
if obj is None:
return None
if not isinstance(obj, dict):
return cls.model_validate(obj)
_obj = cls.model_validate({
"id": obj.get("id"),
"name": obj.get("name")
})
return _obj
id: Optional[int] = Field(alias="id", default=None)
name: Optional[str] = Field(alias="name", default=None)
Tag.update_forward_refs()

View File

@@ -1,38 +1,104 @@
# coding: utf-8
from __future__ import annotations
from datetime import date, datetime # noqa: F401
"""
OpenAPI Petstore
import re # noqa: F401
from typing import Any, Dict, List, Optional # noqa: F401
This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
from pydantic import AnyUrl, BaseModel, EmailStr, Field, validator # noqa: F401
class User(BaseModel):
"""NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
The version of the OpenAPI document: 1.0.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
""" # noqa: E501
User - a model defined in OpenAPI
id: The id of this User [Optional].
username: The username of this User [Optional].
first_name: The first_name of this User [Optional].
last_name: The last_name of this User [Optional].
email: The email of this User [Optional].
password: The password of this User [Optional].
phone: The phone of this User [Optional].
user_status: The user_status of this User [Optional].
from __future__ import annotations
import pprint
import re # noqa: F401
import json
from pydantic import BaseModel, Field, StrictInt, StrictStr
from typing import Any, ClassVar, Dict, List, Optional
try:
from typing import Self
except ImportError:
from typing_extensions import Self
class User(BaseModel):
"""
A User who is purchasing from the pet store
""" # noqa: E501
id: Optional[StrictInt] = None
username: Optional[StrictStr] = None
first_name: Optional[StrictStr] = Field(default=None, alias="firstName")
last_name: Optional[StrictStr] = Field(default=None, alias="lastName")
email: Optional[StrictStr] = None
password: Optional[StrictStr] = None
phone: Optional[StrictStr] = None
user_status: Optional[StrictInt] = Field(default=None, description="User Status", alias="userStatus")
__properties: ClassVar[List[str]] = ["id", "username", "firstName", "lastName", "email", "password", "phone", "userStatus"]
model_config = {
"populate_by_name": True,
"validate_assignment": True,
"protected_namespaces": (),
}
def to_str(self) -> str:
"""Returns the string representation of the model using alias"""
return pprint.pformat(self.model_dump(by_alias=True))
def to_json(self) -> str:
"""Returns the JSON representation of the model using alias"""
# TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
return json.dumps(self.to_dict())
@classmethod
def from_json(cls, json_str: str) -> Self:
"""Create an instance of User from a JSON string"""
return cls.from_dict(json.loads(json_str))
def to_dict(self) -> Dict[str, Any]:
"""Return the dictionary representation of the model using alias.
This has the following differences from calling pydantic's
`self.model_dump(by_alias=True)`:
* `None` is only added to the output dict for nullable fields that
were set at model initialization. Other fields with value `None`
are ignored.
"""
_dict = self.model_dump(
by_alias=True,
exclude={
},
exclude_none=True,
)
return _dict
@classmethod
def from_dict(cls, obj: Dict) -> Self:
"""Create an instance of User from a dict"""
if obj is None:
return None
if not isinstance(obj, dict):
return cls.model_validate(obj)
_obj = cls.model_validate({
"id": obj.get("id"),
"username": obj.get("username"),
"firstName": obj.get("firstName"),
"lastName": obj.get("lastName"),
"email": obj.get("email"),
"password": obj.get("password"),
"phone": obj.get("phone"),
"userStatus": obj.get("userStatus")
})
return _obj
id: Optional[int] = Field(alias="id", default=None)
username: Optional[str] = Field(alias="username", default=None)
first_name: Optional[str] = Field(alias="firstName", default=None)
last_name: Optional[str] = Field(alias="lastName", default=None)
email: Optional[str] = Field(alias="email", default=None)
password: Optional[str] = Field(alias="password", default=None)
phone: Optional[str] = Field(alias="phone", default=None)
user_status: Optional[int] = Field(alias="userStatus", default=None)
User.update_forward_refs()