@typespec/http-client-python 0.7.0 → 0.8.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.
Files changed (67) hide show
  1. package/dist/emitter/code-model.js +6 -6
  2. package/dist/emitter/code-model.js.map +1 -1
  3. package/dist/emitter/emitter.d.ts.map +1 -1
  4. package/dist/emitter/emitter.js +97 -59
  5. package/dist/emitter/emitter.js.map +1 -1
  6. package/dist/emitter/external-process.js +3 -3
  7. package/dist/emitter/external-process.js.map +1 -1
  8. package/dist/emitter/http.d.ts.map +1 -1
  9. package/dist/emitter/http.js +81 -23
  10. package/dist/emitter/http.js.map +1 -1
  11. package/dist/emitter/lib.d.ts +37 -1
  12. package/dist/emitter/lib.d.ts.map +1 -1
  13. package/dist/emitter/lib.js +24 -0
  14. package/dist/emitter/lib.js.map +1 -1
  15. package/dist/emitter/types.d.ts.map +1 -1
  16. package/dist/emitter/types.js +6 -4
  17. package/dist/emitter/types.js.map +1 -1
  18. package/dist/emitter/utils.d.ts +5 -2
  19. package/dist/emitter/utils.d.ts.map +1 -1
  20. package/dist/emitter/utils.js +99 -2
  21. package/dist/emitter/utils.js.map +1 -1
  22. package/emitter/src/code-model.ts +8 -8
  23. package/emitter/src/emitter.ts +101 -58
  24. package/emitter/src/external-process.ts +3 -3
  25. package/emitter/src/http.ts +113 -26
  26. package/emitter/src/lib.ts +24 -0
  27. package/emitter/src/types.ts +7 -4
  28. package/emitter/src/utils.ts +118 -1
  29. package/emitter/temp/tsconfig.tsbuildinfo +1 -1
  30. package/emitter/test/utils.test.ts +6 -1
  31. package/eng/scripts/setup/__pycache__/venvtools.cpython-38.pyc +0 -0
  32. package/eng/scripts/setup/run_tsp.py +4 -5
  33. package/generator/build/lib/pygen/__init__.py +3 -3
  34. package/generator/build/lib/pygen/black.py +2 -2
  35. package/generator/build/lib/pygen/codegen/__init__.py +5 -5
  36. package/generator/build/lib/pygen/codegen/models/paging_operation.py +11 -2
  37. package/generator/build/lib/pygen/codegen/models/parameter.py +2 -1
  38. package/generator/build/lib/pygen/codegen/models/request_builder_parameter.py +2 -0
  39. package/generator/build/lib/pygen/codegen/models/response.py +1 -1
  40. package/generator/build/lib/pygen/codegen/serializers/builder_serializer.py +47 -25
  41. package/generator/build/lib/pygen/preprocess/__init__.py +10 -12
  42. package/generator/build/lib/pygen/preprocess/python_mappings.py +1 -1
  43. package/generator/build/lib/pygen/utils.py +5 -5
  44. package/generator/component-detection-pip-report.json +7 -6
  45. package/generator/dist/pygen-0.1.0-py3-none-any.whl +0 -0
  46. package/generator/pygen/__init__.py +3 -3
  47. package/generator/pygen/black.py +2 -2
  48. package/generator/pygen/codegen/__init__.py +5 -5
  49. package/generator/pygen/codegen/models/paging_operation.py +11 -2
  50. package/generator/pygen/codegen/models/parameter.py +2 -1
  51. package/generator/pygen/codegen/models/request_builder_parameter.py +2 -0
  52. package/generator/pygen/codegen/models/response.py +1 -1
  53. package/generator/pygen/codegen/serializers/builder_serializer.py +47 -25
  54. package/generator/pygen/preprocess/__init__.py +10 -12
  55. package/generator/pygen/preprocess/python_mappings.py +1 -1
  56. package/generator/pygen/utils.py +5 -5
  57. package/generator/pygen.egg-info/PKG-INFO +0 -1
  58. package/generator/pygen.egg-info/SOURCES.txt +0 -1
  59. package/generator/pygen.egg-info/requires.txt +0 -1
  60. package/generator/setup.py +0 -1
  61. package/generator/test/generic_mock_api_tests/asynctests/test_payload_pageable_async.py +75 -0
  62. package/generator/test/generic_mock_api_tests/test_payload_pageable.py +54 -0
  63. package/package.json +2 -1
  64. package/generator/build/lib/pygen/m2r.py +0 -65
  65. package/generator/pygen/m2r.py +0 -65
  66. package/generator/test/generic_mock_api_tests/unittests/test_m2r.py +0 -10
  67. package/generator/test/unbranded/mock_api_tests/cadl-ranch-config.yaml +0 -27
