methodaws 0.0.16__tar.gz → 0.0.18__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. {methodaws-0.0.16 → methodaws-0.0.18}/PKG-INFO +1 -1
  2. {methodaws-0.0.16 → methodaws-0.0.18}/pyproject.toml +1 -1
  3. {methodaws-0.0.16 → methodaws-0.0.18}/src/methodaws/core/pydantic_utilities.py +72 -29
  4. methodaws-0.0.18/src/methodaws/core/serialization.py +254 -0
  5. {methodaws-0.0.16 → methodaws-0.0.18}/src/methodaws/resources/credential/credential_info.py +4 -2
  6. {methodaws-0.0.16 → methodaws-0.0.18}/src/methodaws/resources/credential/credential_report.py +5 -3
  7. {methodaws-0.0.16 → methodaws-0.0.18}/src/methodaws/resources/loadbalancer/certificate.py +4 -2
  8. {methodaws-0.0.16 → methodaws-0.0.18}/src/methodaws/resources/loadbalancer/listener.py +4 -2
  9. {methodaws-0.0.16 → methodaws-0.0.18}/src/methodaws/resources/loadbalancer/load_balancer_report.py +10 -8
  10. methodaws-0.0.18/src/methodaws/resources/loadbalancer/load_balancer_v_1.py +33 -0
  11. {methodaws-0.0.16 → methodaws-0.0.18}/src/methodaws/resources/loadbalancer/load_balancer_v_2.py +16 -9
  12. {methodaws-0.0.16 → methodaws-0.0.18}/src/methodaws/resources/loadbalancer/target.py +4 -2
  13. {methodaws-0.0.16 → methodaws-0.0.18}/src/methodaws/resources/loadbalancer/target_group.py +7 -5
  14. methodaws-0.0.18/src/methodaws/resources/s_3/bucket.py +39 -0
  15. {methodaws-0.0.16 → methodaws-0.0.18}/src/methodaws/resources/s_3/encryption_rule.py +7 -3
  16. {methodaws-0.0.16 → methodaws-0.0.18}/src/methodaws/resources/s_3/external_bucket.py +8 -6
  17. {methodaws-0.0.16 → methodaws-0.0.18}/src/methodaws/resources/s_3/external_s_3_report.py +6 -4
  18. {methodaws-0.0.16 → methodaws-0.0.18}/src/methodaws/resources/s_3/s_3_bucket_acl.py +4 -2
  19. {methodaws-0.0.16 → methodaws-0.0.18}/src/methodaws/resources/s_3/s_3_object_details.py +6 -4
  20. {methodaws-0.0.16 → methodaws-0.0.18}/src/methodaws/resources/s_3/s_3_public_access_block_configuration.py +7 -5
  21. {methodaws-0.0.16 → methodaws-0.0.18}/src/methodaws/resources/s_3/s_3_report.py +7 -4
  22. methodaws-0.0.16/src/methodaws/core/serialization.py +0 -170
  23. methodaws-0.0.16/src/methodaws/resources/loadbalancer/load_balancer_v_1.py +0 -28
  24. methodaws-0.0.16/src/methodaws/resources/s_3/bucket.py +0 -32
  25. {methodaws-0.0.16 → methodaws-0.0.18}/README.md +0 -0
  26. {methodaws-0.0.16 → methodaws-0.0.18}/src/methodaws/__init__.py +0 -0
  27. {methodaws-0.0.16 → methodaws-0.0.18}/src/methodaws/core/__init__.py +0 -0
  28. {methodaws-0.0.16 → methodaws-0.0.18}/src/methodaws/core/datetime_utils.py +0 -0
  29. {methodaws-0.0.16 → methodaws-0.0.18}/src/methodaws/py.typed +0 -0
  30. {methodaws-0.0.16 → methodaws-0.0.18}/src/methodaws/resources/__init__.py +0 -0
  31. {methodaws-0.0.16 → methodaws-0.0.18}/src/methodaws/resources/credential/__init__.py +0 -0
  32. {methodaws-0.0.16 → methodaws-0.0.18}/src/methodaws/resources/loadbalancer/__init__.py +0 -0
  33. {methodaws-0.0.16 → methodaws-0.0.18}/src/methodaws/resources/loadbalancer/ip_address_type.py +0 -0
  34. {methodaws-0.0.16 → methodaws-0.0.18}/src/methodaws/resources/loadbalancer/load_balancer_state.py +0 -0
  35. {methodaws-0.0.16 → methodaws-0.0.18}/src/methodaws/resources/loadbalancer/protocol.py +0 -0
  36. {methodaws-0.0.16 → methodaws-0.0.18}/src/methodaws/resources/loadbalancer/target_group_ip_address_type.py +0 -0
  37. {methodaws-0.0.16 → methodaws-0.0.18}/src/methodaws/resources/loadbalancer/target_type.py +0 -0
  38. {methodaws-0.0.16 → methodaws-0.0.18}/src/methodaws/resources/s_3/__init__.py +0 -0
  39. {methodaws-0.0.16 → methodaws-0.0.18}/src/methodaws/resources/s_3/bucket_versioning_status.py +0 -0
  40. {methodaws-0.0.16 → methodaws-0.0.18}/src/methodaws/resources/s_3/s_3_mfa_delete_status.py +0 -0
  41. {methodaws-0.0.16 → methodaws-0.0.18}/src/methodaws/resources/s_3/s_3_server_side_encryption.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: methodaws
3
- Version: 0.0.16
3
+ Version: 0.0.18
4
4
  Summary:
5
5
  Requires-Python: >=3.8,<4.0
6
6
  Classifier: Intended Audience :: Developers
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "methodaws"
3
- version = "v0.0.16"
3
+ version = "v0.0.18"
4
4
  description = ""
5
5
  readme = "README.md"
6
6
  authors = []
@@ -10,6 +10,7 @@ import typing_extensions
10
10
  import pydantic
11
11
 
12
12
  from .datetime_utils import serialize_datetime
13
+ from .serialization import convert_and_respect_annotation_metadata
13
14
 
14
15
  IS_PYDANTIC_V2 = pydantic.VERSION.startswith("2.")
15
16
 
@@ -56,11 +57,12 @@ Model = typing.TypeVar("Model", bound=pydantic.BaseModel)
56
57
 
57
58
 
58
59
  def parse_obj_as(type_: typing.Type[T], object_: typing.Any) -> T:
60
+ dealiased_object = convert_and_respect_annotation_metadata(object_=object_, annotation=type_, direction="read")
59
61
  if IS_PYDANTIC_V2:
60
62
  adapter = pydantic.TypeAdapter(type_) # type: ignore # Pydantic v2
