@typespec/http-client-python 0.23.1 → 0.24.1

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 (81) hide show
  1. package/dist/emitter/code-model.d.ts.map +1 -1
  2. package/dist/emitter/code-model.js +40 -25
  3. package/dist/emitter/code-model.js.map +1 -1
  4. package/dist/emitter/http.d.ts +4 -4
  5. package/dist/emitter/http.d.ts.map +1 -1
  6. package/dist/emitter/http.js +41 -35
  7. package/dist/emitter/http.js.map +1 -1
  8. package/dist/emitter/types.d.ts +1 -1
  9. package/dist/emitter/types.d.ts.map +1 -1
  10. package/dist/emitter/types.js +2 -2
  11. package/dist/emitter/types.js.map +1 -1
  12. package/dist/emitter/utils.d.ts +2 -2
  13. package/dist/emitter/utils.d.ts.map +1 -1
  14. package/dist/emitter/utils.js +7 -6
  15. package/dist/emitter/utils.js.map +1 -1
  16. package/emitter/src/code-model.ts +65 -18
  17. package/emitter/src/http.ts +107 -22
  18. package/emitter/src/types.ts +2 -1
  19. package/emitter/src/utils.ts +11 -9
  20. package/emitter/temp/tsconfig.tsbuildinfo +1 -1
  21. package/eng/scripts/ci/dev_requirements.txt +3 -3
  22. package/eng/scripts/ci/pylintrc +1 -1
  23. package/eng/scripts/ci/regenerate.ts +8 -1
  24. package/eng/scripts/setup/__pycache__/package_manager.cpython-311.pyc +0 -0
  25. package/eng/scripts/setup/__pycache__/venvtools.cpython-311.pyc +0 -0
  26. package/generator/build/lib/pygen/codegen/models/code_model.py +4 -0
  27. package/generator/build/lib/pygen/codegen/models/enum_type.py +8 -1
  28. package/generator/build/lib/pygen/codegen/models/list_type.py +6 -2
  29. package/generator/build/lib/pygen/codegen/models/model_type.py +2 -2
  30. package/generator/build/lib/pygen/codegen/models/operation.py +10 -1
  31. package/generator/build/lib/pygen/codegen/models/operation_group.py +3 -1
  32. package/generator/build/lib/pygen/codegen/models/request_builder.py +20 -3
  33. package/generator/build/lib/pygen/codegen/models/response.py +2 -2
  34. package/generator/build/lib/pygen/codegen/models/utils.py +7 -0
  35. package/generator/build/lib/pygen/codegen/serializers/builder_serializer.py +20 -11
  36. package/generator/build/lib/pygen/codegen/serializers/client_serializer.py +1 -2
  37. package/generator/build/lib/pygen/codegen/serializers/general_serializer.py +1 -1
  38. package/generator/build/lib/pygen/codegen/serializers/model_serializer.py +3 -0
  39. package/generator/build/lib/pygen/codegen/templates/enum.py.jinja2 +3 -1
  40. package/generator/build/lib/pygen/codegen/templates/model_base.py.jinja2 +10 -7
  41. package/generator/dist/pygen-0.1.0-py3-none-any.whl +0 -0
  42. package/generator/pygen/codegen/models/code_model.py +4 -0
  43. package/generator/pygen/codegen/models/enum_type.py +8 -1
  44. package/generator/pygen/codegen/models/list_type.py +6 -2
  45. package/generator/pygen/codegen/models/model_type.py +2 -2
  46. package/generator/pygen/codegen/models/operation.py +10 -1
  47. package/generator/pygen/codegen/models/operation_group.py +3 -1
  48. package/generator/pygen/codegen/models/request_builder.py +20 -3
  49. package/generator/pygen/codegen/models/response.py +2 -2
  50. package/generator/pygen/codegen/models/utils.py +7 -0
  51. package/generator/pygen/codegen/serializers/builder_serializer.py +20 -11
  52. package/generator/pygen/codegen/serializers/client_serializer.py +1 -2
  53. package/generator/pygen/codegen/serializers/general_serializer.py +1 -1
  54. package/generator/pygen/codegen/serializers/model_serializer.py +3 -0
  55. package/generator/pygen/codegen/templates/enum.py.jinja2 +3 -1
  56. package/generator/pygen/codegen/templates/model_base.py.jinja2 +10 -7
  57. package/generator/test/azure/mock_api_tests/asynctests/test_azure_arm_operationtemplates_async.py +17 -0
  58. package/generator/test/azure/mock_api_tests/asynctests/test_azure_client_generator_core_client_default_value_async.py +46 -0
  59. package/generator/test/azure/mock_api_tests/asynctests/test_azure_client_generator_core_client_location_async.py +48 -21
  60. package/generator/test/azure/mock_api_tests/asynctests/test_azure_resource_manager_multi_service_async.py +110 -0
  61. package/generator/test/azure/mock_api_tests/asynctests/test_payload_multipart_async.py +33 -0
  62. package/generator/test/azure/mock_api_tests/asynctests/test_service_multi_service_async.py +31 -0
  63. package/generator/test/azure/mock_api_tests/asynctests/test_special_words_async.py +18 -0
  64. package/generator/test/azure/mock_api_tests/test_azure_arm_operationtemplates.py +15 -0
  65. package/generator/test/azure/mock_api_tests/test_azure_client_generator_core_client_default_value.py +42 -0
  66. package/generator/test/azure/mock_api_tests/test_azure_client_generator_core_client_location.py +44 -19
  67. package/generator/test/azure/mock_api_tests/test_azure_resource_manager_multi_service.py +104 -0
  68. package/generator/test/azure/mock_api_tests/test_payload_multipart.py +31 -0
  69. package/generator/test/azure/mock_api_tests/test_service_multi_service.py +29 -0
  70. package/generator/test/azure/mock_api_tests/test_special_words.py +17 -0
  71. package/generator/test/azure/requirements.txt +10 -1
  72. package/generator/test/generic_mock_api_tests/asynctests/test_parameters_query_async.py +18 -0
  73. package/generator/test/generic_mock_api_tests/test_parameters_query.py +17 -0
  74. package/generator/test/generic_mock_api_tests/test_typetest_scalar.py +0 -5
  75. package/generator/test/generic_mock_api_tests/test_typetest_union_discriminated.py +290 -0
  76. package/generator/test/unbranded/mock_api_tests/asynctests/test_payload_multipart_async.py +33 -0
  77. package/generator/test/unbranded/mock_api_tests/test_payload_multipart.py +31 -0
  78. package/generator/test/unbranded/mock_api_tests/test_unbranded.py +8 -3
  79. package/generator/test/unbranded/requirements.txt +3 -0
  80. package/generator/test/unittests/test_model_base_serialization.py +66 -0
  81. package/package.json +33 -33