@@ -16,7 +16,7 @@ import { saveCodeModelAsYaml } from "./external-process.js";
16
16
  import { PythonEmitterOptions, PythonSdkContext, reportDiagnostic } from "./lib.js";
17
17
  import { runPython3 } from "./run-python3.js";
18
18
  import { disableGenerationMap, simpleTypesMap, typesMap } from "./types.js";
19
- import { removeUnderscoresFromNamespace } from "./utils.js";
19
+ import { md2Rst, removeUnderscoresFromNamespace } from "./utils.js";
20
20
 
21
21
  export function getModelsMode(context: SdkContext): "dpg" | "none" {
22
22
  const specifiedModelsMode = context.emitContext.options["models-mode"];
@@ -80,6 +80,44 @@ async function createPythonSdkContext<TServiceOperation extends SdkServiceOperat
80
80
  };
81
81
  }
82
82
 
83
+ function walkThroughNodes(yamlMap: Record<string, any>): Record<string, any> {
84
+ const stack = [yamlMap];
85
+ const seen = new WeakSet();
86
+
87
+ while (stack.length > 0) {
88
+ const current = stack.pop();
89
+
90
+ if (seen.has(current!)) {
91
+ continue;
92
+ }
93
+ if (current !== undefined && current !== null) {
94
+ seen.add(current);
95
+ }
96
+
97
+ if (Array.isArray(current)) {
98
+ for (let i = 0; i < current.length; i++) {
99
+ if (current[i] !== undefined && typeof current[i] === "object") {
100
+ stack.push(current[i]);
101
+ }
102
+ }
103
+ } else {
104
+ for (const key in current) {
105
+ if (key === "description" || key === "summary") {
106
+ if (current[key] !== undefined) {
107
+ current[key] = md2Rst(current[key]);
108
+ }
109
+ } else if (Array.isArray(current[key])) {
110
+ stack.push(current[key]);
111
+ } else if (current[key] !== undefined && typeof current[key] === "object") {
112
+ stack.push(current[key]);
113
+ }
114
+ }
115
+ }
116
+ }
117
+
118
+ return yamlMap;
119
+ }
120
+
83
121
  function cleanAllCache() {
84
122
  typesMap.clear();
85
123
  simpleTypesMap.clear();
@@ -87,6 +125,23 @@ function cleanAllCache() {
87
125
  }
88
126
 
89
127
  export async function $onEmit(context: EmitContext<PythonEmitterOptions>) {
128
+ try {
129
+ await onEmitMain(context);
130
+ } catch (error: any) {
131
+ const errStackStart =
132
+ "========================================= error stack start ================================================";
133
+ const errStackEnd =
134
+ "========================================= error stack end ================================================";
135
+ const errStack = error.stack ? `\n${errStackStart}\n${error.stack}\n${errStackEnd}` : "";
136
+ reportDiagnostic(context.program, {
137
+ code: "unknown-error",
138
+ target: NoTarget,
139
+ format: { stack: errStack },
140
+ });
141
+ }
142
+ }
143
+
144
+ async function onEmitMain(context: EmitContext<PythonEmitterOptions>) {
90
145
  // clean all cache to make sure emitter could work in watch mode
91
146
  cleanAllCache();
92
147
 
@@ -103,7 +158,10 @@ export async function $onEmit(context: EmitContext<PythonEmitterOptions>) {
103
158
  });
104
159
  return;
105
160
  }
106
- const yamlPath = await saveCodeModelAsYaml("python-yaml-path", yamlMap);
161
+
162
+ const parsedYamlMap = walkThroughNodes(yamlMap);
163
+
164
+ const yamlPath = await saveCodeModelAsYaml("python-yaml-path", parsedYamlMap);
107
165
  const resolvedOptions = sdkContext.emitContext.options;
