openapi-python-client 0.28.4__py3-none-any.whl → 0.29.1__py3-none-any.whl
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.
- openapi_python_client/__init__.py +26 -17
- openapi_python_client/cli.py +1 -2
- openapi_python_client/config.py +5 -3
- openapi_python_client/parser/bodies.py +14 -23
- openapi_python_client/parser/openapi.py +58 -48
- openapi_python_client/parser/properties/__init__.py +34 -33
- openapi_python_client/parser/properties/any.py +11 -10
- openapi_python_client/parser/properties/boolean.py +13 -13
- openapi_python_client/parser/properties/const.py +11 -10
- openapi_python_client/parser/properties/date.py +15 -14
- openapi_python_client/parser/properties/datetime.py +15 -14
- openapi_python_client/parser/properties/enum_property.py +23 -20
- openapi_python_client/parser/properties/file.py +11 -10
- openapi_python_client/parser/properties/float.py +13 -13
- openapi_python_client/parser/properties/int.py +11 -11
- openapi_python_client/parser/properties/list_property.py +22 -22
- openapi_python_client/parser/properties/literal_enum_property.py +20 -20
- openapi_python_client/parser/properties/merge_properties.py +9 -6
- openapi_python_client/parser/properties/model_property.py +34 -33
- openapi_python_client/parser/properties/none.py +11 -11
- openapi_python_client/parser/properties/protocol.py +42 -32
- openapi_python_client/parser/properties/schemas.py +30 -23
- openapi_python_client/parser/properties/string.py +10 -11
- openapi_python_client/parser/properties/union.py +24 -22
- openapi_python_client/parser/properties/uuid.py +11 -11
- openapi_python_client/parser/responses.py +30 -23
- openapi_python_client/schema/__init__.py +2 -1
- openapi_python_client/schema/data_type.py +2 -2
- openapi_python_client/schema/openapi_schema_pydantic/callback.py +3 -1
- openapi_python_client/schema/openapi_schema_pydantic/components.py +10 -9
- openapi_python_client/schema/openapi_schema_pydantic/contact.py +5 -3
- openapi_python_client/schema/openapi_schema_pydantic/discriminator.py +4 -2
- openapi_python_client/schema/openapi_schema_pydantic/encoding.py +4 -3
- openapi_python_client/schema/openapi_schema_pydantic/example.py +5 -3
- openapi_python_client/schema/openapi_schema_pydantic/external_documentation.py +4 -2
- openapi_python_client/schema/openapi_schema_pydantic/header.py +20 -6
- openapi_python_client/schema/openapi_schema_pydantic/info.py +5 -4
- openapi_python_client/schema/openapi_schema_pydantic/license.py +4 -2
- openapi_python_client/schema/openapi_schema_pydantic/link.py +5 -4
- openapi_python_client/schema/openapi_schema_pydantic/media_type.py +3 -2
- openapi_python_client/schema/openapi_schema_pydantic/oauth_flow.py +6 -4
- openapi_python_client/schema/openapi_schema_pydantic/open_api.py +5 -3
- openapi_python_client/schema/openapi_schema_pydantic/operation.py +6 -5
- openapi_python_client/schema/openapi_schema_pydantic/parameter.py +6 -5
- openapi_python_client/schema/openapi_schema_pydantic/path_item.py +5 -3
- openapi_python_client/schema/openapi_schema_pydantic/paths.py +2 -1
- openapi_python_client/schema/openapi_schema_pydantic/reference.py +3 -1
- openapi_python_client/schema/openapi_schema_pydantic/request_body.py +3 -2
- openapi_python_client/schema/openapi_schema_pydantic/response.py +5 -4
- openapi_python_client/schema/openapi_schema_pydantic/responses.py +2 -1
- openapi_python_client/schema/openapi_schema_pydantic/schema.py +7 -6
- openapi_python_client/schema/openapi_schema_pydantic/security_requirement.py +3 -1
- openapi_python_client/schema/openapi_schema_pydantic/security_scheme.py +8 -7
- openapi_python_client/schema/openapi_schema_pydantic/server.py +4 -3
- openapi_python_client/schema/openapi_schema_pydantic/server_variable.py +5 -3
- openapi_python_client/schema/openapi_schema_pydantic/tag.py +3 -2
- openapi_python_client/schema/openapi_schema_pydantic/xml.py +5 -3
- openapi_python_client/schema/parameter_location.py +7 -22
- openapi_python_client/schema/ref.py +52 -0
- openapi_python_client/schema/untrusted_string.py +56 -0
- openapi_python_client/strings.py +245 -0
- openapi_python_client/templates/README.md.jinja +3 -3
- openapi_python_client/templates/client.py.jinja +5 -5
- openapi_python_client/templates/endpoint_macros.py.jinja +18 -18
- openapi_python_client/templates/endpoint_module.py.jinja +20 -14
- openapi_python_client/templates/helpers.jinja +3 -7
- openapi_python_client/templates/literal_enum.py.jinja +3 -3
- openapi_python_client/templates/model.py.jinja +18 -18
- openapi_python_client/templates/package_init.py.jinja +2 -2
- openapi_python_client/templates/property_templates/const_property.py.jinja +3 -3
- openapi_python_client/templates/property_templates/date_property.py.jinja +2 -2
- openapi_python_client/templates/property_templates/datetime_property.py.jinja +2 -2
- openapi_python_client/templates/property_templates/enum_property.py.jinja +1 -1
- openapi_python_client/templates/property_templates/file_property.py.jinja +1 -1
- openapi_python_client/templates/property_templates/list_property.py.jinja +3 -3
- openapi_python_client/templates/property_templates/literal_enum_property.py.jinja +2 -2
- openapi_python_client/templates/property_templates/model_property.py.jinja +1 -1
- openapi_python_client/templates/property_templates/property_macros.py.jinja +1 -1
- openapi_python_client/templates/property_templates/union_property.py.jinja +9 -9
- openapi_python_client/templates/property_templates/uuid_property.py.jinja +1 -1
- openapi_python_client/templates/pyproject_pdm.toml.jinja +4 -5
- openapi_python_client/templates/pyproject_poetry.toml.jinja +4 -5
- openapi_python_client/templates/pyproject_uv.toml.jinja +5 -6
- openapi_python_client/templates/setup.py.jinja +4 -4
- openapi_python_client/templates/str_enum.py.jinja +2 -2
- {openapi_python_client-0.28.4.dist-info → openapi_python_client-0.29.1.dist-info}/METADATA +6 -9
- openapi_python_client-0.29.1.dist-info/RECORD +115 -0
- {openapi_python_client-0.28.4.dist-info → openapi_python_client-0.29.1.dist-info}/WHEEL +1 -1
- openapi_python_client/utils.py +0 -122
- openapi_python_client-0.28.4.dist-info/RECORD +0 -113
- {openapi_python_client-0.28.4.dist-info → openapi_python_client-0.29.1.dist-info}/entry_points.txt +0 -0
- {openapi_python_client-0.28.4.dist-info → openapi_python_client-0.29.1.dist-info}/licenses/LICENSE +0 -0
|
@@ -18,8 +18,10 @@ from collections.abc import Iterable
|
|
|
18
18
|
|
|
19
19
|
from attrs import evolve
|
|
20
20
|
|
|
21
|
-
from ... import Config,
|
|
21
|
+
from ... import Config, strings
|
|
22
22
|
from ... import schema as oai
|
|
23
|
+
from ...schema.ref import Ref
|
|
24
|
+
from ...schema.untrusted_string import UntrustedString
|
|
23
25
|
from ..errors import ParameterError, ParseError, PropertyError
|
|
24
26
|
from .any import AnyProperty
|
|
25
27
|
from .boolean import BooleanProperty
|
|
@@ -51,11 +53,11 @@ from .uuid import UuidProperty
|
|
|
51
53
|
|
|
52
54
|
|
|
53
55
|
def _string_based_property(
|
|
54
|
-
name:
|
|
56
|
+
name: UntrustedString, required: bool, data: oai.Schema, config: Config
|
|
55
57
|
) -> StringProperty | DateProperty | DateTimeProperty | FileProperty | UuidProperty | PropertyError:
|
|
56
58
|
"""Construct a Property from the type "string" """
|
|
57
59
|
string_format = data.schema_format
|
|
58
|
-
python_name =
|
|
60
|
+
python_name = strings.PythonIdentifier(value=name, prefix=config.field_prefix)
|
|
59
61
|
if string_format == "date-time":
|
|
60
62
|
return DateTimeProperty.build(
|
|
61
63
|
name=name,
|
|
@@ -103,16 +105,16 @@ def _string_based_property(
|
|
|
103
105
|
|
|
104
106
|
|
|
105
107
|
def _property_from_ref(
|
|
106
|
-
name:
|
|
108
|
+
name: UntrustedString,
|
|
107
109
|
required: bool,
|
|
108
110
|
parent: oai.Schema | None,
|
|
109
111
|
data: oai.Reference,
|
|
110
112
|
schemas: Schemas,
|
|
111
113
|
config: Config,
|
|
112
|
-
roots: set[ReferencePath |
|
|
114
|
+
roots: set[ReferencePath | strings.ClassName],
|
|
113
115
|
) -> tuple[Property | PropertyError, Schemas]:
|
|
114
116
|
ref_path = parse_reference_path(data.ref)
|
|
115
|
-
if isinstance(ref_path, ParseError):
|
|
117
|
+
if isinstance(ref_path, ParseError): # pragma: no cover
|
|
116
118
|
return PropertyError(data=data, detail=ref_path.detail), schemas
|
|
117
119
|
existing = schemas.classes_by_reference.get(ref_path)
|
|
118
120
|
if not existing:
|
|
@@ -130,7 +132,7 @@ def _property_from_ref(
|
|
|
130
132
|
existing,
|
|
131
133
|
required=required,
|
|
132
134
|
name=name,
|
|
133
|
-
python_name=
|
|
135
|
+
python_name=strings.PythonIdentifier(value=name, prefix=config.field_prefix),
|
|
134
136
|
default=default, # type: ignore # mypy can't tell that default comes from the same class...
|
|
135
137
|
)
|
|
136
138
|
|
|
@@ -139,18 +141,17 @@ def _property_from_ref(
|
|
|
139
141
|
|
|
140
142
|
|
|
141
143
|
def property_from_data( # noqa: PLR0911, PLR0912
|
|
142
|
-
name:
|
|
144
|
+
name: UntrustedString,
|
|
143
145
|
required: bool,
|
|
144
146
|
data: oai.Reference | oai.Schema,
|
|
145
147
|
schemas: Schemas,
|
|
146
148
|
parent_name: str,
|
|
147
149
|
config: Config,
|
|
148
150
|
process_properties: bool = True,
|
|
149
|
-
roots: set[ReferencePath |
|
|
151
|
+
roots: set[ReferencePath | strings.ClassName] | None = None,
|
|
150
152
|
) -> tuple[Property | PropertyError, Schemas]:
|
|
151
153
|
"""Generate a Property from the OpenAPI dictionary representation of it"""
|
|
152
154
|
roots = roots or set()
|
|
153
|
-
name = utils.remove_string_escapes(name)
|
|
154
155
|
if isinstance(data, oai.Reference):
|
|
155
156
|
return _property_from_ref(
|
|
156
157
|
name=name,
|
|
@@ -190,7 +191,7 @@ def property_from_data( # noqa: PLR0911, PLR0912
|
|
|
190
191
|
name=name,
|
|
191
192
|
required=required,
|
|
192
193
|
default=data.default,
|
|
193
|
-
python_name=
|
|
194
|
+
python_name=strings.PythonIdentifier(value=name, prefix=config.field_prefix),
|
|
194
195
|
description=data.description,
|
|
195
196
|
example=data.example,
|
|
196
197
|
),
|
|
@@ -230,7 +231,7 @@ def property_from_data( # noqa: PLR0911, PLR0912
|
|
|
230
231
|
required=required,
|
|
231
232
|
default=data.default,
|
|
232
233
|
const=data.const,
|
|
233
|
-
python_name=
|
|
234
|
+
python_name=strings.PythonIdentifier(value=name, prefix=config.field_prefix),
|
|
234
235
|
description=data.description,
|
|
235
236
|
),
|
|
236
237
|
schemas,
|
|
@@ -246,7 +247,7 @@ def property_from_data( # noqa: PLR0911, PLR0912
|
|
|
246
247
|
name=name,
|
|
247
248
|
default=data.default,
|
|
248
249
|
required=required,
|
|
249
|
-
python_name=
|
|
250
|
+
python_name=strings.PythonIdentifier(value=name, prefix=config.field_prefix),
|
|
250
251
|
description=data.description,
|
|
251
252
|
example=data.example,
|
|
252
253
|
),
|
|
@@ -258,7 +259,7 @@ def property_from_data( # noqa: PLR0911, PLR0912
|
|
|
258
259
|
name=name,
|
|
259
260
|
default=data.default,
|
|
260
261
|
required=required,
|
|
261
|
-
python_name=
|
|
262
|
+
python_name=strings.PythonIdentifier(value=name, prefix=config.field_prefix),
|
|
262
263
|
description=data.description,
|
|
263
264
|
example=data.example,
|
|
264
265
|
),
|
|
@@ -270,7 +271,7 @@ def property_from_data( # noqa: PLR0911, PLR0912
|
|
|
270
271
|
name=name,
|
|
271
272
|
required=required,
|
|
272
273
|
default=None,
|
|
273
|
-
python_name=
|
|
274
|
+
python_name=strings.PythonIdentifier(value=name, prefix=config.field_prefix),
|
|
274
275
|
description=data.description,
|
|
275
276
|
example=data.example,
|
|
276
277
|
),
|
|
@@ -303,7 +304,7 @@ def property_from_data( # noqa: PLR0911, PLR0912
|
|
|
303
304
|
name=name,
|
|
304
305
|
required=required,
|
|
305
306
|
default=data.default,
|
|
306
|
-
python_name=
|
|
307
|
+
python_name=strings.PythonIdentifier(value=name, prefix=config.field_prefix),
|
|
307
308
|
description=data.description,
|
|
308
309
|
example=data.example,
|
|
309
310
|
),
|
|
@@ -313,11 +314,11 @@ def property_from_data( # noqa: PLR0911, PLR0912
|
|
|
313
314
|
|
|
314
315
|
def _create_schemas(
|
|
315
316
|
*,
|
|
316
|
-
components: dict[
|
|
317
|
+
components: dict[UntrustedString, oai.Reference | oai.Schema],
|
|
317
318
|
schemas: Schemas,
|
|
318
319
|
config: Config,
|
|
319
320
|
) -> Schemas:
|
|
320
|
-
to_process: Iterable[tuple[
|
|
321
|
+
to_process: Iterable[tuple[UntrustedString, oai.Reference | oai.Schema]] = components.items()
|
|
321
322
|
still_making_progress = True
|
|
322
323
|
errors: list[PropertyError] = []
|
|
323
324
|
|
|
@@ -325,12 +326,12 @@ def _create_schemas(
|
|
|
325
326
|
while still_making_progress:
|
|
326
327
|
still_making_progress = False
|
|
327
328
|
errors = []
|
|
328
|
-
next_round: list[tuple[
|
|
329
|
+
next_round: list[tuple[UntrustedString, oai.Reference | oai.Schema]] = []
|
|
329
330
|
# Only accumulate errors from the last round, since we might fix some along the way
|
|
330
331
|
for name, data in to_process:
|
|
331
332
|
schema_data: oai.Reference | oai.Schema | None = data
|
|
332
|
-
ref_path = parse_reference_path(f"#/components/schemas/{name}")
|
|
333
|
-
if isinstance(ref_path, ParseError):
|
|
333
|
+
ref_path = parse_reference_path(Ref(f"#/components/schemas/{name.get_untrusted_value()}"))
|
|
334
|
+
if isinstance(ref_path, ParseError): # pragma: no cover
|
|
334
335
|
schemas.errors.append(PropertyError(detail=ref_path.detail, data=data))
|
|
335
336
|
continue
|
|
336
337
|
if isinstance(data, oai.Reference):
|
|
@@ -361,13 +362,13 @@ def _create_schemas(
|
|
|
361
362
|
return schemas
|
|
362
363
|
|
|
363
364
|
|
|
364
|
-
def _propogate_removal(*, root: ReferencePath |
|
|
365
|
-
if isinstance(root,
|
|
365
|
+
def _propogate_removal(*, root: ReferencePath | strings.ClassName, schemas: Schemas, error: PropertyError) -> None:
|
|
366
|
+
if isinstance(root, strings.ClassName):
|
|
366
367
|
schemas.classes_by_name.pop(root, None)
|
|
367
368
|
return
|
|
368
369
|
if root in schemas.classes_by_reference:
|
|
369
370
|
error.detail = error.detail or ""
|
|
370
|
-
error.detail += f"\n{root}"
|
|
371
|
+
error.detail += f"\n{root.get_untrusted_value()}"
|
|
371
372
|
del schemas.classes_by_reference[root]
|
|
372
373
|
for child in schemas.dependencies.get(root, set()):
|
|
373
374
|
_propogate_removal(root=child, schemas=schemas, error=error)
|
|
@@ -399,10 +400,10 @@ def _process_models(*, schemas: Schemas, config: Config) -> Schemas:
|
|
|
399
400
|
for model_prop in to_process:
|
|
400
401
|
schemas_or_err = process_model(model_prop, schemas=schemas, config=config)
|
|
401
402
|
if isinstance(schemas_or_err, PropertyError):
|
|
402
|
-
schemas_or_err.header = f"\nUnable to process schema {model_prop.name}:"
|
|
403
|
+
schemas_or_err.header = f"\nUnable to process schema {model_prop.name.get_untrusted_value()}:"
|
|
403
404
|
if isinstance(schemas_or_err.data, oai.Reference) and schemas_or_err.data.ref.endswith(
|
|
404
405
|
f"/{model_prop.class_info.name}"
|
|
405
|
-
):
|
|
406
|
+
): # pragma: no cover
|
|
406
407
|
schemas_or_err.detail = schemas_or_err.detail or ""
|
|
407
408
|
schemas_or_err.detail += "\n\nRecursive allOf reference found"
|
|
408
409
|
final_model_errors.append((model_prop, schemas_or_err))
|
|
@@ -421,7 +422,7 @@ def _process_models(*, schemas: Schemas, config: Config) -> Schemas:
|
|
|
421
422
|
|
|
422
423
|
def build_schemas(
|
|
423
424
|
*,
|
|
424
|
-
components: dict[
|
|
425
|
+
components: dict[UntrustedString, oai.Reference | oai.Schema],
|
|
425
426
|
schemas: Schemas,
|
|
426
427
|
config: Config,
|
|
427
428
|
) -> Schemas:
|
|
@@ -433,12 +434,12 @@ def build_schemas(
|
|
|
433
434
|
|
|
434
435
|
def build_parameters(
|
|
435
436
|
*,
|
|
436
|
-
components: dict[
|
|
437
|
+
components: dict[UntrustedString, oai.Reference | oai.Parameter],
|
|
437
438
|
parameters: Parameters,
|
|
438
439
|
config: Config,
|
|
439
440
|
) -> Parameters:
|
|
440
441
|
"""Get a list of Parameters from an OpenAPI dict"""
|
|
441
|
-
to_process: Iterable[tuple[
|
|
442
|
+
to_process: Iterable[tuple[UntrustedString, oai.Reference | oai.Parameter]] = []
|
|
442
443
|
if components is not None:
|
|
443
444
|
to_process = components.items()
|
|
444
445
|
still_making_progress = True
|
|
@@ -451,17 +452,17 @@ def build_parameters(
|
|
|
451
452
|
next_round = []
|
|
452
453
|
# Only accumulate errors from the last round, since we might fix some along the way
|
|
453
454
|
for name, data in to_process:
|
|
454
|
-
if isinstance(data, oai.Reference):
|
|
455
|
+
if isinstance(data, oai.Reference): # pragma: no cover
|
|
455
456
|
parameters.errors.append(ParameterError(data=data, detail="Reference parameters are not supported."))
|
|
456
457
|
continue
|
|
457
|
-
ref_path = parse_reference_path(f"#/components/parameters/{name}")
|
|
458
|
-
if isinstance(ref_path, ParseError):
|
|
458
|
+
ref_path = parse_reference_path(Ref(f"#/components/parameters/{name.get_untrusted_value()}"))
|
|
459
|
+
if isinstance(ref_path, ParseError): # pragma: no cover
|
|
459
460
|
parameters.errors.append(ParameterError(detail=ref_path.detail, data=data))
|
|
460
461
|
continue
|
|
461
462
|
parameters_or_err = update_parameters_with_data(
|
|
462
463
|
ref_path=ref_path, data=data, parameters=parameters, config=config
|
|
463
464
|
)
|
|
464
|
-
if isinstance(parameters_or_err, ParameterError):
|
|
465
|
+
if isinstance(parameters_or_err, ParameterError): # pragma: no cover
|
|
465
466
|
next_round.append((name, data))
|
|
466
467
|
errors.append(parameters_or_err)
|
|
467
468
|
continue
|
|
@@ -2,10 +2,11 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
from typing import Any, ClassVar
|
|
4
4
|
|
|
5
|
-
from attr import define
|
|
5
|
+
from attr import define, field
|
|
6
6
|
|
|
7
|
-
from ...
|
|
8
|
-
from
|
|
7
|
+
from ...schema.untrusted_string import UntrustedString
|
|
8
|
+
from ...strings import PythonCode, PythonIdentifier
|
|
9
|
+
from .protocol import PropertyProtocol, Value, convert_example
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
@define
|
|
@@ -15,12 +16,12 @@ class AnyProperty(PropertyProtocol):
|
|
|
15
16
|
@classmethod
|
|
16
17
|
def build(
|
|
17
18
|
cls,
|
|
18
|
-
name:
|
|
19
|
+
name: UntrustedString,
|
|
19
20
|
required: bool,
|
|
20
21
|
default: Any,
|
|
21
22
|
python_name: PythonIdentifier,
|
|
22
|
-
description:
|
|
23
|
-
example:
|
|
23
|
+
description: UntrustedString | None,
|
|
24
|
+
example: Any,
|
|
24
25
|
) -> AnyProperty:
|
|
25
26
|
return cls(
|
|
26
27
|
name=name,
|
|
@@ -39,13 +40,13 @@ class AnyProperty(PropertyProtocol):
|
|
|
39
40
|
return value
|
|
40
41
|
if isinstance(value, str):
|
|
41
42
|
return StringProperty.convert_value(value)
|
|
42
|
-
return Value(python_code=str(value), raw_value=value)
|
|
43
|
+
return Value(python_code=PythonCode(str(value)), raw_value=value)
|
|
43
44
|
|
|
44
|
-
name:
|
|
45
|
+
name: UntrustedString
|
|
45
46
|
required: bool
|
|
46
47
|
default: Value | None
|
|
47
48
|
python_name: PythonIdentifier
|
|
48
|
-
description:
|
|
49
|
-
example:
|
|
49
|
+
description: UntrustedString | None
|
|
50
|
+
example: UntrustedString | None = field(converter=convert_example)
|
|
50
51
|
_type_string: ClassVar[str] = "Any"
|
|
51
52
|
_json_type_string: ClassVar[str] = "Any"
|
|
@@ -2,24 +2,24 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
from typing import Any, ClassVar
|
|
4
4
|
|
|
5
|
-
from attr import define
|
|
5
|
+
from attr import define, field
|
|
6
6
|
|
|
7
7
|
from ... import schema as oai
|
|
8
|
-
from ...
|
|
8
|
+
from ...strings import PythonCode, PythonIdentifier
|
|
9
9
|
from ..errors import PropertyError
|
|
10
|
-
from .protocol import PropertyProtocol, Value
|
|
10
|
+
from .protocol import PropertyProtocol, Value, convert_example
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
@define
|
|
14
14
|
class BooleanProperty(PropertyProtocol):
|
|
15
15
|
"""Property for bool"""
|
|
16
16
|
|
|
17
|
-
name:
|
|
17
|
+
name: oai.UntrustedString
|
|
18
18
|
required: bool
|
|
19
19
|
default: Value | None
|
|
20
20
|
python_name: PythonIdentifier
|
|
21
|
-
description:
|
|
22
|
-
example:
|
|
21
|
+
description: oai.UntrustedString | None
|
|
22
|
+
example: oai.UntrustedString | None = field(converter=convert_example)
|
|
23
23
|
|
|
24
24
|
_type_string: ClassVar[str] = "bool"
|
|
25
25
|
_json_type_string: ClassVar[str] = "bool"
|
|
@@ -34,12 +34,12 @@ class BooleanProperty(PropertyProtocol):
|
|
|
34
34
|
@classmethod
|
|
35
35
|
def build(
|
|
36
36
|
cls,
|
|
37
|
-
name:
|
|
37
|
+
name: oai.UntrustedString,
|
|
38
38
|
required: bool,
|
|
39
39
|
default: Any,
|
|
40
40
|
python_name: PythonIdentifier,
|
|
41
|
-
description:
|
|
42
|
-
example:
|
|
41
|
+
description: oai.UntrustedString | None,
|
|
42
|
+
example: Any,
|
|
43
43
|
) -> BooleanProperty | PropertyError:
|
|
44
44
|
checked_default = cls.convert_value(default)
|
|
45
45
|
if isinstance(checked_default, PropertyError):
|
|
@@ -54,14 +54,14 @@ class BooleanProperty(PropertyProtocol):
|
|
|
54
54
|
)
|
|
55
55
|
|
|
56
56
|
@classmethod
|
|
57
|
-
def convert_value(cls, value: Any) -> Value |
|
|
57
|
+
def convert_value(cls, value: Any) -> Value | PropertyError | None:
|
|
58
58
|
if isinstance(value, Value) or value is None:
|
|
59
59
|
return value
|
|
60
60
|
if isinstance(value, str):
|
|
61
61
|
if value.lower() == "true":
|
|
62
|
-
return Value(python_code="True", raw_value=value)
|
|
62
|
+
return Value(python_code=PythonCode("True"), raw_value=value)
|
|
63
63
|
elif value.lower() == "false":
|
|
64
|
-
return Value(python_code="False", raw_value=value)
|
|
64
|
+
return Value(python_code=PythonCode("False"), raw_value=value)
|
|
65
65
|
if isinstance(value, bool):
|
|
66
|
-
return Value(python_code=str(value), raw_value=value)
|
|
66
|
+
return Value(python_code=PythonCode(str(value)), raw_value=value)
|
|
67
67
|
return PropertyError(f"Invalid boolean value: {value}")
|
|
@@ -4,7 +4,8 @@ from typing import Any, ClassVar, overload
|
|
|
4
4
|
|
|
5
5
|
from attr import define
|
|
6
6
|
|
|
7
|
-
from ...
|
|
7
|
+
from ... import schema as oai
|
|
8
|
+
from ...strings import PythonCode, PythonIdentifier
|
|
8
9
|
from ..errors import PropertyError
|
|
9
10
|
from .protocol import PropertyProtocol, Value
|
|
10
11
|
from .string import StringProperty
|
|
@@ -14,12 +15,12 @@ from .string import StringProperty
|
|
|
14
15
|
class ConstProperty(PropertyProtocol):
|
|
15
16
|
"""A property representing a const value"""
|
|
16
17
|
|
|
17
|
-
name:
|
|
18
|
+
name: oai.UntrustedString
|
|
18
19
|
required: bool
|
|
19
20
|
value: Value
|
|
20
21
|
default: Value | None
|
|
21
22
|
python_name: PythonIdentifier
|
|
22
|
-
description:
|
|
23
|
+
description: oai.UntrustedString | None
|
|
23
24
|
example: None
|
|
24
25
|
template: ClassVar[str] = "const_property.py.jinja"
|
|
25
26
|
|
|
@@ -29,10 +30,10 @@ class ConstProperty(PropertyProtocol):
|
|
|
29
30
|
*,
|
|
30
31
|
const: str | int | float | bool,
|
|
31
32
|
default: Any,
|
|
32
|
-
name:
|
|
33
|
+
name: oai.UntrustedString,
|
|
33
34
|
python_name: PythonIdentifier,
|
|
34
35
|
required: bool,
|
|
35
|
-
description:
|
|
36
|
+
description: oai.UntrustedString | None,
|
|
36
37
|
) -> ConstProperty | PropertyError:
|
|
37
38
|
"""
|
|
38
39
|
Create a `ConstProperty` the right way.
|
|
@@ -62,7 +63,7 @@ class ConstProperty(PropertyProtocol):
|
|
|
62
63
|
prop.default = converted_default
|
|
63
64
|
return prop
|
|
64
65
|
|
|
65
|
-
def convert_value(self, value: Any) -> Value |
|
|
66
|
+
def convert_value(self, value: Any) -> Value | PropertyError | None:
|
|
66
67
|
value = self._convert_value(value)
|
|
67
68
|
if value is None:
|
|
68
69
|
return value
|
|
@@ -87,16 +88,16 @@ class ConstProperty(PropertyProtocol):
|
|
|
87
88
|
return value
|
|
88
89
|
if isinstance(value, str):
|
|
89
90
|
return StringProperty.convert_value(value)
|
|
90
|
-
return Value(python_code=str(value), raw_value=value)
|
|
91
|
+
return Value(python_code=PythonCode(str(value)), raw_value=value)
|
|
91
92
|
|
|
92
93
|
def get_type_string(
|
|
93
94
|
self,
|
|
94
95
|
no_optional: bool = False,
|
|
95
96
|
json: bool = False,
|
|
96
|
-
) ->
|
|
97
|
-
lit = f"Literal[{self.value.python_code}]"
|
|
97
|
+
) -> PythonCode:
|
|
98
|
+
lit = PythonCode(f"Literal[{self.value.python_code.as_unembedded_code()}]")
|
|
98
99
|
if not no_optional and not self.required:
|
|
99
|
-
return f"{lit} | Unset"
|
|
100
|
+
return PythonCode(f"{lit.as_unembedded_code()} | Unset")
|
|
100
101
|
return lit
|
|
101
102
|
|
|
102
103
|
def get_imports(self, *, prefix: str) -> set[str]:
|
|
@@ -1,25 +1,26 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
import datetime
|
|
3
4
|
from typing import Any, ClassVar
|
|
4
5
|
|
|
5
|
-
from attr import define
|
|
6
|
-
from dateutil.parser import isoparse
|
|
6
|
+
from attr import define, field
|
|
7
7
|
|
|
8
|
-
from ...
|
|
8
|
+
from ... import schema as oai
|
|
9
|
+
from ...strings import PythonCode, PythonIdentifier
|
|
9
10
|
from ..errors import PropertyError
|
|
10
|
-
from .protocol import PropertyProtocol, Value
|
|
11
|
+
from .protocol import PropertyProtocol, Value, convert_example
|
|
11
12
|
|
|
12
13
|
|
|
13
14
|
@define
|
|
14
15
|
class DateProperty(PropertyProtocol):
|
|
15
16
|
"""A property of type datetime.date"""
|
|
16
17
|
|
|
17
|
-
name:
|
|
18
|
+
name: oai.UntrustedString
|
|
18
19
|
required: bool
|
|
19
20
|
default: Value | None
|
|
20
21
|
python_name: PythonIdentifier
|
|
21
|
-
description:
|
|
22
|
-
example:
|
|
22
|
+
description: oai.UntrustedString | None
|
|
23
|
+
example: oai.UntrustedString | None = field(converter=convert_example)
|
|
23
24
|
|
|
24
25
|
_type_string: ClassVar[str] = "datetime.date"
|
|
25
26
|
_json_type_string: ClassVar[str] = "str"
|
|
@@ -28,12 +29,12 @@ class DateProperty(PropertyProtocol):
|
|
|
28
29
|
@classmethod
|
|
29
30
|
def build(
|
|
30
31
|
cls,
|
|
31
|
-
name:
|
|
32
|
+
name: oai.UntrustedString,
|
|
32
33
|
required: bool,
|
|
33
34
|
default: Any,
|
|
34
35
|
python_name: PythonIdentifier,
|
|
35
|
-
description:
|
|
36
|
-
example:
|
|
36
|
+
description: oai.UntrustedString | None,
|
|
37
|
+
example: Any,
|
|
37
38
|
) -> DateProperty | PropertyError:
|
|
38
39
|
checked_default = cls.convert_value(default)
|
|
39
40
|
if isinstance(checked_default, PropertyError):
|
|
@@ -49,15 +50,15 @@ class DateProperty(PropertyProtocol):
|
|
|
49
50
|
)
|
|
50
51
|
|
|
51
52
|
@classmethod
|
|
52
|
-
def convert_value(cls, value: Any) -> Value |
|
|
53
|
+
def convert_value(cls, value: Any) -> Value | PropertyError | None:
|
|
53
54
|
if isinstance(value, Value) or value is None:
|
|
54
55
|
return value
|
|
55
56
|
if isinstance(value, str):
|
|
56
57
|
try:
|
|
57
|
-
|
|
58
|
+
datetime.date.fromisoformat(value) # make sure it's a valid value
|
|
58
59
|
except ValueError as e:
|
|
59
60
|
return PropertyError(f"Invalid date: {e}")
|
|
60
|
-
return Value(python_code=f"
|
|
61
|
+
return Value(python_code=PythonCode(f"datetime.date.fromisoformat({value!r})"), raw_value=value)
|
|
61
62
|
return PropertyError(f"Cannot convert {value} to a date")
|
|
62
63
|
|
|
63
64
|
def get_imports(self, *, prefix: str) -> set[str]:
|
|
@@ -69,5 +70,5 @@ class DateProperty(PropertyProtocol):
|
|
|
69
70
|
back to the root of the generated client.
|
|
70
71
|
"""
|
|
71
72
|
imports = super().get_imports(prefix=prefix)
|
|
72
|
-
imports.update({"import datetime", "from typing import cast"
|
|
73
|
+
imports.update({"import datetime", "from typing import cast"})
|
|
73
74
|
return imports
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
import datetime
|
|
3
4
|
from typing import Any, ClassVar
|
|
4
5
|
|
|
5
|
-
from attr import define
|
|
6
|
-
from dateutil.parser import isoparse
|
|
6
|
+
from attr import define, field
|
|
7
7
|
|
|
8
|
-
from ...
|
|
8
|
+
from ... import schema as oai
|
|
9
|
+
from ...strings import PythonCode, PythonIdentifier
|
|
9
10
|
from ..errors import PropertyError
|
|
10
|
-
from .protocol import PropertyProtocol, Value
|
|
11
|
+
from .protocol import PropertyProtocol, Value, convert_example
|
|
11
12
|
|
|
12
13
|
|
|
13
14
|
@define
|
|
@@ -16,12 +17,12 @@ class DateTimeProperty(PropertyProtocol):
|
|
|
16
17
|
A property of type datetime.datetime
|
|
17
18
|
"""
|
|
18
19
|
|
|
19
|
-
name:
|
|
20
|
+
name: oai.UntrustedString
|
|
20
21
|
required: bool
|
|
21
22
|
default: Value | None
|
|
22
23
|
python_name: PythonIdentifier
|
|
23
|
-
description:
|
|
24
|
-
example:
|
|
24
|
+
description: oai.UntrustedString | None
|
|
25
|
+
example: oai.UntrustedString | None = field(converter=convert_example)
|
|
25
26
|
|
|
26
27
|
_type_string: ClassVar[str] = "datetime.datetime"
|
|
27
28
|
_json_type_string: ClassVar[str] = "str"
|
|
@@ -30,12 +31,12 @@ class DateTimeProperty(PropertyProtocol):
|
|
|
30
31
|
@classmethod
|
|
31
32
|
def build(
|
|
32
33
|
cls,
|
|
33
|
-
name:
|
|
34
|
+
name: oai.UntrustedString,
|
|
34
35
|
required: bool,
|
|
35
36
|
default: Any,
|
|
36
37
|
python_name: PythonIdentifier,
|
|
37
|
-
description:
|
|
38
|
-
example:
|
|
38
|
+
description: oai.UntrustedString | None,
|
|
39
|
+
example: Any,
|
|
39
40
|
) -> DateTimeProperty | PropertyError:
|
|
40
41
|
checked_default = cls.convert_value(default)
|
|
41
42
|
if isinstance(checked_default, PropertyError):
|
|
@@ -51,15 +52,15 @@ class DateTimeProperty(PropertyProtocol):
|
|
|
51
52
|
)
|
|
52
53
|
|
|
53
54
|
@classmethod
|
|
54
|
-
def convert_value(cls, value: Any) -> Value |
|
|
55
|
+
def convert_value(cls, value: Any) -> Value | PropertyError | None:
|
|
55
56
|
if value is None or isinstance(value, Value):
|
|
56
57
|
return value
|
|
57
58
|
if isinstance(value, str):
|
|
58
59
|
try:
|
|
59
|
-
|
|
60
|
+
datetime.datetime.fromisoformat(value) # make sure it's a valid value
|
|
60
61
|
except ValueError as e:
|
|
61
62
|
return PropertyError(f"Invalid datetime: {e}")
|
|
62
|
-
return Value(python_code=f"
|
|
63
|
+
return Value(python_code=PythonCode(f"datetime.datetime.fromisoformat({value!r})"), raw_value=value)
|
|
63
64
|
return PropertyError(f"Cannot convert {value} to a datetime")
|
|
64
65
|
|
|
65
66
|
def get_imports(self, *, prefix: str) -> set[str]:
|
|
@@ -71,5 +72,5 @@ class DateTimeProperty(PropertyProtocol):
|
|
|
71
72
|
back to the root of the generated client.
|
|
72
73
|
"""
|
|
73
74
|
imports = super().get_imports(prefix=prefix)
|
|
74
|
-
imports.update({"import datetime", "from typing import cast"
|
|
75
|
+
imports.update({"import datetime", "from typing import cast"})
|
|
75
76
|
return imports
|