@typespec/http-client-python 0.9.0-dev.1 → 0.9.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.
- package/README.md +86 -84
- package/dist/emitter/code-model.d.ts +1 -2
- package/dist/emitter/code-model.d.ts.map +1 -1
- package/dist/emitter/code-model.js +17 -21
- package/dist/emitter/code-model.js.map +1 -1
- package/dist/emitter/emitter.d.ts +0 -2
- package/dist/emitter/emitter.d.ts.map +1 -1
- package/dist/emitter/emitter.js +15 -28
- package/dist/emitter/emitter.js.map +1 -1
- package/dist/emitter/http.d.ts +4 -4
- package/dist/emitter/http.d.ts.map +1 -1
- package/dist/emitter/http.js.map +1 -1
- package/dist/emitter/index.d.ts +1 -1
- package/dist/emitter/index.d.ts.map +1 -1
- package/dist/emitter/index.js +1 -1
- package/dist/emitter/index.js.map +1 -1
- package/dist/emitter/lib.d.ts +63 -21
- package/dist/emitter/lib.d.ts.map +1 -1
- package/dist/emitter/lib.js +47 -27
- package/dist/emitter/lib.js.map +1 -1
- package/dist/emitter/system-requirements.d.ts.map +1 -1
- package/dist/emitter/types.d.ts +3 -3
- package/dist/emitter/types.d.ts.map +1 -1
- package/dist/emitter/types.js +4 -3
- package/dist/emitter/types.js.map +1 -1
- package/dist/emitter/utils.d.ts +5 -5
- package/dist/emitter/utils.d.ts.map +1 -1
- package/dist/emitter/utils.js.map +1 -1
- package/emitter/src/code-model.ts +26 -30
- package/emitter/src/emitter.ts +29 -46
- package/emitter/src/http.ts +18 -21
- package/emitter/src/index.ts +1 -1
- package/emitter/src/lib.ts +66 -39
- package/emitter/src/types.ts +20 -26
- package/emitter/src/utils.ts +6 -9
- package/emitter/temp/tsconfig.tsbuildinfo +1 -1
- package/eng/scripts/Generate.ps1 +3 -0
- package/eng/scripts/ci/lint.ts +3 -6
- package/eng/scripts/ci/pylintrc +1 -1
- package/eng/scripts/ci/regenerate.ts +21 -26
- package/eng/scripts/ci/utils.ts +13 -18
- package/eng/scripts/setup/__pycache__/venvtools.cpython-38.pyc +0 -0
- package/generator/build/lib/pygen/codegen/__init__.py +7 -21
- package/generator/build/lib/pygen/codegen/_utils.py +26 -2
- package/generator/build/lib/pygen/codegen/models/code_model.py +33 -0
- package/generator/build/lib/pygen/codegen/models/credential_types.py +5 -2
- package/generator/build/lib/pygen/codegen/serializers/__init__.py +3 -1
- package/generator/build/lib/pygen/codegen/templates/client_container.py.jinja2 +3 -1
- package/generator/build/lib/pygen/codegen/templates/config_container.py.jinja2 +3 -1
- package/generator/build/lib/pygen/codegen/templates/conftest.py.jinja2 +3 -1
- package/generator/build/lib/pygen/codegen/templates/enum_container.py.jinja2 +3 -1
- package/generator/build/lib/pygen/codegen/templates/init.py.jinja2 +3 -1
- package/generator/build/lib/pygen/codegen/templates/model_base.py.jinja2 +3 -5
- package/generator/build/lib/pygen/codegen/templates/model_container.py.jinja2 +3 -1
- package/generator/build/lib/pygen/codegen/templates/model_init.py.jinja2 +3 -1
- package/generator/build/lib/pygen/codegen/templates/operation_groups_container.py.jinja2 +3 -1
- package/generator/build/lib/pygen/codegen/templates/operations_folder_init.py.jinja2 +3 -1
- package/generator/build/lib/pygen/codegen/templates/packaging_templates/LICENSE.jinja2 +1 -21
- package/generator/build/lib/pygen/codegen/templates/packaging_templates/setup.py.jinja2 +6 -4
- package/generator/build/lib/pygen/codegen/templates/patch.py.jinja2 +9 -4
- package/generator/build/lib/pygen/codegen/templates/request_builders.py.jinja2 +3 -1
- package/generator/build/lib/pygen/codegen/templates/rest_init.py.jinja2 +3 -1
- package/generator/build/lib/pygen/codegen/templates/sample.py.jinja2 +3 -1
- package/generator/build/lib/pygen/codegen/templates/serialization.py.jinja2 +4 -25
- package/generator/build/lib/pygen/codegen/templates/test.py.jinja2 +3 -1
- package/generator/build/lib/pygen/codegen/templates/testpreparer.py.jinja2 +3 -1
- package/generator/build/lib/pygen/codegen/templates/types.py.jinja2 +3 -1
- package/generator/build/lib/pygen/codegen/templates/validation.py.jinja2 +3 -1
- package/generator/build/lib/pygen/codegen/templates/vendor.py.jinja2 +3 -1
- package/generator/build/lib/pygen/codegen/templates/version.py.jinja2 +3 -1
- package/generator/dist/pygen-0.1.0-py3-none-any.whl +0 -0
- package/generator/pygen/codegen/__init__.py +7 -21
- package/generator/pygen/codegen/_utils.py +26 -2
- package/generator/pygen/codegen/models/code_model.py +33 -0
- package/generator/pygen/codegen/models/credential_types.py +5 -2
- package/generator/pygen/codegen/serializers/__init__.py +3 -1
- package/generator/pygen/codegen/templates/client_container.py.jinja2 +3 -1
- package/generator/pygen/codegen/templates/config_container.py.jinja2 +3 -1
- package/generator/pygen/codegen/templates/conftest.py.jinja2 +3 -1
- package/generator/pygen/codegen/templates/enum_container.py.jinja2 +3 -1
- package/generator/pygen/codegen/templates/init.py.jinja2 +3 -1
- package/generator/pygen/codegen/templates/model_base.py.jinja2 +3 -5
- package/generator/pygen/codegen/templates/model_container.py.jinja2 +3 -1
- package/generator/pygen/codegen/templates/model_init.py.jinja2 +3 -1
- package/generator/pygen/codegen/templates/operation_groups_container.py.jinja2 +3 -1
- package/generator/pygen/codegen/templates/operations_folder_init.py.jinja2 +3 -1
- package/generator/pygen/codegen/templates/packaging_templates/LICENSE.jinja2 +1 -21
- package/generator/pygen/codegen/templates/packaging_templates/setup.py.jinja2 +6 -4
- package/generator/pygen/codegen/templates/patch.py.jinja2 +9 -4
- package/generator/pygen/codegen/templates/request_builders.py.jinja2 +3 -1
- package/generator/pygen/codegen/templates/rest_init.py.jinja2 +3 -1
- package/generator/pygen/codegen/templates/sample.py.jinja2 +3 -1
- package/generator/pygen/codegen/templates/serialization.py.jinja2 +4 -25
- package/generator/pygen/codegen/templates/test.py.jinja2 +3 -1
- package/generator/pygen/codegen/templates/testpreparer.py.jinja2 +3 -1
- package/generator/pygen/codegen/templates/types.py.jinja2 +3 -1
- package/generator/pygen/codegen/templates/validation.py.jinja2 +3 -1
- package/generator/pygen/codegen/templates/vendor.py.jinja2 +3 -1
- package/generator/pygen/codegen/templates/version.py.jinja2 +3 -1
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_core_lro_rpc_async.py +2 -2
- package/generator/test/azure/mock_api_tests/test_azure_core_lro_rpc.py +1 -1
- package/generator/test/azure/requirements.txt +2 -1
- package/generator/test/generic_mock_api_tests/asynctests/test_authentication_async.py +4 -0
- package/generator/test/generic_mock_api_tests/asynctests/test_headasboolean_async.py +4 -4
- package/generator/test/generic_mock_api_tests/asynctests/test_streaming_jsonl_async.py +27 -0
- package/generator/test/generic_mock_api_tests/asynctests/test_typetest_model_visibility_async.py +1 -1
- package/generator/test/generic_mock_api_tests/test_authentication.py +4 -0
- package/generator/test/generic_mock_api_tests/test_headasboolean.py +4 -4
- package/generator/test/generic_mock_api_tests/test_streaming_jsonl.py +25 -0
- package/generator/test/generic_mock_api_tests/test_typetest_model_visibility.py +1 -1
- package/generator/test/unbranded/mock_api_tests/asynctests/test_auth_flow_async.py +19 -0
- package/generator/test/unbranded/mock_api_tests/test_auth_flow.py +17 -0
- package/generator/test/unbranded/requirements.txt +1 -0
- package/package.json +35 -26
package/emitter/src/emitter.ts
CHANGED
|
@@ -1,9 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
createSdkContext,
|
|
3
|
-
SdkContext,
|
|
4
|
-
SdkHttpOperation,
|
|
5
|
-
SdkServiceOperation,
|
|
6
|
-
} from "@azure-tools/typespec-client-generator-core";
|
|
1
|
+
import { createSdkContext } from "@azure-tools/typespec-client-generator-core";
|
|
7
2
|
import { EmitContext, NoTarget } from "@typespec/compiler";
|
|
8
3
|
import { execSync } from "child_process";
|
|
9
4
|
import fs from "fs";
|
|
@@ -18,39 +13,18 @@ import { runPython3 } from "./run-python3.js";
|
|
|
18
13
|
import { disableGenerationMap, simpleTypesMap, typesMap } from "./types.js";
|
|
19
14
|
import { getRootNamespace, md2Rst } from "./utils.js";
|
|
20
15
|
|
|
21
|
-
|
|
22
|
-
const specifiedModelsMode = context.emitContext.options["models-mode"];
|
|
23
|
-
if (specifiedModelsMode) {
|
|
24
|
-
const modelModes = ["dpg", "none"];
|
|
25
|
-
if (modelModes.includes(specifiedModelsMode)) {
|
|
26
|
-
return specifiedModelsMode;
|
|
27
|
-
}
|
|
28
|
-
reportDiagnostic(context.program, {
|
|
29
|
-
code: "invalid-models-mode",
|
|
30
|
-
target: NoTarget,
|
|
31
|
-
format: { inValidValue: specifiedModelsMode },
|
|
32
|
-
});
|
|
33
|
-
}
|
|
34
|
-
return "dpg";
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
function addDefaultOptions(sdkContext: SdkContext) {
|
|
16
|
+
function addDefaultOptions(sdkContext: PythonSdkContext) {
|
|
38
17
|
const defaultOptions = {
|
|
39
18
|
"package-version": "1.0.0b1",
|
|
40
19
|
"generate-packaging-files": true,
|
|
41
|
-
flavor: undefined,
|
|
42
20
|
};
|
|
43
21
|
sdkContext.emitContext.options = {
|
|
44
22
|
...defaultOptions,
|
|
45
23
|
...sdkContext.emitContext.options,
|
|
46
24
|
};
|
|
47
25
|
const options = sdkContext.emitContext.options;
|
|
48
|
-
options["models-mode"] = getModelsMode(sdkContext);
|
|
49
|
-
if (options["generate-packaging-files"]) {
|
|
50
|
-
options["package-mode"] = sdkContext.arm ? "azure-mgmt" : "azure-dataplane";
|
|
51
|
-
}
|
|
52
26
|
if (!options["package-name"]) {
|
|
53
|
-
const namespace = getRootNamespace(sdkContext
|
|
27
|
+
const namespace = getRootNamespace(sdkContext);
|
|
54
28
|
const packageName = namespace.replace(/\./g, "-");
|
|
55
29
|
reportDiagnostic(sdkContext.program, {
|
|
56
30
|
code: "no-package-name",
|
|
@@ -59,19 +33,31 @@ function addDefaultOptions(sdkContext: SdkContext) {
|
|
|
59
33
|
});
|
|
60
34
|
options["package-name"] = packageName;
|
|
61
35
|
}
|
|
62
|
-
if (options.flavor !== "azure") {
|
|
36
|
+
if ((options as any).flavor !== "azure") {
|
|
63
37
|
// if they pass in a flavor other than azure, we want to ignore the value
|
|
64
|
-
options.flavor = undefined;
|
|
38
|
+
(options as any).flavor = undefined;
|
|
39
|
+
}
|
|
40
|
+
if (
|
|
41
|
+
(options as any).flavor === undefined &&
|
|
42
|
+
sdkContext.emitContext.emitterOutputDir.includes("azure")
|
|
43
|
+
) {
|
|
44
|
+
(options as any).flavor = "azure";
|
|
65
45
|
}
|
|
66
|
-
|
|
67
|
-
|
|
46
|
+
|
|
47
|
+
if (
|
|
48
|
+
options["package-pprint-name"] !== undefined &&
|
|
49
|
+
!options["package-pprint-name"].startsWith('"')
|
|
50
|
+
) {
|
|
51
|
+
options["package-pprint-name"] = options["use-pyodide"]
|
|
52
|
+
? `${options["package-pprint-name"]}`
|
|
53
|
+
: `"${options["package-pprint-name"]}"`;
|
|
68
54
|
}
|
|
69
55
|
}
|
|
70
56
|
|
|
71
|
-
async function createPythonSdkContext
|
|
57
|
+
async function createPythonSdkContext(
|
|
72
58
|
context: EmitContext<PythonEmitterOptions>,
|
|
73
|
-
): Promise<PythonSdkContext
|
|
74
|
-
const sdkContext = await createSdkContext<PythonEmitterOptions
|
|
59
|
+
): Promise<PythonSdkContext> {
|
|
60
|
+
const sdkContext = await createSdkContext<PythonEmitterOptions>(
|
|
75
61
|
context,
|
|
76
62
|
"@azure-tools/typespec-python",
|
|
77
63
|
);
|
|
@@ -148,7 +134,7 @@ async function onEmitMain(context: EmitContext<PythonEmitterOptions>) {
|
|
|
148
134
|
cleanAllCache();
|
|
149
135
|
|
|
150
136
|
const program = context.program;
|
|
151
|
-
const sdkContext = await createPythonSdkContext
|
|
137
|
+
const sdkContext = await createPythonSdkContext(context);
|
|
152
138
|
const root = path.join(dirname(fileURLToPath(import.meta.url)), "..", "..");
|
|
153
139
|
const outputDir = context.emitterOutputDir;
|
|
154
140
|
addDefaultOptions(sdkContext);
|
|
@@ -175,25 +161,22 @@ async function onEmitMain(context: EmitContext<PythonEmitterOptions>) {
|
|
|
175
161
|
commandArgs["packaging-files-config"] = keyValuePairs.join("|");
|
|
176
162
|
resolvedOptions["packaging-files-config"] = undefined;
|
|
177
163
|
}
|
|
178
|
-
if (
|
|
179
|
-
resolvedOptions["package-pprint-name"] !== undefined &&
|
|
180
|
-
!resolvedOptions["package-pprint-name"].startsWith('"')
|
|
181
|
-
) {
|
|
182
|
-
resolvedOptions["package-pprint-name"] = resolvedOptions["use-pyodide"]
|
|
183
|
-
? `${resolvedOptions["package-pprint-name"]}`
|
|
184
|
-
: `"${resolvedOptions["package-pprint-name"]}"`;
|
|
185
|
-
}
|
|
186
164
|
|
|
187
165
|
for (const [key, value] of Object.entries(resolvedOptions)) {
|
|
166
|
+
if (key === "license") continue; // skip license since it is passed in codeModel
|
|
188
167
|
commandArgs[key] = value;
|
|
189
168
|
}
|
|
169
|
+
if (resolvedOptions["generate-packaging-files"]) {
|
|
170
|
+
commandArgs["package-mode"] = sdkContext.arm ? "azure-mgmt" : "azure-dataplane";
|
|
171
|
+
}
|
|
190
172
|
if (sdkContext.arm === true) {
|
|
191
173
|
commandArgs["azure-arm"] = "true";
|
|
192
174
|
}
|
|
193
|
-
if (resolvedOptions.flavor === "azure") {
|
|
175
|
+
if ((resolvedOptions as any).flavor === "azure") {
|
|
194
176
|
commandArgs["emit-cross-language-definition-file"] = "true";
|
|
195
177
|
}
|
|
196
178
|
commandArgs["from-typespec"] = "true";
|
|
179
|
+
commandArgs["models-mode"] = (resolvedOptions as any)["models-mode"] ?? "dpg";
|
|
197
180
|
|
|
198
181
|
if (!program.compilerOptions.noEmit && !program.hasError()) {
|
|
199
182
|
// if not using pyodide and there's no venv, we try to create venv
|
package/emitter/src/http.ts
CHANGED
|
@@ -48,7 +48,7 @@ function arrayToRecord(examples: SdkHttpOperationExample[] | undefined): Record<
|
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
export function emitBasicHttpMethod(
|
|
51
|
-
context: PythonSdkContext
|
|
51
|
+
context: PythonSdkContext,
|
|
52
52
|
rootClient: SdkClientType<SdkHttpOperation>,
|
|
53
53
|
method: SdkBasicServiceMethod<SdkHttpOperation>,
|
|
54
54
|
operationGroupName: string,
|
|
@@ -65,7 +65,7 @@ export function emitBasicHttpMethod(
|
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
function emitInitialLroHttpMethod(
|
|
68
|
-
context: PythonSdkContext
|
|
68
|
+
context: PythonSdkContext,
|
|
69
69
|
rootClient: SdkClientType<SdkHttpOperation>,
|
|
70
70
|
method: SdkLroServiceMethod<SdkHttpOperation> | SdkLroPagingServiceMethod<SdkHttpOperation>,
|
|
71
71
|
operationGroupName: string,
|
|
@@ -82,7 +82,7 @@ function emitInitialLroHttpMethod(
|
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
function addLroInformation(
|
|
85
|
-
context: PythonSdkContext
|
|
85
|
+
context: PythonSdkContext,
|
|
86
86
|
rootClient: SdkClientType<SdkHttpOperation>,
|
|
87
87
|
method: SdkLroServiceMethod<SdkHttpOperation> | SdkLroPagingServiceMethod<SdkHttpOperation>,
|
|
88
88
|
operationGroupName: string,
|
|
@@ -110,7 +110,7 @@ function getWireNameFromPropertySegments(segments: SdkModelPropertyType[]): stri
|
|
|
110
110
|
}
|
|
111
111
|
|
|
112
112
|
function getWireNameWithDiagnostics(
|
|
113
|
-
context: PythonSdkContext
|
|
113
|
+
context: PythonSdkContext,
|
|
114
114
|
segments: SdkModelPropertyType[] | undefined,
|
|
115
115
|
code: "invalid-paging-items" | "invalid-next-link" | "invalid-lro-result",
|
|
116
116
|
method?: SdkServiceMethod<SdkHttpOperation>,
|
|
@@ -132,7 +132,7 @@ function getWireNameWithDiagnostics(
|
|
|
132
132
|
}
|
|
133
133
|
|
|
134
134
|
function buildContinuationToken(
|
|
135
|
-
context: PythonSdkContext
|
|
135
|
+
context: PythonSdkContext,
|
|
136
136
|
method: SdkPagingServiceMethod<SdkHttpOperation> | SdkLroPagingServiceMethod<SdkHttpOperation>,
|
|
137
137
|
segments: SdkModelPropertyType[],
|
|
138
138
|
input: boolean = true,
|
|
@@ -166,7 +166,7 @@ function buildContinuationToken(
|
|
|
166
166
|
}
|
|
167
167
|
|
|
168
168
|
function buildAllContinuationToken(
|
|
169
|
-
context: PythonSdkContext
|
|
169
|
+
context: PythonSdkContext,
|
|
170
170
|
method: SdkPagingServiceMethod<SdkHttpOperation> | SdkLroPagingServiceMethod<SdkHttpOperation>,
|
|
171
171
|
): Record<string, any> {
|
|
172
172
|
const parameterSegments = method.pagingMetadata.continuationTokenParameterSegments ?? [];
|
|
@@ -181,7 +181,7 @@ function buildAllContinuationToken(
|
|
|
181
181
|
}
|
|
182
182
|
|
|
183
183
|
function addPagingInformation(
|
|
184
|
-
context: PythonSdkContext
|
|
184
|
+
context: PythonSdkContext,
|
|
185
185
|
rootClient: SdkClientType<SdkHttpOperation>,
|
|
186
186
|
method: SdkPagingServiceMethod<SdkHttpOperation> | SdkLroPagingServiceMethod<SdkHttpOperation>,
|
|
187
187
|
operationGroupName: string,
|
|
@@ -223,7 +223,7 @@ function addPagingInformation(
|
|
|
223
223
|
}
|
|
224
224
|
|
|
225
225
|
export function emitLroHttpMethod(
|
|
226
|
-
context: PythonSdkContext
|
|
226
|
+
context: PythonSdkContext,
|
|
227
227
|
rootClient: SdkClientType<SdkHttpOperation>,
|
|
228
228
|
method: SdkLroServiceMethod<SdkHttpOperation>,
|
|
229
229
|
operationGroupName: string,
|
|
@@ -233,7 +233,7 @@ export function emitLroHttpMethod(
|
|
|
233
233
|
}
|
|
234
234
|
|
|
235
235
|
export function emitPagingHttpMethod(
|
|
236
|
-
context: PythonSdkContext
|
|
236
|
+
context: PythonSdkContext,
|
|
237
237
|
rootClient: SdkClientType<SdkHttpOperation>,
|
|
238
238
|
method: SdkPagingServiceMethod<SdkHttpOperation>,
|
|
239
239
|
operationGroupName: string,
|
|
@@ -243,7 +243,7 @@ export function emitPagingHttpMethod(
|
|
|
243
243
|
}
|
|
244
244
|
|
|
245
245
|
export function emitLroPagingHttpMethod(
|
|
246
|
-
context: PythonSdkContext
|
|
246
|
+
context: PythonSdkContext,
|
|
247
247
|
rootClient: SdkClientType<SdkHttpOperation>,
|
|
248
248
|
method: SdkLroPagingServiceMethod<SdkHttpOperation>,
|
|
249
249
|
operationGroupName: string,
|
|
@@ -254,7 +254,7 @@ export function emitLroPagingHttpMethod(
|
|
|
254
254
|
}
|
|
255
255
|
|
|
256
256
|
function emitHttpOperation(
|
|
257
|
-
context: PythonSdkContext
|
|
257
|
+
context: PythonSdkContext,
|
|
258
258
|
rootClient: SdkClientType<SdkHttpOperation>,
|
|
259
259
|
operationGroupName: string,
|
|
260
260
|
operation: SdkHttpOperation,
|
|
@@ -339,10 +339,7 @@ function emitFlattenedParameter(
|
|
|
339
339
|
};
|
|
340
340
|
}
|
|
341
341
|
|
|
342
|
-
function emitHttpPathParameter(
|
|
343
|
-
context: PythonSdkContext<SdkHttpOperation>,
|
|
344
|
-
parameter: SdkPathParameter,
|
|
345
|
-
) {
|
|
342
|
+
function emitHttpPathParameter(context: PythonSdkContext, parameter: SdkPathParameter) {
|
|
346
343
|
const base = emitParamBase(context, parameter);
|
|
347
344
|
return {
|
|
348
345
|
...base,
|
|
@@ -354,7 +351,7 @@ function emitHttpPathParameter(
|
|
|
354
351
|
};
|
|
355
352
|
}
|
|
356
353
|
function emitHttpHeaderParameter(
|
|
357
|
-
context: PythonSdkContext
|
|
354
|
+
context: PythonSdkContext,
|
|
358
355
|
parameter: SdkHeaderParameter,
|
|
359
356
|
method: SdkServiceMethod<SdkHttpOperation>,
|
|
360
357
|
): Record<string, any> {
|
|
@@ -380,7 +377,7 @@ function emitHttpHeaderParameter(
|
|
|
380
377
|
}
|
|
381
378
|
|
|
382
379
|
function emitHttpQueryParameter(
|
|
383
|
-
context: PythonSdkContext
|
|
380
|
+
context: PythonSdkContext,
|
|
384
381
|
parameter: SdkQueryParameter,
|
|
385
382
|
method: SdkServiceMethod<SdkHttpOperation>,
|
|
386
383
|
): Record<string, any> {
|
|
@@ -398,7 +395,7 @@ function emitHttpQueryParameter(
|
|
|
398
395
|
}
|
|
399
396
|
|
|
400
397
|
function emitHttpParameters(
|
|
401
|
-
context: PythonSdkContext
|
|
398
|
+
context: PythonSdkContext,
|
|
402
399
|
rootClient: SdkClientType<SdkHttpOperation>,
|
|
403
400
|
operation: SdkHttpOperation,
|
|
404
401
|
method: SdkServiceMethod<SdkHttpOperation>,
|
|
@@ -421,7 +418,7 @@ function emitHttpParameters(
|
|
|
421
418
|
}
|
|
422
419
|
|
|
423
420
|
function emitHttpBodyParameter(
|
|
424
|
-
context: PythonSdkContext
|
|
421
|
+
context: PythonSdkContext,
|
|
425
422
|
bodyParam?: SdkBodyParameter,
|
|
426
423
|
): Record<string, any> | undefined {
|
|
427
424
|
if (bodyParam === undefined) return undefined;
|
|
@@ -438,7 +435,7 @@ function emitHttpBodyParameter(
|
|
|
438
435
|
}
|
|
439
436
|
|
|
440
437
|
function emitHttpResponse(
|
|
441
|
-
context: PythonSdkContext
|
|
438
|
+
context: PythonSdkContext,
|
|
442
439
|
statusCodes: HttpStatusCodeRange | number | "*",
|
|
443
440
|
response: SdkHttpResponse | SdkHttpErrorResponse,
|
|
444
441
|
method?: SdkServiceMethod<SdkHttpOperation>,
|
|
@@ -479,7 +476,7 @@ function emitHttpResponse(
|
|
|
479
476
|
}
|
|
480
477
|
|
|
481
478
|
function emitHttpResponseHeader(
|
|
482
|
-
context: PythonSdkContext
|
|
479
|
+
context: PythonSdkContext,
|
|
483
480
|
header: SdkServiceResponseHeader,
|
|
484
481
|
): Record<string, any> {
|
|
485
482
|
return {
|
package/emitter/src/index.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export * from "./emitter.js";
|
|
2
|
-
export { $lib } from "./lib.js";
|
|
2
|
+
export { $lib, PythonEmitterOptions, PythonEmitterOptionsSchema } from "./lib.js";
|
package/emitter/src/lib.ts
CHANGED
|
@@ -1,52 +1,85 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
SdkContext,
|
|
3
|
+
UnbrandedSdkEmitterOptions,
|
|
4
|
+
} from "@azure-tools/typespec-client-generator-core";
|
|
2
5
|
import { createTypeSpecLibrary, JSONSchemaType, paramMessage } from "@typespec/compiler";
|
|
3
6
|
|
|
4
7
|
export interface PythonEmitterOptions {
|
|
8
|
+
"api-version"?: string;
|
|
9
|
+
license?: {
|
|
10
|
+
name: string;
|
|
11
|
+
company?: string;
|
|
12
|
+
link?: string;
|
|
13
|
+
header?: string;
|
|
14
|
+
description?: string;
|
|
15
|
+
};
|
|
16
|
+
|
|
5
17
|
"package-version"?: string;
|
|
6
18
|
"package-name"?: string;
|
|
7
|
-
"output-dir"?: string;
|
|
8
19
|
"generate-packaging-files"?: boolean;
|
|
9
20
|
"packaging-files-dir"?: string;
|
|
10
21
|
"packaging-files-config"?: object;
|
|
11
22
|
"package-pprint-name"?: string;
|
|
12
23
|
"head-as-boolean"?: boolean;
|
|
13
|
-
"models-mode"?: string;
|
|
14
|
-
tracing?: boolean;
|
|
15
|
-
"company-name"?: string;
|
|
16
|
-
"generate-test"?: boolean;
|
|
17
|
-
debug?: boolean;
|
|
18
|
-
flavor?: "azure";
|
|
19
|
-
"examples-dir"?: string;
|
|
20
|
-
namespace?: string;
|
|
21
24
|
"use-pyodide"?: boolean;
|
|
22
25
|
}
|
|
23
26
|
|
|
24
|
-
export interface PythonSdkContext
|
|
25
|
-
extends SdkContext<PythonEmitterOptions, TServiceOperation> {
|
|
27
|
+
export interface PythonSdkContext extends SdkContext<PythonEmitterOptions> {
|
|
26
28
|
__endpointPathParameters: Record<string, any>[];
|
|
27
29
|
}
|
|
28
30
|
|
|
29
|
-
const
|
|
31
|
+
export const PythonEmitterOptionsSchema: JSONSchemaType<PythonEmitterOptions> = {
|
|
30
32
|
type: "object",
|
|
31
|
-
additionalProperties: true,
|
|
33
|
+
additionalProperties: true, // since we test azure with unbranded emitter, we need to allow additional properties
|
|
32
34
|
properties: {
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
|
|
36
|
-
"
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
"
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
35
|
+
...UnbrandedSdkEmitterOptions["api-version"],
|
|
36
|
+
...UnbrandedSdkEmitterOptions["license"],
|
|
37
|
+
|
|
38
|
+
"package-version": {
|
|
39
|
+
type: "string",
|
|
40
|
+
nullable: true,
|
|
41
|
+
description: "The version of the package.",
|
|
42
|
+
},
|
|
43
|
+
"package-name": {
|
|
44
|
+
type: "string",
|
|
45
|
+
nullable: true,
|
|
46
|
+
description: "The name of the package.",
|
|
47
|
+
},
|
|
48
|
+
"generate-packaging-files": {
|
|
49
|
+
type: "boolean",
|
|
50
|
+
nullable: true,
|
|
51
|
+
description:
|
|
52
|
+
"Whether to generate packaging files. Packaging files refer to the `setup.py`, `README`, and other files that are needed to package your code.",
|
|
53
|
+
},
|
|
54
|
+
"packaging-files-dir": {
|
|
55
|
+
type: "string",
|
|
56
|
+
nullable: true,
|
|
57
|
+
description:
|
|
58
|
+
"If you are using a custom packaging files directory, you can specify it here. We won't generate with the default packaging files we have.",
|
|
59
|
+
},
|
|
60
|
+
"packaging-files-config": {
|
|
61
|
+
type: "object",
|
|
62
|
+
nullable: true,
|
|
63
|
+
description:
|
|
64
|
+
"If you are using a custom packaging files directory, and have additional configuration parameters you want to pass in during generation, you can specify it here. Only applicable if `packaging-files-dir` is set.",
|
|
65
|
+
},
|
|
66
|
+
"package-pprint-name": {
|
|
67
|
+
type: "string",
|
|
68
|
+
nullable: true,
|
|
69
|
+
description:
|
|
70
|
+
"The name of the package to be used in pretty-printing. Will be the name of the package in `README` and pprinting of `setup.py`.",
|
|
71
|
+
},
|
|
72
|
+
"head-as-boolean": {
|
|
73
|
+
type: "boolean",
|
|
74
|
+
nullable: true,
|
|
75
|
+
description: "Whether to return responses from HEAD requests as boolean. Defaults to `true`.",
|
|
76
|
+
},
|
|
77
|
+
"use-pyodide": {
|
|
78
|
+
type: "boolean",
|
|
79
|
+
nullable: true,
|
|
80
|
+
description:
|
|
81
|
+
"Whether to generate using `pyodide` instead of `python`. If there is no python installed on your device, we will default to using pyodide to generate the code.",
|
|
82
|
+
},
|
|
50
83
|
},
|
|
51
84
|
required: [],
|
|
52
85
|
};
|
|
@@ -61,12 +94,6 @@ const libDef = {
|
|
|
61
94
|
default: paramMessage`Can't generate Python client code from this TypeSpec. Please open an issue on https://github.com/microsoft/typespec'.${"stack"}`,
|
|
62
95
|
},
|
|
63
96
|
},
|
|
64
|
-
"invalid-models-mode": {
|
|
65
|
-
severity: "error",
|
|
66
|
-
messages: {
|
|
67
|
-
default: paramMessage`Invalid value '${"inValidValue"}' for 'models-mode' of tspconfig.yaml and expected values are 'dpg'/'none'.`,
|
|
68
|
-
},
|
|
69
|
-
},
|
|
70
97
|
"pyodide-flag-conflict": {
|
|
71
98
|
severity: "error",
|
|
72
99
|
messages: {
|
|
@@ -113,9 +140,9 @@ const libDef = {
|
|
|
113
140
|
},
|
|
114
141
|
},
|
|
115
142
|
emitter: {
|
|
116
|
-
options:
|
|
143
|
+
options: PythonEmitterOptionsSchema,
|
|
117
144
|
},
|
|
118
145
|
} as const;
|
|
119
146
|
|
|
120
147
|
export const $lib = createTypeSpecLibrary(libDef);
|
|
121
|
-
export const { reportDiagnostic,
|
|
148
|
+
export const { reportDiagnostic, createDiagnostic } = $lib;
|
package/emitter/src/types.ts
CHANGED
|
@@ -11,7 +11,6 @@ import {
|
|
|
11
11
|
SdkEnumType,
|
|
12
12
|
SdkEnumValueType,
|
|
13
13
|
SdkModelType,
|
|
14
|
-
SdkServiceOperation,
|
|
15
14
|
SdkType,
|
|
16
15
|
SdkUnionType,
|
|
17
16
|
UsageFlags,
|
|
@@ -70,8 +69,8 @@ export function getSimpleTypeResult(result: Record<string, any>): Record<string,
|
|
|
70
69
|
return result;
|
|
71
70
|
}
|
|
72
71
|
|
|
73
|
-
export function getType
|
|
74
|
-
context: PythonSdkContext
|
|
72
|
+
export function getType(
|
|
73
|
+
context: PythonSdkContext,
|
|
75
74
|
type: CredentialType | CredentialTypeUnion | Type | SdkType | MultiPartFileType,
|
|
76
75
|
): Record<string, any> {
|
|
77
76
|
switch (type.kind) {
|
|
@@ -93,7 +92,7 @@ export function getType<TServiceOperation extends SdkServiceOperation>(
|
|
|
93
92
|
case "enumvalue":
|
|
94
93
|
return emitEnumMember(type, emitEnum(context, type.enumType));
|
|
95
94
|
case "credential":
|
|
96
|
-
return emitCredential(type);
|
|
95
|
+
return emitCredential(context, type);
|
|
97
96
|
case "bytes":
|
|
98
97
|
case "boolean":
|
|
99
98
|
case "plainDate":
|
|
@@ -128,8 +127,8 @@ export function getType<TServiceOperation extends SdkServiceOperation>(
|
|
|
128
127
|
}
|
|
129
128
|
}
|
|
130
129
|
|
|
131
|
-
function emitMultiPartFile
|
|
132
|
-
context: PythonSdkContext
|
|
130
|
+
function emitMultiPartFile(
|
|
131
|
+
context: PythonSdkContext,
|
|
133
132
|
type: MultiPartFileType,
|
|
134
133
|
): Record<string, any> {
|
|
135
134
|
if (type.type.kind === "array") {
|
|
@@ -144,7 +143,10 @@ function emitMultiPartFile<TServiceOperation extends SdkServiceOperation>(
|
|
|
144
143
|
});
|
|
145
144
|
}
|
|
146
145
|
|
|
147
|
-
function emitCredential(
|
|
146
|
+
function emitCredential(
|
|
147
|
+
context: PythonSdkContext,
|
|
148
|
+
credential: SdkCredentialType,
|
|
149
|
+
): Record<string, any> {
|
|
148
150
|
let credential_type: Record<string, any> = {};
|
|
149
151
|
const scheme = credential.scheme;
|
|
150
152
|
if (scheme.type === "oauth2") {
|
|
@@ -153,6 +155,7 @@ function emitCredential(credential: SdkCredentialType): Record<string, any> {
|
|
|
153
155
|
policy: {
|
|
154
156
|
type: "BearerTokenCredentialPolicy",
|
|
155
157
|
credentialScopes: [],
|
|
158
|
+
flows: (context.emitContext.options as any).flavor === "azure" ? [] : scheme.flows,
|
|
156
159
|
},
|
|
157
160
|
};
|
|
158
161
|
for (const flow of scheme.flows) {
|
|
@@ -218,8 +221,8 @@ function addDisableGenerationMap(type: SdkType): void {
|
|
|
218
221
|
}
|
|
219
222
|
}
|
|
220
223
|
|
|
221
|
-
function emitProperty
|
|
222
|
-
context: PythonSdkContext
|
|
224
|
+
function emitProperty(
|
|
225
|
+
context: PythonSdkContext,
|
|
223
226
|
model: SdkModelType,
|
|
224
227
|
property: SdkBodyModelPropertyType,
|
|
225
228
|
): Record<string, any> {
|
|
@@ -254,10 +257,7 @@ function emitProperty<TServiceOperation extends SdkServiceOperation>(
|
|
|
254
257
|
};
|
|
255
258
|
}
|
|
256
259
|
|
|
257
|
-
function emitModel<
|
|
258
|
-
context: PythonSdkContext<TServiceOperation>,
|
|
259
|
-
type: SdkModelType,
|
|
260
|
-
): Record<string, any> {
|
|
260
|
+
function emitModel(context: PythonSdkContext, type: SdkModelType): Record<string, any> {
|
|
261
261
|
if (isEmptyModel(type)) {
|
|
262
262
|
return KnownTypes.any;
|
|
263
263
|
}
|
|
@@ -320,10 +320,7 @@ function emitModel<TServiceOperation extends SdkServiceOperation>(
|
|
|
320
320
|
return newValue;
|
|
321
321
|
}
|
|
322
322
|
|
|
323
|
-
function emitEnum<
|
|
324
|
-
context: PythonSdkContext<TServiceOperation>,
|
|
325
|
-
type: SdkEnumType,
|
|
326
|
-
): Record<string, any> {
|
|
323
|
+
function emitEnum(context: PythonSdkContext, type: SdkEnumType): Record<string, any> {
|
|
327
324
|
if (typesMap.has(type)) {
|
|
328
325
|
return typesMap.get(type)!;
|
|
329
326
|
}
|
|
@@ -401,8 +398,8 @@ function emitDurationOrDateType(type: SdkDurationType | SdkDateTimeType): Record
|
|
|
401
398
|
});
|
|
402
399
|
}
|
|
403
400
|
|
|
404
|
-
function emitArrayOrDict
|
|
405
|
-
context: PythonSdkContext
|
|
401
|
+
function emitArrayOrDict(
|
|
402
|
+
context: PythonSdkContext,
|
|
406
403
|
type: SdkArrayType | SdkDictionaryType,
|
|
407
404
|
): Record<string, any> {
|
|
408
405
|
const kind = type.kind === "array" ? "list" : type.kind;
|
|
@@ -470,10 +467,7 @@ function emitBuiltInType(
|
|
|
470
467
|
});
|
|
471
468
|
}
|
|
472
469
|
|
|
473
|
-
function emitUnion<
|
|
474
|
-
context: PythonSdkContext<TServiceOperation>,
|
|
475
|
-
type: SdkUnionType,
|
|
476
|
-
): Record<string, any> {
|
|
470
|
+
function emitUnion(context: PythonSdkContext, type: SdkUnionType): Record<string, any> {
|
|
477
471
|
return getSimpleTypeResult({
|
|
478
472
|
name: type.isGeneratedName ? undefined : type.name,
|
|
479
473
|
snakeCaseName: type.isGeneratedName ? undefined : camelToSnakeCase(type.name),
|
|
@@ -508,8 +502,8 @@ export const KnownTypes = {
|
|
|
508
502
|
any: { type: "any" },
|
|
509
503
|
};
|
|
510
504
|
|
|
511
|
-
export function emitEndpointType
|
|
512
|
-
context: PythonSdkContext
|
|
505
|
+
export function emitEndpointType(
|
|
506
|
+
context: PythonSdkContext,
|
|
513
507
|
type: SdkEndpointType,
|
|
514
508
|
): Record<string, any>[] {
|
|
515
509
|
const params: Record<string, any>[] = [];
|
|
@@ -523,7 +517,7 @@ export function emitEndpointType<TServiceOperation extends SdkServiceOperation>(
|
|
|
523
517
|
location: "endpointPath",
|
|
524
518
|
implementation: getImplementation(context, param),
|
|
525
519
|
clientDefaultValue: param.clientDefaultValue,
|
|
526
|
-
skipUrlEncoding: param.allowReserved
|
|
520
|
+
skipUrlEncoding: param.allowReserved,
|
|
527
521
|
});
|
|
528
522
|
context.__endpointPathParameters!.push(params.at(-1)!);
|
|
529
523
|
}
|
package/emitter/src/utils.ts
CHANGED
|
@@ -110,8 +110,8 @@ export function removeUnderscoresFromNamespace(name?: string): string {
|
|
|
110
110
|
return (name || "").replace(/_/g, "");
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
-
export function getImplementation
|
|
114
|
-
context: PythonSdkContext
|
|
113
|
+
export function getImplementation(
|
|
114
|
+
context: PythonSdkContext,
|
|
115
115
|
parameter: SdkParameter | SdkHttpParameter,
|
|
116
116
|
): "Client" | "Method" {
|
|
117
117
|
if (parameter.onClient) return "Client";
|
|
@@ -156,7 +156,7 @@ type ParamBase = {
|
|
|
156
156
|
};
|
|
157
157
|
|
|
158
158
|
export function getAddedOn<TServiceOperation extends SdkServiceOperation>(
|
|
159
|
-
context: PythonSdkContext
|
|
159
|
+
context: PythonSdkContext,
|
|
160
160
|
type: SdkModelPropertyType | SdkMethod<TServiceOperation>,
|
|
161
161
|
): string | undefined {
|
|
162
162
|
// since we do not support multi-service for now, we can just check the root client's api version
|
|
@@ -200,7 +200,7 @@ export function isContinuationToken<TServiceOperation extends SdkServiceOperatio
|
|
|
200
200
|
}
|
|
201
201
|
|
|
202
202
|
export function emitParamBase<TServiceOperation extends SdkServiceOperation>(
|
|
203
|
-
context: PythonSdkContext
|
|
203
|
+
context: PythonSdkContext,
|
|
204
204
|
parameter: SdkParameter | SdkHttpParameter,
|
|
205
205
|
method?: SdkServiceMethod<TServiceOperation>,
|
|
206
206
|
): ParamBase {
|
|
@@ -251,7 +251,7 @@ const LIB_NAMESPACE = [
|
|
|
251
251
|
"typespec.versioning",
|
|
252
252
|
];
|
|
253
253
|
|
|
254
|
-
export function getRootNamespace(context: PythonSdkContext
|
|
254
|
+
export function getRootNamespace(context: PythonSdkContext): string {
|
|
255
255
|
let rootNamespace = "";
|
|
256
256
|
if (context.sdkPackage.clients.length > 0) {
|
|
257
257
|
rootNamespace = context.sdkPackage.clients[0].namespace;
|
|
@@ -270,10 +270,7 @@ export function getRootNamespace(context: PythonSdkContext<SdkServiceOperation>)
|
|
|
270
270
|
return removeUnderscoresFromNamespace(rootNamespace).toLowerCase();
|
|
271
271
|
}
|
|
272
272
|
|
|
273
|
-
export function getClientNamespace
|
|
274
|
-
context: PythonSdkContext<TServiceOperation>,
|
|
275
|
-
clientNamespace: string,
|
|
276
|
-
) {
|
|
273
|
+
export function getClientNamespace(context: PythonSdkContext, clientNamespace: string) {
|
|
277
274
|
if (
|
|
278
275
|
clientNamespace === "" ||
|
|
279
276
|
LIB_NAMESPACE.some((item) => clientNamespace.toLowerCase().startsWith(item))
|