108
166
  const commandArgs: Record<string, string> = {};
109
167
  if (resolvedOptions["packaging-files-config"]) {
@@ -147,70 +205,55 @@ export async function $onEmit(context: EmitContext<PythonEmitterOptions>) {
147
205
  }
148
206
  }
149
207
 
150
- try {
151
- if (resolvedOptions["use-pyodide"]) {
152
- // here we run with pyodide
153
- const pyodide = await setupPyodideCall(root);
154
- // create the output folder if not exists
155
- if (!fs.existsSync(outputDir)) {
156
- fs.mkdirSync(outputDir, { recursive: true });
157
- }
158
- // mount output folder to pyodide
159
- pyodide.FS.mkdirTree("/output");
160
- pyodide.FS.mount(pyodide.FS.filesystems.NODEFS, { root: outputDir }, "/output");
161
- // mount yaml file to pyodide
162
- pyodide.FS.mkdirTree("/yaml");
163
- pyodide.FS.mount(pyodide.FS.filesystems.NODEFS, { root: path.dirname(yamlPath) }, "/yaml");
164
- const globals = pyodide.toPy({
165
- outputFolder: "/output",
166
- yamlFile: `/yaml/${path.basename(yamlPath)}`,
167
- commandArgs,
168
- });
169
- const pythonCode = `
208
+ if (resolvedOptions["use-pyodide"]) {
209
+ // here we run with pyodide
210
+ const pyodide = await setupPyodideCall(root);
211
+ // create the output folder if not exists
212
+ if (!fs.existsSync(outputDir)) {
213
+ fs.mkdirSync(outputDir, { recursive: true });
214
+ }
215
+ // mount output folder to pyodide
216
+ pyodide.FS.mkdirTree("/output");
217
+ pyodide.FS.mount(pyodide.FS.filesystems.NODEFS, { root: outputDir }, "/output");
218
+ // mount yaml file to pyodide
219
+ pyodide.FS.mkdirTree("/yaml");
220
+ pyodide.FS.mount(pyodide.FS.filesystems.NODEFS, { root: path.dirname(yamlPath) }, "/yaml");
221
+ const globals = pyodide.toPy({
222
+ outputFolder: "/output",
223
+ yamlFile: `/yaml/${path.basename(yamlPath)}`,
224
+ commandArgs,
225
+ });
226
+ const pythonCode = `
170
227
  async def main():
171
228
  import warnings
172
229
  with warnings.catch_warnings():
173
- warnings.simplefilter("ignore", SyntaxWarning) # bc of m2r2 dep issues
174
- from pygen import m2r, preprocess, codegen, black
175
- m2r.M2R(output_folder=outputFolder, cadl_file=yamlFile, **commandArgs).process()
176
- preprocess.PreProcessPlugin(output_folder=outputFolder, cadl_file=yamlFile, **commandArgs).process()
177
- codegen.CodeGenerator(output_folder=outputFolder, cadl_file=yamlFile, **commandArgs).process()
230
+ from pygen import preprocess, codegen, black
231
+ preprocess.PreProcessPlugin(output_folder=outputFolder, tsp_file=yamlFile, **commandArgs).process()
232
+ codegen.CodeGenerator(output_folder=outputFolder, tsp_file=yamlFile, **commandArgs).process()
178
233
  black.BlackScriptPlugin(output_folder=outputFolder, **commandArgs).process()
179
234
 
180
235
  await main()`;
181
- await pyodide.runPythonAsync(pythonCode, { globals });
236
+ await pyodide.runPythonAsync(pythonCode, { globals });
237
+ } else {
238
+ // here we run with native python
239
+ let venvPath = path.join(root, "venv");
240
+ if (fs.existsSync(path.join(venvPath, "bin"))) {
241
+ venvPath = path.join(venvPath, "bin", "python");
242
+ } else if (fs.existsSync(path.join(venvPath, "Scripts"))) {
243
+ venvPath = path.join(venvPath, "Scripts", "python.exe");
182
244
  } else {
183
- // here we run with native python
184
- let venvPath = path.join(root, "venv");
185
- if (fs.existsSync(path.join(venvPath, "bin"))) {
186
- venvPath = path.join(venvPath, "bin", "python");
187
- } else if (fs.existsSync(path.join(venvPath, "Scripts"))) {
188
- venvPath = path.join(venvPath, "Scripts", "python.exe");
189
- } else {
190
- reportDiagnostic(program, {
191
- code: "pyodide-flag-conflict",
192
- target: NoTarget,
193
- });
194
- }
195
- commandArgs["output-folder"] = outputDir;
196
- commandArgs["cadl-file"] = yamlPath;
197
- const commandFlags = Object.entries(commandArgs)
198
- .map(([key, value]) => `--${key}=${value}`)
199
- .join(" ");
200
- const command = `${venvPath} ${root}/eng/scripts/setup/run_tsp.py ${commandFlags}`;
201
- execSync(command, { stdio: [process.stdin, process.stdout] });
245
+ reportDiagnostic(program, {
246
+ code: "pyodide-flag-conflict",
247
+ target: NoTarget,
248
+ });
202
249
  }
203
- } catch (error: any) {
204
- const errStackStart =
205
- "========================================= error stack start ================================================";
206
- const errStackEnd =
207
- "========================================= error stack end ================================================";
208
- const errStack = error.stack ? `\n${errStackStart}\n${error.stack}\n${errStackEnd}` : "";
209
- reportDiagnostic(program, {
210
- code: "unknown-error",
211
- target: NoTarget,
212
- format: { stack: errStack },
213
- });
250
+ commandArgs["output-folder"] = outputDir;
251
+ commandArgs["tsp-file"] = yamlPath;
252
+ const commandFlags = Object.entries(commandArgs)
253
+ .map(([key, value]) => `--${key}=${value}`)
254
+ .join(" ");
255
+ const command = `${venvPath} ${root}/eng/scripts/setup/run_tsp.py ${commandFlags}`;
256
+ execSync(command, { stdio: [process.stdin, process.stdout] });
214
257
  }
215
258
  }
216
259
  }
@@ -5,10 +5,10 @@ import { mkdir, writeFile } from "fs/promises";
5
5
  import jsyaml from "js-yaml";
6
6
  import os from "os";
7
7
 
8
- const cadlCodeGenTempDir = joinPaths(os.tmpdir(), "cadl-codegen");
8
+ const tspCodeGenTempDir = joinPaths(os.tmpdir(), "tsp-codegen");
9
9
 
10
10
  export function createTempPath(extension: string, prefix: string = "") {
11
- return joinPaths(cadlCodeGenTempDir, prefix + randomUUID() + extension);
11
+ return joinPaths(tspCodeGenTempDir, prefix + randomUUID() + extension);
12
12
  }
13
13
 
14
14
  /**
@@ -18,7 +18,7 @@ export function createTempPath(extension: string, prefix: string = "") {
18
18
  * @return the absolute path to the created codemodel.
19
19
  */
20
20
  export async function saveCodeModelAsYaml(name: string, codemodel: unknown): Promise<string> {
21
- await mkdir(cadlCodeGenTempDir, { recursive: true });
21
+ await mkdir(tspCodeGenTempDir, { recursive: true });
22
22
  const filename = createTempPath(".yaml", name);
23
23
  const yamlStr = jsyaml.dump(codemodel);
24
24
  await writeFile(filename, yamlStr);
@@ -1,6 +1,7 @@
1
+ import { NoTarget } from "@typespec/compiler";
2
+
1
3
  import {
2
4
  SdkBasicServiceMethod,
3
- SdkBodyModelPropertyType,
4
5
  SdkBodyParameter,
5
6
  SdkClientType,
6
7
  SdkHeaderParameter,
@@ -10,16 +11,16 @@ import {
10
11
  SdkHttpResponse,
11
12
  SdkLroPagingServiceMethod,
12
13
  SdkLroServiceMethod,
14
+ SdkModelPropertyType,
13
15
  SdkPagingServiceMethod,
14
16
  SdkPathParameter,
15
17
  SdkQueryParameter,
16
18
  SdkServiceMethod,
17
19
  SdkServiceResponseHeader,
18
- SdkType,
19
20
  UsageFlags,
20
21
  } from "@azure-tools/typespec-client-generator-core";
21
22
  import { HttpStatusCodeRange } from "@typespec/http";
22
- import { PythonSdkContext } from "./lib.js";
23
+ import { PythonSdkContext, reportDiagnostic } from "./lib.js";
23
24
  import { KnownTypes, getType } from "./types.js";
24
25
  import {
25
26
  camelToSnakeCase,
@@ -29,6 +30,7 @@ import {
29
30
  getImplementation,
30
31
  isAbstract,
31
32
  isAzureCoreErrorResponse,
33
+ isContinuationToken,
32
34
  } from "./utils.js";
33
35
 
34
36
  function isContentTypeParameter(parameter: SdkHeaderParameter) {
@@ -96,6 +98,88 @@ function addLroInformation(
96
98
  };
97
99
  }
98
100
 
101
+ function getWireNameFromPropertySegments(segments: SdkModelPropertyType[]): string | undefined {
102
+ if (segments[0].kind === "property") {
103
+ return segments
104
+ .filter((s) => s.kind === "property")
105
+ .map((s) => s.serializationOptions.json?.name ?? "")
106
+ .join(".");
107
+ }
108
+
109
+ return undefined;
110
+ }
111
+
112
+ function getWireNameWithDiagnostics(
113
+ context: PythonSdkContext<SdkHttpOperation>,
114
+ segments: SdkModelPropertyType[] | undefined,
115
+ code: "invalid-paging-items" | "invalid-next-link" | "invalid-lro-result",
116
+ method?: SdkServiceMethod<SdkHttpOperation>,
117
+ ): string | undefined {
118
+ if (segments && segments.length > 0) {
119
+ const result = getWireNameFromPropertySegments(segments);
120
+ if (result) {
121
+ return result;
122
+ }
123
+ const operationId = method ? method.name : "";
124
+ reportDiagnostic(context.program, {
125
+ code: code,
126
+ target: NoTarget,
127
+ format: { operationId: operationId },
128
+ });
129
+ }
130
+
131
+ return undefined;
132
+ }
133
+
134
+ function buildContinuationToken(
135
+ context: PythonSdkContext<SdkHttpOperation>,
136
+ method: SdkPagingServiceMethod<SdkHttpOperation> | SdkLroPagingServiceMethod<SdkHttpOperation>,
137
+ segments: SdkModelPropertyType[],
138
+ input: boolean = true,
139
+ ): Record<string, any> {
140
+ if (segments[0].kind === "property") {
141
+ const wireName = getWireNameFromPropertySegments(segments);
142
+ if (wireName) {
143
+ return { wireName, location: "body" };
144
+ }
145
+ } else if (input) {
146
+ for (const parameter of method.operation.parameters) {
147
+ if (isContinuationToken(parameter, method)) {
148
+ return { wireName: parameter.serializedName, location: parameter.kind };
149
+ }
150
+ }
151
+ } else {
152
+ for (const response of method.operation.responses) {
153
+ for (const header of response.headers) {
154
+ if (isContinuationToken(header, method, false)) {
155
+ return { wireName: header.serializedName, location: "header" };
156
+ }
157
+ }
158
+ }
159
+ }
160
+ reportDiagnostic(context.program, {
161
+ code: "invalid-continuation-token",
162
+ target: NoTarget,
163
+ format: { operationId: method.name, direction: input ? "request" : "response" },
164
+ });
165
+ return {};
166
+ }
167
+
168
+ function buildAllContinuationToken(
169
+ context: PythonSdkContext<SdkHttpOperation>,
170
+ method: SdkPagingServiceMethod<SdkHttpOperation> | SdkLroPagingServiceMethod<SdkHttpOperation>,
171
+ ): Record<string, any> {
172
+ const parameterSegments = method.pagingMetadata.continuationTokenParameterSegments ?? [];
173
+ const responseSegments = method.pagingMetadata.continuationTokenResponseSegments ?? [];
174
+ if (parameterSegments.length > 0 && responseSegments.length > 0) {
175
+ return {
176
+ input: buildContinuationToken(context, method, parameterSegments),
177
+ output: buildContinuationToken(context, method, responseSegments, false),
178
+ };
179
+ }
180
+ return {};
181
+ }
182
+
99
183
  function addPagingInformation(
100
184
  context: PythonSdkContext<SdkHttpOperation>,
101
185
  rootClient: SdkClientType<SdkHttpOperation>,
@@ -109,13 +193,17 @@ function addPagingInformation(
109
193
  }
110
194
  const itemType = getType(context, method.response.type!);
111
195
  const base = emitHttpOperation(context, rootClient, operationGroupName, method.operation, method);
112
- const itemName = getPropertyWireName(
113
- method.operation.responses[0].type,
114
- method.response.resultPath,
196
+ const itemName = getWireNameWithDiagnostics(
197
+ context,
198
+ method.response.resultSegments,
199
+ "invalid-paging-items",
200
+ method,
115
201
  );
116
- const continuationTokenName = getPropertyWireName(
117
- method.operation.responses[0].type,
118
- method.nextLinkPath,
202
+ const nextLinkName = getWireNameWithDiagnostics(
203
+ context,
204
+ method.pagingMetadata.nextLinkSegments,
205
+ "invalid-next-link",
206
+ method,
119
207
  );
120
208
  base.responses.forEach((resp: Record<string, any>) => {
121
209
  resp.type = itemType;
@@ -126,23 +214,14 @@ function addPagingInformation(
126
214
  discriminator: "paging",
127
215
  exposeStreamKeyword: false,
128
216
  itemName,
129
- continuationTokenName,
217
+ nextLinkName,
130
218
  itemType,
131
219
  description: method.doc ?? "",
132
220
  summary: method.summary,
221
+ continuationToken: buildAllContinuationToken(context, method),
133
222
  };
134
223
  }
135
224
 
136
- function getPropertyWireName(type: SdkType | undefined, path?: string) {
137
- if (!path || !type || type.kind !== "model") return path;
138
- for (const property of type.properties) {
139
- if (property.name === path) {
140
- return (property as SdkBodyModelPropertyType).serializedName;
141
- }
142
- }
143
- return path;
144
- }
145
-
146
225
  export function emitLroHttpMethod(
147
226
  context: PythonSdkContext<SdkHttpOperation>,
148
227
  rootClient: SdkClientType<SdkHttpOperation>,
@@ -192,7 +271,7 @@ function emitHttpOperation(
192
271
  const result = {
193
272
  url: operation.path,
194
273
  method: operation.verb.toUpperCase(),
195
- parameters: emitHttpParameters(context, rootClient, operation),
274
+ parameters: emitHttpParameters(context, rootClient, operation, method),
196
275
  bodyParameter: emitHttpBodyParameter(context, operation.bodyParam),
197
276
  responses,
198
277
  exceptions,
@@ -277,8 +356,9 @@ function emitHttpPathParameter(
277
356
  function emitHttpHeaderParameter(
278
357
  context: PythonSdkContext<SdkHttpOperation>,
279
358
  parameter: SdkHeaderParameter,
359
+ method: SdkServiceMethod<SdkHttpOperation>,
280
360
  ): Record<string, any> {
281
- const base = emitParamBase(context, parameter);
361
+ const base = emitParamBase(context, parameter, method);
282
362
  const [delimiter, explode] = getDelimiterAndExplode(parameter);
283
363
  let clientDefaultValue = parameter.clientDefaultValue;
284
364
  if (isContentTypeParameter(parameter)) {
@@ -302,8 +382,9 @@ function emitHttpHeaderParameter(
302
382
  function emitHttpQueryParameter(
303
383
  context: PythonSdkContext<SdkHttpOperation>,
304
384
  parameter: SdkQueryParameter,
385
+ method: SdkServiceMethod<SdkHttpOperation>,
305
386
  ): Record<string, any> {
306
- const base = emitParamBase(context, parameter);
387
+ const base = emitParamBase(context, parameter, method);
307
388
  const [delimiter, explode] = getDelimiterAndExplode(parameter);
308
389
  return {
309
390
  ...base,
@@ -320,15 +401,16 @@ function emitHttpParameters(
320
401
  context: PythonSdkContext<SdkHttpOperation>,
321
402
  rootClient: SdkClientType<SdkHttpOperation>,
322
403
  operation: SdkHttpOperation,
404
+ method: SdkServiceMethod<SdkHttpOperation>,
323
405
  ): Record<string, any>[] {
324
406
  const parameters: Record<string, any>[] = [...context.__endpointPathParameters];
325
407
  for (const parameter of operation.parameters) {
326
408
  switch (parameter.kind) {
327
409
  case "header":
328
- parameters.push(emitHttpHeaderParameter(context, parameter));
410
+ parameters.push(emitHttpHeaderParameter(context, parameter, method));
329
411
  break;
330
412
  case "query":
331
- parameters.push(emitHttpQueryParameter(context, parameter));
413
+ parameters.push(emitHttpQueryParameter(context, parameter, method));
332
414
  break;
333
415
  case "path":
334
416
  parameters.push(emitHttpPathParameter(context, parameter));
@@ -387,7 +469,12 @@ function emitHttpResponse(
387
469
  type,
388
470
  contentTypes: response.contentTypes,
389
471
  defaultContentType: response.defaultContentType ?? "application/json",
390
- resultProperty: method?.response.resultPath,
472
+ resultProperty: getWireNameWithDiagnostics(
473
+ context,
474
+ method?.response.resultSegments,
475
+ "invalid-lro-result",
476
+ method,
477
+ ),
391
478
  };
392
479
  }
393
480
 
@@ -83,6 +83,30 @@ const libDef = {
83
83
  default: "Can't generate Python SDK since no client defined in typespec file.",
84
84
  },
85
85
  },
86
+ "invalid-paging-items": {
87
+ severity: "warning",
88
+ messages: {
89
+ default: paramMessage`No valid paging items for operation '${"operationId"}'.`,
90
+ },
91
+ },
92
+ "invalid-next-link": {
93
+ severity: "warning",
94
+ messages: {
95
+ default: paramMessage`No valid next link for operation '${"operationId"}'.`,
96
+ },
97
+ },
98
+ "invalid-lro-result": {
99
+ severity: "warning",
100
+ messages: {
101
+ default: paramMessage`No valid LRO result for operation '${"operationId"}'.`,
102
+ },
103
+ },
104
+ "invalid-continuation-token": {
105
+ severity: "warning",
106
+ messages: {
107
+ default: paramMessage`No valid continuation token in '${"direction"}' for operation '${"operationId"}'.`,
108
+ },
109
+ },
86
110
  },
87
111
  emitter: {
88
112
  options: EmitterOptionsSchema as JSONSchemaType<PythonEmitterOptions>,
@@ -294,7 +294,7 @@ function emitModel<TServiceOperation extends SdkServiceOperation>(
294
294
  usage: type.usage,
295
295
  isXml: type.usage & UsageFlags.Xml ? true : false,
296
296
  xmlMetadata: getXmlMetadata(type),
297
- clientNamespace: getClientNamespace(context, type.clientNamespace),
297
+ clientNamespace: getClientNamespace(context, type.namespace),
298
298
  };
299
299
 
300
300
  typesMap.set(type, newValue);
@@ -341,13 +341,16 @@ function emitEnum<TServiceOperation extends SdkServiceOperation>(
341
341
  if (!type.isFixed) {
342
342
  types.push(emitBuiltInType(type.valueType));
343
343
  }
344
- return {
344
+
345
+ const newValue = {
345
346
  description: "",
346
347
  internal: true,
347
348
  type: "combined",
348
349
  types,
349
350
  xmlMetadata: {},
350
351
  };
352
+ typesMap.set(type, newValue);
353
+ return newValue;
351
354
  }
352
355
  const values: Record<string, any>[] = [];
353
356
  const name = type.name;
@@ -361,7 +364,7 @@ function emitEnum<TServiceOperation extends SdkServiceOperation>(
361
364
  values,
362
365
  xmlMetadata: {},
363
366
  crossLanguageDefinitionId: type.crossLanguageDefinitionId,
364
- clientNamespace: getClientNamespace(context, type.clientNamespace),
367
+ clientNamespace: getClientNamespace(context, type.namespace),
365
368
  };
366
369
  for (const value of type.values) {
367
370
  newValue.values.push(emitEnumMember(value, newValue));
@@ -479,7 +482,7 @@ function emitUnion<TServiceOperation extends SdkServiceOperation>(
479
482
  type: "combined",
480
483
  types: type.variantTypes.map((x) => getType(context, x)),
481
484
  xmlMetadata: {},
482
- clientNamespace: getClientNamespace(context, type.clientNamespace),
485
+ clientNamespace: getClientNamespace(context, type.namespace),
483
486
  });
484
487
  }
485
488