61
- return adapter.validate_python(object_)
63
+ return adapter.validate_python(dealiased_object)
62
64
  else:
63
- return pydantic.parse_obj_as(type_, object_)
65
+ return pydantic.parse_obj_as(type_, dealiased_object)
64
66
 
65
67
 
66
68
  def to_jsonable_with_fallback(
@@ -75,11 +77,16 @@ def to_jsonable_with_fallback(
75
77
 
76
78
 
77
79
  class UniversalBaseModel(pydantic.BaseModel):
78
- class Config:
79
- populate_by_name = True
80
- smart_union = True
81
- allow_population_by_field_name = True
82
- json_encoders = {dt.datetime: serialize_datetime}
80
+ if IS_PYDANTIC_V2:
81
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(
82
+ protected_namespaces=(),
83
+ json_encoders={dt.datetime: serialize_datetime},
84
+ ) # type: ignore # Pydantic v2
85
+ else:
86
+
87
+ class Config:
88
+ smart_union = True
89
+ json_encoders = {dt.datetime: serialize_datetime}
83
90
 
84
91
  def json(self, **kwargs: typing.Any) -> str:
85
92
  kwargs_with_defaults: typing.Any = {
@@ -97,30 +104,66 @@ class UniversalBaseModel(pydantic.BaseModel):
97
104
  Override the default dict method to `exclude_unset` by default. This function patches
98
105
  `exclude_unset` to work include fields within non-None default values.
99
106
  """
100
- _fields_set = self.__fields_set__
101
-
102
- fields = _get_model_fields(self.__class__)
103
- for name, field in fields.items():
104
- if name not in _fields_set:
105
- default = _get_field_default(field)
106
-
107
- # If the default values are non-null act like they've been set
108
- # This effectively allows exclude_unset to work like exclude_none where
109
- # the latter passes through intentionally set none values.
110
- if default != None:
111
- _fields_set.add(name)
112
-
113
- kwargs_with_defaults_exclude_unset: typing.Any = {
114
- "by_alias": True,
115
- "exclude_unset": True,
116
- "include": _fields_set,
117
- **kwargs,
118
- }
119
-
107
+ # Note: the logic here is multi-plexed given the levers exposed in Pydantic V1 vs V2
108
+ # Pydantic V1's .dict can be extremely slow, so we do not want to call it twice.
109
+ #
110
+ # We'd ideally do the same for Pydantic V2, but it shells out to a library to serialize models
111
+ # that we have less control over, and this is less intrusive than custom serializers for now.
120
112
  if IS_PYDANTIC_V2:
121
- return super().model_dump(**kwargs_with_defaults_exclude_unset) # type: ignore # Pydantic v2
113
+ kwargs_with_defaults_exclude_unset: typing.Any = {
114
+ **kwargs,
115
+ "by_alias": True,
116
+ "exclude_unset": True,
117
+ "exclude_none": False,
118
+ }
119
+ kwargs_with_defaults_exclude_none: typing.Any = {
120
+ **kwargs,
121
+ "by_alias": True,
122
+ "exclude_none": True,
123
+ "exclude_unset": False,
124
+ }
125
+ dict_dump = deep_union_pydantic_dicts(
126
+ super().model_dump(**kwargs_with_defaults_exclude_unset), # type: ignore # Pydantic v2
127
+ super().model_dump(**kwargs_with_defaults_exclude_none), # type: ignore # Pydantic v2
128
+ )
129
+
130
+ else:
131
+ _fields_set = self.__fields_set__
132
+
133
+ fields = _get_model_fields(self.__class__)
134
+ for name, field in fields.items():
135
+ if name not in _fields_set:
136
+ default = _get_field_default(field)
137
+
138
+ # If the default values are non-null act like they've been set
139
+ # This effectively allows exclude_unset to work like exclude_none where
140
+ # the latter passes through intentionally set none values.
141
+ if default != None:
142
+ _fields_set.add(name)
143
+
144
+ kwargs_with_defaults_exclude_unset_include_fields: typing.Any = {
145
+ "by_alias": True,
146
+ "exclude_unset": True,
147
+ "include": _fields_set,
148
+ **kwargs,
149
+ }
150
+
151
+ dict_dump = super().dict(**kwargs_with_defaults_exclude_unset_include_fields)
152
+
153
+ return convert_and_respect_annotation_metadata(object_=dict_dump, annotation=self.__class__, direction="write")
154
+
155
+
156
+ def deep_union_pydantic_dicts(
157
+ source: typing.Dict[str, typing.Any], destination: typing.Dict[str, typing.Any]
158
+ ) -> typing.Dict[str, typing.Any]:
159
+ for key, value in source.items():
160
+ if isinstance(value, dict):
161
+ node = destination.setdefault(key, {})
162
+ deep_union_pydantic_dicts(value, node)
122
163
  else:
123
- return super().dict(**kwargs_with_defaults_exclude_unset)
164
+ destination[key] = value
165
+
166
+ return destination
124
167
 
125
168
 
126
169
  if IS_PYDANTIC_V2:
@@ -0,0 +1,254 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import collections
4
+ import inspect
5
+ import typing
6
+
7
+ import typing_extensions
8
+
9
+ import pydantic
10
+
11
+
12
+ class FieldMetadata:
13
+ """
14
+ Metadata class used to annotate fields to provide additional information.
15
+
16
+ Example:
17
+ class MyDict(TypedDict):
18
+ field: typing.Annotated[str, FieldMetadata(alias="field_name")]
19
+
20
+ Will serialize: `{"field": "value"}`
21
+ To: `{"field_name": "value"}`
22
+ """
23
+
24
+ alias: str
25
+
26
+ def __init__(self, *, alias: str) -> None:
27
+ self.alias = alias
28
+
29
+
30
+ def convert_and_respect_annotation_metadata(
31
+ *,
32
+ object_: typing.Any,
33
+ annotation: typing.Any,
34
+ inner_type: typing.Optional[typing.Any] = None,
35
+ direction: typing.Literal["read", "write"],
36
+ ) -> typing.Any:
37
+ """
38
+ Respect the metadata annotations on a field, such as aliasing. This function effectively
39
+ manipulates the dict-form of an object to respect the metadata annotations. This is primarily used for
40
+ TypedDicts, which cannot support aliasing out of the box, and can be extended for additional
41
+ utilities, such as defaults.
42
+
43
+ Parameters
44
+ ----------
45
+ object_ : typing.Any
46
+
47
+ annotation : type
48
+ The type we're looking to apply typing annotations from
49
+
50
+ inner_type : typing.Optional[type]
51
+
52
+ Returns
53
+ -------
54
+ typing.Any
55
+ """
56
+
57
+ if object_ is None:
58
+ return None
59
+ if inner_type is None:
60
+ inner_type = annotation
61
+
62
+ clean_type = _remove_annotations(inner_type)
63
+ # Pydantic models
64
+ if (
65
+ inspect.isclass(clean_type)
66
+ and issubclass(clean_type, pydantic.BaseModel)
67
+ and isinstance(object_, typing.Mapping)
68
+ ):
69
+ return _convert_mapping(object_, clean_type, direction)
70
+ # TypedDicts
71
+ if typing_extensions.is_typeddict(clean_type) and isinstance(object_, typing.Mapping):
72
+ return _convert_mapping(object_, clean_type, direction)
73
+
74
+ # If you're iterating on a string, do not bother to coerce it to a sequence.
75
+ if not isinstance(object_, str):
76
+ if (
77
+ typing_extensions.get_origin(clean_type) == typing.Set
78
+ or typing_extensions.get_origin(clean_type) == set
79
+ or clean_type == typing.Set
80
+ ) and isinstance(object_, typing.Set):
81
+ inner_type = typing_extensions.get_args(clean_type)[0]
82
+ return {
83
+ convert_and_respect_annotation_metadata(
84
+ object_=item,
85
+ annotation=annotation,
86
+ inner_type=inner_type,
87
+ direction=direction,
88
+ )
89
+ for item in object_
90
+ }
91
+ elif (
92
+ (
93
+ typing_extensions.get_origin(clean_type) == typing.List
94
+ or typing_extensions.get_origin(clean_type) == list
95
+ or clean_type == typing.List
96
+ )
97
+ and isinstance(object_, typing.List)
98
+ ) or (
99
+ (
100
+ typing_extensions.get_origin(clean_type) == typing.Sequence
101
+ or typing_extensions.get_origin(clean_type) == collections.abc.Sequence
102
+ or clean_type == typing.Sequence
103
+ )
104
+ and isinstance(object_, typing.Sequence)
105
+ ):
106
+ inner_type = typing_extensions.get_args(clean_type)[0]
107
+ return [
108
+ convert_and_respect_annotation_metadata(
109
+ object_=item,
110
+ annotation=annotation,
111
+ inner_type=inner_type,
112
+ direction=direction,
113
+ )
114
+ for item in object_
115
+ ]
116
+
117
+ if typing_extensions.get_origin(clean_type) == typing.Union:
118
+ # We should be able to ~relatively~ safely try to convert keys against all
119
+ # member types in the union, the edge case here is if one member aliases a field
120
+ # of the same name to a different name from another member
121
+ # Or if another member aliases a field of the same name that another member does not.
122
+ for member in typing_extensions.get_args(clean_type):
123
+ object_ = convert_and_respect_annotation_metadata(
124
+ object_=object_,
125
+ annotation=annotation,
126
+ inner_type=member,
127
+ direction=direction,
128
+ )
129
+ return object_
130
+
131
+ annotated_type = _get_annotation(annotation)
132
+ if annotated_type is None:
133
+ return object_
134
+
135
+ # If the object is not a TypedDict, a Union, or other container (list, set, sequence, etc.)
136
+ # Then we can safely call it on the recursive conversion.
137
+ return object_
138
+
139
+
140
+ def _convert_mapping(
141
+ object_: typing.Mapping[str, object],
142
+ expected_type: typing.Any,
143
+ direction: typing.Literal["read", "write"],
144
+ ) -> typing.Mapping[str, object]:
145
+ converted_object: typing.Dict[str, object] = {}
146
+ annotations = typing_extensions.get_type_hints(expected_type, include_extras=True)
147
+ aliases_to_field_names = _get_alias_to_field_name(annotations)
148
+ for key, value in object_.items():
149
+ if direction == "read" and key in aliases_to_field_names:
150
+ dealiased_key = aliases_to_field_names.get(key)
151
+ if dealiased_key is not None:
152
+ type_ = annotations.get(dealiased_key)
153
+ else:
154
+ type_ = annotations.get(key)
155
+ # Note you can't get the annotation by the field name if you're in read mode, so you must check the aliases map
156
+ #
157
+ # So this is effectively saying if we're in write mode, and we don't have a type, or if we're in read mode and we don't have an alias
158
+ # then we can just pass the value through as is
159
+ if type_ is None:
160
+ converted_object[key] = value
161
+ elif direction == "read" and key not in aliases_to_field_names:
162
+ converted_object[key] = convert_and_respect_annotation_metadata(
163
+ object_=value, annotation=type_, direction=direction
164
+ )
165
+ else:
166
+ converted_object[_alias_key(key, type_, direction, aliases_to_field_names)] = (
167
+ convert_and_respect_annotation_metadata(object_=value, annotation=type_, direction=direction)
168
+ )
169
+ return converted_object
170
+
171
+
172
+ def _get_annotation(type_: typing.Any) -> typing.Optional[typing.Any]:
173
+ maybe_annotated_type = typing_extensions.get_origin(type_)
174
+ if maybe_annotated_type is None:
175
+ return None
176
+
177
+ if maybe_annotated_type == typing_extensions.NotRequired:
178
+ type_ = typing_extensions.get_args(type_)[0]
179
+ maybe_annotated_type = typing_extensions.get_origin(type_)
180
+
181
+ if maybe_annotated_type == typing_extensions.Annotated:
182
+ return type_
183
+
184
+ return None
185
+
186
+
187
+ def _remove_annotations(type_: typing.Any) -> typing.Any:
188
+ maybe_annotated_type = typing_extensions.get_origin(type_)
189
+ if maybe_annotated_type is None:
190
+ return type_
191
+
192
+ if maybe_annotated_type == typing_extensions.NotRequired:
193
+ return _remove_annotations(typing_extensions.get_args(type_)[0])
194
+
195
+ if maybe_annotated_type == typing_extensions.Annotated:
196
+ return _remove_annotations(typing_extensions.get_args(type_)[0])
197
+
198
+ return type_
199
+
200
+
201
+ def get_alias_to_field_mapping(type_: typing.Any) -> typing.Dict[str, str]:
202
+ annotations = typing_extensions.get_type_hints(type_, include_extras=True)
203
+ return _get_alias_to_field_name(annotations)
204
+
205
+
206
+ def get_field_to_alias_mapping(type_: typing.Any) -> typing.Dict[str, str]:
207
+ annotations = typing_extensions.get_type_hints(type_, include_extras=True)
208
+ return _get_field_to_alias_name(annotations)
209
+
210
+
211
+ def _get_alias_to_field_name(
212
+ field_to_hint: typing.Dict[str, typing.Any],
213
+ ) -> typing.Dict[str, str]:
214
+ aliases = {}
215
+ for field, hint in field_to_hint.items():
216
+ maybe_alias = _get_alias_from_type(hint)
217
+ if maybe_alias is not None:
218
+ aliases[maybe_alias] = field
219
+ return aliases
220
+
221
+
222
+ def _get_field_to_alias_name(
223
+ field_to_hint: typing.Dict[str, typing.Any],
224
+ ) -> typing.Dict[str, str]:
225
+ aliases = {}
226
+ for field, hint in field_to_hint.items():
227
+ maybe_alias = _get_alias_from_type(hint)
228
+ if maybe_alias is not None:
229
+ aliases[field] = maybe_alias
230
+ return aliases
231
+
232
+
233
+ def _get_alias_from_type(type_: typing.Any) -> typing.Optional[str]:
234
+ maybe_annotated_type = _get_annotation(type_)
235
+
236
+ if maybe_annotated_type is not None:
237
+ # The actual annotations are 1 onward, the first is the annotated type
238
+ annotations = typing_extensions.get_args(maybe_annotated_type)[1:]
239
+
240
+ for annotation in annotations:
241
+ if isinstance(annotation, FieldMetadata) and annotation.alias is not None:
242
+ return annotation.alias
243
+ return None
244
+
245
+
246
+ def _alias_key(
247
+ key: str,
248
+ type_: typing.Any,
249
+ direction: typing.Literal["read", "write"],
250
+ aliases_to_field_names: typing.Dict[str, str],
251
+ ) -> str:
252
+ if direction == "read":
253
+ return aliases_to_field_names.get(key, key)
254
+ return _get_alias_from_type(type_=type_) or key
@@ -1,16 +1,18 @@
1
1
  # This file was auto-generated by Fern from our API Definition.
2
2
 
3
3
  from ...core.pydantic_utilities import UniversalBaseModel
4
+ import typing_extensions
4
5
  import typing
5
- import pydantic
6
+ from ...core.serialization import FieldMetadata
6
7
  import datetime as dt
7
8
  from ...core.pydantic_utilities import IS_PYDANTIC_V2
9
+ import pydantic
8
10
 
9
11
 
10
12
  class CredentialInfo(UniversalBaseModel):
11
13
  url: str
12
14
  token: str
13
- ca_cert: typing.Optional[str] = pydantic.Field(alias="caCert", default=None)
15
+ ca_cert: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="caCert")] = None
14
16
  expiration: typing.Optional[dt.datetime] = None
15
17
 
16
18
  if IS_PYDANTIC_V2:
@@ -1,15 +1,17 @@
1
1
  # This file was auto-generated by Fern from our API Definition.
2
2
 
3
3
  from ...core.pydantic_utilities import UniversalBaseModel
4
- import pydantic
4
+ import typing_extensions
5
+ from ...core.serialization import FieldMetadata
5
6
  import typing
6
7
  from .credential_info import CredentialInfo
7
8
  from ...core.pydantic_utilities import IS_PYDANTIC_V2
9
+ import pydantic
8
10
 
9
11
 
10
12
  class CredentialReport(UniversalBaseModel):
11
- account_id: str = pydantic.Field(alias="accountId")
12
- cluster_name: str = pydantic.Field(alias="clusterName")
13
+ account_id: typing_extensions.Annotated[str, FieldMetadata(alias="accountId")]
14
+ cluster_name: typing_extensions.Annotated[str, FieldMetadata(alias="clusterName")]
13
15
  credential: typing.Optional[CredentialInfo] = None
14
16
  errors: typing.Optional[typing.List[str]] = None
15
17
 
@@ -1,14 +1,16 @@
1
1
  # This file was auto-generated by Fern from our API Definition.
2
2
 
3
3
  from ...core.pydantic_utilities import UniversalBaseModel
4
- import pydantic
4
+ import typing_extensions
5
+ from ...core.serialization import FieldMetadata
5
6
  from ...core.pydantic_utilities import IS_PYDANTIC_V2
6
7
  import typing
8
+ import pydantic
7
9
 
8
10
 
9
11
  class Certificate(UniversalBaseModel):
10
12
  arn: str
11
- is_default: bool = pydantic.Field(alias="isDefault")
13
+ is_default: typing_extensions.Annotated[bool, FieldMetadata(alias="isDefault")]
12
14
 
13
15
  if IS_PYDANTIC_V2:
14
16
  model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2
@@ -4,8 +4,10 @@ from ...core.pydantic_utilities import UniversalBaseModel
4
4
  import typing
5
5
  from .protocol import Protocol
6
6
  from .certificate import Certificate
7
- import pydantic
7
+ import typing_extensions
8
+ from ...core.serialization import FieldMetadata
8
9
  from ...core.pydantic_utilities import IS_PYDANTIC_V2
10
+ import pydantic
9
11
 
10
12
 
11
13
  class Listener(UniversalBaseModel):
@@ -13,7 +15,7 @@ class Listener(UniversalBaseModel):
13
15
  protocol: typing.Optional[Protocol] = None
14
16
  port: int
15
17
  certificates: typing.Optional[typing.List[Certificate]] = None
16
- load_balancer_arn: typing.Optional[str] = pydantic.Field(alias="loadBalancerArn", default=None)
18
+ load_balancer_arn: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="loadBalancerArn")] = None
17
19
 
18
20
  if IS_PYDANTIC_V2:
19
21
  model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2
@@ -1,21 +1,23 @@
1
1
  # This file was auto-generated by Fern from our API Definition.
2
2
 
3
3
  from ...core.pydantic_utilities import UniversalBaseModel
4
- import pydantic
4
+ import typing_extensions
5
+ from ...core.serialization import FieldMetadata
5
6
  import typing
6
7
  from .load_balancer_v_2 import LoadBalancerV2
7
8
  from .load_balancer_v_1 import LoadBalancerV1
8
9
  from ...core.pydantic_utilities import IS_PYDANTIC_V2
10
+ import pydantic
9
11
 
10
12
 
11
13
  class LoadBalancerReport(UniversalBaseModel):
12
- account_id: str = pydantic.Field(alias="accountId")
13
- v_2_load_balancers: typing.Optional[typing.List[LoadBalancerV2]] = pydantic.Field(
14
- alias="v2LoadBalancers", default=None
15
- )
16
- v_1_load_balancers: typing.Optional[typing.List[LoadBalancerV1]] = pydantic.Field(
17
- alias="v1LoadBalancers", default=None
18
- )
14
+ account_id: typing_extensions.Annotated[str, FieldMetadata(alias="accountId")]
15
+ v_2_load_balancers: typing_extensions.Annotated[
16
+ typing.Optional[typing.List[LoadBalancerV2]], FieldMetadata(alias="v2LoadBalancers")
17
+ ] = None
18
+ v_1_load_balancers: typing_extensions.Annotated[
19
+ typing.Optional[typing.List[LoadBalancerV1]], FieldMetadata(alias="v1LoadBalancers")
20
+ ] = None
19
21
  errors: typing.Optional[typing.List[str]] = None
20
22
 
21
23
  if IS_PYDANTIC_V2:
@@ -0,0 +1,33 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ from ...core.pydantic_utilities import UniversalBaseModel
4
+ import typing_extensions
5
+ import datetime as dt
6
+ from ...core.serialization import FieldMetadata
7
+ import typing
8
+ from .target import Target
9
+ from .listener import Listener
10
+ from ...core.pydantic_utilities import IS_PYDANTIC_V2
11
+ import pydantic
12
+
13
+
14
+ class LoadBalancerV1(UniversalBaseModel):
15
+ name: str
16
+ region: str
17
+ created_time: typing_extensions.Annotated[dt.datetime, FieldMetadata(alias="createdTime")]
18
+ dns_name: typing_extensions.Annotated[str, FieldMetadata(alias="dnsName")]
19
+ security_group_ids: typing_extensions.Annotated[
20
+ typing.Optional[typing.List[str]], FieldMetadata(alias="securityGroupIds")
21
+ ] = None
22
+ vpc_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="vpcId")] = None
23
+ subnet_ids: typing_extensions.Annotated[typing.Optional[typing.List[str]], FieldMetadata(alias="subnetIds")] = None
24
+ hosted_zone_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="hostedZoneId")] = None
25
+ targets: typing.Optional[typing.List[Target]] = None
26
+ listeners: typing.Optional[typing.List[Listener]] = None
27
+
28
+ if IS_PYDANTIC_V2:
29
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2
30
+ else:
31
+
32
+ class Config:
33
+ extra = pydantic.Extra.allow
@@ -1,14 +1,16 @@
1
1
  # This file was auto-generated by Fern from our API Definition.
2
2
 
3
3
  from ...core.pydantic_utilities import UniversalBaseModel
4
+ import typing_extensions
4
5
  import datetime as dt
5
- import pydantic
6
+ from ...core.serialization import FieldMetadata
6
7
  from .ip_address_type import IpAddressType
7
8
  import typing
8
9
  from .load_balancer_state import LoadBalancerState
9
10
  from .listener import Listener
10
11
  from .target_group import TargetGroup
11
12
  from ...core.pydantic_utilities import IS_PYDANTIC_V2
13
+ import pydantic
12
14
 
13
15
 
14
16
  class LoadBalancerV2(UniversalBaseModel):
@@ -19,16 +21,21 @@ class LoadBalancerV2(UniversalBaseModel):
19
21
 
20
22
  arn: str
21
23
  name: str
22
- created_time: dt.datetime = pydantic.Field(alias="createdTime")
23
- dns_name: str = pydantic.Field(alias="dnsName")
24
- ip_address_type: IpAddressType = pydantic.Field(alias="ipAddressType")
25
- security_group_ids: typing.List[str] = pydantic.Field(alias="securityGroupIds")
24
+ region: str
25
+ created_time: typing_extensions.Annotated[dt.datetime, FieldMetadata(alias="createdTime")]
26
+ dns_name: typing_extensions.Annotated[str, FieldMetadata(alias="dnsName")]
27
+ ip_address_type: typing_extensions.Annotated[IpAddressType, FieldMetadata(alias="ipAddressType")]
28
+ security_group_ids: typing_extensions.Annotated[
29
+ typing.Optional[typing.List[str]], FieldMetadata(alias="securityGroupIds")
30
+ ] = None
26
31
  state: typing.Optional[LoadBalancerState] = None
27
- vpc_id: str = pydantic.Field(alias="vpcId")
32
+ vpc_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="vpcId")] = None
28
33
  listeners: typing.Optional[typing.List[Listener]] = None
29
- subnet_ids: typing.List[str] = pydantic.Field(alias="subnetIds")
30
- hosted_zone_id: typing.Optional[str] = pydantic.Field(alias="hostedZoneId", default=None)
31
- target_groups: typing.List[TargetGroup] = pydantic.Field(alias="targetGroups")
34
+ subnet_ids: typing_extensions.Annotated[typing.Optional[typing.List[str]], FieldMetadata(alias="subnetIds")] = None
35
+ hosted_zone_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="hostedZoneId")] = None
36
+ target_groups: typing_extensions.Annotated[
37
+ typing.Optional[typing.List[TargetGroup]], FieldMetadata(alias="targetGroups")
38
+ ] = None
32
39
 
33
40
  if IS_PYDANTIC_V2:
34
41
  model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2
@@ -2,16 +2,18 @@
2
2
 
3
3
  from ...core.pydantic_utilities import UniversalBaseModel
4
4
  from .target_type import TargetType
5
+ import typing_extensions
5
6
  import typing
6
- import pydantic
7
+ from ...core.serialization import FieldMetadata
7
8
  from ...core.pydantic_utilities import IS_PYDANTIC_V2
9
+ import pydantic
8
10
 
9
11
 
10
12
  class Target(UniversalBaseModel):
11
13
  id: str
12
14
  type: TargetType
13
15
  port: int
14
- availability_zone: typing.Optional[str] = pydantic.Field(alias="availabilityZone", default=None)
16
+ availability_zone: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="availabilityZone")] = None
15
17
 
16
18
  if IS_PYDANTIC_V2:
17
19
  model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2
@@ -1,23 +1,25 @@
1
1
  # This file was auto-generated by Fern from our API Definition.
2
2
 
3
3
  from ...core.pydantic_utilities import UniversalBaseModel
4
+ import typing_extensions
4
5
  from .target_group_ip_address_type import TargetGroupIpAddressType
5
- import pydantic
6
+ from ...core.serialization import FieldMetadata
6
7
  import typing
7
8
  from .protocol import Protocol
8
9
  from .target import Target
9
10
  from ...core.pydantic_utilities import IS_PYDANTIC_V2
11
+ import pydantic
10
12
 
11
13
 
12
14
  class TargetGroup(UniversalBaseModel):
13
15
  arn: str
14
16
  name: str
15
- ip_address_type: TargetGroupIpAddressType = pydantic.Field(alias="ipAddressType")
16
- load_balancer_arn: str = pydantic.Field(alias="loadBalancerArn")
17
+ ip_address_type: typing_extensions.Annotated[TargetGroupIpAddressType, FieldMetadata(alias="ipAddressType")]
18
+ load_balancer_arn: typing_extensions.Annotated[str, FieldMetadata(alias="loadBalancerArn")]
17
19
  port: int
18
20
  protocol: typing.Optional[Protocol] = None
19
- vpc_id: str = pydantic.Field(alias="vpcId")
20
- targets: typing.List[Target]
21
+ vpc_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="vpcId")] = None
22
+ targets: typing.Optional[typing.List[Target]] = None
21
23
 
22
24
  if IS_PYDANTIC_V2:
23
25
  model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2
@@ -0,0 +1,39 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ from ...core.pydantic_utilities import UniversalBaseModel
4
+ import typing_extensions
5
+ import datetime as dt
6
+ from ...core.serialization import FieldMetadata
7
+ from .s_3_public_access_block_configuration import S3PublicAccessBlockConfiguration
8
+ import typing
9
+ from .bucket_versioning_status import BucketVersioningStatus
10
+ from .s_3_mfa_delete_status import S3MfaDeleteStatus
11
+ from .encryption_rule import EncryptionRule
12
+ from ...core.pydantic_utilities import IS_PYDANTIC_V2
13
+ import pydantic
14
+
15
+
16
+ class Bucket(UniversalBaseModel):
17
+ name: str
18
+ arn: str
19
+ url: str
20
+ region: str
21
+ creation_date: typing_extensions.Annotated[dt.datetime, FieldMetadata(alias="creationDate")]
22
+ owner_id: typing_extensions.Annotated[str, FieldMetadata(alias="ownerID")]
23
+ owner_name: typing_extensions.Annotated[str, FieldMetadata(alias="ownerName")]
24
+ public_access_config: typing_extensions.Annotated[
25
+ S3PublicAccessBlockConfiguration, FieldMetadata(alias="publicAccessConfig")
26
+ ]
27
+ policy: typing.Optional[str] = None
28
+ bucket_versioning: typing_extensions.Annotated[
29
+ typing.Optional[BucketVersioningStatus], FieldMetadata(alias="bucketVersioning")
30
+ ] = None
31
+ mfa_delete: typing_extensions.Annotated[typing.Optional[S3MfaDeleteStatus], FieldMetadata(alias="mfaDelete")] = None
32
+ encryption_rules: typing_extensions.Annotated[typing.List[EncryptionRule], FieldMetadata(alias="encryptionRules")]
33
+
34
+ if IS_PYDANTIC_V2:
35
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2
36
+ else:
37
+
38
+ class Config:
39
+ extra = pydantic.Extra.allow
@@ -1,15 +1,19 @@
1
1
  # This file was auto-generated by Fern from our API Definition.
2
2
 
3
3
  from ...core.pydantic_utilities import UniversalBaseModel
4
+ import typing_extensions
4
5
  import typing
5
6
  from .s_3_server_side_encryption import S3ServerSideEncryption
6
- import pydantic
7
+ from ...core.serialization import FieldMetadata
7
8
  from ...core.pydantic_utilities import IS_PYDANTIC_V2
9
+ import pydantic
8
10
 
9
11
 
10
12
  class EncryptionRule(UniversalBaseModel):
11
- sse_algorithm: typing.Optional[S3ServerSideEncryption] = pydantic.Field(alias="sseAlgorithm", default=None)
12
- kms_master_key_id: typing.Optional[str] = pydantic.Field(alias="kmsMasterKeyID", default=None)
13
+ sse_algorithm: typing_extensions.Annotated[
14
+ typing.Optional[S3ServerSideEncryption], FieldMetadata(alias="sseAlgorithm")
15
+ ] = None
16
+ kms_master_key_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="kmsMasterKeyID")] = None
13
17
 
14
18
  if IS_PYDANTIC_V2:
15
19
  model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2
@@ -1,22 +1,24 @@
1
1
  # This file was auto-generated by Fern from our API Definition.
2
2
 
3
3
  from ...core.pydantic_utilities import UniversalBaseModel
4
+ import typing_extensions
4
5
  import typing
5
6
  from .s_3_object_details import S3ObjectDetails
6
- import pydantic
7
+ from ...core.serialization import FieldMetadata
7
8
  from .s_3_bucket_acl import S3BucketAcl
8
9
  from ...core.pydantic_utilities import IS_PYDANTIC_V2
10
+ import pydantic
9
11
 
10
12
 
11
13
  class ExternalBucket(UniversalBaseModel):
12
14
  name: str
13
15
  url: str
14
16
  region: str
15
- directory_contents: typing.Optional[typing.List[S3ObjectDetails]] = pydantic.Field(
16
- alias="directoryContents", default=None
17
- )
18
- allow_directory_listing: bool = pydantic.Field(alias="allowDirectoryListing")
19
- allow_anonymous_read: bool = pydantic.Field(alias="allowAnonymousRead")
17
+ directory_contents: typing_extensions.Annotated[
18
+ typing.Optional[typing.List[S3ObjectDetails]], FieldMetadata(alias="directoryContents")
19
+ ] = None
20
+ allow_directory_listing: typing_extensions.Annotated[bool, FieldMetadata(alias="allowDirectoryListing")]
21
+ allow_anonymous_read: typing_extensions.Annotated[bool, FieldMetadata(alias="allowAnonymousRead")]
20
22
  policy: typing.Optional[str] = None
21
23
  acls: typing.Optional[typing.List[S3BucketAcl]] = None
22
24
 
@@ -1,16 +1,18 @@
1
1
  # This file was auto-generated by Fern from our API Definition.
2
2
 
3
3
  from ...core.pydantic_utilities import UniversalBaseModel
4
+ import typing_extensions
4
5
  import typing
5
6
  from .external_bucket import ExternalBucket
6
- import pydantic
7
+ from ...core.serialization import FieldMetadata
7
8
  from ...core.pydantic_utilities import IS_PYDANTIC_V2
9
+ import pydantic
8
10
 
9
11
 
10
12
  class ExternalS3Report(UniversalBaseModel):
11
- external_buckets: typing.Optional[typing.List[ExternalBucket]] = pydantic.Field(
12
- alias="externalBuckets", default=None
13
- )
13
+ external_buckets: typing_extensions.Annotated[
14
+ typing.Optional[typing.List[ExternalBucket]], FieldMetadata(alias="externalBuckets")
15
+ ] = None
14
16
  errors: typing.Optional[typing.List[str]] = None
15
17
 
16
18
  if IS_PYDANTIC_V2:
@@ -1,13 +1,15 @@
1
1
  # This file was auto-generated by Fern from our API Definition.
2
2
 
3
3
  from ...core.pydantic_utilities import UniversalBaseModel
4
- import pydantic
4
+ import typing_extensions
5
+ from ...core.serialization import FieldMetadata
5
6
  from ...core.pydantic_utilities import IS_PYDANTIC_V2
6
7
  import typing
8
+ import pydantic
7
9
 
8
10
 
9
11
  class S3BucketAcl(UniversalBaseModel):
10
- grantee_uri: str = pydantic.Field(alias="granteeURI")
12
+ grantee_uri: typing_extensions.Annotated[str, FieldMetadata(alias="granteeURI")]
11
13
  permission: str
12
14
 
13
15
  if IS_PYDANTIC_V2:
@@ -1,18 +1,20 @@
1
1
  # This file was auto-generated by Fern from our API Definition.
2
2
 
3
3
  from ...core.pydantic_utilities import UniversalBaseModel
4
+ import typing_extensions
4
5
  import typing
5
6
  import datetime as dt
6
- import pydantic
7
+ from ...core.serialization import FieldMetadata
7
8
  from ...core.pydantic_utilities import IS_PYDANTIC_V2
9
+ import pydantic
8
10
 
9
11
 
10
12
  class S3ObjectDetails(UniversalBaseModel):
11
13
  key: str
12
- last_modified: typing.Optional[dt.datetime] = pydantic.Field(alias="lastModified", default=None)
14
+ last_modified: typing_extensions.Annotated[typing.Optional[dt.datetime], FieldMetadata(alias="lastModified")] = None
13
15
  size: typing.Optional[int] = None
14
- owner_id: typing.Optional[str] = pydantic.Field(alias="ownerID", default=None)
15
- owner_name: typing.Optional[str] = pydantic.Field(alias="ownerName", default=None)
16
+ owner_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="ownerID")] = None
17
+ owner_name: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="ownerName")] = None
16
18
 
17
19
  if IS_PYDANTIC_V2:
18
20
  model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2
@@ -1,16 +1,18 @@
1
1
  # This file was auto-generated by Fern from our API Definition.
2
2
 
3
3
  from ...core.pydantic_utilities import UniversalBaseModel
4
- import pydantic
4
+ import typing_extensions
5
+ from ...core.serialization import FieldMetadata
5
6
  from ...core.pydantic_utilities import IS_PYDANTIC_V2
6
7
  import typing
8
+ import pydantic
7
9
 
8
10
 
9
11
  class S3PublicAccessBlockConfiguration(UniversalBaseModel):
10
- block_public_acls: bool = pydantic.Field(alias="blockPublicAcls")
11
- ignore_public_acls: bool = pydantic.Field(alias="ignorePublicAcls")
12
- block_public_policy: bool = pydantic.Field(alias="blockPublicPolicy")
13
- restrict_public_buckets: bool = pydantic.Field(alias="restrictPublicBuckets")
12
+ block_public_acls: typing_extensions.Annotated[bool, FieldMetadata(alias="blockPublicAcls")]
13
+ ignore_public_acls: typing_extensions.Annotated[bool, FieldMetadata(alias="ignorePublicAcls")]
14
+ block_public_policy: typing_extensions.Annotated[bool, FieldMetadata(alias="blockPublicPolicy")]
15
+ restrict_public_buckets: typing_extensions.Annotated[bool, FieldMetadata(alias="restrictPublicBuckets")]
14
16
 
15
17
  if IS_PYDANTIC_V2:
16
18
  model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2
@@ -1,16 +1,19 @@
1
1
  # This file was auto-generated by Fern from our API Definition.
2
2
 
3
3
  from ...core.pydantic_utilities import UniversalBaseModel
4
- import pydantic
4
+ import typing_extensions
5
+ from ...core.serialization import FieldMetadata
5
6
  import typing
6
7
  from .bucket import Bucket
7
8
  from ...core.pydantic_utilities import IS_PYDANTIC_V2
9
+ import pydantic
8
10
 
9
11
 
10
12
  class S3Report(UniversalBaseModel):
11
- account_id: str = pydantic.Field(alias="accountId")
12
- region: str
13
- s_3_buckets: typing.Optional[typing.List[Bucket]] = pydantic.Field(alias="s3Buckets", default=None)
13
+ account_id: typing_extensions.Annotated[str, FieldMetadata(alias="accountId")]
14
+ s_3_buckets: typing_extensions.Annotated[typing.Optional[typing.List[Bucket]], FieldMetadata(alias="s3Buckets")] = (
15
+ None
16
+ )
14
17
  errors: typing.Optional[typing.List[str]] = None
15
18
 
16
19
  if IS_PYDANTIC_V2:
@@ -1,170 +0,0 @@
1
- # This file was auto-generated by Fern from our API Definition.
2
-
3
- import collections
4
- import typing
5
-
6
- import typing_extensions
7
-
8
-
9
- class FieldMetadata:
10
- """
11
- Metadata class used to annotate fields to provide additional information.
12
-
13
- Example:
14
- class MyDict(TypedDict):
15
- field: typing.Annotated[str, FieldMetadata(alias="field_name")]
16
-
17
- Will serialize: `{"field": "value"}`
18
- To: `{"field_name": "value"}`
19
- """
20
-
21
- alias: str
22
-
23
- def __init__(self, *, alias: str) -> None:
24
- self.alias = alias
25
-
26
-
27
- def convert_and_respect_annotation_metadata(
28
- *,
29
- object_: typing.Any,
30
- annotation: typing.Any,
31
- inner_type: typing.Optional[typing.Any] = None,
32
- ) -> typing.Any:
33
- """
34
- Respect the metadata annotations on a field, such as aliasing. This function effectively
35
- manipulates the dict-form of an object to respect the metadata annotations. This is primarily used for
36
- TypedDicts, which cannot support aliasing out of the box, and can be extended for additional
37
- utilities, such as defaults.
38
-
39
- Parameters
40
- ----------
41
- object_ : typing.Any
42
-
43
- annotation : type
44
- The type we're looking to apply typing annotations from
45
-
46
- inner_type : typing.Optional[type]
47
-
48
- Returns
49
- -------
50
- typing.Any
51
- """
52
-
53
- if object_ is None:
54
- return None
55
- if inner_type is None:
56
- inner_type = annotation
57
-
58
- clean_type = _remove_annotations(inner_type)
59
- if typing_extensions.is_typeddict(clean_type) and isinstance(object_, typing.Mapping):
60
- return _convert_typeddict(object_, clean_type)
61
-
62
- if (
63
- # If you're iterating on a string, do not bother to coerce it to a sequence.
64
- (not isinstance(object_, str))
65
- and (
66
- (
67
- (
68
- typing_extensions.get_origin(clean_type) == typing.List
69
- or typing_extensions.get_origin(clean_type) == list
70
- or clean_type == typing.List
71
- )
72
- and isinstance(object_, typing.List)
73
- )
74
- or (
75
- (
76
- typing_extensions.get_origin(clean_type) == typing.Set
77
- or typing_extensions.get_origin(clean_type) == set
78
- or clean_type == typing.Set
79
- )
80
- and isinstance(object_, typing.Set)
81
- )
82
- or (
83
- (
84
- typing_extensions.get_origin(clean_type) == typing.Sequence
85
- or typing_extensions.get_origin(clean_type) == collections.abc.Sequence
86
- or clean_type == typing.Sequence
87
- )
88
- and isinstance(object_, typing.Sequence)
89
- )
90
- )
91
- ):
92
- inner_type = typing_extensions.get_args(clean_type)[0]
93
- return [
94
- convert_and_respect_annotation_metadata(object_=item, annotation=annotation, inner_type=inner_type)
95
- for item in object_
96
- ]
97
-
98
- if typing_extensions.get_origin(clean_type) == typing.Union:
99
- # We should be able to ~relatively~ safely try to convert keys against all
100
- # member types in the union, the edge case here is if one member aliases a field
101
- # of the same name to a different name from another member
102
- # Or if another member aliases a field of the same name that another member does not.
103
- for member in typing_extensions.get_args(clean_type):
104
- object_ = convert_and_respect_annotation_metadata(object_=object_, annotation=annotation, inner_type=member)
105
- return object_
106
-
107
- annotated_type = _get_annotation(annotation)
108
- if annotated_type is None:
109
- return object_
110
-
111
- # If the object is not a TypedDict, a Union, or other container (list, set, sequence, etc.)
112
- # Then we can safely call it on the recursive conversion.
113
- return object_
114
-
115
-
116
- def _convert_typeddict(object_: typing.Mapping[str, object], expected_type: typing.Any) -> typing.Mapping[str, object]:
117
- converted_object: typing.Dict[str, object] = {}
118
- annotations = typing_extensions.get_type_hints(expected_type, include_extras=True)
119
- for key, value in object_.items():
120
- type_ = annotations.get(key)
121
- if type_ is None:
122
- converted_object[key] = value
123
- else:
124
- converted_object[_alias_key(key, type_)] = convert_and_respect_annotation_metadata(
125
- object_=value, annotation=type_
126
- )
127
- return converted_object
128
-
129
-
130
- def _get_annotation(type_: typing.Any) -> typing.Optional[typing.Any]:
131
- maybe_annotated_type = typing_extensions.get_origin(type_)
132
- if maybe_annotated_type is None:
133
- return None
134
-
135
- if maybe_annotated_type == typing_extensions.NotRequired:
136
- type_ = typing_extensions.get_args(type_)[0]
137
- maybe_annotated_type = typing_extensions.get_origin(type_)
138
-
139
- if maybe_annotated_type == typing_extensions.Annotated:
140
- return type_
141
-
142
- return None
143
-
144
-
145
- def _remove_annotations(type_: typing.Any) -> typing.Any:
146
- maybe_annotated_type = typing_extensions.get_origin(type_)
147
- if maybe_annotated_type is None:
148
- return type_
149
-
150
- if maybe_annotated_type == typing_extensions.NotRequired:
151
- return _remove_annotations(typing_extensions.get_args(type_)[0])
152
-
153
- if maybe_annotated_type == typing_extensions.Annotated:
154
- return _remove_annotations(typing_extensions.get_args(type_)[0])
155
-
156
- return type_
157
-
158
-
159
- def _alias_key(key: str, type_: typing.Any) -> str:
160
- maybe_annotated_type = _get_annotation(type_)
161
-
162
- if maybe_annotated_type is not None:
163
- # The actual annotations are 1 onward, the first is the annotated type
164
- annotations = typing_extensions.get_args(maybe_annotated_type)[1:]
165
-
166
- for annotation in annotations:
167
- if isinstance(annotation, FieldMetadata) and annotation.alias is not None:
168
- return annotation.alias
169
-
170
- return key
@@ -1,28 +0,0 @@
1
- # This file was auto-generated by Fern from our API Definition.
2
-
3
- from ...core.pydantic_utilities import UniversalBaseModel
4
- import datetime as dt
5
- import pydantic
6
- import typing
7
- from .target import Target
8
- from .listener import Listener
9
- from ...core.pydantic_utilities import IS_PYDANTIC_V2
10
-
11
-
12
- class LoadBalancerV1(UniversalBaseModel):
13
- name: str
14
- created_time: dt.datetime = pydantic.Field(alias="createdTime")
15
- dns_name: str = pydantic.Field(alias="dnsName")
16
- security_group_ids: typing.List[str] = pydantic.Field(alias="securityGroupIds")
17
- vpc_id: str = pydantic.Field(alias="vpcId")
18
- subnet_ids: typing.List[str] = pydantic.Field(alias="subnetIds")
19
- hosted_zone_id: typing.Optional[str] = pydantic.Field(alias="hostedZoneId", default=None)
20
- targets: typing.List[Target]
21
- listeners: typing.List[Listener]
22
-
23
- if IS_PYDANTIC_V2:
24
- model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2
25
- else:
26
-
27
- class Config:
28
- extra = pydantic.Extra.allow
@@ -1,32 +0,0 @@
1
- # This file was auto-generated by Fern from our API Definition.
2
-
3
- from ...core.pydantic_utilities import UniversalBaseModel
4
- import datetime as dt
5
- import pydantic
6
- from .s_3_public_access_block_configuration import S3PublicAccessBlockConfiguration
7
- import typing
8
- from .bucket_versioning_status import BucketVersioningStatus
9
- from .s_3_mfa_delete_status import S3MfaDeleteStatus
10
- from .encryption_rule import EncryptionRule
11
- from ...core.pydantic_utilities import IS_PYDANTIC_V2
12
-
13
-
14
- class Bucket(UniversalBaseModel):
15
- name: str
16
- arn: str
17
- url: str
18
- creation_date: dt.datetime = pydantic.Field(alias="creationDate")
19
- owner_id: str = pydantic.Field(alias="ownerID")
20
- owner_name: str = pydantic.Field(alias="ownerName")
21
- public_access_config: S3PublicAccessBlockConfiguration = pydantic.Field(alias="publicAccessConfig")
22
- policy: typing.Optional[str] = None
23
- bucket_versioning: typing.Optional[BucketVersioningStatus] = pydantic.Field(alias="bucketVersioning", default=None)
24
- mfa_delete: typing.Optional[S3MfaDeleteStatus] = pydantic.Field(alias="mfaDelete", default=None)
25
- encryption_rules: typing.List[EncryptionRule] = pydantic.Field(alias="encryptionRules")
26
-
27
- if IS_PYDANTIC_V2:
28
- model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2
29
- else:
30
-
31
- class Config:
32
- extra = pydantic.Extra.allow
File without changes