@typespec/http-client-python 0.30.0-alpha.20260601.1 → 0.30.0-alpha.20260601.2
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/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/preprocess/__init__.py +103 -34
- package/generator/dist/pygen-0.1.0-py3-none-any.whl +0 -0
- package/generator/pygen/preprocess/__init__.py +103 -34
- package/package.json +1 -1
|
Binary file
|
|
Binary file
|
|
@@ -158,6 +158,8 @@ CLOUD_SETTING = {
|
|
|
158
158
|
"isTypingOnly": True,
|
|
159
159
|
},
|
|
160
160
|
}
|
|
161
|
+
STANDARD_IF_MATCH_WIRE_NAME = "if-match"
|
|
162
|
+
STANDARD_IF_NONE_MATCH_WIRE_NAME = "if-none-match"
|
|
161
163
|
|
|
162
164
|
|
|
163
165
|
def get_wire_name_lower(parameter: dict[str, Any]) -> str:
|
|
@@ -169,6 +171,106 @@ def _get_etag_role(parameter: dict[str, Any]) -> Optional[str]:
|
|
|
169
171
|
return parameter.get("etagRole")
|
|
170
172
|
|
|
171
173
|
|
|
174
|
+
def _pick_etag_slot(
|
|
175
|
+
candidates: list[dict[str, Any]], standard_wire_name: str
|
|
176
|
+
) -> Optional[dict[str, Any]]:
|
|
177
|
+
"""Choose which etag-typed header should be promoted to the etag/match_condition slot.
|
|
178
|
+
|
|
179
|
+
When more than one etag-typed header is present in an operation, prefer the
|
|
180
|
+
standard If-Match/If-None-Match header (matched on wireName). Otherwise
|
|
181
|
+
fall back to the first candidate. Returns None if there are no candidates.
|
|
182
|
+
"""
|
|
183
|
+
if not candidates:
|
|
184
|
+
return None
|
|
185
|
+
for c in candidates:
|
|
186
|
+
if get_wire_name_lower(c) == standard_wire_name:
|
|
187
|
+
return c
|
|
188
|
+
return candidates[0]
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
def _resolve_etag_pair(
|
|
192
|
+
if_match_candidates: list[dict[str, Any]],
|
|
193
|
+
if_none_match_candidates: list[dict[str, Any]],
|
|
194
|
+
) -> tuple[Optional[dict[str, Any]], Optional[dict[str, Any]]]:
|
|
195
|
+
"""Select and reconcile the etag header pair for an operation.
|
|
196
|
+
|
|
197
|
+
When multiple etag-typed headers are present, prefer the standard
|
|
198
|
+
If-Match / If-None-Match pair. Synthesize a missing partner when only
|
|
199
|
+
one side is present, and strip etagRole from non-selected candidates.
|
|
200
|
+
|
|
201
|
+
Returns (property_if_match, property_if_none_match) — both None when
|
|
202
|
+
there are no etag candidates.
|
|
203
|
+
"""
|
|
204
|
+
property_if_match = _pick_etag_slot(if_match_candidates, STANDARD_IF_MATCH_WIRE_NAME)
|
|
205
|
+
property_if_none_match = _pick_etag_slot(if_none_match_candidates, STANDARD_IF_NONE_MATCH_WIRE_NAME)
|
|
206
|
+
|
|
207
|
+
# Ensure the promoted pair come from the same family. When one slot is
|
|
208
|
+
# standard and the other custom (cross-family), replace the custom slot
|
|
209
|
+
# with a synthetic standard partner. Also synthesize the missing partner
|
|
210
|
+
# when only one side is present.
|
|
211
|
+
if property_if_match and property_if_none_match:
|
|
212
|
+
match_is_std = get_wire_name_lower(property_if_match) == STANDARD_IF_MATCH_WIRE_NAME
|
|
213
|
+
none_match_is_std = get_wire_name_lower(property_if_none_match) == STANDARD_IF_NONE_MATCH_WIRE_NAME
|
|
214
|
+
if match_is_std and not none_match_is_std:
|
|
215
|
+
property_if_none_match = property_if_match.copy()
|
|
216
|
+
property_if_none_match["wireName"] = STANDARD_IF_NONE_MATCH_WIRE_NAME
|
|
217
|
+
property_if_none_match["etagRole"] = "ifNoneMatch"
|
|
218
|
+
elif none_match_is_std and not match_is_std:
|
|
219
|
+
property_if_match = property_if_none_match.copy()
|
|
220
|
+
property_if_match["wireName"] = STANDARD_IF_MATCH_WIRE_NAME
|
|
221
|
+
property_if_match["etagRole"] = "ifMatch"
|
|
222
|
+
elif not property_if_match and property_if_none_match:
|
|
223
|
+
property_if_match = property_if_none_match.copy()
|
|
224
|
+
property_if_match["wireName"] = STANDARD_IF_MATCH_WIRE_NAME
|
|
225
|
+
property_if_match["etagRole"] = "ifMatch"
|
|
226
|
+
elif property_if_match and not property_if_none_match:
|
|
227
|
+
property_if_none_match = property_if_match.copy()
|
|
228
|
+
property_if_none_match["wireName"] = STANDARD_IF_NONE_MATCH_WIRE_NAME
|
|
229
|
+
property_if_none_match["etagRole"] = "ifNoneMatch"
|
|
230
|
+
|
|
231
|
+
for c in if_match_candidates:
|
|
232
|
+
if c is not property_if_match:
|
|
233
|
+
c.pop("etagRole", None)
|
|
234
|
+
for c in if_none_match_candidates:
|
|
235
|
+
if c is not property_if_none_match:
|
|
236
|
+
c.pop("etagRole", None)
|
|
237
|
+
|
|
238
|
+
return property_if_match, property_if_none_match
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
def _process_operation_etag_headers(
|
|
242
|
+
operation: dict[str, Any],
|
|
243
|
+
client: dict[str, Any],
|
|
244
|
+
version_tolerant: bool,
|
|
245
|
+
) -> None:
|
|
246
|
+
"""Collect etag candidates from *operation*, resolve the promoted pair,
|
|
247
|
+
and update *operation* / *client* accordingly."""
|
|
248
|
+
if_match_candidates: list[dict[str, Any]] = []
|
|
249
|
+
if_none_match_candidates: list[dict[str, Any]] = []
|
|
250
|
+
for p in operation["parameters"]:
|
|
251
|
+
wire_name_lower = get_wire_name_lower(p)
|
|
252
|
+
if p["location"] == "header" and wire_name_lower == "client-request-id":
|
|
253
|
+
client["requestIdHeaderName"] = wire_name_lower
|
|
254
|
+
if version_tolerant and p["location"] == "header":
|
|
255
|
+
role = _get_etag_role(p)
|
|
256
|
+
if role == "ifMatch":
|
|
257
|
+
if_match_candidates.append(p)
|
|
258
|
+
elif role == "ifNoneMatch":
|
|
259
|
+
if_none_match_candidates.append(p)
|
|
260
|
+
|
|
261
|
+
property_if_match, property_if_none_match = _resolve_etag_pair(
|
|
262
|
+
if_match_candidates, if_none_match_candidates
|
|
263
|
+
)
|
|
264
|
+
|
|
265
|
+
if property_if_match and property_if_none_match:
|
|
266
|
+
etag_params = {id(property_if_match), id(property_if_none_match)}
|
|
267
|
+
operation["parameters"] = [
|
|
268
|
+
item for item in operation["parameters"] if id(item) not in etag_params
|
|
269
|
+
] + [property_if_match, property_if_none_match]
|
|
270
|
+
operation["hasEtag"] = True
|
|
271
|
+
client["hasEtag"] = True
|
|
272
|
+
|
|
273
|
+
|
|
172
274
|
def headers_convert(yaml_data: dict[str, Any], replace_data: Any) -> None:
|
|
173
275
|
if isinstance(replace_data, dict):
|
|
174
276
|
for k, v in replace_data.items():
|
|
@@ -313,40 +415,7 @@ class PreProcessPlugin(YamlUpdatePlugin):
|
|
|
313
415
|
yaml_data["builderPadName"] = to_snake_case(prop_name)
|
|
314
416
|
for og in yaml_data.get("operationGroups", []):
|
|
315
417
|
for o in og["operations"]:
|
|
316
|
-
|
|
317
|
-
property_if_none_match = None
|
|
318
|
-
for p in o["parameters"]:
|
|
319
|
-
wire_name_lower = get_wire_name_lower(p)
|
|
320
|
-
if p["location"] == "header" and wire_name_lower == "client-request-id":
|
|
321
|
-
yaml_data["requestIdHeaderName"] = wire_name_lower
|
|
322
|
-
if self.version_tolerant and p["location"] == "header":
|
|
323
|
-
role = _get_etag_role(p)
|
|
324
|
-
if role == "ifMatch" and not property_if_match:
|
|
325
|
-
property_if_match = p
|
|
326
|
-
elif role == "ifNoneMatch" and not property_if_none_match:
|
|
327
|
-
property_if_none_match = p
|
|
328
|
-
# pylint: disable=line-too-long
|
|
329
|
-
# some service(e.g. https://github.com/Azure/azure-rest-api-specs/blob/main/specification/cosmos-db/data-plane/Microsoft.Tables/preview/2019-02-02/table.json)
|
|
330
|
-
# only has one, so we need to add "if-none-match" or "if-match" if it's missing
|
|
331
|
-
if not property_if_match and property_if_none_match:
|
|
332
|
-
property_if_match = property_if_none_match.copy()
|
|
333
|
-
property_if_match["wireName"] = "if-match"
|
|
334
|
-
property_if_match["etagRole"] = "ifMatch"
|
|
335
|
-
if not property_if_none_match and property_if_match:
|
|
336
|
-
property_if_none_match = property_if_match.copy()
|
|
337
|
-
property_if_none_match["wireName"] = "if-none-match"
|
|
338
|
-
property_if_none_match["etagRole"] = "ifNoneMatch"
|
|
339
|
-
|
|
340
|
-
if property_if_match and property_if_none_match:
|
|
341
|
-
# arrange if-match and if-none-match to the end of parameters
|
|
342
|
-
etag_params = {id(property_if_match), id(property_if_none_match)}
|
|
343
|
-
o["parameters"] = [item for item in o["parameters"] if id(item) not in etag_params] + [
|
|
344
|
-
property_if_match,
|
|
345
|
-
property_if_none_match,
|
|
346
|
-
]
|
|
347
|
-
|
|
348
|
-
o["hasEtag"] = True
|
|
349
|
-
yaml_data["hasEtag"] = True
|
|
418
|
+
_process_operation_etag_headers(o, yaml_data, self.version_tolerant)
|
|
350
419
|
|
|
351
420
|
# add client signature cloud_setting for arm
|
|
352
421
|
if self.azure_arm and yaml_data["parameters"]:
|
|
Binary file
|
|
@@ -158,6 +158,8 @@ CLOUD_SETTING = {
|
|
|
158
158
|
"isTypingOnly": True,
|
|
159
159
|
},
|
|
160
160
|
}
|
|
161
|
+
STANDARD_IF_MATCH_WIRE_NAME = "if-match"
|
|
162
|
+
STANDARD_IF_NONE_MATCH_WIRE_NAME = "if-none-match"
|
|
161
163
|
|
|
162
164
|
|
|
163
165
|
def get_wire_name_lower(parameter: dict[str, Any]) -> str:
|
|
@@ -169,6 +171,106 @@ def _get_etag_role(parameter: dict[str, Any]) -> Optional[str]:
|
|
|
169
171
|
return parameter.get("etagRole")
|
|
170
172
|
|
|
171
173
|
|
|
174
|
+
def _pick_etag_slot(
|
|
175
|
+
candidates: list[dict[str, Any]], standard_wire_name: str
|
|
176
|
+
) -> Optional[dict[str, Any]]:
|
|
177
|
+
"""Choose which etag-typed header should be promoted to the etag/match_condition slot.
|
|
178
|
+
|
|
179
|
+
When more than one etag-typed header is present in an operation, prefer the
|
|
180
|
+
standard If-Match/If-None-Match header (matched on wireName). Otherwise
|
|
181
|
+
fall back to the first candidate. Returns None if there are no candidates.
|
|
182
|
+
"""
|
|
183
|
+
if not candidates:
|
|
184
|
+
return None
|
|
185
|
+
for c in candidates:
|
|
186
|
+
if get_wire_name_lower(c) == standard_wire_name:
|
|
187
|
+
return c
|
|
188
|
+
return candidates[0]
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
def _resolve_etag_pair(
|
|
192
|
+
if_match_candidates: list[dict[str, Any]],
|
|
193
|
+
if_none_match_candidates: list[dict[str, Any]],
|
|
194
|
+
) -> tuple[Optional[dict[str, Any]], Optional[dict[str, Any]]]:
|
|
195
|
+
"""Select and reconcile the etag header pair for an operation.
|
|
196
|
+
|
|
197
|
+
When multiple etag-typed headers are present, prefer the standard
|
|
198
|
+
If-Match / If-None-Match pair. Synthesize a missing partner when only
|
|
199
|
+
one side is present, and strip etagRole from non-selected candidates.
|
|
200
|
+
|
|
201
|
+
Returns (property_if_match, property_if_none_match) — both None when
|
|
202
|
+
there are no etag candidates.
|
|
203
|
+
"""
|
|
204
|
+
property_if_match = _pick_etag_slot(if_match_candidates, STANDARD_IF_MATCH_WIRE_NAME)
|
|
205
|
+
property_if_none_match = _pick_etag_slot(if_none_match_candidates, STANDARD_IF_NONE_MATCH_WIRE_NAME)
|
|
206
|
+
|
|
207
|
+
# Ensure the promoted pair come from the same family. When one slot is
|
|
208
|
+
# standard and the other custom (cross-family), replace the custom slot
|
|
209
|
+
# with a synthetic standard partner. Also synthesize the missing partner
|
|
210
|
+
# when only one side is present.
|
|
211
|
+
if property_if_match and property_if_none_match:
|
|
212
|
+
match_is_std = get_wire_name_lower(property_if_match) == STANDARD_IF_MATCH_WIRE_NAME
|
|
213
|
+
none_match_is_std = get_wire_name_lower(property_if_none_match) == STANDARD_IF_NONE_MATCH_WIRE_NAME
|
|
214
|
+
if match_is_std and not none_match_is_std:
|
|
215
|
+
property_if_none_match = property_if_match.copy()
|
|
216
|
+
property_if_none_match["wireName"] = STANDARD_IF_NONE_MATCH_WIRE_NAME
|
|
217
|
+
property_if_none_match["etagRole"] = "ifNoneMatch"
|
|
218
|
+
elif none_match_is_std and not match_is_std:
|
|
219
|
+
property_if_match = property_if_none_match.copy()
|
|
220
|
+
property_if_match["wireName"] = STANDARD_IF_MATCH_WIRE_NAME
|
|
221
|
+
property_if_match["etagRole"] = "ifMatch"
|
|
222
|
+
elif not property_if_match and property_if_none_match:
|
|
223
|
+
property_if_match = property_if_none_match.copy()
|
|
224
|
+
property_if_match["wireName"] = STANDARD_IF_MATCH_WIRE_NAME
|
|
225
|
+
property_if_match["etagRole"] = "ifMatch"
|
|
226
|
+
elif property_if_match and not property_if_none_match:
|
|
227
|
+
property_if_none_match = property_if_match.copy()
|
|
228
|
+
property_if_none_match["wireName"] = STANDARD_IF_NONE_MATCH_WIRE_NAME
|
|
229
|
+
property_if_none_match["etagRole"] = "ifNoneMatch"
|
|
230
|
+
|
|
231
|
+
for c in if_match_candidates:
|
|
232
|
+
if c is not property_if_match:
|
|
233
|
+
c.pop("etagRole", None)
|
|
234
|
+
for c in if_none_match_candidates:
|
|
235
|
+
if c is not property_if_none_match:
|
|
236
|
+
c.pop("etagRole", None)
|
|
237
|
+
|
|
238
|
+
return property_if_match, property_if_none_match
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
def _process_operation_etag_headers(
|
|
242
|
+
operation: dict[str, Any],
|
|
243
|
+
client: dict[str, Any],
|
|
244
|
+
version_tolerant: bool,
|
|
245
|
+
) -> None:
|
|
246
|
+
"""Collect etag candidates from *operation*, resolve the promoted pair,
|
|
247
|
+
and update *operation* / *client* accordingly."""
|
|
248
|
+
if_match_candidates: list[dict[str, Any]] = []
|
|
249
|
+
if_none_match_candidates: list[dict[str, Any]] = []
|
|
250
|
+
for p in operation["parameters"]:
|
|
251
|
+
wire_name_lower = get_wire_name_lower(p)
|
|
252
|
+
if p["location"] == "header" and wire_name_lower == "client-request-id":
|
|
253
|
+
client["requestIdHeaderName"] = wire_name_lower
|
|
254
|
+
if version_tolerant and p["location"] == "header":
|
|
255
|
+
role = _get_etag_role(p)
|
|
256
|
+
if role == "ifMatch":
|
|
257
|
+
if_match_candidates.append(p)
|
|
258
|
+
elif role == "ifNoneMatch":
|
|
259
|
+
if_none_match_candidates.append(p)
|
|
260
|
+
|
|
261
|
+
property_if_match, property_if_none_match = _resolve_etag_pair(
|
|
262
|
+
if_match_candidates, if_none_match_candidates
|
|
263
|
+
)
|
|
264
|
+
|
|
265
|
+
if property_if_match and property_if_none_match:
|
|
266
|
+
etag_params = {id(property_if_match), id(property_if_none_match)}
|
|
267
|
+
operation["parameters"] = [
|
|
268
|
+
item for item in operation["parameters"] if id(item) not in etag_params
|
|
269
|
+
] + [property_if_match, property_if_none_match]
|
|
270
|
+
operation["hasEtag"] = True
|
|
271
|
+
client["hasEtag"] = True
|
|
272
|
+
|
|
273
|
+
|
|
172
274
|
def headers_convert(yaml_data: dict[str, Any], replace_data: Any) -> None:
|
|
173
275
|
if isinstance(replace_data, dict):
|
|
174
276
|
for k, v in replace_data.items():
|
|
@@ -313,40 +415,7 @@ class PreProcessPlugin(YamlUpdatePlugin):
|
|
|
313
415
|
yaml_data["builderPadName"] = to_snake_case(prop_name)
|
|
314
416
|
for og in yaml_data.get("operationGroups", []):
|
|
315
417
|
for o in og["operations"]:
|
|
316
|
-
|
|
317
|
-
property_if_none_match = None
|
|
318
|
-
for p in o["parameters"]:
|
|
319
|
-
wire_name_lower = get_wire_name_lower(p)
|
|
320
|
-
if p["location"] == "header" and wire_name_lower == "client-request-id":
|
|
321
|
-
yaml_data["requestIdHeaderName"] = wire_name_lower
|
|
322
|
-
if self.version_tolerant and p["location"] == "header":
|
|
323
|
-
role = _get_etag_role(p)
|
|
324
|
-
if role == "ifMatch" and not property_if_match:
|
|
325
|
-
property_if_match = p
|
|
326
|
-
elif role == "ifNoneMatch" and not property_if_none_match:
|
|
327
|
-
property_if_none_match = p
|
|
328
|
-
# pylint: disable=line-too-long
|
|
329
|
-
# some service(e.g. https://github.com/Azure/azure-rest-api-specs/blob/main/specification/cosmos-db/data-plane/Microsoft.Tables/preview/2019-02-02/table.json)
|
|
330
|
-
# only has one, so we need to add "if-none-match" or "if-match" if it's missing
|
|
331
|
-
if not property_if_match and property_if_none_match:
|
|
332
|
-
property_if_match = property_if_none_match.copy()
|
|
333
|
-
property_if_match["wireName"] = "if-match"
|
|
334
|
-
property_if_match["etagRole"] = "ifMatch"
|
|
335
|
-
if not property_if_none_match and property_if_match:
|
|
336
|
-
property_if_none_match = property_if_match.copy()
|
|
337
|
-
property_if_none_match["wireName"] = "if-none-match"
|
|
338
|
-
property_if_none_match["etagRole"] = "ifNoneMatch"
|
|
339
|
-
|
|
340
|
-
if property_if_match and property_if_none_match:
|
|
341
|
-
# arrange if-match and if-none-match to the end of parameters
|
|
342
|
-
etag_params = {id(property_if_match), id(property_if_none_match)}
|
|
343
|
-
o["parameters"] = [item for item in o["parameters"] if id(item) not in etag_params] + [
|
|
344
|
-
property_if_match,
|
|
345
|
-
property_if_none_match,
|
|
346
|
-
]
|
|
347
|
-
|
|
348
|
-
o["hasEtag"] = True
|
|
349
|
-
yaml_data["hasEtag"] = True
|
|
418
|
+
_process_operation_etag_headers(o, yaml_data, self.version_tolerant)
|
|
350
419
|
|
|
351
420
|
# add client signature cloud_setting for arm
|
|
352
421
|
if self.azure_arm and yaml_data["parameters"]:
|
package/package.json
CHANGED