Skip to content

Commit 02eb6d0

Browse files
author
iscai-msft
committed
add support for exact client name
1 parent 429d74a commit 02eb6d0

7 files changed

Lines changed: 41 additions & 12 deletions

File tree

packages/http-client-python/emitter/src/http.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,7 @@ function emitFlattenedParameter(
459459
checkClientInput: false,
460460
clientDefaultValue: null,
461461
clientName: property.clientName,
462+
isExactName: property.isExactName,
462463
delimiter: null,
463464
description: property.description,
464465
implementation: "Method",
@@ -622,7 +623,11 @@ function emitHttpBodyParameter(
622623
...emitParamBase(context, bodyParam, undefined, serviceApiVersions),
623624
contentTypes: bodyParam.contentTypes,
624625
location: bodyParam.kind,
625-
clientName: bodyParam.isGeneratedName ? "body" : camelToSnakeCase(bodyParam.name),
626+
clientName: bodyParam.isGeneratedName
627+
? "body"
628+
: bodyParam.isExactName
629+
? bodyParam.name
630+
: camelToSnakeCase(bodyParam.name),
626631
wireName: bodyParam.isGeneratedName ? "body" : bodyParam.name,
627632
implementation: getImplementation(context, bodyParam),
628633
clientDefaultValue: bodyParam.clientDefaultValue,

packages/http-client-python/emitter/src/types.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,8 @@ function emitProperty(
233233
addDisableGenerationMap(context, property.type);
234234
}
235235
return {
236-
clientName: camelToSnakeCase(property.name),
236+
clientName: property.isExactName ? property.name : camelToSnakeCase(property.name),
237+
isExactName: property.isExactName,
237238
wireName:
238239
(property.serializationOptions?.multipart
239240
? property.serializationOptions?.multipart?.name

packages/http-client-python/emitter/src/utils.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ type ParamBase = {
146146
description: string;
147147
addedOn: string | undefined;
148148
clientName: string;
149+
isExactName: boolean;
149150
inOverload: boolean;
150151
isApiVersion: boolean;
151152
type: Record<string, any>;
@@ -220,21 +221,24 @@ export function emitParamBase<TServiceOperation extends SdkServiceOperation>(
220221
});
221222
}
222223
}
223-
let clientName = camelToSnakeCase(parameter.name);
224+
let clientName = parameter.isExactName ? parameter.name : camelToSnakeCase(parameter.name);
224225
if (
225226
parameter.kind !== "method" &&
226227
parameter.kind !== "credential" &&
227228
parameter.kind !== "endpoint" &&
228229
parameter.onClient &&
229230
parameter.correspondingMethodParams[0]
230231
) {
231-
clientName = camelToSnakeCase(parameter.correspondingMethodParams[0].name);
232+
clientName = parameter.correspondingMethodParams[0].isExactName
233+
? parameter.correspondingMethodParams[0].name
234+
: camelToSnakeCase(parameter.correspondingMethodParams[0].name);
232235
}
233236
return {
234237
optional: parameter.optional,
235238
description: (parameter.summary ? parameter.summary : parameter.doc) ?? "",
236239
addedOn: getAddedOn(context, parameter, serviceApiVersions),
237240
clientName,
241+
isExactName: parameter.isExactName,
238242
inOverload: false,
239243
isApiVersion: parameter.isApiVersionParam,
240244
isContinuationToken:

packages/http-client-python/generator/pygen/codegen/models/operation.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,11 +91,16 @@ def __init__(
9191
self.has_etag: bool = self.yaml_data.get("hasEtag", False)
9292
self.cross_language_definition_id: Optional[str] = self.yaml_data.get("crossLanguageDefinitionId")
9393

94+
@property
95+
def exact_name_params(self) -> set[str]:
96+
"""Return the set of client names for parameters with isExactName."""
97+
return {p.client_name for p in self.parameters.method if p.is_exact_name}
98+
9499
@property
95100
def stream_value(self) -> Union[str, bool]:
96101
return (
97102
f'kwargs.pop("stream", {self.has_stream_response})'
98-
if self.expose_stream_keyword and self.has_response_body
103+
if self.expose_stream_keyword and self.has_response_body and "stream" not in self.exact_name_params
99104
else self.has_stream_response
100105
)
101106

packages/http-client-python/generator/pygen/codegen/models/parameter.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ def __init__(
8787
self.default_to_unset_sentinel: bool = self.yaml_data.get("defaultToUnsetSentinel", False)
8888
self.hide_in_method: bool = self.yaml_data.get("hideInMethod", False)
8989
self.is_continuation_token: bool = bool(self.yaml_data.get("isContinuationToken"))
90+
self.is_exact_name: bool = self.yaml_data.get("isExactName", False)
9091

9192
def get_declaration(self, value: Any = None) -> Any:
9293
return self.type.get_declaration(value)

packages/http-client-python/generator/pygen/codegen/serializers/builder_serializer.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -627,7 +627,8 @@ def _api_version_validation(self, builder: OperationType) -> str:
627627
return ""
628628

629629
def pop_kwargs_from_signature(self, builder: OperationType) -> list[str]:
630-
kwargs_to_pop = builder.parameters.kwargs_to_pop
630+
exact_names = builder.exact_name_params
631+
kwargs_to_pop = [k for k in builder.parameters.kwargs_to_pop if k.client_name not in exact_names]
631632
kwargs = self.parameter_serializer.pop_kwargs_from_signature(
632633
kwargs_to_pop,
633634
check_kwarg_dict=True,
@@ -645,7 +646,7 @@ def pop_kwargs_from_signature(self, builder: OperationType) -> list[str]:
645646
body_parameter=builder.parameters.body_parameter if builder.parameters.has_body else None,
646647
)
647648
for p in builder.parameters.parameters:
648-
if p.hide_in_operation_signature and not p.is_continuation_token:
649+
if p.hide_in_operation_signature and not p.is_continuation_token and p.client_name not in exact_names:
649650
kwargs.append(f'{p.client_name} = kwargs.pop("{p.client_name}", None)')
650651
cls_annotation = builder.cls_type_annotation(
651652
async_mode=self.async_mode, serialize_namespace=self.serialize_namespace

packages/http-client-python/generator/pygen/preprocess/__init__.py

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -264,9 +264,10 @@ def update_types(self, yaml_data: list[dict[str, Any]]) -> None:
264264
for type in yaml_data:
265265
for property in type.get("properties", []):
266266
property["description"] = update_description(property.get("description", ""))
267-
property["clientName"] = self.pad_reserved_words(
268-
property["clientName"].lower(), PadType.PROPERTY, property
269-
)
267+
if not property.get("isExactName", False):
268+
property["clientName"] = self.pad_reserved_words(
269+
property["clientName"].lower(), PadType.PROPERTY, property
270+
)
270271
add_redefined_builtin_info(property["clientName"], property)
271272
if type.get("name"):
272273
pad_type = PadType.MODEL if type["type"] == "model" else PadType.ENUM_CLASS
@@ -362,14 +363,25 @@ def get_operation_updater(self, yaml_data: dict[str, Any]) -> Callable[[dict[str
362363

363364
def update_parameter(self, yaml_data: dict[str, Any]) -> None:
364365
yaml_data["description"] = update_description(yaml_data.get("description", ""))
365-
if not (yaml_data["location"] == "header" and yaml_data["clientName"] in ("content_type", "accept")):
366+
if not yaml_data.get("isExactName", False) and not (
367+
yaml_data["location"] == "header" and yaml_data["clientName"] in ("content_type", "accept")
368+
):
366369
yaml_data["clientName"] = self.pad_reserved_words(
367370
yaml_data["clientName"].lower(), PadType.PARAMETER, yaml_data
368371
)
369372
if yaml_data.get("propertyToParameterName"):
370373
# need to create a new one with padded values (but NOT keys, since keys are wire names)
374+
# build a lookup of exact-name properties from the body type's properties
375+
exact_name_props = set()
376+
for prop in yaml_data.get("type", {}).get("properties", []):
377+
if prop.get("isExactName", False):
378+
exact_name_props.add(prop.get("wireName", ""))
371379
yaml_data["propertyToParameterName"] = {
372-
prop: self.pad_reserved_words(param_name, PadType.PARAMETER, yaml_data).lower()
380+
prop: (
381+
param_name
382+
if prop in exact_name_props
383+
else self.pad_reserved_words(param_name, PadType.PARAMETER, yaml_data).lower()
384+
)
373385
for prop, param_name in yaml_data["propertyToParameterName"].items()
374386
}
375387
wire_name_lower = (yaml_data.get("wireName") or "").lower()

0 commit comments

Comments
 (0)