@typespec/http-client-python 0.31.1 → 0.32.0
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.
- package/dist/emitter/emitter.d.ts.map +1 -1
- package/dist/emitter/emitter.js +10 -167
- package/dist/emitter/emitter.js.map +1 -1
- package/dist/emitter/node-runner.browser.d.ts +12 -0
- package/dist/emitter/node-runner.browser.d.ts.map +1 -0
- package/dist/emitter/node-runner.browser.js +16 -0
- package/dist/emitter/node-runner.browser.js.map +1 -0
- package/dist/emitter/node-runner.d.ts +12 -0
- package/dist/emitter/node-runner.d.ts.map +1 -0
- package/dist/emitter/node-runner.js +180 -0
- package/dist/emitter/node-runner.js.map +1 -0
- package/dist/emitter/pyodide-loader.browser.d.ts +12 -0
- package/dist/emitter/pyodide-loader.browser.d.ts.map +1 -0
- package/dist/emitter/pyodide-loader.browser.js +33 -0
- package/dist/emitter/pyodide-loader.browser.js.map +1 -0
- package/dist/emitter/pyodide-loader.d.ts +3 -0
- package/dist/emitter/pyodide-loader.d.ts.map +1 -0
- package/dist/emitter/pyodide-loader.js +6 -0
- package/dist/emitter/pyodide-loader.js.map +1 -0
- package/dist/emitter/types.d.ts.map +1 -1
- package/dist/emitter/types.js +7 -0
- package/dist/emitter/types.js.map +1 -1
- package/emitter/src/emitter.ts +9 -188
- package/emitter/src/node-runner.browser.ts +33 -0
- package/emitter/src/node-runner.ts +220 -0
- package/emitter/src/pyodide-loader.browser.ts +49 -0
- package/emitter/src/pyodide-loader.ts +6 -0
- package/emitter/src/types.ts +7 -0
- package/emitter/temp/tsconfig.tsbuildinfo +1 -1
- package/eng/scripts/setup/__pycache__/package_manager.cpython-311.pyc +0 -0
- package/eng/scripts/setup/__pycache__/venvtools.cpython-311.pyc +0 -0
- package/generator/build/lib/pygen/codegen/models/primitive_types.py +15 -1
- package/generator/build/lib/pygen/codegen/models/utils.py +13 -3
- package/generator/build/lib/pygen/codegen/serializers/builder_serializer.py +9 -2
- package/generator/build/lib/pygen/codegen/templates/model_base.py.jinja2 +34 -1
- package/generator/build/lib/pygen/codegen/templates/serialization.py.jinja2 +109 -0
- package/generator/component-detection-pip-report.json +2 -2
- package/generator/dist/pygen-0.1.0-py3-none-any.whl +0 -0
- package/generator/pygen/codegen/models/primitive_types.py +15 -1
- package/generator/pygen/codegen/models/utils.py +13 -3
- package/generator/pygen/codegen/serializers/builder_serializer.py +9 -2
- package/generator/pygen/codegen/templates/model_base.py.jinja2 +34 -1
- package/generator/pygen/codegen/templates/serialization.py.jinja2 +109 -0
- package/package.json +12 -8
|
Binary file
|
|
Binary file
|
|
@@ -522,8 +522,22 @@ class DateType(PrimitiveType):
|
|
|
522
522
|
|
|
523
523
|
|
|
524
524
|
class DurationType(PrimitiveType):
|
|
525
|
+
def __init__(self, yaml_data: dict[str, Any], code_model: "CodeModel") -> None:
|
|
526
|
+
super().__init__(yaml_data=yaml_data, code_model=code_model)
|
|
527
|
+
# ``seconds`` and ``milliseconds`` encodings serialize a timedelta to a numeric
|
|
528
|
+
# wire value. ``encode`` is set to a combined format token (e.g.
|
|
529
|
+
# ``duration-seconds-int``) so that serialization/deserialization can convert
|
|
530
|
+
# between ``datetime.timedelta`` and the numeric wire type. ISO8601 (the default)
|
|
531
|
+
# leaves ``encode`` unset and keeps the legacy ISO 8601 string behavior.
|
|
532
|
+
self.encode: Optional[str] = None
|
|
533
|
+
encode = yaml_data.get("encode")
|
|
534
|
+
if encode in ("seconds", "milliseconds"):
|
|
535
|
+
wire_type = yaml_data.get("wireType") or {}
|
|
536
|
+
wire = "int" if wire_type.get("type") == "integer" else "float"
|
|
537
|
+
self.encode = f"duration-{encode}-{wire}"
|
|
538
|
+
|
|
525
539
|
def serialization_type(self, **kwargs: Any) -> str:
|
|
526
|
-
return "duration"
|
|
540
|
+
return self.encode or "duration"
|
|
527
541
|
|
|
528
542
|
def docstring_type(self, **kwargs: Any) -> str:
|
|
529
543
|
return "~" + self.type_annotation()
|
|
@@ -11,10 +11,20 @@ T = TypeVar("T")
|
|
|
11
11
|
OrderedSet = dict[T, None]
|
|
12
12
|
|
|
13
13
|
|
|
14
|
+
CODE_BLOCK_MARKER = ".. code-block::"
|
|
15
|
+
|
|
16
|
+
|
|
14
17
|
def add_to_description(description: str, entry: str) -> str:
|
|
15
|
-
if description:
|
|
16
|
-
return
|
|
17
|
-
|
|
18
|
+
if not description:
|
|
19
|
+
return entry
|
|
20
|
+
# When the description contains a code block, the entry (e.g. "Required.") must be
|
|
21
|
+
# inserted into the prose *before* the code block. Appending it after the code block
|
|
22
|
+
# (e.g. "]. Required.") leaves it dangling at the end of the rendered block and breaks
|
|
23
|
+
# Sphinx rendering.
|
|
24
|
+
if CODE_BLOCK_MARKER in description:
|
|
25
|
+
prose, _, code_block = description.partition(CODE_BLOCK_MARKER)
|
|
26
|
+
return f"{prose.rstrip()} {entry}\n\n{CODE_BLOCK_MARKER}{code_block}"
|
|
27
|
+
return f"{description} {entry}"
|
|
18
28
|
|
|
19
29
|
|
|
20
30
|
def add_to_pylint_disable(curr_str: str, entry: str) -> str:
|
|
@@ -931,7 +931,8 @@ class _OperationSerializer(_BuilderBaseSerializer[OperationType]):
|
|
|
931
931
|
if builder.parameters.has_body and builder.parameters.body_parameter.flattened:
|
|
932
932
|
# serialize flattened body before passing to request builder as well
|
|
933
933
|
retval.extend(_serialize_flattened_body(builder.parameters.body_parameter))
|
|
934
|
-
if is_json_model_type(builder.parameters):
|
|
934
|
+
if is_json_model_type(builder.parameters) and not is_paging:
|
|
935
|
+
# For paging, we put the json model body outside `prepare_request`
|
|
935
936
|
retval.extend(_serialize_json_model_body(builder.parameters.body_parameter, builder.parameters.parameters))
|
|
936
937
|
if builder.has_form_data_body:
|
|
937
938
|
retval.extend(self._create_body_parameter(builder))
|
|
@@ -1369,7 +1370,13 @@ class _PagingOperationSerializer(_OperationSerializer[PagingOperationType]):
|
|
|
1369
1370
|
return retval
|
|
1370
1371
|
|
|
1371
1372
|
def _prepare_request_callback(self, builder: PagingOperationType) -> list[str]:
|
|
1372
|
-
retval =
|
|
1373
|
+
retval: list[str] = []
|
|
1374
|
+
# The json model body must be constructed before `_initialize_overloads`
|
|
1375
|
+
# serializes it into the request content, and outside `prepare_request` so
|
|
1376
|
+
# the closure doesn't treat `body` as an unbound local.
|
|
1377
|
+
if is_json_model_type(builder.parameters):
|
|
1378
|
+
retval.extend(_serialize_json_model_body(builder.parameters.body_parameter, builder.parameters.parameters))
|
|
1379
|
+
retval.extend(self._initialize_overloads(builder))
|
|
1373
1380
|
if builder.has_continuation_token:
|
|
1374
1381
|
retval.append(f"def prepare_request({builder.next_variable_name}=None):")
|
|
1375
1382
|
retval.extend([f" {line}" for line in self.call_request_builder(builder, is_paging=True)])
|
|
@@ -112,6 +112,29 @@ def _serialize_bytes(o, format: typing.Optional[str] = None) -> str:
|
|
|
112
112
|
return encoded
|
|
113
113
|
|
|
114
114
|
|
|
115
|
+
def _serialize_duration(td: timedelta, format: typing.Optional[str] = None):
|
|
116
|
+
"""Serialize a timedelta to its wire representation.
|
|
117
|
+
|
|
118
|
+
For the ``seconds``/``milliseconds`` encodings the value is converted to a
|
|
119
|
+
numeric value, otherwise it falls back to an ISO 8601 duration string.
|
|
120
|
+
|
|
121
|
+
:param timedelta td: The timedelta to serialize.
|
|
122
|
+
:param str format: The duration encoding format.
|
|
123
|
+
:rtype: int or float or str
|
|
124
|
+
:return: serialized duration
|
|
125
|
+
"""
|
|
126
|
+
seconds = td.total_seconds()
|
|
127
|
+
if format == "duration-seconds-int":
|
|
128
|
+
return int(seconds)
|
|
129
|
+
if format == "duration-seconds-float":
|
|
130
|
+
return seconds
|
|
131
|
+
if format == "duration-milliseconds-int":
|
|
132
|
+
return int(seconds * 1000)
|
|
133
|
+
if format == "duration-milliseconds-float":
|
|
134
|
+
return seconds * 1000
|
|
135
|
+
return _timedelta_as_isostr(td)
|
|
136
|
+
|
|
137
|
+
|
|
115
138
|
def _serialize_datetime(o, format: typing.Optional[str] = None):
|
|
116
139
|
if hasattr(o, "year") and hasattr(o, "hour"):
|
|
117
140
|
if format == "rfc7231":
|
|
@@ -307,6 +330,12 @@ def _deserialize_duration(attr):
|
|
|
307
330
|
return isodate.parse_duration(attr)
|
|
308
331
|
|
|
309
332
|
|
|
333
|
+
def _deserialize_duration_numeric(attr, unit):
|
|
334
|
+
if isinstance(attr, timedelta):
|
|
335
|
+
return attr
|
|
336
|
+
return timedelta(**{unit: float(attr)})
|
|
337
|
+
|
|
338
|
+
|
|
310
339
|
def _deserialize_decimal(attr):
|
|
311
340
|
if isinstance(attr, decimal.Decimal):
|
|
312
341
|
return attr
|
|
@@ -336,6 +365,10 @@ _DESERIALIZE_MAPPING_WITHFORMAT = {
|
|
|
336
365
|
"unix-timestamp": _deserialize_datetime_unix_timestamp,
|
|
337
366
|
"base64": _deserialize_bytes,
|
|
338
367
|
"base64url": _deserialize_bytes_base64,
|
|
368
|
+
"duration-seconds-int": functools.partial(_deserialize_duration_numeric, unit="seconds"),
|
|
369
|
+
"duration-seconds-float": functools.partial(_deserialize_duration_numeric, unit="seconds"),
|
|
370
|
+
"duration-milliseconds-int": functools.partial(_deserialize_duration_numeric, unit="milliseconds"),
|
|
371
|
+
"duration-milliseconds-float": functools.partial(_deserialize_duration_numeric, unit="milliseconds"),
|
|
339
372
|
}
|
|
340
373
|
|
|
341
374
|
|
|
@@ -576,7 +609,7 @@ def _serialize(o, format: typing.Optional[str] = None): # pylint: disable=too-m
|
|
|
576
609
|
pass
|
|
577
610
|
# Last, try datetime.timedelta
|
|
578
611
|
try:
|
|
579
|
-
return
|
|
612
|
+
return _serialize_duration(o, format)
|
|
580
613
|
except AttributeError:
|
|
581
614
|
# This will be raised when it hits value.total_seconds in the method above
|
|
582
615
|
pass
|
|
@@ -516,6 +516,10 @@ class Serializer: # pylint: disable=too-many-public-methods
|
|
|
516
516
|
"rfc-1123": Serializer.serialize_rfc,
|
|
517
517
|
"unix-time": Serializer.serialize_unix,
|
|
518
518
|
"duration": Serializer.serialize_duration,
|
|
519
|
+
"duration-seconds-int": Serializer.serialize_duration_seconds_int,
|
|
520
|
+
"duration-seconds-float": Serializer.serialize_duration_seconds_float,
|
|
521
|
+
"duration-milliseconds-int": Serializer.serialize_duration_milliseconds_int,
|
|
522
|
+
"duration-milliseconds-float": Serializer.serialize_duration_milliseconds_float,
|
|
519
523
|
"date": Serializer.serialize_date,
|
|
520
524
|
"time": Serializer.serialize_time,
|
|
521
525
|
"decimal": Serializer.serialize_decimal,
|
|
@@ -1105,6 +1109,61 @@ class Serializer: # pylint: disable=too-many-public-methods
|
|
|
1105
1109
|
attr = isodate.parse_duration(attr)
|
|
1106
1110
|
return isodate.duration_isoformat(attr)
|
|
1107
1111
|
|
|
1112
|
+
@staticmethod
|
|
1113
|
+
def _serialize_duration_numeric(attr, scale, as_int):
|
|
1114
|
+
"""Serialize a TimeDelta into a numeric value scaled to the wire unit.
|
|
1115
|
+
|
|
1116
|
+
:param TimeDelta attr: Object to be serialized.
|
|
1117
|
+
:param int scale: Multiplier applied to total seconds (1 for seconds, 1000 for milliseconds).
|
|
1118
|
+
:param bool as_int: Whether to truncate the result to an int.
|
|
1119
|
+
:rtype: int or float
|
|
1120
|
+
:return: serialized duration
|
|
1121
|
+
"""
|
|
1122
|
+
if isinstance(attr, str):
|
|
1123
|
+
attr = isodate.parse_duration(attr)
|
|
1124
|
+
value = attr.total_seconds() * scale if isinstance(attr, datetime.timedelta) else attr
|
|
1125
|
+
return int(value) if as_int else float(value)
|
|
1126
|
+
|
|
1127
|
+
@staticmethod
|
|
1128
|
+
def serialize_duration_seconds_int(attr, **kwargs): # pylint: disable=unused-argument
|
|
1129
|
+
"""Serialize TimeDelta object into an integer number of seconds.
|
|
1130
|
+
|
|
1131
|
+
:param TimeDelta attr: Object to be serialized.
|
|
1132
|
+
:rtype: int
|
|
1133
|
+
:return: serialized duration
|
|
1134
|
+
"""
|
|
1135
|
+
return Serializer._serialize_duration_numeric(attr, 1, True)
|
|
1136
|
+
|
|
1137
|
+
@staticmethod
|
|
1138
|
+
def serialize_duration_seconds_float(attr, **kwargs): # pylint: disable=unused-argument
|
|
1139
|
+
"""Serialize TimeDelta object into a floating point number of seconds.
|
|
1140
|
+
|
|
1141
|
+
:param TimeDelta attr: Object to be serialized.
|
|
1142
|
+
:rtype: float
|
|
1143
|
+
:return: serialized duration
|
|
1144
|
+
"""
|
|
1145
|
+
return Serializer._serialize_duration_numeric(attr, 1, False)
|
|
1146
|
+
|
|
1147
|
+
@staticmethod
|
|
1148
|
+
def serialize_duration_milliseconds_int(attr, **kwargs): # pylint: disable=unused-argument
|
|
1149
|
+
"""Serialize TimeDelta object into an integer number of milliseconds.
|
|
1150
|
+
|
|
1151
|
+
:param TimeDelta attr: Object to be serialized.
|
|
1152
|
+
:rtype: int
|
|
1153
|
+
:return: serialized duration
|
|
1154
|
+
"""
|
|
1155
|
+
return Serializer._serialize_duration_numeric(attr, 1000, True)
|
|
1156
|
+
|
|
1157
|
+
@staticmethod
|
|
1158
|
+
def serialize_duration_milliseconds_float(attr, **kwargs): # pylint: disable=unused-argument
|
|
1159
|
+
"""Serialize TimeDelta object into a floating point number of milliseconds.
|
|
1160
|
+
|
|
1161
|
+
:param TimeDelta attr: Object to be serialized.
|
|
1162
|
+
:rtype: float
|
|
1163
|
+
:return: serialized duration
|
|
1164
|
+
"""
|
|
1165
|
+
return Serializer._serialize_duration_numeric(attr, 1000, False)
|
|
1166
|
+
|
|
1108
1167
|
@staticmethod
|
|
1109
1168
|
def serialize_rfc(attr, **kwargs): # pylint: disable=unused-argument
|
|
1110
1169
|
"""Serialize Datetime object into RFC-1123 formatted string.
|
|
@@ -1377,6 +1436,10 @@ class Deserializer:
|
|
|
1377
1436
|
"rfc-1123": Deserializer.deserialize_rfc,
|
|
1378
1437
|
"unix-time": Deserializer.deserialize_unix,
|
|
1379
1438
|
"duration": Deserializer.deserialize_duration,
|
|
1439
|
+
"duration-seconds-int": Deserializer.deserialize_duration_seconds,
|
|
1440
|
+
"duration-seconds-float": Deserializer.deserialize_duration_seconds,
|
|
1441
|
+
"duration-milliseconds-int": Deserializer.deserialize_duration_milliseconds,
|
|
1442
|
+
"duration-milliseconds-float": Deserializer.deserialize_duration_milliseconds,
|
|
1380
1443
|
"date": Deserializer.deserialize_date,
|
|
1381
1444
|
"time": Deserializer.deserialize_time,
|
|
1382
1445
|
"decimal": Deserializer.deserialize_decimal,
|
|
@@ -1389,6 +1452,10 @@ class Deserializer:
|
|
|
1389
1452
|
}
|
|
1390
1453
|
self.deserialize_expected_types = {
|
|
1391
1454
|
"duration": (isodate.Duration, datetime.timedelta),
|
|
1455
|
+
"duration-seconds-int": (isodate.Duration, datetime.timedelta),
|
|
1456
|
+
"duration-seconds-float": (isodate.Duration, datetime.timedelta),
|
|
1457
|
+
"duration-milliseconds-int": (isodate.Duration, datetime.timedelta),
|
|
1458
|
+
"duration-milliseconds-float": (isodate.Duration, datetime.timedelta),
|
|
1392
1459
|
"iso-8601": (datetime.datetime),
|
|
1393
1460
|
}
|
|
1394
1461
|
self.dependencies: dict[str, type] = dict(classes) if classes else {}
|
|
@@ -1950,6 +2017,48 @@ class Deserializer:
|
|
|
1950
2017
|
raise DeserializationError(msg) from err
|
|
1951
2018
|
return duration
|
|
1952
2019
|
|
|
2020
|
+
@staticmethod
|
|
2021
|
+
def _deserialize_duration_numeric(attr, unit):
|
|
2022
|
+
"""Deserialize a numeric duration value into a TimeDelta object.
|
|
2023
|
+
|
|
2024
|
+
:param float attr: response value to be deserialized.
|
|
2025
|
+
:param str unit: The wire unit, used as the ``timedelta`` keyword
|
|
2026
|
+
(``"seconds"`` or ``"milliseconds"``).
|
|
2027
|
+
:return: Deserialized duration
|
|
2028
|
+
:rtype: TimeDelta
|
|
2029
|
+
:raises DeserializationError: if value is invalid.
|
|
2030
|
+
"""
|
|
2031
|
+
if isinstance(attr, ET.Element):
|
|
2032
|
+
attr = attr.text
|
|
2033
|
+
try:
|
|
2034
|
+
duration = datetime.timedelta(**{unit: float(attr)}) # type: ignore
|
|
2035
|
+
except (ValueError, OverflowError, TypeError) as err:
|
|
2036
|
+
msg = "Cannot deserialize duration object."
|
|
2037
|
+
raise DeserializationError(msg) from err
|
|
2038
|
+
return duration
|
|
2039
|
+
|
|
2040
|
+
@staticmethod
|
|
2041
|
+
def deserialize_duration_seconds(attr):
|
|
2042
|
+
"""Deserialize a numeric number of seconds into a TimeDelta object.
|
|
2043
|
+
|
|
2044
|
+
:param float attr: response value to be deserialized.
|
|
2045
|
+
:return: Deserialized duration
|
|
2046
|
+
:rtype: TimeDelta
|
|
2047
|
+
:raises DeserializationError: if value is invalid.
|
|
2048
|
+
"""
|
|
2049
|
+
return Deserializer._deserialize_duration_numeric(attr, "seconds")
|
|
2050
|
+
|
|
2051
|
+
@staticmethod
|
|
2052
|
+
def deserialize_duration_milliseconds(attr):
|
|
2053
|
+
"""Deserialize a numeric number of milliseconds into a TimeDelta object.
|
|
2054
|
+
|
|
2055
|
+
:param float attr: response value to be deserialized.
|
|
2056
|
+
:return: Deserialized duration
|
|
2057
|
+
:rtype: TimeDelta
|
|
2058
|
+
:raises DeserializationError: if value is invalid.
|
|
2059
|
+
"""
|
|
2060
|
+
return Deserializer._deserialize_duration_numeric(attr, "milliseconds")
|
|
2061
|
+
|
|
1953
2062
|
@staticmethod
|
|
1954
2063
|
def deserialize_date(attr):
|
|
1955
2064
|
"""Deserialize ISO-8601 formatted string into Date object.
|
|
@@ -125,9 +125,9 @@
|
|
|
125
125
|
"implementation_version": "3.11.15",
|
|
126
126
|
"os_name": "posix",
|
|
127
127
|
"platform_machine": "x86_64",
|
|
128
|
-
"platform_release": "6.17.0-
|
|
128
|
+
"platform_release": "6.17.0-1018-azure",
|
|
129
129
|
"platform_system": "Linux",
|
|
130
|
-
"platform_version": "#
|
|
130
|
+
"platform_version": "#18~24.04.1-Ubuntu SMP Thu May 28 16:39:11 UTC 2026",
|
|
131
131
|
"python_full_version": "3.11.15",
|
|
132
132
|
"platform_python_implementation": "CPython",
|
|
133
133
|
"python_version": "3.11",
|
|
Binary file
|
|
@@ -522,8 +522,22 @@ class DateType(PrimitiveType):
|
|
|
522
522
|
|
|
523
523
|
|
|
524
524
|
class DurationType(PrimitiveType):
|
|
525
|
+
def __init__(self, yaml_data: dict[str, Any], code_model: "CodeModel") -> None:
|
|
526
|
+
super().__init__(yaml_data=yaml_data, code_model=code_model)
|
|
527
|
+
# ``seconds`` and ``milliseconds`` encodings serialize a timedelta to a numeric
|
|
528
|
+
# wire value. ``encode`` is set to a combined format token (e.g.
|
|
529
|
+
# ``duration-seconds-int``) so that serialization/deserialization can convert
|
|
530
|
+
# between ``datetime.timedelta`` and the numeric wire type. ISO8601 (the default)
|
|
531
|
+
# leaves ``encode`` unset and keeps the legacy ISO 8601 string behavior.
|
|
532
|
+
self.encode: Optional[str] = None
|
|
533
|
+
encode = yaml_data.get("encode")
|
|
534
|
+
if encode in ("seconds", "milliseconds"):
|
|
535
|
+
wire_type = yaml_data.get("wireType") or {}
|
|
536
|
+
wire = "int" if wire_type.get("type") == "integer" else "float"
|
|
537
|
+
self.encode = f"duration-{encode}-{wire}"
|
|
538
|
+
|
|
525
539
|
def serialization_type(self, **kwargs: Any) -> str:
|
|
526
|
-
return "duration"
|
|
540
|
+
return self.encode or "duration"
|
|
527
541
|
|
|
528
542
|
def docstring_type(self, **kwargs: Any) -> str:
|
|
529
543
|
return "~" + self.type_annotation()
|
|
@@ -11,10 +11,20 @@ T = TypeVar("T")
|
|
|
11
11
|
OrderedSet = dict[T, None]
|
|
12
12
|
|
|
13
13
|
|
|
14
|
+
CODE_BLOCK_MARKER = ".. code-block::"
|
|
15
|
+
|
|
16
|
+
|
|
14
17
|
def add_to_description(description: str, entry: str) -> str:
|
|
15
|
-
if description:
|
|
16
|
-
return
|
|
17
|
-
|
|
18
|
+
if not description:
|
|
19
|
+
return entry
|
|
20
|
+
# When the description contains a code block, the entry (e.g. "Required.") must be
|
|
21
|
+
# inserted into the prose *before* the code block. Appending it after the code block
|
|
22
|
+
# (e.g. "]. Required.") leaves it dangling at the end of the rendered block and breaks
|
|
23
|
+
# Sphinx rendering.
|
|
24
|
+
if CODE_BLOCK_MARKER in description:
|
|
25
|
+
prose, _, code_block = description.partition(CODE_BLOCK_MARKER)
|
|
26
|
+
return f"{prose.rstrip()} {entry}\n\n{CODE_BLOCK_MARKER}{code_block}"
|
|
27
|
+
return f"{description} {entry}"
|
|
18
28
|
|
|
19
29
|
|
|
20
30
|
def add_to_pylint_disable(curr_str: str, entry: str) -> str:
|
|
@@ -931,7 +931,8 @@ class _OperationSerializer(_BuilderBaseSerializer[OperationType]):
|
|
|
931
931
|
if builder.parameters.has_body and builder.parameters.body_parameter.flattened:
|
|
932
932
|
# serialize flattened body before passing to request builder as well
|
|
933
933
|
retval.extend(_serialize_flattened_body(builder.parameters.body_parameter))
|
|
934
|
-
if is_json_model_type(builder.parameters):
|
|
934
|
+
if is_json_model_type(builder.parameters) and not is_paging:
|
|
935
|
+
# For paging, we put the json model body outside `prepare_request`
|
|
935
936
|
retval.extend(_serialize_json_model_body(builder.parameters.body_parameter, builder.parameters.parameters))
|
|
936
937
|
if builder.has_form_data_body:
|
|
937
938
|
retval.extend(self._create_body_parameter(builder))
|
|
@@ -1369,7 +1370,13 @@ class _PagingOperationSerializer(_OperationSerializer[PagingOperationType]):
|
|
|
1369
1370
|
return retval
|
|
1370
1371
|
|
|
1371
1372
|
def _prepare_request_callback(self, builder: PagingOperationType) -> list[str]:
|
|
1372
|
-
retval =
|
|
1373
|
+
retval: list[str] = []
|
|
1374
|
+
# The json model body must be constructed before `_initialize_overloads`
|
|
1375
|
+
# serializes it into the request content, and outside `prepare_request` so
|
|
1376
|
+
# the closure doesn't treat `body` as an unbound local.
|
|
1377
|
+
if is_json_model_type(builder.parameters):
|
|
1378
|
+
retval.extend(_serialize_json_model_body(builder.parameters.body_parameter, builder.parameters.parameters))
|
|
1379
|
+
retval.extend(self._initialize_overloads(builder))
|
|
1373
1380
|
if builder.has_continuation_token:
|
|
1374
1381
|
retval.append(f"def prepare_request({builder.next_variable_name}=None):")
|
|
1375
1382
|
retval.extend([f" {line}" for line in self.call_request_builder(builder, is_paging=True)])
|
|
@@ -112,6 +112,29 @@ def _serialize_bytes(o, format: typing.Optional[str] = None) -> str:
|
|
|
112
112
|
return encoded
|
|
113
113
|
|
|
114
114
|
|
|
115
|
+
def _serialize_duration(td: timedelta, format: typing.Optional[str] = None):
|
|
116
|
+
"""Serialize a timedelta to its wire representation.
|
|
117
|
+
|
|
118
|
+
For the ``seconds``/``milliseconds`` encodings the value is converted to a
|
|
119
|
+
numeric value, otherwise it falls back to an ISO 8601 duration string.
|
|
120
|
+
|
|
121
|
+
:param timedelta td: The timedelta to serialize.
|
|
122
|
+
:param str format: The duration encoding format.
|
|
123
|
+
:rtype: int or float or str
|
|
124
|
+
:return: serialized duration
|
|
125
|
+
"""
|
|
126
|
+
seconds = td.total_seconds()
|
|
127
|
+
if format == "duration-seconds-int":
|
|
128
|
+
return int(seconds)
|
|
129
|
+
if format == "duration-seconds-float":
|
|
130
|
+
return seconds
|
|
131
|
+
if format == "duration-milliseconds-int":
|
|
132
|
+
return int(seconds * 1000)
|
|
133
|
+
if format == "duration-milliseconds-float":
|
|
134
|
+
return seconds * 1000
|
|
135
|
+
return _timedelta_as_isostr(td)
|
|
136
|
+
|
|
137
|
+
|
|
115
138
|
def _serialize_datetime(o, format: typing.Optional[str] = None):
|
|
116
139
|
if hasattr(o, "year") and hasattr(o, "hour"):
|
|
117
140
|
if format == "rfc7231":
|
|
@@ -307,6 +330,12 @@ def _deserialize_duration(attr):
|
|
|
307
330
|
return isodate.parse_duration(attr)
|
|
308
331
|
|
|
309
332
|
|
|
333
|
+
def _deserialize_duration_numeric(attr, unit):
|
|
334
|
+
if isinstance(attr, timedelta):
|
|
335
|
+
return attr
|
|
336
|
+
return timedelta(**{unit: float(attr)})
|
|
337
|
+
|
|
338
|
+
|
|
310
339
|
def _deserialize_decimal(attr):
|
|
311
340
|
if isinstance(attr, decimal.Decimal):
|
|
312
341
|
return attr
|
|
@@ -336,6 +365,10 @@ _DESERIALIZE_MAPPING_WITHFORMAT = {
|
|
|
336
365
|
"unix-timestamp": _deserialize_datetime_unix_timestamp,
|
|
337
366
|
"base64": _deserialize_bytes,
|
|
338
367
|
"base64url": _deserialize_bytes_base64,
|
|
368
|
+
"duration-seconds-int": functools.partial(_deserialize_duration_numeric, unit="seconds"),
|
|
369
|
+
"duration-seconds-float": functools.partial(_deserialize_duration_numeric, unit="seconds"),
|
|
370
|
+
"duration-milliseconds-int": functools.partial(_deserialize_duration_numeric, unit="milliseconds"),
|
|
371
|
+
"duration-milliseconds-float": functools.partial(_deserialize_duration_numeric, unit="milliseconds"),
|
|
339
372
|
}
|
|
340
373
|
|
|
341
374
|
|
|
@@ -576,7 +609,7 @@ def _serialize(o, format: typing.Optional[str] = None): # pylint: disable=too-m
|
|
|
576
609
|
pass
|
|
577
610
|
# Last, try datetime.timedelta
|
|
578
611
|
try:
|
|
579
|
-
return
|
|
612
|
+
return _serialize_duration(o, format)
|
|
580
613
|
except AttributeError:
|
|
581
614
|
# This will be raised when it hits value.total_seconds in the method above
|
|
582
615
|
pass
|
|
@@ -516,6 +516,10 @@ class Serializer: # pylint: disable=too-many-public-methods
|
|
|
516
516
|
"rfc-1123": Serializer.serialize_rfc,
|
|
517
517
|
"unix-time": Serializer.serialize_unix,
|
|
518
518
|
"duration": Serializer.serialize_duration,
|
|
519
|
+
"duration-seconds-int": Serializer.serialize_duration_seconds_int,
|
|
520
|
+
"duration-seconds-float": Serializer.serialize_duration_seconds_float,
|
|
521
|
+
"duration-milliseconds-int": Serializer.serialize_duration_milliseconds_int,
|
|
522
|
+
"duration-milliseconds-float": Serializer.serialize_duration_milliseconds_float,
|
|
519
523
|
"date": Serializer.serialize_date,
|
|
520
524
|
"time": Serializer.serialize_time,
|
|
521
525
|
"decimal": Serializer.serialize_decimal,
|
|
@@ -1105,6 +1109,61 @@ class Serializer: # pylint: disable=too-many-public-methods
|
|
|
1105
1109
|
attr = isodate.parse_duration(attr)
|
|
1106
1110
|
return isodate.duration_isoformat(attr)
|
|
1107
1111
|
|
|
1112
|
+
@staticmethod
|
|
1113
|
+
def _serialize_duration_numeric(attr, scale, as_int):
|
|
1114
|
+
"""Serialize a TimeDelta into a numeric value scaled to the wire unit.
|
|
1115
|
+
|
|
1116
|
+
:param TimeDelta attr: Object to be serialized.
|
|
1117
|
+
:param int scale: Multiplier applied to total seconds (1 for seconds, 1000 for milliseconds).
|
|
1118
|
+
:param bool as_int: Whether to truncate the result to an int.
|
|
1119
|
+
:rtype: int or float
|
|
1120
|
+
:return: serialized duration
|
|
1121
|
+
"""
|
|
1122
|
+
if isinstance(attr, str):
|
|
1123
|
+
attr = isodate.parse_duration(attr)
|
|
1124
|
+
value = attr.total_seconds() * scale if isinstance(attr, datetime.timedelta) else attr
|
|
1125
|
+
return int(value) if as_int else float(value)
|
|
1126
|
+
|
|
1127
|
+
@staticmethod
|
|
1128
|
+
def serialize_duration_seconds_int(attr, **kwargs): # pylint: disable=unused-argument
|
|
1129
|
+
"""Serialize TimeDelta object into an integer number of seconds.
|
|
1130
|
+
|
|
1131
|
+
:param TimeDelta attr: Object to be serialized.
|
|
1132
|
+
:rtype: int
|
|
1133
|
+
:return: serialized duration
|
|
1134
|
+
"""
|
|
1135
|
+
return Serializer._serialize_duration_numeric(attr, 1, True)
|
|
1136
|
+
|
|
1137
|
+
@staticmethod
|
|
1138
|
+
def serialize_duration_seconds_float(attr, **kwargs): # pylint: disable=unused-argument
|
|
1139
|
+
"""Serialize TimeDelta object into a floating point number of seconds.
|
|
1140
|
+
|
|
1141
|
+
:param TimeDelta attr: Object to be serialized.
|
|
1142
|
+
:rtype: float
|
|
1143
|
+
:return: serialized duration
|
|
1144
|
+
"""
|
|
1145
|
+
return Serializer._serialize_duration_numeric(attr, 1, False)
|
|
1146
|
+
|
|
1147
|
+
@staticmethod
|
|
1148
|
+
def serialize_duration_milliseconds_int(attr, **kwargs): # pylint: disable=unused-argument
|
|
1149
|
+
"""Serialize TimeDelta object into an integer number of milliseconds.
|
|
1150
|
+
|
|
1151
|
+
:param TimeDelta attr: Object to be serialized.
|
|
1152
|
+
:rtype: int
|
|
1153
|
+
:return: serialized duration
|
|
1154
|
+
"""
|
|
1155
|
+
return Serializer._serialize_duration_numeric(attr, 1000, True)
|
|
1156
|
+
|
|
1157
|
+
@staticmethod
|
|
1158
|
+
def serialize_duration_milliseconds_float(attr, **kwargs): # pylint: disable=unused-argument
|
|
1159
|
+
"""Serialize TimeDelta object into a floating point number of milliseconds.
|
|
1160
|
+
|
|
1161
|
+
:param TimeDelta attr: Object to be serialized.
|
|
1162
|
+
:rtype: float
|
|
1163
|
+
:return: serialized duration
|
|
1164
|
+
"""
|
|
1165
|
+
return Serializer._serialize_duration_numeric(attr, 1000, False)
|
|
1166
|
+
|
|
1108
1167
|
@staticmethod
|
|
1109
1168
|
def serialize_rfc(attr, **kwargs): # pylint: disable=unused-argument
|
|
1110
1169
|
"""Serialize Datetime object into RFC-1123 formatted string.
|
|
@@ -1377,6 +1436,10 @@ class Deserializer:
|
|
|
1377
1436
|
"rfc-1123": Deserializer.deserialize_rfc,
|
|
1378
1437
|
"unix-time": Deserializer.deserialize_unix,
|
|
1379
1438
|
"duration": Deserializer.deserialize_duration,
|
|
1439
|
+
"duration-seconds-int": Deserializer.deserialize_duration_seconds,
|
|
1440
|
+
"duration-seconds-float": Deserializer.deserialize_duration_seconds,
|
|
1441
|
+
"duration-milliseconds-int": Deserializer.deserialize_duration_milliseconds,
|
|
1442
|
+
"duration-milliseconds-float": Deserializer.deserialize_duration_milliseconds,
|
|
1380
1443
|
"date": Deserializer.deserialize_date,
|
|
1381
1444
|
"time": Deserializer.deserialize_time,
|
|
1382
1445
|
"decimal": Deserializer.deserialize_decimal,
|
|
@@ -1389,6 +1452,10 @@ class Deserializer:
|
|
|
1389
1452
|
}
|
|
1390
1453
|
self.deserialize_expected_types = {
|
|
1391
1454
|
"duration": (isodate.Duration, datetime.timedelta),
|
|
1455
|
+
"duration-seconds-int": (isodate.Duration, datetime.timedelta),
|
|
1456
|
+
"duration-seconds-float": (isodate.Duration, datetime.timedelta),
|
|
1457
|
+
"duration-milliseconds-int": (isodate.Duration, datetime.timedelta),
|
|
1458
|
+
"duration-milliseconds-float": (isodate.Duration, datetime.timedelta),
|
|
1392
1459
|
"iso-8601": (datetime.datetime),
|
|
1393
1460
|
}
|
|
1394
1461
|
self.dependencies: dict[str, type] = dict(classes) if classes else {}
|
|
@@ -1950,6 +2017,48 @@ class Deserializer:
|
|
|
1950
2017
|
raise DeserializationError(msg) from err
|
|
1951
2018
|
return duration
|
|
1952
2019
|
|
|
2020
|
+
@staticmethod
|
|
2021
|
+
def _deserialize_duration_numeric(attr, unit):
|
|
2022
|
+
"""Deserialize a numeric duration value into a TimeDelta object.
|
|
2023
|
+
|
|
2024
|
+
:param float attr: response value to be deserialized.
|
|
2025
|
+
:param str unit: The wire unit, used as the ``timedelta`` keyword
|
|
2026
|
+
(``"seconds"`` or ``"milliseconds"``).
|
|
2027
|
+
:return: Deserialized duration
|
|
2028
|
+
:rtype: TimeDelta
|
|
2029
|
+
:raises DeserializationError: if value is invalid.
|
|
2030
|
+
"""
|
|
2031
|
+
if isinstance(attr, ET.Element):
|
|
2032
|
+
attr = attr.text
|
|
2033
|
+
try:
|
|
2034
|
+
duration = datetime.timedelta(**{unit: float(attr)}) # type: ignore
|
|
2035
|
+
except (ValueError, OverflowError, TypeError) as err:
|
|
2036
|
+
msg = "Cannot deserialize duration object."
|
|
2037
|
+
raise DeserializationError(msg) from err
|
|
2038
|
+
return duration
|
|
2039
|
+
|
|
2040
|
+
@staticmethod
|
|
2041
|
+
def deserialize_duration_seconds(attr):
|
|
2042
|
+
"""Deserialize a numeric number of seconds into a TimeDelta object.
|
|
2043
|
+
|
|
2044
|
+
:param float attr: response value to be deserialized.
|
|
2045
|
+
:return: Deserialized duration
|
|
2046
|
+
:rtype: TimeDelta
|
|
2047
|
+
:raises DeserializationError: if value is invalid.
|
|
2048
|
+
"""
|
|
2049
|
+
return Deserializer._deserialize_duration_numeric(attr, "seconds")
|
|
2050
|
+
|
|
2051
|
+
@staticmethod
|
|
2052
|
+
def deserialize_duration_milliseconds(attr):
|
|
2053
|
+
"""Deserialize a numeric number of milliseconds into a TimeDelta object.
|
|
2054
|
+
|
|
2055
|
+
:param float attr: response value to be deserialized.
|
|
2056
|
+
:return: Deserialized duration
|
|
2057
|
+
:rtype: TimeDelta
|
|
2058
|
+
:raises DeserializationError: if value is invalid.
|
|
2059
|
+
"""
|
|
2060
|
+
return Deserializer._deserialize_duration_numeric(attr, "milliseconds")
|
|
2061
|
+
|
|
1953
2062
|
@staticmethod
|
|
1954
2063
|
def deserialize_date(attr):
|
|
1955
2064
|
"""Deserialize ISO-8601 formatted string into Date object.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@typespec/http-client-python",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.32.0",
|
|
4
4
|
"author": "Microsoft Corporation",
|
|
5
5
|
"description": "TypeSpec emitter for Python SDKs",
|
|
6
6
|
"homepage": "https://typespec.io",
|
|
@@ -25,6 +25,10 @@
|
|
|
25
25
|
"default": "./dist/emitter/index.js"
|
|
26
26
|
}
|
|
27
27
|
},
|
|
28
|
+
"browser": {
|
|
29
|
+
"./dist/emitter/node-runner.js": "./dist/emitter/node-runner.browser.js",
|
|
30
|
+
"./dist/emitter/pyodide-loader.js": "./dist/emitter/pyodide-loader.browser.js"
|
|
31
|
+
},
|
|
28
32
|
"engines": {
|
|
29
33
|
"node": ">=22.0.0"
|
|
30
34
|
},
|
|
@@ -60,10 +64,10 @@
|
|
|
60
64
|
"emitter"
|
|
61
65
|
],
|
|
62
66
|
"peerDependencies": {
|
|
63
|
-
"@azure-tools/typespec-autorest": ">=0.69.
|
|
67
|
+
"@azure-tools/typespec-autorest": ">=0.69.1 <1.0.0",
|
|
64
68
|
"@azure-tools/typespec-azure-core": ">=0.69.0 <1.0.0",
|
|
65
|
-
"@azure-tools/typespec-azure-resource-manager": ">=0.69.
|
|
66
|
-
"@azure-tools/typespec-azure-rulesets": ">=0.69.
|
|
69
|
+
"@azure-tools/typespec-azure-resource-manager": ">=0.69.1 <1.0.0",
|
|
70
|
+
"@azure-tools/typespec-azure-rulesets": ">=0.69.1 <1.0.0",
|
|
67
71
|
"@azure-tools/typespec-client-generator-core": ">=0.69.0 <1.0.0",
|
|
68
72
|
"@typespec/compiler": "^1.13.0",
|
|
69
73
|
"@typespec/http": "^1.13.0",
|
|
@@ -98,10 +102,10 @@
|
|
|
98
102
|
"tsx": "^4.21.0"
|
|
99
103
|
},
|
|
100
104
|
"devDependencies": {
|
|
101
|
-
"@azure-tools/typespec-autorest": "~0.69.
|
|
105
|
+
"@azure-tools/typespec-autorest": "~0.69.1",
|
|
102
106
|
"@azure-tools/typespec-azure-core": "~0.69.0",
|
|
103
|
-
"@azure-tools/typespec-azure-resource-manager": "~0.69.
|
|
104
|
-
"@azure-tools/typespec-azure-rulesets": "~0.69.
|
|
107
|
+
"@azure-tools/typespec-azure-resource-manager": "~0.69.1",
|
|
108
|
+
"@azure-tools/typespec-azure-rulesets": "~0.69.1",
|
|
105
109
|
"@azure-tools/typespec-client-generator-core": "~0.69.0",
|
|
106
110
|
"@azure-tools/azure-http-specs": "0.1.0-alpha.42",
|
|
107
111
|
"@typespec/compiler": "^1.13.0",
|
|
@@ -115,7 +119,7 @@
|
|
|
115
119
|
"@typespec/sse": "~0.83.0",
|
|
116
120
|
"@typespec/streams": "~0.83.0",
|
|
117
121
|
"@typespec/xml": "~0.83.0",
|
|
118
|
-
"@typespec/http-specs": "0.1.0-alpha.
|
|
122
|
+
"@typespec/http-specs": "0.1.0-alpha.39-dev.1",
|
|
119
123
|
"@types/js-yaml": "~4.0.5",
|
|
120
124
|
"@types/node": "~25.0.2",
|
|
121
125
|
"@types/semver": "7.5.8",
|