Skip to content

Add additional property support by subscripting model #252

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
a96621d
Add additional property support by subscripting model
packyg Nov 25, 2020
f8ca735
Update e2e golden records
packyg Nov 25, 2020
62fad1e
Add models with additionalProperties to golden record
packyg Nov 25, 2020
f6028d3
PR Feedback: Set additional properties directly
packyg Nov 30, 2020
4c0fbd0
PR Feedback: Just make additionalProperties public
packyg Nov 30, 2020
b13d282
Handle edge cases of additionalProperties to interpret per the spec
packyg Nov 30, 2020
7b72c9a
Update golden record's spec to specify no additional props on existin…
packyg Nov 30, 2020
3a827f1
Support modeled additionalProperties
packyg Dec 1, 2020
78015fc
Typing fixes for model properties
packyg Dec 3, 2020
e3e0fb4
Add ModelWithPrimitiveAdditionalProperties to e2e test spec
packyg Dec 3, 2020
45ce82b
Regen golden records
packyg Dec 3, 2020
b2285cd
Merge branch 'main' into additionalProperties-support
packyg Dec 3, 2020
0d175c0
Update templates to not attempt to pop the same attr multiple times
packyg Dec 3, 2020
1f38a05
Update golden record
packyg Dec 3, 2020
da0bc8e
Typing fixes for additional_properties when building model prop
packyg Dec 3, 2020
827d367
Remove unused import from model_property
packyg Dec 3, 2020
daf9628
Update existing tests to account for additional_properties
packyg Dec 3, 2020
036f372
Parametrize test_build_model_property to test various additional_prop…
packyg Dec 4, 2020
e1ef9a7
Rename AdditionalProperties models to AdditionalProperty as each one …
packyg Dec 4, 2020
0cbe2de
Add test for bad additionalProperties schema
packyg Dec 4, 2020
6ccdde4
uncomment part of test
packyg Dec 4, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
def _parse_response(*, response: httpx.Response) -> Optional[Union[List[AModel], HTTPValidationError]]:
if response.status_code == 200:
response_200 = []
for response_200_item_data in response.json():
_response_200 = response.json()
for response_200_item_data in _response_200:
response_200_item = AModel.from_dict(response_200_item_data)

response_200.append(response_200_item)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,15 @@
from .an_int_enum import AnIntEnum
from .body_upload_file_tests_upload_post import BodyUploadFileTestsUploadPost
from .different_enum import DifferentEnum
from .free_form_model import FreeFormModel
from .http_validation_error import HTTPValidationError
from .model_with_additional_properties_inlined import ModelWithAdditionalPropertiesInlined
from .model_with_additional_properties_inlined_additional_property import (
ModelWithAdditionalPropertiesInlinedAdditionalProperty,
)
from .model_with_additional_properties_refed import ModelWithAdditionalPropertiesRefed
from .model_with_primitive_additional_properties import ModelWithPrimitiveAdditionalProperties
from .model_with_primitive_additional_properties_a_date_holder import ModelWithPrimitiveAdditionalPropertiesADateHolder
from .model_with_union_property import ModelWithUnionProperty
from .test_inline_objects_json_body import TestInlineObjectsJsonBody
from .test_inline_objects_response_200 import TestInlineObjectsResponse_200
Expand Down
46 changes: 27 additions & 19 deletions end_to_end_tests/golden-record-custom/custom_e2e/models/a_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,16 @@ def to_dict(self) -> Dict[str, Any]:
not_required_nullable = self.not_required_nullable
not_required_not_nullable = self.not_required_not_nullable

field_dict = {
"an_enum_value": an_enum_value,
"aCamelDateTime": a_camel_date_time,
"a_date": a_date,
"required_not_nullable": required_not_nullable,
"required_nullable": required_nullable,
}
field_dict: Dict[str, Any] = {}
field_dict.update(
{
"an_enum_value": an_enum_value,
"aCamelDateTime": a_camel_date_time,
"a_date": a_date,
"required_not_nullable": required_not_nullable,
"required_nullable": required_nullable,
}
)
if nested_list_of_enums is not UNSET:
field_dict["nested_list_of_enums"] = nested_list_of_enums
if attr_1_leading_digit is not UNSET:
Expand All @@ -71,8 +74,9 @@ def to_dict(self) -> Dict[str, Any]:
return field_dict

@staticmethod
def from_dict(d: Dict[str, Any]) -> "AModel":
an_enum_value = AnEnum(d["an_enum_value"])
def from_dict(src_dict: Dict[str, Any]) -> "AModel":
d = src_dict.copy()
an_enum_value = AnEnum(d.pop("an_enum_value"))