@@ -60,10 +60,18 @@ export function emitBasicHttpMethod(
60
60
  rootClient: SdkClientType<SdkHttpOperation>,
61
61
  method: SdkBasicServiceMethod<SdkHttpOperation>,
62
62
  operationGroupName: string,
63
+ serviceApiVersions: string[],
63
64
  ): Record<string, any>[] {
64
65
  return [
65
66
  {
66
- ...emitHttpOperation(context, rootClient, operationGroupName, method.operation, method),
67
+ ...emitHttpOperation(
68
+ context,
69
+ rootClient,
70
+ operationGroupName,
71
+ method.operation,
72
+ method,
73
+ serviceApiVersions,
74
+ ),
67
75
  abstract: isAbstract(method),
68
76
  name: camelToSnakeCase(method.name),
69
77
  description: method.doc ?? "",
@@ -77,9 +85,17 @@ function emitInitialLroHttpMethod(
77
85
  rootClient: SdkClientType<SdkHttpOperation>,
78
86
  method: SdkLroServiceMethod<SdkHttpOperation> | SdkLroPagingServiceMethod<SdkHttpOperation>,
79
87
  operationGroupName: string,
88
+ serviceApiVersions: string[],
80
89
  ): Record<string, any> {
81
90
  return {
82
- ...emitHttpOperation(context, rootClient, operationGroupName, method.operation, method),
91
+ ...emitHttpOperation(
92
+ context,
93
+ rootClient,
94
+ operationGroupName,
95
+ method.operation,
96
+ method,
97
+ serviceApiVersions,
98
+ ),
83
99
  name: `_${camelToSnakeCase(method.name)}_initial`,
84
100
  isLroInitialOperation: true,
85
101
  wantTracing: false,
@@ -94,12 +110,26 @@ function addLroInformation(
94
110
  rootClient: SdkClientType<SdkHttpOperation>,
95
111
  method: SdkLroServiceMethod<SdkHttpOperation> | SdkLroPagingServiceMethod<SdkHttpOperation>,
96
112
  operationGroupName: string,
113
+ serviceApiVersions: string[],
97
114
  ) {
98
115
  return {
99
- ...emitHttpOperation(context, rootClient, operationGroupName, method.operation, method),
116
+ ...emitHttpOperation(
117
+ context,
118
+ rootClient,
119
+ operationGroupName,
120
+ method.operation,
121
+ method,
122
+ serviceApiVersions,
123
+ ),
100
124
  name: camelToSnakeCase(method.name),
101
125
  discriminator: "lro",
102
- initialOperation: emitInitialLroHttpMethod(context, rootClient, method, operationGroupName),
126
+ initialOperation: emitInitialLroHttpMethod(
127
+ context,
128
+ rootClient,
129
+ method,
130
+ operationGroupName,
131
+ serviceApiVersions,
132
+ ),
103
133
  exposeStreamKeyword: false,
104
134
  description: method.doc ?? "",
105
135
  summary: method.summary,
@@ -195,6 +225,7 @@ function addPagingInformation(
195
225
  rootClient: SdkClientType<SdkHttpOperation>,
196
226
  method: SdkPagingServiceMethod<SdkHttpOperation> | SdkLroPagingServiceMethod<SdkHttpOperation>,
197
227
  operationGroupName: string,
228
+ serviceApiVersions: string[],
198
229
  ) {
199
230
  for (const response of method.operation.responses) {
200
231
  if (response.type) {
@@ -206,7 +237,14 @@ function addPagingInformation(
206
237
  }
207
238
  }
208
239
  const itemType = getType(context, method.response.type!);
209
- const base = emitHttpOperation(context, rootClient, operationGroupName, method.operation, method);
240
+ const base = emitHttpOperation(
241
+ context,
242
+ rootClient,
243
+ operationGroupName,
244
+ method.operation,
245
+ method,
246
+ serviceApiVersions,
247
+ );
210
248
  const itemName = getWireNameWithDiagnostics(
211
249
  context,
212
250
  method.response.resultSegments,
@@ -228,7 +266,9 @@ function addPagingInformation(
228
266
  if (param.kind === "method") {
229
267
  for (const parameter of method.operation.parameters) {
230
268
  if (parameter.kind === "query" && parameter.correspondingMethodParams.includes(param)) {
231
- nextLinkReInjectedParameters.push(emitHttpQueryParameter(context, parameter, method));
269
+ nextLinkReInjectedParameters.push(
270
+ emitHttpQueryParameter(context, rootClient, parameter, method, serviceApiVersions),
271
+ );
232
272
  }
233
273
  }
234
274
  }
@@ -257,8 +297,15 @@ export function emitLroHttpMethod(
257
297
  rootClient: SdkClientType<SdkHttpOperation>,
258
298
  method: SdkLroServiceMethod<SdkHttpOperation>,
259
299
  operationGroupName: string,
300
+ serviceApiVersions: string[],
260
301
  ): Record<string, any>[] {
261
- const lroMethod = addLroInformation(context, rootClient, method, operationGroupName);
302
+ const lroMethod = addLroInformation(
303
+ context,
304
+ rootClient,
305
+ method,
306
+ operationGroupName,
307
+ serviceApiVersions,
308
+ );
262
309
  return [lroMethod.initialOperation, lroMethod];
263
310
  }
264
311
 
@@ -267,8 +314,15 @@ export function emitPagingHttpMethod(
267
314
  rootClient: SdkClientType<SdkHttpOperation>,
268
315
  method: SdkPagingServiceMethod<SdkHttpOperation>,
269
316
  operationGroupName: string,
317
+ serviceApiVersions: string[],
270
318
  ): Record<string, any>[] {
271
- const pagingMethod = addPagingInformation(context, rootClient, method, operationGroupName);
319
+ const pagingMethod = addPagingInformation(
320
+ context,
321
+ rootClient,
322
+ method,
323
+ operationGroupName,
324
+ serviceApiVersions,
325
+ );
272
326
  return [pagingMethod];
273
327
  }
274
328
 
@@ -277,10 +331,27 @@ export function emitLroPagingHttpMethod(
277
331
  rootClient: SdkClientType<SdkHttpOperation>,
278
332
  method: SdkLroPagingServiceMethod<SdkHttpOperation>,
279
333
  operationGroupName: string,
334
+ serviceApiVersions: string[],
280
335
  ): Record<string, any>[] {
281
- const pagingMethod = addPagingInformation(context, rootClient, method, operationGroupName);
282
- const lroMethod = addLroInformation(context, rootClient, method, operationGroupName);
283
- return [lroMethod.initialOperation, pagingMethod, lroMethod];
336
+ const pagingMethod = addPagingInformation(
337
+ context,
338
+ rootClient,
339
+ method,
340
+ operationGroupName,
341
+ serviceApiVersions,
342
+ );
343
+ const lroMethod = addLroInformation(
344
+ context,
345
+ rootClient,
346
+ method,
347
+ operationGroupName,
348
+ serviceApiVersions,
349
+ );
350
+
351
+ // merge paging method and lro method into lropaging method
352
+ const lroPagingMethod = { ...lroMethod, ...pagingMethod, discriminator: "lropaging" };
353
+
354
+ return [lroMethod.initialOperation, lroPagingMethod];
284
355
  }
285
356
 
286
357
  function emitHttpOperation(
@@ -289,6 +360,7 @@ function emitHttpOperation(
289
360
  operationGroupName: string,
290
361
  operation: SdkHttpOperation,
291
362
  method: SdkServiceMethod<SdkHttpOperation>,
363
+ serviceApiVersions: string[],
292
364
  ): Record<string, any> {
293
365
  const responses: Record<string, any>[] = [];
294
366
  const exceptions: Record<string, any>[] = [];
@@ -301,12 +373,12 @@ function emitHttpOperation(
301
373
  const result = {
302
374
  url: operation.path,
303
375
  method: operation.verb.toUpperCase(),
304
- parameters: emitHttpParameters(context, rootClient, operation, method),
305
- bodyParameter: emitHttpBodyParameter(context, operation.bodyParam),
376
+ parameters: emitHttpParameters(context, rootClient, operation, method, serviceApiVersions),
377
+ bodyParameter: emitHttpBodyParameter(context, operation.bodyParam, serviceApiVersions),
306
378
  responses,
307
379
  exceptions,
308
380
  groupName: operationGroupName,
309
- addedOn: method ? getAddedOn(context, method) : "",
381
+ addedOn: method ? getAddedOn(context, method, serviceApiVersions) : "",
310
382
  discriminator: "basic",
311
383
  isOverload: false,
312
384
  overloads: [],
@@ -373,8 +445,9 @@ function emitHttpPathParameter(
373
445
  context: PythonSdkContext,
374
446
  parameter: SdkPathParameter,
375
447
  operation: SdkHttpOperation,
448
+ serviceApiVersions: string[],
376
449
  ): Record<string, any> {
377
- const base = emitParamBase(context, parameter);
450
+ const base = emitParamBase(context, parameter, undefined, serviceApiVersions);
378
451
  if (parameter.optional && operation.path.includes(`/{${parameter.serializedName}}`)) {
379
452
  operation.path = operation.path.replace(
380
453
  `/{${parameter.serializedName}}`,
@@ -390,12 +463,14 @@ function emitHttpPathParameter(
390
463
  skipUrlEncoding: parameter.allowReserved,
391
464
  };
392
465
  }
466
+
393
467
  function emitHttpHeaderParameter(
394
468
  context: PythonSdkContext,
395
469
  parameter: SdkHeaderParameter,
396
470
  method: SdkServiceMethod<SdkHttpOperation>,
471
+ serviceApiVersions: string[],
397
472
  ): Record<string, any> {
398
- const base = emitParamBase(context, parameter, method);
473
+ const base = emitParamBase(context, parameter, method, serviceApiVersions);
399
474
  const [delimiter, explode] = getDelimiterAndExplode(parameter);
400
475
  let clientDefaultValue = parameter.clientDefaultValue;
401
476
  if (isContentTypeParameter(parameter)) {
@@ -418,16 +493,22 @@ function emitHttpHeaderParameter(
418
493
 
419
494
  function emitHttpQueryParameter(
420
495
  context: PythonSdkContext,
496
+ rootClient: SdkClientType<SdkHttpOperation>,
421
497
  parameter: SdkQueryParameter,
422
498
  method: SdkServiceMethod<SdkHttpOperation>,
499
+ serviceApiVersions: string[],
423
500
  ): Record<string, any> {
424
- const base = emitParamBase(context, parameter, method);
501
+ const base = emitParamBase(context, parameter, method, serviceApiVersions);
425
502
  const [delimiter, explode] = getDelimiterAndExplode(parameter);
426
503
  return {
427
504
  ...base,
428
505
  wireName: parameter.serializedName,
429
506
  location: parameter.kind,
430
- implementation: getImplementation(context, parameter),
507
+ implementation: parameter.isApiVersionParam
508
+ ? rootClient.apiVersions.length > 0 && parameter.onClient
509
+ ? "Client"
510
+ : "Method"
511
+ : getImplementation(context, parameter),
431
512
  delimiter,
432
513
  explode,
433
514
  clientDefaultValue: parameter.clientDefaultValue,
@@ -439,6 +520,7 @@ function emitHttpParameters(
439
520
  rootClient: SdkClientType<SdkHttpOperation>,
440
521
  operation: SdkHttpOperation,
441
522
  method: SdkServiceMethod<SdkHttpOperation>,
523
+ serviceApiVersions: string[],
442
524
  ): Record<string, any>[] {
443
525
  const parameters: Record<string, any>[] = [...context.__endpointPathParameters];
444
526
 
@@ -478,13 +560,15 @@ function emitHttpParameters(
478
560
  for (const parameter of httpParameters) {
479
561
  switch (parameter.kind) {
480
562
  case "header":
481
- parameters.push(emitHttpHeaderParameter(context, parameter, method));
563
+ parameters.push(emitHttpHeaderParameter(context, parameter, method, serviceApiVersions));
482
564
  break;
483
565
  case "query":
484
- parameters.push(emitHttpQueryParameter(context, parameter, method));
566
+ parameters.push(
567
+ emitHttpQueryParameter(context, rootClient, parameter, method, serviceApiVersions),
568
+ );
485
569
  break;
486
570
  case "path":
487
- parameters.push(emitHttpPathParameter(context, parameter, operation));
571
+ parameters.push(emitHttpPathParameter(context, parameter, operation, serviceApiVersions));
488
572
  break;
489
573
  }
490
574
  }
@@ -495,10 +579,11 @@ function emitHttpParameters(
495
579
  function emitHttpBodyParameter(
496
580
  context: PythonSdkContext,
497
581
  bodyParam?: SdkBodyParameter,
582
+ serviceApiVersions: string[] = [],
498
583
  ): Record<string, any> | undefined {
499
584
  if (bodyParam === undefined) return undefined;
500
585
  return {
501
- ...emitParamBase(context, bodyParam),
586
+ ...emitParamBase(context, bodyParam, undefined, serviceApiVersions),
502
587
  contentTypes: bodyParam.contentTypes,
503
588
  location: bodyParam.kind,
504
589
  clientName: bodyParam.isGeneratedName ? "body" : camelToSnakeCase(bodyParam.name),
@@ -514,10 +514,11 @@ export const KnownTypes = {
514
514
  export function emitEndpointType(
515
515
  context: PythonSdkContext,
516
516
  type: SdkEndpointType,
517
+ serviceApiVersions: string[],
517
518
  ): Record<string, any>[] {
518
519
  const params: Record<string, any>[] = [];
519
520
  for (const param of type.templateArguments) {
520
- const paramBase = emitParamBase(context, param);
521
+ const paramBase = emitParamBase(context, param, undefined, serviceApiVersions);
521
522
  paramBase.clientName = context.arm ? "base_url" : paramBase.clientName;
522
523
  params.push({
523
524
  ...paramBase,
@@ -162,16 +162,17 @@ export function getAddedOn<TServiceOperation extends SdkServiceOperation>(
162
162
  | SdkMethodParameter
163
163
  | SdkHttpParameter
164
164
  | SdkMethod<TServiceOperation>,
165
+ serviceApiVersions: string[] = [],
165
166
  ): string | undefined {
166
- // since we do not support multi-service for now, we can just check the root client's api version
167
167
  // if type is added in the first version of the client, we do not need to add the versioning info
168
- if (
169
- type.apiVersions[0] ===
170
- context.sdkPackage.clients.find(
171
- (c) => c.clientInitialization.initializedBy | InitializedByFlags.Individually,
172
- )?.apiVersions[0]
173
- )
174
- return undefined;
168
+ const apiVersions =
169
+ serviceApiVersions.length > 0
170
+ ? serviceApiVersions
171
+ : (context.sdkPackage.clients.find(
172
+ (c) => c.clientInitialization.initializedBy | InitializedByFlags.Individually,
173
+ )?.apiVersions ?? []);
174
+
175
+ if (type.apiVersions[0] === apiVersions[0]) return undefined;
175
176
  return type.apiVersions[0];
176
177
  }
177
178
 
@@ -207,6 +208,7 @@ export function emitParamBase<TServiceOperation extends SdkServiceOperation>(
207
208
  context: PythonSdkContext,
208
209
  parameter: SdkEndpointParameter | SdkCredentialParameter | SdkMethodParameter | SdkHttpParameter,
209
210
  method?: SdkServiceMethod<TServiceOperation>,
211
+ serviceApiVersions: string[] = [],
210
212
  ): ParamBase {
211
213
  let type = getType(context, parameter.type);
212
214
  if (parameter.isApiVersionParam) {
@@ -231,7 +233,7 @@ export function emitParamBase<TServiceOperation extends SdkServiceOperation>(
231
233
  return {
232
234
  optional: parameter.optional,
233
235
  description: (parameter.summary ? parameter.summary : parameter.doc) ?? "",
234
- addedOn: getAddedOn(context, parameter),
236
+ addedOn: getAddedOn(context, parameter, serviceApiVersions),
235
237
  clientName,
236
238
  inOverload: false,
237
239
  isApiVersion: parameter.isApiVersionParam,