@typespec/http-client-python 0.5.0 → 0.6.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.
- package/dist/emitter/code-model.d.ts.map +1 -1
- package/dist/emitter/code-model.js +10 -7
- package/dist/emitter/code-model.js.map +1 -1
- package/dist/emitter/emitter.d.ts.map +1 -1
- package/dist/emitter/emitter.js +35 -7
- package/dist/emitter/emitter.js.map +1 -1
- package/dist/emitter/http.js +1 -1
- package/dist/emitter/http.js.map +1 -1
- package/dist/emitter/lib.d.ts +1 -0
- package/dist/emitter/lib.d.ts.map +1 -1
- package/dist/emitter/lib.js +1 -0
- package/dist/emitter/lib.js.map +1 -1
- package/dist/emitter/types.d.ts.map +1 -1
- package/dist/emitter/types.js +7 -4
- package/dist/emitter/types.js.map +1 -1
- package/dist/emitter/utils.d.ts +1 -0
- package/dist/emitter/utils.d.ts.map +1 -1
- package/dist/emitter/utils.js +19 -0
- package/dist/emitter/utils.js.map +1 -1
- package/emitter/src/code-model.ts +16 -6
- package/emitter/src/emitter.ts +37 -11
- package/emitter/src/http.ts +1 -1
- package/emitter/src/lib.ts +4 -0
- package/emitter/src/types.ts +16 -4
- package/emitter/src/utils.ts +27 -0
- package/emitter/temp/tsconfig.tsbuildinfo +1 -1
- package/eng/scripts/Test-Packages.ps1 +1 -1
- package/eng/scripts/ci/regenerate.ts +21 -14
- package/eng/scripts/setup/__pycache__/venvtools.cpython-38.pyc +0 -0
- package/eng/scripts/setup/install.py +0 -5
- package/eng/scripts/setup/install.ts +0 -20
- package/generator/build/lib/pygen/black.py +2 -2
- package/generator/build/lib/pygen/codegen/__init__.py +6 -4
- package/generator/build/lib/pygen/codegen/_utils.py +4 -0
- package/generator/build/lib/pygen/codegen/models/base.py +2 -3
- package/generator/build/lib/pygen/codegen/models/base_builder.py +5 -3
- package/generator/build/lib/pygen/codegen/models/client.py +28 -19
- package/generator/build/lib/pygen/codegen/models/code_model.py +200 -33
- package/generator/build/lib/pygen/codegen/models/combined_type.py +8 -5
- package/generator/build/lib/pygen/codegen/models/constant_type.py +2 -3
- package/generator/build/lib/pygen/codegen/models/credential_types.py +1 -2
- package/generator/build/lib/pygen/codegen/models/dictionary_type.py +2 -3
- package/generator/build/lib/pygen/codegen/models/enum_type.py +47 -24
- package/generator/build/lib/pygen/codegen/models/imports.py +14 -12
- package/generator/build/lib/pygen/codegen/models/list_type.py +2 -3
- package/generator/build/lib/pygen/codegen/models/lro_operation.py +8 -4
- package/generator/build/lib/pygen/codegen/models/lro_paging_operation.py +2 -2
- package/generator/build/lib/pygen/codegen/models/model_type.py +34 -19
- package/generator/build/lib/pygen/codegen/models/operation.py +66 -29
- package/generator/build/lib/pygen/codegen/models/operation_group.py +56 -11
- package/generator/build/lib/pygen/codegen/models/paging_operation.py +9 -6
- package/generator/build/lib/pygen/codegen/models/parameter.py +10 -10
- package/generator/build/lib/pygen/codegen/models/parameter_list.py +7 -7
- package/generator/build/lib/pygen/codegen/models/primitive_types.py +23 -43
- package/generator/build/lib/pygen/codegen/models/property.py +7 -7
- package/generator/build/lib/pygen/codegen/models/request_builder.py +9 -15
- package/generator/build/lib/pygen/codegen/models/response.py +6 -8
- package/generator/build/lib/pygen/codegen/models/utils.py +11 -0
- package/generator/build/lib/pygen/codegen/serializers/__init__.py +201 -242
- package/generator/build/lib/pygen/codegen/serializers/base_serializer.py +19 -1
- package/generator/build/lib/pygen/codegen/serializers/builder_serializer.py +53 -35
- package/generator/build/lib/pygen/codegen/serializers/client_serializer.py +9 -5
- package/generator/build/lib/pygen/codegen/serializers/enum_serializer.py +17 -3
- package/generator/build/lib/pygen/codegen/serializers/general_serializer.py +26 -14
- package/generator/build/lib/pygen/codegen/serializers/metadata_serializer.py +26 -8
- package/generator/build/lib/pygen/codegen/serializers/model_init_serializer.py +9 -4
- package/generator/build/lib/pygen/codegen/serializers/model_serializer.py +62 -22
- package/generator/build/lib/pygen/codegen/serializers/operation_groups_serializer.py +19 -16
- package/generator/build/lib/pygen/codegen/serializers/operations_init_serializer.py +5 -10
- package/generator/build/lib/pygen/codegen/serializers/parameter_serializer.py +10 -7
- package/generator/build/lib/pygen/codegen/serializers/request_builders_serializer.py +10 -1
- package/generator/build/lib/pygen/codegen/serializers/sample_serializer.py +7 -10
- package/generator/build/lib/pygen/codegen/serializers/test_serializer.py +24 -28
- package/generator/build/lib/pygen/codegen/serializers/types_serializer.py +6 -1
- package/generator/build/lib/pygen/codegen/serializers/utils.py +1 -15
- package/generator/build/lib/pygen/codegen/templates/client_container.py.jinja2 +1 -1
- package/generator/build/lib/pygen/codegen/templates/config_container.py.jinja2 +1 -1
- package/generator/build/lib/pygen/codegen/templates/enum_container.py.jinja2 +1 -1
- package/generator/build/lib/pygen/codegen/templates/init.py.jinja2 +1 -1
- package/generator/build/lib/pygen/codegen/templates/model_container.py.jinja2 +1 -1
- package/generator/build/lib/pygen/codegen/templates/operations_folder_init.py.jinja2 +2 -4
- package/generator/build/lib/pygen/codegen/templates/test.py.jinja2 +3 -3
- package/generator/build/lib/pygen/codegen/templates/testpreparer.py.jinja2 +2 -2
- package/generator/build/lib/pygen/codegen/templates/vendor.py.jinja2 +4 -4
- package/generator/build/lib/pygen/preprocess/__init__.py +0 -4
- package/generator/dev_requirements.txt +2 -2
- package/generator/dist/pygen-0.1.0-py3-none-any.whl +0 -0
- package/generator/pygen/black.py +2 -2
- package/generator/pygen/codegen/__init__.py +6 -4
- package/generator/pygen/codegen/_utils.py +4 -0
- package/generator/pygen/codegen/models/base.py +2 -3
- package/generator/pygen/codegen/models/base_builder.py +5 -3
- package/generator/pygen/codegen/models/client.py +28 -19
- package/generator/pygen/codegen/models/code_model.py +200 -33
- package/generator/pygen/codegen/models/combined_type.py +8 -5
- package/generator/pygen/codegen/models/constant_type.py +2 -3
- package/generator/pygen/codegen/models/credential_types.py +1 -2
- package/generator/pygen/codegen/models/dictionary_type.py +2 -3
- package/generator/pygen/codegen/models/enum_type.py +47 -24
- package/generator/pygen/codegen/models/imports.py +14 -12
- package/generator/pygen/codegen/models/list_type.py +2 -3
- package/generator/pygen/codegen/models/lro_operation.py +8 -4
- package/generator/pygen/codegen/models/lro_paging_operation.py +2 -2
- package/generator/pygen/codegen/models/model_type.py +34 -19
- package/generator/pygen/codegen/models/operation.py +66 -29
- package/generator/pygen/codegen/models/operation_group.py +56 -11
- package/generator/pygen/codegen/models/paging_operation.py +9 -6
- package/generator/pygen/codegen/models/parameter.py +10 -10
- package/generator/pygen/codegen/models/parameter_list.py +7 -7
- package/generator/pygen/codegen/models/primitive_types.py +23 -43
- package/generator/pygen/codegen/models/property.py +7 -7
- package/generator/pygen/codegen/models/request_builder.py +9 -15
- package/generator/pygen/codegen/models/response.py +6 -8
- package/generator/pygen/codegen/models/utils.py +11 -0
- package/generator/pygen/codegen/serializers/__init__.py +201 -242
- package/generator/pygen/codegen/serializers/base_serializer.py +19 -1
- package/generator/pygen/codegen/serializers/builder_serializer.py +53 -35
- package/generator/pygen/codegen/serializers/client_serializer.py +9 -5
- package/generator/pygen/codegen/serializers/enum_serializer.py +17 -3
- package/generator/pygen/codegen/serializers/general_serializer.py +26 -14
- package/generator/pygen/codegen/serializers/metadata_serializer.py +26 -8
- package/generator/pygen/codegen/serializers/model_init_serializer.py +9 -4
- package/generator/pygen/codegen/serializers/model_serializer.py +62 -22
- package/generator/pygen/codegen/serializers/operation_groups_serializer.py +19 -16
- package/generator/pygen/codegen/serializers/operations_init_serializer.py +5 -10
- package/generator/pygen/codegen/serializers/parameter_serializer.py +10 -7
- package/generator/pygen/codegen/serializers/request_builders_serializer.py +10 -1
- package/generator/pygen/codegen/serializers/sample_serializer.py +7 -10
- package/generator/pygen/codegen/serializers/test_serializer.py +24 -28
- package/generator/pygen/codegen/serializers/types_serializer.py +6 -1
- package/generator/pygen/codegen/serializers/utils.py +1 -15
- package/generator/pygen/codegen/templates/client_container.py.jinja2 +1 -1
- package/generator/pygen/codegen/templates/config_container.py.jinja2 +1 -1
- package/generator/pygen/codegen/templates/enum_container.py.jinja2 +1 -1
- package/generator/pygen/codegen/templates/init.py.jinja2 +1 -1
- package/generator/pygen/codegen/templates/model_container.py.jinja2 +1 -1
- package/generator/pygen/codegen/templates/operations_folder_init.py.jinja2 +2 -4
- package/generator/pygen/codegen/templates/test.py.jinja2 +3 -3
- package/generator/pygen/codegen/templates/testpreparer.py.jinja2 +2 -2
- package/generator/pygen/codegen/templates/vendor.py.jinja2 +4 -4
- package/generator/pygen/preprocess/__init__.py +0 -4
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_client_generator_core_flatten_async.py +1 -1
- package/generator/test/{generic_mock_api_tests/asynctests/test_payload_pageable_async.py → azure/mock_api_tests/asynctests/test_azure_payload_pageable_async.py} +1 -1
- package/generator/test/azure/mock_api_tests/asynctests/test_client_namespace_async.py +31 -0
- package/generator/test/azure/mock_api_tests/conftest.py +5 -4
- package/generator/test/azure/mock_api_tests/test_azure_client_generator_core_flatten.py +1 -1
- package/generator/test/{generic_mock_api_tests/test_payload_pageable.py → azure/mock_api_tests/test_azure_payload_pageable.py} +1 -1
- package/generator/test/azure/mock_api_tests/test_client_namespace.py +29 -0
- package/generator/test/{generic_mock_api_tests → azure/mock_api_tests}/test_resiliency_srv_driven.py +4 -2
- package/generator/test/{generic_mock_api_tests/asynctests → azure/mock_api_tests}/test_resiliency_srv_driven_async.py +4 -2
- package/generator/test/azure/requirements.txt +11 -9
- package/generator/test/azure/tox.ini +2 -2
- package/generator/test/generic_mock_api_tests/conftest.py +9 -4
- package/generator/test/unbranded/mock_api_tests/conftest.py +4 -4
- package/generator/test/unbranded/mock_api_tests/test_unbranded.py +1 -1
- package/generator/test/unbranded/requirements.txt +2 -9
- package/generator/test/unbranded/tox.ini +2 -2
- package/package.json +5 -6
- package/generator/requirements.txt +0 -7
- /package/generator/test/{generic_mock_api_tests → azure/mock_api_tests}/asynctests/test_client_naming_async.py +0 -0
- /package/generator/test/{generic_mock_api_tests → azure/mock_api_tests}/asynctests/test_client_structure_async.py +0 -0
- /package/generator/test/{generic_mock_api_tests → azure/mock_api_tests}/test_client_naming.py +0 -0
- /package/generator/test/{generic_mock_api_tests → azure/mock_api_tests}/test_client_structure.py +0 -0
|
@@ -3,13 +3,14 @@
|
|
|
3
3
|
# Licensed under the MIT License. See License.txt in the project root for
|
|
4
4
|
# license information.
|
|
5
5
|
# --------------------------------------------------------------------------
|
|
6
|
-
from typing import List
|
|
6
|
+
from typing import List, Optional
|
|
7
7
|
from abc import ABC, abstractmethod
|
|
8
8
|
|
|
9
9
|
from ..models import ModelType, Property, ConstantType, EnumValue
|
|
10
10
|
from ..models.imports import FileImport, TypingSection, MsrestImportType, ImportType
|
|
11
11
|
from .import_serializer import FileImportSerializer
|
|
12
12
|
from .base_serializer import BaseSerializer
|
|
13
|
+
from ..models.utils import NamespaceType
|
|
13
14
|
|
|
14
15
|
|
|
15
16
|
def _documentation_string(prop: Property, description_keyword: str, docstring_type_keyword: str) -> List[str]:
|
|
@@ -22,6 +23,12 @@ def _documentation_string(prop: Property, description_keyword: str, docstring_ty
|
|
|
22
23
|
|
|
23
24
|
|
|
24
25
|
class _ModelSerializer(BaseSerializer, ABC):
|
|
26
|
+
def __init__(
|
|
27
|
+
self, code_model, env, async_mode=False, *, models: List[ModelType], client_namespace: Optional[str] = None
|
|
28
|
+
):
|
|
29
|
+
super().__init__(code_model, env, async_mode, client_namespace=client_namespace)
|
|
30
|
+
self.models = models
|
|
31
|
+
|
|
25
32
|
@abstractmethod
|
|
26
33
|
def imports(self) -> FileImport: ...
|
|
27
34
|
|
|
@@ -33,6 +40,7 @@ class _ModelSerializer(BaseSerializer, ABC):
|
|
|
33
40
|
imports=FileImportSerializer(self.imports()),
|
|
34
41
|
str=str,
|
|
35
42
|
serializer=self,
|
|
43
|
+
models=self.models,
|
|
36
44
|
)
|
|
37
45
|
|
|
38
46
|
@abstractmethod
|
|
@@ -63,12 +71,12 @@ class _ModelSerializer(BaseSerializer, ABC):
|
|
|
63
71
|
typing = "str"
|
|
64
72
|
return f"self.{prop.client_name}: {typing} = {discriminator_value}"
|
|
65
73
|
|
|
66
|
-
|
|
67
|
-
def initialize_standard_property(prop: Property):
|
|
74
|
+
def initialize_standard_property(self, prop: Property):
|
|
68
75
|
if not (prop.optional or prop.client_default_value is not None):
|
|
69
|
-
|
|
76
|
+
type_annotation = prop.type_annotation(serialize_namespace=self.serialize_namespace)
|
|
77
|
+
return f"{prop.client_name}: {type_annotation},{prop.pylint_disable()}"
|
|
70
78
|
return (
|
|
71
|
-
f"{prop.client_name}: {prop.type_annotation()} = "
|
|
79
|
+
f"{prop.client_name}: {prop.type_annotation(serialize_namespace=self.serialize_namespace)} = "
|
|
72
80
|
f"{prop.client_default_value_declaration},{prop.pylint_disable()}"
|
|
73
81
|
)
|
|
74
82
|
|
|
@@ -127,19 +135,29 @@ class _ModelSerializer(BaseSerializer, ABC):
|
|
|
127
135
|
def global_pylint_disables(self) -> str:
|
|
128
136
|
return ""
|
|
129
137
|
|
|
138
|
+
@property
|
|
139
|
+
def serialize_namespace(self) -> str:
|
|
140
|
+
return self.code_model.get_serialize_namespace(self.client_namespace, client_namespace_type=NamespaceType.MODEL)
|
|
141
|
+
|
|
130
142
|
|
|
131
143
|
class MsrestModelSerializer(_ModelSerializer):
|
|
132
144
|
def imports(self) -> FileImport:
|
|
133
145
|
file_import = FileImport(self.code_model)
|
|
134
146
|
file_import.add_msrest_import(
|
|
135
|
-
|
|
147
|
+
serialize_namespace=self.serialize_namespace,
|
|
136
148
|
msrest_import_type=MsrestImportType.Module,
|
|
137
149
|
typing_section=TypingSection.REGULAR,
|
|
138
150
|
)
|
|
139
|
-
for model in self.
|
|
151
|
+
for model in self.models:
|
|
140
152
|
file_import.merge(model.imports(is_operation_file=False))
|
|
141
153
|
for param in self._init_line_parameters(model):
|
|
142
|
-
file_import.merge(
|
|
154
|
+
file_import.merge(
|
|
155
|
+
param.imports(
|
|
156
|
+
serialize_namespace=self.serialize_namespace,
|
|
157
|
+
serialize_namespace_type=NamespaceType.MODEL,
|
|
158
|
+
called_by_property=True,
|
|
159
|
+
)
|
|
160
|
+
)
|
|
143
161
|
|
|
144
162
|
return file_import
|
|
145
163
|
|
|
@@ -209,19 +227,41 @@ class DpgModelSerializer(_ModelSerializer):
|
|
|
209
227
|
|
|
210
228
|
def imports(self) -> FileImport:
|
|
211
229
|
file_import = FileImport(self.code_model)
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
for model in self.
|
|
230
|
+
if any(not m.parents for m in self.models):
|
|
231
|
+
file_import.add_submodule_import(
|
|
232
|
+
self.code_model.get_relative_import_path(self.serialize_namespace),
|
|
233
|
+
"_model_base",
|
|
234
|
+
ImportType.LOCAL,
|
|
235
|
+
TypingSection.REGULAR,
|
|
236
|
+
)
|
|
237
|
+
for model in self.models:
|
|
220
238
|
if model.base == "json":
|
|
221
239
|
continue
|
|
222
|
-
file_import.merge(
|
|
240
|
+
file_import.merge(
|
|
241
|
+
model.imports(
|
|
242
|
+
is_operation_file=False,
|
|
243
|
+
serialize_namespace=self.serialize_namespace,
|
|
244
|
+
serialize_namespace_type=NamespaceType.MODEL,
|
|
245
|
+
)
|
|
246
|
+
)
|
|
223
247
|
for prop in model.properties:
|
|
224
|
-
file_import.merge(
|
|
248
|
+
file_import.merge(
|
|
249
|
+
prop.imports(
|
|
250
|
+
serialize_namespace=self.serialize_namespace,
|
|
251
|
+
serialize_namespace_type=NamespaceType.MODEL,
|
|
252
|
+
called_by_property=True,
|
|
253
|
+
)
|
|
254
|
+
)
|
|
255
|
+
for parent in model.parents:
|
|
256
|
+
if parent.client_namespace != model.client_namespace:
|
|
257
|
+
file_import.add_submodule_import(
|
|
258
|
+
self.code_model.get_relative_import_path(
|
|
259
|
+
self.serialize_namespace,
|
|
260
|
+
self.code_model.get_imported_namespace_for_model(parent.client_namespace),
|
|
261
|
+
),
|
|
262
|
+
parent.name,
|
|
263
|
+
ImportType.LOCAL,
|
|
264
|
+
)
|
|
225
265
|
if model.is_polymorphic:
|
|
226
266
|
file_import.add_submodule_import("typing", "Dict", ImportType.STDLIB)
|
|
227
267
|
if not model.internal and self.init_line(model):
|
|
@@ -258,8 +298,7 @@ class DpgModelSerializer(_ModelSerializer):
|
|
|
258
298
|
raise ValueError("We do not generate anonymous properties")
|
|
259
299
|
return properties_to_declare
|
|
260
300
|
|
|
261
|
-
|
|
262
|
-
def declare_property(prop: Property) -> str:
|
|
301
|
+
def declare_property(self, prop: Property) -> str:
|
|
263
302
|
args = []
|
|
264
303
|
if prop.client_name != prop.wire_name or prop.is_discriminator:
|
|
265
304
|
args.append(f'name="{prop.wire_name}"')
|
|
@@ -283,7 +322,8 @@ class DpgModelSerializer(_ModelSerializer):
|
|
|
283
322
|
if prop.is_discriminator and isinstance(prop.type, (ConstantType, EnumValue)) and prop.type.value
|
|
284
323
|
else ""
|
|
285
324
|
)
|
|
286
|
-
|
|
325
|
+
type_annotation = prop.type_annotation(serialize_namespace=self.serialize_namespace)
|
|
326
|
+
generated_code = f'{prop.client_name}: {type_annotation} = {field}({", ".join(args)})'
|
|
287
327
|
# there is 4 spaces indentation so original line length limit 120 - 4 = 116
|
|
288
328
|
pylint_disable = (
|
|
289
329
|
" # pylint: disable=line-too-long"
|
|
@@ -324,7 +364,7 @@ class DpgModelSerializer(_ModelSerializer):
|
|
|
324
364
|
|
|
325
365
|
def global_pylint_disables(self) -> str:
|
|
326
366
|
result = []
|
|
327
|
-
for model in self.
|
|
367
|
+
for model in self.models:
|
|
328
368
|
if self.need_init(model):
|
|
329
369
|
for item in self.pylint_disable_items(model):
|
|
330
370
|
if item:
|
|
@@ -7,15 +7,14 @@ from typing import Optional, List, Union
|
|
|
7
7
|
import functools
|
|
8
8
|
from jinja2 import Environment
|
|
9
9
|
|
|
10
|
-
from .utils import get_all_operation_groups_recursively
|
|
11
10
|
from ..models import (
|
|
12
11
|
CodeModel,
|
|
13
12
|
OperationGroup,
|
|
14
13
|
RequestBuilder,
|
|
15
14
|
OverloadedRequestBuilder,
|
|
16
|
-
Client,
|
|
17
15
|
FileImport,
|
|
18
16
|
)
|
|
17
|
+
from ..models.utils import NamespaceType
|
|
19
18
|
from .import_serializer import FileImportSerializer
|
|
20
19
|
from .builder_serializer import (
|
|
21
20
|
get_operation_serializer,
|
|
@@ -28,23 +27,22 @@ class OperationGroupsSerializer(BaseSerializer):
|
|
|
28
27
|
def __init__(
|
|
29
28
|
self,
|
|
30
29
|
code_model: CodeModel,
|
|
31
|
-
|
|
30
|
+
operation_groups: List[OperationGroup],
|
|
32
31
|
env: Environment,
|
|
33
32
|
async_mode: bool,
|
|
34
|
-
|
|
33
|
+
*,
|
|
34
|
+
client_namespace: Optional[str] = None,
|
|
35
35
|
):
|
|
36
|
-
super().__init__(code_model, env)
|
|
37
|
-
self.
|
|
36
|
+
super().__init__(code_model, env, async_mode, client_namespace=client_namespace)
|
|
37
|
+
self.operation_groups = operation_groups
|
|
38
38
|
self.async_mode = async_mode
|
|
39
|
-
self.operation_group = operation_group
|
|
40
39
|
|
|
41
40
|
def _get_request_builders(
|
|
42
41
|
self, operation_group: OperationGroup
|
|
43
42
|
) -> List[Union[OverloadedRequestBuilder, RequestBuilder]]:
|
|
44
43
|
return [
|
|
45
44
|
r
|
|
46
|
-
for
|
|
47
|
-
for r in client.request_builders
|
|
45
|
+
for r in operation_group.client.request_builders
|
|
48
46
|
if r.client.name == operation_group.client.name
|
|
49
47
|
and r.group_name == operation_group.identify_name
|
|
50
48
|
and not r.is_overload
|
|
@@ -52,17 +50,20 @@ class OperationGroupsSerializer(BaseSerializer):
|
|
|
52
50
|
and not r.is_lro # lro has already initial builder
|
|
53
51
|
]
|
|
54
52
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
53
|
+
@property
|
|
54
|
+
def serialize_namespace(self) -> str:
|
|
55
|
+
return self.code_model.get_serialize_namespace(
|
|
56
|
+
self.client_namespace, async_mode=self.async_mode, client_namespace_type=NamespaceType.OPERATION
|
|
57
|
+
)
|
|
60
58
|
|
|
59
|
+
def serialize(self) -> str:
|
|
61
60
|
imports = FileImport(self.code_model)
|
|
62
|
-
for operation_group in operation_groups:
|
|
61
|
+
for operation_group in self.operation_groups:
|
|
63
62
|
imports.merge(
|
|
64
63
|
operation_group.imports(
|
|
65
64
|
async_mode=self.async_mode,
|
|
65
|
+
serialize_namespace=self.serialize_namespace,
|
|
66
|
+
serialize_namespace_type=NamespaceType.OPERATION,
|
|
66
67
|
)
|
|
67
68
|
)
|
|
68
69
|
|
|
@@ -70,7 +71,7 @@ class OperationGroupsSerializer(BaseSerializer):
|
|
|
70
71
|
|
|
71
72
|
return template.render(
|
|
72
73
|
code_model=self.code_model,
|
|
73
|
-
operation_groups=operation_groups,
|
|
74
|
+
operation_groups=self.operation_groups,
|
|
74
75
|
imports=FileImportSerializer(
|
|
75
76
|
imports,
|
|
76
77
|
async_mode=self.async_mode,
|
|
@@ -80,10 +81,12 @@ class OperationGroupsSerializer(BaseSerializer):
|
|
|
80
81
|
get_operation_serializer,
|
|
81
82
|
code_model=self.code_model,
|
|
82
83
|
async_mode=self.async_mode,
|
|
84
|
+
client_namespace=self.client_namespace,
|
|
83
85
|
),
|
|
84
86
|
request_builder_serializer=RequestBuilderSerializer(
|
|
85
87
|
self.code_model,
|
|
86
88
|
async_mode=False,
|
|
89
|
+
client_namespace=self.client_namespace,
|
|
87
90
|
),
|
|
88
91
|
get_request_builders=self._get_request_builders,
|
|
89
92
|
)
|
|
@@ -6,20 +6,19 @@
|
|
|
6
6
|
from typing import List
|
|
7
7
|
from jinja2 import Environment
|
|
8
8
|
|
|
9
|
-
from ..models
|
|
10
|
-
from ..models import CodeModel, Client
|
|
9
|
+
from ..models import CodeModel, OperationGroup
|
|
11
10
|
|
|
12
11
|
|
|
13
12
|
class OperationsInitSerializer:
|
|
14
13
|
def __init__(
|
|
15
14
|
self,
|
|
16
15
|
code_model: CodeModel,
|
|
17
|
-
|
|
16
|
+
operation_groups: List[OperationGroup],
|
|
18
17
|
env: Environment,
|
|
19
18
|
async_mode: bool,
|
|
20
19
|
) -> None:
|
|
21
20
|
self.code_model = code_model
|
|
22
|
-
self.
|
|
21
|
+
self.operation_groups = [og for og in operation_groups if not og.has_parent_operation_group]
|
|
23
22
|
self.env = env
|
|
24
23
|
self.async_mode = async_mode
|
|
25
24
|
|
|
@@ -27,11 +26,7 @@ class OperationsInitSerializer:
|
|
|
27
26
|
def _get_filename(operation_group: OperationGroup) -> str:
|
|
28
27
|
return "_operations" if self.code_model.options["combine_operation_files"] else operation_group.filename
|
|
29
28
|
|
|
30
|
-
return [
|
|
31
|
-
f"from .{_get_filename(og)} import {og.class_name} # type: ignore"
|
|
32
|
-
for client in self.clients
|
|
33
|
-
for og in client.operation_groups
|
|
34
|
-
]
|
|
29
|
+
return [f"from .{_get_filename(og)} import {og.class_name} # type: ignore" for og in self.operation_groups]
|
|
35
30
|
|
|
36
31
|
def serialize(self) -> str:
|
|
37
32
|
operation_group_init_template = self.env.get_template("operations_folder_init.py.jinja2")
|
|
@@ -40,5 +35,5 @@ class OperationsInitSerializer:
|
|
|
40
35
|
code_model=self.code_model,
|
|
41
36
|
async_mode=self.async_mode,
|
|
42
37
|
operation_group_imports=self.operation_group_imports,
|
|
43
|
-
|
|
38
|
+
operation_groups=self.operation_groups,
|
|
44
39
|
)
|
|
@@ -52,8 +52,11 @@ SPECIAL_HEADER_SERIALIZATION: Dict[str, List[str]] = {
|
|
|
52
52
|
|
|
53
53
|
|
|
54
54
|
class ParameterSerializer:
|
|
55
|
-
|
|
56
|
-
def
|
|
55
|
+
|
|
56
|
+
def __init__(self, serialize_namespace: str) -> None:
|
|
57
|
+
self.serialize_namespace = serialize_namespace
|
|
58
|
+
|
|
59
|
+
def serialize_parameter(self, parameter: ParameterType, serializer_name: str) -> str:
|
|
57
60
|
optional_parameters = []
|
|
58
61
|
|
|
59
62
|
if parameter.skip_url_encoding:
|
|
@@ -88,7 +91,7 @@ class ParameterSerializer:
|
|
|
88
91
|
parameters = [
|
|
89
92
|
f'"{origin_name.lstrip("_")}"',
|
|
90
93
|
"q" if parameter.explode else origin_name,
|
|
91
|
-
f"'{type.serialization_type}'",
|
|
94
|
+
f"'{type.serialization_type(serialize_namespace=self.serialize_namespace)}'",
|
|
92
95
|
*optional_parameters,
|
|
93
96
|
]
|
|
94
97
|
parameters_line = ", ".join(parameters)
|
|
@@ -106,8 +109,8 @@ class ParameterSerializer:
|
|
|
106
109
|
return f"[{serialize_line} if q is not None else '' for q in {origin_name}]"
|
|
107
110
|
return serialize_line
|
|
108
111
|
|
|
109
|
-
@staticmethod
|
|
110
112
|
def serialize_path(
|
|
113
|
+
self,
|
|
111
114
|
parameters: Union[
|
|
112
115
|
List[Parameter],
|
|
113
116
|
List[RequestBuilderParameter],
|
|
@@ -121,7 +124,7 @@ class ParameterSerializer:
|
|
|
121
124
|
[
|
|
122
125
|
' "{}": {},'.format(
|
|
123
126
|
path_parameter.wire_name,
|
|
124
|
-
|
|
127
|
+
self.serialize_parameter(path_parameter, serializer_name),
|
|
125
128
|
)
|
|
126
129
|
for path_parameter in parameters
|
|
127
130
|
]
|
|
@@ -129,8 +132,8 @@ class ParameterSerializer:
|
|
|
129
132
|
retval.append("}")
|
|
130
133
|
return retval
|
|
131
134
|
|
|
132
|
-
@staticmethod
|
|
133
135
|
def serialize_query_header(
|
|
136
|
+
self,
|
|
134
137
|
param: Parameter,
|
|
135
138
|
kwarg_name: str,
|
|
136
139
|
serializer_name: str,
|
|
@@ -146,7 +149,7 @@ class ParameterSerializer:
|
|
|
146
149
|
set_parameter = "_{}['{}'] = {}".format(
|
|
147
150
|
kwarg_name,
|
|
148
151
|
param.wire_name,
|
|
149
|
-
|
|
152
|
+
self.serialize_parameter(param, serializer_name),
|
|
150
153
|
)
|
|
151
154
|
if not param.optional and (param.in_method_signature or param.constant):
|
|
152
155
|
retval = [set_parameter]
|
|
@@ -7,6 +7,7 @@ from typing import List
|
|
|
7
7
|
from jinja2 import Environment
|
|
8
8
|
|
|
9
9
|
from ..models import FileImport
|
|
10
|
+
from ..models.utils import NamespaceType
|
|
10
11
|
from .import_serializer import FileImportSerializer
|
|
11
12
|
from ..models import CodeModel, RequestBuilderType
|
|
12
13
|
from .builder_serializer import RequestBuilderSerializer
|
|
@@ -39,6 +40,12 @@ class RequestBuildersSerializer(BaseSerializer):
|
|
|
39
40
|
request_builders=[r for r in self.request_builders if not r.is_overload],
|
|
40
41
|
)
|
|
41
42
|
|
|
43
|
+
@property
|
|
44
|
+
def serialize_namespace(self) -> str:
|
|
45
|
+
return self.code_model.get_serialize_namespace(
|
|
46
|
+
self.client_namespace, client_namespace_type=NamespaceType.OPERATION
|
|
47
|
+
)
|
|
48
|
+
|
|
42
49
|
def serialize_request_builders(self) -> str:
|
|
43
50
|
template = self.env.get_template("request_builders.py.jinja2")
|
|
44
51
|
|
|
@@ -48,5 +55,7 @@ class RequestBuildersSerializer(BaseSerializer):
|
|
|
48
55
|
imports=FileImportSerializer(
|
|
49
56
|
self.imports,
|
|
50
57
|
),
|
|
51
|
-
request_builder_serializer=RequestBuilderSerializer(
|
|
58
|
+
request_builder_serializer=RequestBuilderSerializer(
|
|
59
|
+
self.code_model, async_mode=False, client_namespace=self.client_namespace
|
|
60
|
+
),
|
|
52
61
|
)
|
|
@@ -20,7 +20,7 @@ from ..models import (
|
|
|
20
20
|
BodyParameter,
|
|
21
21
|
FileImport,
|
|
22
22
|
)
|
|
23
|
-
from
|
|
23
|
+
from .._utils import get_parent_namespace
|
|
24
24
|
|
|
25
25
|
_LOGGER = logging.getLogger(__name__)
|
|
26
26
|
|
|
@@ -44,15 +44,12 @@ class SampleSerializer(BaseSerializer):
|
|
|
44
44
|
|
|
45
45
|
def _imports(self) -> FileImportSerializer:
|
|
46
46
|
imports = FileImport(self.code_model)
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
):
|
|
54
|
-
namespace = namespace_config
|
|
55
|
-
client = self.code_model.clients[0]
|
|
47
|
+
client = self.operation_group.client
|
|
48
|
+
namespace = (
|
|
49
|
+
get_parent_namespace(client.client_namespace)
|
|
50
|
+
if self.code_model.options["multiapi"]
|
|
51
|
+
else client.client_namespace
|
|
52
|
+
)
|
|
56
53
|
imports.add_submodule_import(namespace, client.name, ImportType.LOCAL)
|
|
57
54
|
credential_type = getattr(client.credential, "type", None)
|
|
58
55
|
if isinstance(credential_type, TokenCredentialType):
|
|
@@ -35,18 +35,18 @@ def is_common_operation(operation_type: str) -> bool:
|
|
|
35
35
|
|
|
36
36
|
|
|
37
37
|
class TestName:
|
|
38
|
-
def __init__(self, code_model: CodeModel, client_name: str, *,
|
|
38
|
+
def __init__(self, code_model: CodeModel, client_name: str, *, async_mode: bool = False) -> None:
|
|
39
39
|
self.code_model = code_model
|
|
40
40
|
self.client_name = client_name
|
|
41
|
-
self.
|
|
41
|
+
self.async_mode = async_mode
|
|
42
42
|
|
|
43
43
|
@property
|
|
44
44
|
def async_suffix_capt(self) -> str:
|
|
45
|
-
return "Async" if self.
|
|
45
|
+
return "Async" if self.async_mode else ""
|
|
46
46
|
|
|
47
47
|
@property
|
|
48
48
|
def create_client_name(self) -> str:
|
|
49
|
-
return "create_async_client" if self.
|
|
49
|
+
return "create_async_client" if self.async_mode else "create_client"
|
|
50
50
|
|
|
51
51
|
@property
|
|
52
52
|
def prefix(self) -> str:
|
|
@@ -72,12 +72,12 @@ class TestCase:
|
|
|
72
72
|
params: Dict[str, Any],
|
|
73
73
|
operation: OperationType,
|
|
74
74
|
*,
|
|
75
|
-
|
|
75
|
+
async_mode: bool = False,
|
|
76
76
|
) -> None:
|
|
77
77
|
self.operation_groups = operation_groups
|
|
78
78
|
self.params = params
|
|
79
79
|
self.operation = operation
|
|
80
|
-
self.
|
|
80
|
+
self.async_mode = async_mode
|
|
81
81
|
|
|
82
82
|
@property
|
|
83
83
|
def name(self) -> str:
|
|
@@ -93,7 +93,7 @@ class TestCase:
|
|
|
93
93
|
|
|
94
94
|
@property
|
|
95
95
|
def response(self) -> str:
|
|
96
|
-
if self.
|
|
96
|
+
if self.async_mode:
|
|
97
97
|
if is_lro(self.operation.operation_type):
|
|
98
98
|
return "response = await (await "
|
|
99
99
|
if is_common_operation(self.operation.operation_type):
|
|
@@ -107,14 +107,14 @@ class TestCase:
|
|
|
107
107
|
@property
|
|
108
108
|
def operation_suffix(self) -> str:
|
|
109
109
|
if is_lro(self.operation.operation_type):
|
|
110
|
-
extra = ")" if self.
|
|
110
|
+
extra = ")" if self.async_mode else ""
|
|
111
111
|
return f"{extra}.result(){self.lro_comment}"
|
|
112
112
|
return ""
|
|
113
113
|
|
|
114
114
|
@property
|
|
115
115
|
def extra_operation(self) -> str:
|
|
116
116
|
if is_paging(self.operation.operation_type):
|
|
117
|
-
async_str = "async " if self.
|
|
117
|
+
async_str = "async " if self.async_mode else ""
|
|
118
118
|
return f"result = [r {async_str}for r in response]"
|
|
119
119
|
return ""
|
|
120
120
|
|
|
@@ -128,43 +128,39 @@ class Test(TestName):
|
|
|
128
128
|
testcases: List[TestCase],
|
|
129
129
|
test_class_name: str,
|
|
130
130
|
*,
|
|
131
|
-
|
|
131
|
+
async_mode: bool = False,
|
|
132
132
|
) -> None:
|
|
133
|
-
super().__init__(code_model, client_name,
|
|
133
|
+
super().__init__(code_model, client_name, async_mode=async_mode)
|
|
134
134
|
self.operation_group = operation_group
|
|
135
135
|
self.testcases = testcases
|
|
136
136
|
self.test_class_name = test_class_name
|
|
137
137
|
|
|
138
138
|
|
|
139
139
|
class TestGeneralSerializer(BaseSerializer):
|
|
140
|
-
def __init__(self, code_model: CodeModel, env: Environment, *, is_async: bool = False) -> None:
|
|
141
|
-
super().__init__(code_model, env)
|
|
142
|
-
self.is_async = is_async
|
|
143
140
|
|
|
144
141
|
@property
|
|
145
142
|
def aio_str(self) -> str:
|
|
146
|
-
return ".aio" if self.
|
|
143
|
+
return ".aio" if self.async_mode else ""
|
|
147
144
|
|
|
148
145
|
@property
|
|
149
146
|
def test_names(self) -> List[TestName]:
|
|
150
|
-
return [TestName(self.code_model, c.name,
|
|
147
|
+
return [TestName(self.code_model, c.name, async_mode=self.async_mode) for c in self.code_model.clients]
|
|
151
148
|
|
|
152
149
|
def add_import_client(self, imports: FileImport) -> None:
|
|
153
|
-
namespace = get_namespace_from_package_name(self.code_model.options["package_name"])
|
|
154
150
|
for client in self.code_model.clients:
|
|
155
|
-
imports.add_submodule_import(
|
|
151
|
+
imports.add_submodule_import(client.client_namespace + self.aio_str, client.name, ImportType.STDLIB)
|
|
156
152
|
|
|
157
153
|
@property
|
|
158
154
|
def import_clients(self) -> FileImportSerializer:
|
|
159
155
|
imports = self.init_file_import()
|
|
160
156
|
|
|
161
157
|
imports.add_submodule_import("devtools_testutils", "AzureRecordedTestCase", ImportType.STDLIB)
|
|
162
|
-
if not self.
|
|
158
|
+
if not self.async_mode:
|
|
163
159
|
imports.add_import("functools", ImportType.STDLIB)
|
|
164
160
|
imports.add_submodule_import("devtools_testutils", "PowerShellPreparer", ImportType.STDLIB)
|
|
165
161
|
self.add_import_client(imports)
|
|
166
162
|
|
|
167
|
-
return FileImportSerializer(imports, self.
|
|
163
|
+
return FileImportSerializer(imports, self.async_mode)
|
|
168
164
|
|
|
169
165
|
def serialize_conftest(self) -> str:
|
|
170
166
|
return self.env.get_template("conftest.py.jinja2").render(
|
|
@@ -188,17 +184,17 @@ class TestSerializer(TestGeneralSerializer):
|
|
|
188
184
|
*,
|
|
189
185
|
client: Client,
|
|
190
186
|
operation_group: OperationGroup,
|
|
191
|
-
|
|
187
|
+
async_mode: bool = False,
|
|
192
188
|
) -> None:
|
|
193
|
-
super().__init__(code_model, env,
|
|
189
|
+
super().__init__(code_model, env, async_mode=async_mode)
|
|
194
190
|
self.client = client
|
|
195
191
|
self.operation_group = operation_group
|
|
196
192
|
|
|
197
193
|
@property
|
|
198
194
|
def import_test(self) -> FileImportSerializer:
|
|
199
195
|
imports = self.init_file_import()
|
|
200
|
-
test_name = TestName(self.code_model, self.client.name,
|
|
201
|
-
async_suffix = "_async" if self.
|
|
196
|
+
test_name = TestName(self.code_model, self.client.name, async_mode=self.async_mode)
|
|
197
|
+
async_suffix = "_async" if self.async_mode else ""
|
|
202
198
|
imports.add_submodule_import(
|
|
203
199
|
"devtools_testutils" if self.code_model.options["azure_arm"] else "testpreparer" + async_suffix,
|
|
204
200
|
test_name.base_test_class_name,
|
|
@@ -216,7 +212,7 @@ class TestSerializer(TestGeneralSerializer):
|
|
|
216
212
|
)
|
|
217
213
|
if self.code_model.options["azure_arm"]:
|
|
218
214
|
self.add_import_client(imports)
|
|
219
|
-
return FileImportSerializer(imports, self.
|
|
215
|
+
return FileImportSerializer(imports, self.async_mode)
|
|
220
216
|
|
|
221
217
|
@property
|
|
222
218
|
def breadth_search_operation_group(self) -> List[List[OperationGroup]]:
|
|
@@ -263,7 +259,7 @@ class TestSerializer(TestGeneralSerializer):
|
|
|
263
259
|
operation_groups=operation_groups,
|
|
264
260
|
params=operation_params,
|
|
265
261
|
operation=operation,
|
|
266
|
-
|
|
262
|
+
async_mode=self.async_mode,
|
|
267
263
|
)
|
|
268
264
|
testcases.append(testcase)
|
|
269
265
|
if not testcases:
|
|
@@ -275,12 +271,12 @@ class TestSerializer(TestGeneralSerializer):
|
|
|
275
271
|
operation_group=self.operation_group,
|
|
276
272
|
testcases=testcases,
|
|
277
273
|
test_class_name=self.test_class_name,
|
|
278
|
-
|
|
274
|
+
async_mode=self.async_mode,
|
|
279
275
|
)
|
|
280
276
|
|
|
281
277
|
@property
|
|
282
278
|
def test_class_name(self) -> str:
|
|
283
|
-
test_name = TestName(self.code_model, self.client.name,
|
|
279
|
+
test_name = TestName(self.code_model, self.client.name, async_mode=self.async_mode)
|
|
284
280
|
class_name = "" if self.operation_group.is_mixin else self.operation_group.class_name
|
|
285
281
|
return f"Test{test_name.prefix}{class_name}{test_name.async_suffix_capt}"
|
|
286
282
|
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
# license information.
|
|
5
5
|
# --------------------------------------------------------------------------
|
|
6
6
|
from ..models.imports import FileImport, ImportType
|
|
7
|
+
from ..models.utils import NamespaceType
|
|
7
8
|
from .import_serializer import FileImportSerializer
|
|
8
9
|
from .base_serializer import BaseSerializer
|
|
9
10
|
|
|
@@ -18,7 +19,11 @@ class TypesSerializer(BaseSerializer):
|
|
|
18
19
|
ImportType.STDLIB,
|
|
19
20
|
)
|
|
20
21
|
for nu in self.code_model.named_unions:
|
|
21
|
-
file_import.merge(
|
|
22
|
+
file_import.merge(
|
|
23
|
+
nu.imports(
|
|
24
|
+
serialize_namespace=self.serialize_namespace, serialize_namespace_type=NamespaceType.TYPES_FILE
|
|
25
|
+
)
|
|
26
|
+
)
|
|
22
27
|
return file_import
|
|
23
28
|
|
|
24
29
|
def serialize(self) -> str:
|
|
@@ -4,11 +4,9 @@
|
|
|
4
4
|
# license information.
|
|
5
5
|
# --------------------------------------------------------------------------
|
|
6
6
|
import json
|
|
7
|
-
from typing import Optional,
|
|
7
|
+
from typing import Optional, Any
|
|
8
8
|
from pathlib import Path
|
|
9
9
|
|
|
10
|
-
from ..models import Client, OperationGroup
|
|
11
|
-
|
|
12
10
|
|
|
13
11
|
def method_signature_and_response_type_annotation_template(
|
|
14
12
|
*,
|
|
@@ -35,18 +33,6 @@ def get_namespace_from_package_name(package_name: Optional[str]) -> str:
|
|
|
35
33
|
return (package_name or "").replace("-", ".")
|
|
36
34
|
|
|
37
35
|
|
|
38
|
-
def get_all_operation_groups_recursively(clients: List[Client]) -> List[OperationGroup]:
|
|
39
|
-
operation_groups = []
|
|
40
|
-
queue = []
|
|
41
|
-
for client in clients:
|
|
42
|
-
queue.extend(client.operation_groups)
|
|
43
|
-
while queue:
|
|
44
|
-
operation_groups.append(queue.pop(0))
|
|
45
|
-
if operation_groups[-1].operation_groups:
|
|
46
|
-
queue.extend(operation_groups[-1].operation_groups)
|
|
47
|
-
return operation_groups
|
|
48
|
-
|
|
49
|
-
|
|
50
36
|
def _improve_json_string(template_representation: str) -> Any:
|
|
51
37
|
origin = template_representation.split("\n")
|
|
52
38
|
final = []
|