def _parse_a_camel_date_time(data: Any) -> Union[datetime.datetime, datetime.date]:
data = None if isinstance(data, Unset) else data
Expand All @@ -87,31 +91,33 @@ def _parse_a_camel_date_time(data: Any) -> Union[datetime.datetime, datetime.dat

return a_camel_date_time

a_camel_date_time = _parse_a_camel_date_time(d["aCamelDateTime"])
a_camel_date_time = _parse_a_camel_date_time(d.pop("aCamelDateTime"))

a_date = isoparse(d["a_date"]).date()
a_date = isoparse(d.pop("a_date")).date()

required_not_nullable = d["required_not_nullable"]
required_not_nullable = d.pop("required_not_nullable")

nested_list_of_enums = []
for nested_list_of_enums_item_data in d.get("nested_list_of_enums", UNSET) or []:
_nested_list_of_enums = d.pop("nested_list_of_enums", UNSET)
for nested_list_of_enums_item_data in _nested_list_of_enums or []:
nested_list_of_enums_item = []
for nested_list_of_enums_item_item_data in nested_list_of_enums_item_data:
_nested_list_of_enums_item = nested_list_of_enums_item_data
for nested_list_of_enums_item_item_data in _nested_list_of_enums_item:
nested_list_of_enums_item_item = DifferentEnum(nested_list_of_enums_item_item_data)

nested_list_of_enums_item.append(nested_list_of_enums_item_item)

nested_list_of_enums.append(nested_list_of_enums_item)

attr_1_leading_digit = d.get("1_leading_digit", UNSET)
attr_1_leading_digit = d.pop("1_leading_digit", UNSET)

required_nullable = d["required_nullable"]
required_nullable = d.pop("required_nullable")

not_required_nullable = d.get("not_required_nullable", UNSET)
not_required_nullable = d.pop("not_required_nullable", UNSET)

not_required_not_nullable = d.get("not_required_not_nullable", UNSET)
not_required_not_nullable = d.pop("not_required_not_nullable", UNSET)

return AModel(
a_model = AModel(
an_enum_value=an_enum_value,
a_camel_date_time=a_camel_date_time,
a_date=a_date,
Expand All @@ -122,3 +128,5 @@ def _parse_a_camel_date_time(data: Any) -> Union[datetime.datetime, datetime.dat
not_required_nullable=not_required_nullable,
not_required_not_nullable=not_required_not_nullable,
)

return a_model
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,22 @@ class BodyUploadFileTestsUploadPost:
def to_dict(self) -> Dict[str, Any]:
some_file = self.some_file.to_tuple()

field_dict = {
"some_file": some_file,
}
field_dict: Dict[str, Any] = {}
field_dict.update(
{
"some_file": some_file,
}
)

return field_dict

@staticmethod
def from_dict(d: Dict[str, Any]) -> "BodyUploadFileTestsUploadPost":
some_file = File(payload=BytesIO(d["some_file"]))
def from_dict(src_dict: Dict[str, Any]) -> "BodyUploadFileTestsUploadPost":
d = src_dict.copy()
some_file = File(payload=BytesIO(d.pop("some_file")))

return BodyUploadFileTestsUploadPost(
body_upload_file_tests_upload_post = BodyUploadFileTestsUploadPost(
some_file=some_file,
)

return body_upload_file_tests_upload_post
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
from typing import Any, Dict, List

import attr


@attr.s(auto_attribs=True)
class FreeFormModel:
""" """

additional_properties: Dict[str, Any] = attr.ib(init=False, factory=dict)

def to_dict(self) -> Dict[str, Any]:

field_dict: Dict[str, Any] = {}
field_dict.update(self.additional_properties)
field_dict.update({})

return field_dict

@staticmethod
def from_dict(src_dict: Dict[str, Any]) -> "FreeFormModel":
d = src_dict.copy()
free_form_model = FreeFormModel()

free_form_model.additional_properties = d
return free_form_model

@property
def additional_keys(self) -> List[str]:
return list(self.additional_properties.keys())

def __getitem__(self, key: str) -> Any:
return self.additional_properties[key]

def __setitem__(self, key: str, value: Any) -> None:
self.additional_properties[key] = value

def __delitem__(self, key: str) -> None:
del self.additional_properties[key]

def __contains__(self, key: str) -> bool:
return key in self.additional_properties
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,25 @@ def to_dict(self) -> Dict[str, Any]:

detail.append(detail_item)

field_dict = {}
field_dict: Dict[str, Any] = {}
field_dict.update({})
if detail is not UNSET:
field_dict["detail"] = detail

return field_dict

@staticmethod
def from_dict(d: Dict[str, Any]) -> "HTTPValidationError":
def from_dict(src_dict: Dict[str, Any]) -> "HTTPValidationError":
d = src_dict.copy()
detail = []
for detail_item_data in d.get("detail", UNSET) or []:
_detail = d.pop("detail", UNSET)
for detail_item_data in _detail or []:
detail_item = ValidationError.from_dict(detail_item_data)

detail.append(detail_item)

return HTTPValidationError(
http_validation_error = HTTPValidationError(
detail=detail,
)

return http_validation_error
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
from typing import Any, Dict, List, Union

import attr

from ..models.model_with_additional_properties_inlined_additional_property import (
ModelWithAdditionalPropertiesInlinedAdditionalProperty,
)
from ..types import UNSET, Unset


@attr.s(auto_attribs=True)
class ModelWithAdditionalPropertiesInlined:
""" """

a_number: Union[Unset, float] = UNSET
additional_properties: Dict[str, ModelWithAdditionalPropertiesInlinedAdditionalProperty] = attr.ib(
init=False, factory=dict
)

def to_dict(self) -> Dict[str, Any]:
a_number = self.a_number

field_dict: Dict[str, Any] = {}
for prop_name, prop in self.additional_properties.items():
field_dict[prop_name] = prop.to_dict()

field_dict.update({})
if a_number is not UNSET:
field_dict["a_number"] = a_number

return field_dict

@staticmethod
def from_dict(src_dict: Dict[str, Any]) -> "ModelWithAdditionalPropertiesInlined":
d = src_dict.copy()
a_number = d.pop("a_number", UNSET)

model_with_additional_properties_inlined = ModelWithAdditionalPropertiesInlined(
a_number=a_number,
)

additional_properties = {}
for prop_name, prop_dict in d.items():
additional_property = ModelWithAdditionalPropertiesInlinedAdditionalProperty.from_dict(prop_dict)

additional_properties[prop_name] = additional_property

model_with_additional_properties_inlined.additional_properties = additional_properties
return model_with_additional_properties_inlined

@property
def additional_keys(self) -> List[str]:
return list(self.additional_properties.keys())

def __getitem__(self, key: str) -> ModelWithAdditionalPropertiesInlinedAdditionalProperty:
return self.additional_properties[key]

def __setitem__(self, key: str, value: ModelWithAdditionalPropertiesInlinedAdditionalProperty) -> None:
self.additional_properties[key] = value

def __delitem__(self, key: str) -> None:
del self.additional_properties[key]

def __contains__(self, key: str) -> bool:
return key in self.additional_properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
from typing import Any, Dict, List, Union

import attr

from ..types import UNSET, Unset


@attr.s(auto_attribs=True)
class ModelWithAdditionalPropertiesInlinedAdditionalProperty:
""" """

extra_props_prop: Union[Unset, str] = UNSET
additional_properties: Dict[str, Any] = attr.ib(init=False, factory=dict)

def to_dict(self) -> Dict[str, Any]:
extra_props_prop = self.extra_props_prop

field_dict: Dict[str, Any] = {}
field_dict.update(self.additional_properties)
field_dict.update({})
if extra_props_prop is not UNSET:
field_dict["extra_props_prop"] = extra_props_prop

return field_dict

@staticmethod
def from_dict(src_dict: Dict[str, Any]) -> "ModelWithAdditionalPropertiesInlinedAdditionalProperty":
d = src_dict.copy()
extra_props_prop = d.pop("extra_props_prop", UNSET)

model_with_additional_properties_inlined_additional_property = (
ModelWithAdditionalPropertiesInlinedAdditionalProperty(
extra_props_prop=extra_props_prop,
)
)

model_with_additional_properties_inlined_additional_property.additional_properties = d
return model_with_additional_properties_inlined_additional_property

@property
def additional_keys(self) -> List[str]:
return list(self.additional_properties.keys())

def __getitem__(self, key: str) -> Any:
return self.additional_properties[key]

def __setitem__(self, key: str, value: Any) -> None:
self.additional_properties[key] = value

def __delitem__(self, key: str) -> None:
del self.additional_properties[key]

def __contains__(self, key: str) -> bool:
return key in self.additional_properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
from typing import Any, Dict, List

import attr

from ..models.an_enum import AnEnum


@attr.s(auto_attribs=True)
class ModelWithAdditionalPropertiesRefed:
""" """

additional_properties: Dict[str, AnEnum] = attr.ib(init=False, factory=dict)

def to_dict(self) -> Dict[str, Any]:

field_dict: Dict[str, Any] = {}
for prop_name, prop in self.additional_properties.items():
field_dict[prop_name] = prop.value

field_dict.update({})

return field_dict

@staticmethod
def from_dict(src_dict: Dict[str, Any]) -> "ModelWithAdditionalPropertiesRefed":
d = src_dict.copy()
model_with_additional_properties_refed = ModelWithAdditionalPropertiesRefed()

additional_properties = {}
for prop_name, prop_dict in d.items():
additional_property = AnEnum(prop_dict)

additional_properties[prop_name] = additional_property

model_with_additional_properties_refed.additional_properties = additional_properties
return model_with_additional_properties_refed

@property
def additional_keys(self) -> List[str]:
return list(self.additional_properties.keys())

def __getitem__(self, key: str) -> AnEnum:
return self.additional_properties[key]

def __setitem__(self, key: str, value: AnEnum) -> None:
self.additional_properties[key] = value

def __delitem__(self, key: str) -> None:
del self.additional_properties[key]

def __contains__(self, key: str) -> bool:
return key in self.additional_properties
Loading