@autorest/python 5.15.0 → 5.18.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/ChangeLog.md +98 -4
- package/README.md +30 -4
- package/autorest/__init__.py +2 -3
- package/autorest/black/__init__.py +12 -5
- package/autorest/codegen/__init__.py +122 -211
- package/autorest/codegen/models/__init__.py +122 -78
- package/autorest/codegen/models/base_builder.py +70 -72
- package/autorest/codegen/models/base_model.py +7 -5
- package/autorest/codegen/models/{base_schema.py → base_type.py} +68 -45
- package/autorest/codegen/models/client.py +193 -40
- package/autorest/codegen/models/code_model.py +145 -245
- package/autorest/codegen/models/combined_type.py +107 -0
- package/autorest/codegen/models/constant_type.py +122 -0
- package/autorest/codegen/models/credential_types.py +224 -0
- package/autorest/codegen/models/dictionary_type.py +131 -0
- package/autorest/codegen/models/enum_type.py +195 -0
- package/autorest/codegen/models/imports.py +93 -41
- package/autorest/codegen/models/list_type.py +149 -0
- package/autorest/codegen/models/lro_operation.py +90 -133
- package/autorest/codegen/models/lro_paging_operation.py +28 -12
- package/autorest/codegen/models/model_type.py +262 -0
- package/autorest/codegen/models/operation.py +412 -259
- package/autorest/codegen/models/operation_group.py +80 -91
- package/autorest/codegen/models/paging_operation.py +101 -117
- package/autorest/codegen/models/parameter.py +302 -341
- package/autorest/codegen/models/parameter_list.py +373 -357
- package/autorest/codegen/models/primitive_types.py +544 -0
- package/autorest/codegen/models/property.py +136 -134
- package/autorest/codegen/models/request_builder.py +138 -86
- package/autorest/codegen/models/request_builder_parameter.py +122 -86
- package/autorest/codegen/models/response.py +325 -0
- package/autorest/codegen/models/utils.py +13 -17
- package/autorest/codegen/serializers/__init__.py +212 -112
- package/autorest/codegen/serializers/builder_serializer.py +931 -1040
- package/autorest/codegen/serializers/client_serializer.py +140 -84
- package/autorest/codegen/serializers/general_serializer.py +26 -50
- package/autorest/codegen/serializers/import_serializer.py +96 -31
- package/autorest/codegen/serializers/metadata_serializer.py +39 -79
- package/autorest/codegen/serializers/model_base_serializer.py +62 -34
- package/autorest/codegen/serializers/model_generic_serializer.py +9 -10
- package/autorest/codegen/serializers/model_init_serializer.py +4 -2
- package/autorest/codegen/serializers/model_python3_serializer.py +29 -22
- package/autorest/codegen/serializers/operation_groups_serializer.py +21 -19
- package/autorest/codegen/serializers/operations_init_serializer.py +23 -11
- package/autorest/codegen/serializers/parameter_serializer.py +174 -0
- package/autorest/codegen/serializers/patch_serializer.py +4 -1
- package/autorest/codegen/serializers/request_builders_serializer.py +57 -0
- package/autorest/codegen/serializers/utils.py +0 -126
- package/autorest/codegen/templates/MANIFEST.in.jinja2 +1 -0
- package/autorest/codegen/templates/{service_client.py.jinja2 → client.py.jinja2} +7 -7
- package/autorest/codegen/templates/config.py.jinja2 +13 -13
- package/autorest/codegen/templates/enum.py.jinja2 +4 -4
- package/autorest/codegen/templates/enum_container.py.jinja2 +1 -1
- package/autorest/codegen/templates/init.py.jinja2 +3 -3
- package/autorest/codegen/templates/lro_operation.py.jinja2 +6 -5
- package/autorest/codegen/templates/lro_paging_operation.py.jinja2 +6 -5
- package/autorest/codegen/templates/metadata.json.jinja2 +36 -35
- package/autorest/codegen/templates/model.py.jinja2 +23 -24
- package/autorest/codegen/templates/model_container.py.jinja2 +2 -1
- package/autorest/codegen/templates/model_init.py.jinja2 +3 -5
- package/autorest/codegen/templates/operation.py.jinja2 +10 -14
- package/autorest/codegen/templates/operation_group.py.jinja2 +9 -15
- package/autorest/codegen/templates/operation_groups_container.py.jinja2 +1 -1
- package/autorest/codegen/templates/operation_tools.jinja2 +8 -2
- package/autorest/codegen/templates/paging_operation.py.jinja2 +7 -8
- package/autorest/codegen/templates/request_builder.py.jinja2 +19 -10
- package/autorest/codegen/templates/setup.py.jinja2 +9 -3
- package/autorest/codegen/templates/vendor.py.jinja2 +1 -1
- package/autorest/jsonrpc/__init__.py +7 -12
- package/autorest/jsonrpc/localapi.py +4 -3
- package/autorest/jsonrpc/server.py +28 -9
- package/autorest/jsonrpc/stdstream.py +13 -6
- package/autorest/m2r/__init__.py +5 -8
- package/autorest/m4reformatter/__init__.py +1126 -0
- package/autorest/multiapi/__init__.py +24 -14
- package/autorest/multiapi/models/client.py +21 -11
- package/autorest/multiapi/models/code_model.py +23 -10
- package/autorest/multiapi/models/config.py +4 -1
- package/autorest/multiapi/models/constant_global_parameter.py +1 -0
- package/autorest/multiapi/models/global_parameter.py +2 -1
- package/autorest/multiapi/models/global_parameters.py +14 -8
- package/autorest/multiapi/models/imports.py +24 -17
- package/autorest/multiapi/models/mixin_operation.py +5 -5
- package/autorest/multiapi/models/operation_group.py +2 -1
- package/autorest/multiapi/models/operation_mixin_group.py +21 -10
- package/autorest/multiapi/serializers/__init__.py +20 -25
- package/autorest/multiapi/serializers/import_serializer.py +47 -17
- package/autorest/multiapi/serializers/multiapi_serializer.py +17 -17
- package/autorest/multiapi/templates/multiapi_config.py.jinja2 +3 -3
- package/autorest/multiapi/templates/multiapi_init.py.jinja2 +2 -2
- package/autorest/multiapi/templates/multiapi_operations_mixin.py.jinja2 +4 -4
- package/autorest/multiapi/templates/multiapi_service_client.py.jinja2 +9 -9
- package/autorest/multiapi/utils.py +3 -3
- package/autorest/postprocess/__init__.py +202 -0
- package/autorest/postprocess/get_all.py +19 -0
- package/autorest/postprocess/venvtools.py +73 -0
- package/autorest/preprocess/__init__.py +210 -0
- package/autorest/preprocess/helpers.py +54 -0
- package/autorest/{namer → preprocess}/python_mappings.py +25 -32
- package/package.json +3 -3
- package/run-python3.js +2 -3
- package/venvtools.py +1 -1
- package/autorest/codegen/models/constant_schema.py +0 -101
- package/autorest/codegen/models/credential_model.py +0 -47
- package/autorest/codegen/models/credential_schema.py +0 -91
- package/autorest/codegen/models/credential_schema_policy.py +0 -77
- package/autorest/codegen/models/dictionary_schema.py +0 -103
- package/autorest/codegen/models/enum_schema.py +0 -215
- package/autorest/codegen/models/list_schema.py +0 -123
- package/autorest/codegen/models/object_schema.py +0 -253
- package/autorest/codegen/models/primitive_schemas.py +0 -466
- package/autorest/codegen/models/request_builder_parameter_list.py +0 -280
- package/autorest/codegen/models/rest.py +0 -42
- package/autorest/codegen/models/schema_request.py +0 -45
- package/autorest/codegen/models/schema_response.py +0 -136
- package/autorest/codegen/serializers/rest_serializer.py +0 -57
- package/autorest/namer/__init__.py +0 -25
- package/autorest/namer/name_converter.py +0 -412
|
@@ -3,63 +3,70 @@
|
|
|
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
|
|
6
|
+
from typing import List
|
|
7
7
|
from jinja2 import Environment
|
|
8
8
|
from .model_base_serializer import ModelBaseSerializer
|
|
9
|
-
from ..models import
|
|
9
|
+
from ..models import ModelType, CodeModel, Property
|
|
10
10
|
from ..models.imports import FileImport
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
class ModelPython3Serializer(ModelBaseSerializer):
|
|
14
|
-
|
|
15
14
|
def __init__(self, code_model: CodeModel, env: Environment) -> None:
|
|
16
|
-
super(
|
|
17
|
-
code_model=code_model, env=env, is_python3_file=True
|
|
18
|
-
)
|
|
15
|
+
super().__init__(code_model=code_model, env=env, is_python3_file=True)
|
|
19
16
|
|
|
20
|
-
def init_line(self, model:
|
|
17
|
+
def init_line(self, model: ModelType) -> List[str]:
|
|
21
18
|
init_properties_declaration = []
|
|
22
19
|
init_line_parameters = [
|
|
23
|
-
p
|
|
20
|
+
p
|
|
21
|
+
for p in model.properties
|
|
22
|
+
if not p.readonly and not p.is_discriminator and not p.constant
|
|
24
23
|
]
|
|
25
|
-
init_line_parameters.sort(key=lambda x: x.
|
|
24
|
+
init_line_parameters.sort(key=lambda x: x.optional)
|
|
26
25
|
if init_line_parameters:
|
|
27
|
-
init_properties_declaration.append("
|
|
26
|
+
init_properties_declaration.append("*,")
|
|
28
27
|
for param in init_line_parameters:
|
|
29
28
|
init_properties_declaration.append(self.initialize_standard_property(param))
|
|
30
29
|
|
|
31
30
|
return init_properties_declaration
|
|
32
31
|
|
|
33
|
-
def properties_to_pass_to_super(self, model:
|
|
32
|
+
def properties_to_pass_to_super(self, model: ModelType) -> str:
|
|
34
33
|
properties_to_pass_to_super = []
|
|
35
|
-
for
|
|
36
|
-
base_model = cast(ObjectSchema, uncast_base_model)
|
|
34
|
+
for parent in model.parents:
|
|
37
35
|
for prop in model.properties:
|
|
38
36
|
if (
|
|
39
|
-
prop in
|
|
37
|
+
prop in parent.properties
|
|
40
38
|
and not prop.is_discriminator
|
|
41
39
|
and not prop.constant
|
|
42
40
|
and not prop.readonly
|
|
43
41
|
):
|
|
44
|
-
properties_to_pass_to_super.append(
|
|
42
|
+
properties_to_pass_to_super.append(
|
|
43
|
+
f"{prop.client_name}={prop.client_name}"
|
|
44
|
+
)
|
|
45
45
|
properties_to_pass_to_super.append("**kwargs")
|
|
46
46
|
return ", ".join(properties_to_pass_to_super)
|
|
47
47
|
|
|
48
48
|
def required_property_no_default_init(self, prop: Property) -> str:
|
|
49
|
-
return f"{prop.
|
|
49
|
+
return f"{prop.client_name}: {prop.type_annotation()},{prop.pylint_disable}"
|
|
50
50
|
|
|
51
51
|
def optional_property_init(self, prop: Property) -> str:
|
|
52
|
-
|
|
53
|
-
|
|
52
|
+
return (
|
|
53
|
+
f"{prop.client_name}: {prop.type_annotation()} = "
|
|
54
|
+
f"{prop.client_default_value_declaration},{prop.pylint_disable}"
|
|
55
|
+
)
|
|
54
56
|
|
|
55
57
|
def initialize_standard_arg(self, prop: Property) -> str:
|
|
56
|
-
return f"self.{prop.
|
|
58
|
+
return f"self.{prop.client_name} = {prop.client_name}"
|
|
59
|
+
|
|
60
|
+
def super_call_template(self, model: ModelType) -> str:
|
|
61
|
+
return "super().__init__({})"
|
|
57
62
|
|
|
58
63
|
def imports(self) -> FileImport:
|
|
59
64
|
file_import = super(ModelPython3Serializer, self).imports()
|
|
60
|
-
for model in self.code_model.
|
|
61
|
-
init_line_parameters = [
|
|
65
|
+
for model in self.code_model.model_types:
|
|
66
|
+
init_line_parameters = [
|
|
67
|
+
p for p in model.properties if not p.readonly and not p.is_discriminator
|
|
68
|
+
]
|
|
62
69
|
for param in init_line_parameters:
|
|
63
|
-
file_import.merge(param.
|
|
70
|
+
file_import.merge(param.imports())
|
|
64
71
|
|
|
65
72
|
return file_import
|
|
@@ -11,11 +11,10 @@ from ..models import (
|
|
|
11
11
|
CodeModel,
|
|
12
12
|
OperationGroup,
|
|
13
13
|
FileImport,
|
|
14
|
-
LROOperation,
|
|
15
|
-
PagingOperation
|
|
16
14
|
)
|
|
17
15
|
from .import_serializer import FileImportSerializer
|
|
18
|
-
from .builder_serializer import get_operation_serializer,
|
|
16
|
+
from .builder_serializer import get_operation_serializer, RequestBuilderSerializer
|
|
17
|
+
|
|
19
18
|
|
|
20
19
|
class OperationGroupsSerializer:
|
|
21
20
|
def __init__(
|
|
@@ -33,39 +32,42 @@ class OperationGroupsSerializer:
|
|
|
33
32
|
self.operation_group = operation_group
|
|
34
33
|
|
|
35
34
|
def serialize(self) -> str:
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
operation_groups = [self.operation_group] if self.operation_group else self.code_model.operation_groups
|
|
35
|
+
operation_groups = (
|
|
36
|
+
[self.operation_group]
|
|
37
|
+
if self.operation_group
|
|
38
|
+
else self.code_model.operation_groups
|
|
39
|
+
)
|
|
42
40
|
imports = FileImport()
|
|
43
41
|
for operation_group in operation_groups:
|
|
44
|
-
imports.merge(
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
42
|
+
imports.merge(
|
|
43
|
+
operation_group.imports(
|
|
44
|
+
async_mode=self.async_mode,
|
|
45
|
+
is_python3_file=self.is_python3_file,
|
|
46
|
+
)
|
|
47
|
+
)
|
|
48
48
|
|
|
49
|
-
template = self.env.get_or_select_template(
|
|
49
|
+
template = self.env.get_or_select_template(
|
|
50
|
+
"operation_groups_container.py.jinja2"
|
|
51
|
+
)
|
|
50
52
|
return template.render(
|
|
51
53
|
code_model=self.code_model,
|
|
52
54
|
operation_groups=operation_groups,
|
|
53
55
|
imports=FileImportSerializer(
|
|
54
56
|
imports,
|
|
55
57
|
is_python3_file=self.is_python3_file,
|
|
56
|
-
async_mode=self.async_mode
|
|
58
|
+
async_mode=self.async_mode,
|
|
57
59
|
),
|
|
58
60
|
async_mode=self.async_mode,
|
|
59
61
|
is_python3_file=self.is_python3_file,
|
|
60
|
-
is_lro=_is_lro,
|
|
61
|
-
is_paging=_is_paging,
|
|
62
62
|
get_operation_serializer=functools.partial(
|
|
63
63
|
get_operation_serializer,
|
|
64
64
|
code_model=self.code_model,
|
|
65
65
|
async_mode=self.async_mode,
|
|
66
66
|
is_python3_file=self.is_python3_file,
|
|
67
67
|
),
|
|
68
|
-
request_builder_serializer=
|
|
69
|
-
self.code_model,
|
|
68
|
+
request_builder_serializer=RequestBuilderSerializer(
|
|
69
|
+
self.code_model,
|
|
70
|
+
async_mode=False,
|
|
71
|
+
is_python3_file=self.is_python3_file,
|
|
70
72
|
),
|
|
71
73
|
)
|
|
@@ -11,15 +11,22 @@ from ..models import CodeModel
|
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
class OperationsInitSerializer:
|
|
14
|
-
def __init__(
|
|
14
|
+
def __init__(
|
|
15
|
+
self, code_model: CodeModel, env: Environment, async_mode: bool
|
|
16
|
+
) -> None:
|
|
15
17
|
self.code_model = code_model
|
|
16
18
|
self.env = env
|
|
17
19
|
self.async_mode = async_mode
|
|
18
20
|
|
|
19
21
|
def _operation_group_imports_helper(self, filename_suffix: str = "") -> List[str]:
|
|
20
22
|
def _get_filename(operation_group: OperationGroup) -> str:
|
|
21
|
-
prefix =
|
|
23
|
+
prefix = (
|
|
24
|
+
"_operations"
|
|
25
|
+
if self.code_model.options["combine_operation_files"]
|
|
26
|
+
else operation_group.filename
|
|
27
|
+
)
|
|
22
28
|
return prefix + filename_suffix
|
|
29
|
+
|
|
23
30
|
return [
|
|
24
31
|
f"from .{_get_filename(og)} import {og.class_name}"
|
|
25
32
|
for og in self.code_model.operation_groups
|
|
@@ -30,20 +37,25 @@ class OperationsInitSerializer:
|
|
|
30
37
|
py3_only = self.code_model.options["python3_only"]
|
|
31
38
|
if typed_py3_files and not py3_only and not self.async_mode:
|
|
32
39
|
retval: List[str] = ["try:"]
|
|
33
|
-
retval.extend(
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
40
|
+
retval.extend(
|
|
41
|
+
[
|
|
42
|
+
f" {line}"
|
|
43
|
+
for line in self._operation_group_imports_helper(
|
|
44
|
+
filename_suffix="_py3"
|
|
45
|
+
)
|
|
46
|
+
]
|
|
47
|
+
)
|
|
37
48
|
retval.append("except (SyntaxError, ImportError):")
|
|
38
|
-
retval.extend(
|
|
39
|
-
f" {line}"
|
|
40
|
-
|
|
41
|
-
])
|
|
49
|
+
retval.extend(
|
|
50
|
+
[f" {line}" for line in self._operation_group_imports_helper()]
|
|
51
|
+
)
|
|
42
52
|
return retval
|
|
43
53
|
return self._operation_group_imports_helper()
|
|
44
54
|
|
|
45
55
|
def serialize(self) -> str:
|
|
46
|
-
operation_group_init_template = self.env.get_template(
|
|
56
|
+
operation_group_init_template = self.env.get_template(
|
|
57
|
+
"operations_folder_init.py.jinja2"
|
|
58
|
+
)
|
|
47
59
|
|
|
48
60
|
return operation_group_init_template.render(
|
|
49
61
|
code_model=self.code_model,
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
# -------------------------------------------------------------------------
|
|
2
|
+
# Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
+
# Licensed under the MIT License. See License.txt in the project root for
|
|
4
|
+
# license information.
|
|
5
|
+
# --------------------------------------------------------------------------
|
|
6
|
+
from typing import List, Sequence, Union
|
|
7
|
+
from enum import Enum, auto
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
from ..models import (
|
|
11
|
+
Parameter,
|
|
12
|
+
ParameterLocation,
|
|
13
|
+
ListType,
|
|
14
|
+
ParameterDelimeter,
|
|
15
|
+
RequestBuilderParameter,
|
|
16
|
+
ClientParameter,
|
|
17
|
+
ConfigParameter,
|
|
18
|
+
ParameterType,
|
|
19
|
+
)
|
|
20
|
+
from ..models.parameter import _ParameterBase
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class PopKwargType(Enum):
|
|
24
|
+
NO = auto()
|
|
25
|
+
SIMPLE = auto()
|
|
26
|
+
CASE_INSENSITIVE = auto()
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class ParameterSerializer:
|
|
30
|
+
@staticmethod
|
|
31
|
+
def serialize_parameter(parameter: ParameterType, serializer_name: str) -> str:
|
|
32
|
+
optional_parameters = []
|
|
33
|
+
|
|
34
|
+
if parameter.skip_url_encoding:
|
|
35
|
+
optional_parameters.append("skip_quote=True")
|
|
36
|
+
|
|
37
|
+
if parameter.delimiter and not parameter.explode:
|
|
38
|
+
if parameter.delimiter == ParameterDelimeter.COMMA:
|
|
39
|
+
div_char = ","
|
|
40
|
+
elif parameter.delimiter == ParameterDelimeter.SPACE:
|
|
41
|
+
div_char = " "
|
|
42
|
+
elif parameter.delimiter == ParameterDelimeter.PIPE:
|
|
43
|
+
div_char = "|"
|
|
44
|
+
elif parameter.delimiter == ParameterDelimeter.TAB:
|
|
45
|
+
div_char = "\t"
|
|
46
|
+
else:
|
|
47
|
+
raise ValueError(f"We do not support {parameter.delimiter} yet")
|
|
48
|
+
optional_parameters.append(f"div='{div_char}'")
|
|
49
|
+
|
|
50
|
+
if parameter.explode:
|
|
51
|
+
if not isinstance(parameter.type, ListType):
|
|
52
|
+
raise ValueError("Got a explode boolean on a non-array schema")
|
|
53
|
+
type = parameter.type.element_type
|
|
54
|
+
else:
|
|
55
|
+
type = parameter.type
|
|
56
|
+
|
|
57
|
+
serialization_constraints = type.serialization_constraints
|
|
58
|
+
if serialization_constraints:
|
|
59
|
+
optional_parameters += serialization_constraints
|
|
60
|
+
|
|
61
|
+
origin_name = parameter.full_client_name
|
|
62
|
+
|
|
63
|
+
parameters = [
|
|
64
|
+
f'"{origin_name.lstrip("_")}"',
|
|
65
|
+
"q" if parameter.explode else origin_name,
|
|
66
|
+
f"'{type.serialization_type}'",
|
|
67
|
+
*optional_parameters,
|
|
68
|
+
]
|
|
69
|
+
parameters_line = ", ".join(parameters)
|
|
70
|
+
|
|
71
|
+
msrest_function_name = {
|
|
72
|
+
ParameterLocation.PATH: "url",
|
|
73
|
+
ParameterLocation.ENDPOINT_PATH: "url",
|
|
74
|
+
ParameterLocation.HEADER: "header",
|
|
75
|
+
ParameterLocation.QUERY: "query",
|
|
76
|
+
}[parameter.location]
|
|
77
|
+
|
|
78
|
+
serialize_line = f"{serializer_name}.{msrest_function_name}({parameters_line})"
|
|
79
|
+
|
|
80
|
+
if parameter.explode:
|
|
81
|
+
return f"[{serialize_line} if q is not None else '' for q in {origin_name}]"
|
|
82
|
+
return serialize_line
|
|
83
|
+
|
|
84
|
+
def serialize_path(
|
|
85
|
+
self,
|
|
86
|
+
parameters: Union[
|
|
87
|
+
List[Parameter],
|
|
88
|
+
List[RequestBuilderParameter],
|
|
89
|
+
List[ClientParameter],
|
|
90
|
+
List[ConfigParameter],
|
|
91
|
+
],
|
|
92
|
+
serializer_name: str,
|
|
93
|
+
) -> List[str]:
|
|
94
|
+
retval = ["path_format_arguments = {"]
|
|
95
|
+
retval.extend(
|
|
96
|
+
[
|
|
97
|
+
' "{}": {},'.format(
|
|
98
|
+
path_parameter.rest_api_name,
|
|
99
|
+
self.serialize_parameter(path_parameter, serializer_name),
|
|
100
|
+
)
|
|
101
|
+
for path_parameter in parameters
|
|
102
|
+
]
|
|
103
|
+
)
|
|
104
|
+
retval.append("}")
|
|
105
|
+
return retval
|
|
106
|
+
|
|
107
|
+
@staticmethod
|
|
108
|
+
def pop_kwargs_from_signature(
|
|
109
|
+
parameters: Sequence[_ParameterBase],
|
|
110
|
+
check_kwarg_dict: bool,
|
|
111
|
+
pop_headers_kwarg: PopKwargType,
|
|
112
|
+
pop_params_kwarg: PopKwargType,
|
|
113
|
+
check_client_input: bool = False,
|
|
114
|
+
) -> List[str]:
|
|
115
|
+
retval = []
|
|
116
|
+
|
|
117
|
+
def append_pop_kwarg(key: str, pop_type: PopKwargType) -> None:
|
|
118
|
+
if PopKwargType.CASE_INSENSITIVE == pop_type:
|
|
119
|
+
retval.append(
|
|
120
|
+
f'_{key} = case_insensitive_dict(kwargs.pop("{key}", {{}}) or {{}})'
|
|
121
|
+
)
|
|
122
|
+
elif PopKwargType.SIMPLE == pop_type:
|
|
123
|
+
retval.append(f'_{key} = kwargs.pop("{key}", {{}}) or {{}}')
|
|
124
|
+
|
|
125
|
+
append_pop_kwarg("headers", pop_headers_kwarg)
|
|
126
|
+
append_pop_kwarg("params", pop_params_kwarg)
|
|
127
|
+
if pop_headers_kwarg != PopKwargType.NO or pop_params_kwarg != PopKwargType.NO:
|
|
128
|
+
retval.append("")
|
|
129
|
+
for kwarg in parameters:
|
|
130
|
+
if kwarg.client_default_value is not None or kwarg.optional:
|
|
131
|
+
if check_client_input and kwarg.check_client_input:
|
|
132
|
+
default_value = f"self._config.{kwarg.client_name}"
|
|
133
|
+
else:
|
|
134
|
+
default_value = kwarg.client_default_value_declaration
|
|
135
|
+
if check_kwarg_dict and (
|
|
136
|
+
kwarg.location
|
|
137
|
+
in [ParameterLocation.HEADER, ParameterLocation.QUERY]
|
|
138
|
+
):
|
|
139
|
+
kwarg_dict = (
|
|
140
|
+
"headers"
|
|
141
|
+
if kwarg.location == ParameterLocation.HEADER
|
|
142
|
+
else "params"
|
|
143
|
+
)
|
|
144
|
+
default_value = (
|
|
145
|
+
f"_{kwarg_dict}.pop('{kwarg.rest_api_name}', {default_value})"
|
|
146
|
+
)
|
|
147
|
+
retval.append(
|
|
148
|
+
f"{kwarg.client_name} = kwargs.pop('{kwarg.client_name}', "
|
|
149
|
+
+ f"{default_value}) # type: {kwarg.type_annotation()}"
|
|
150
|
+
)
|
|
151
|
+
else:
|
|
152
|
+
type_annot = kwarg.type_annotation()
|
|
153
|
+
retval.append(
|
|
154
|
+
f"{kwarg.client_name} = kwargs.pop('{kwarg.client_name}') # type: {type_annot}"
|
|
155
|
+
)
|
|
156
|
+
return retval
|
|
157
|
+
|
|
158
|
+
@staticmethod
|
|
159
|
+
def serialize_method(
|
|
160
|
+
*,
|
|
161
|
+
function_def: str,
|
|
162
|
+
method_name: str,
|
|
163
|
+
need_self_param: bool,
|
|
164
|
+
method_param_signatures: List[str],
|
|
165
|
+
pylint_disable: str = "",
|
|
166
|
+
):
|
|
167
|
+
lines: List[str] = []
|
|
168
|
+
first_line = f"{function_def} {method_name}({pylint_disable}"
|
|
169
|
+
lines.append(first_line)
|
|
170
|
+
if need_self_param:
|
|
171
|
+
lines.append(" self,")
|
|
172
|
+
lines.extend([(" " + line) for line in method_param_signatures])
|
|
173
|
+
lines.append(")")
|
|
174
|
+
return "\n".join(lines)
|
|
@@ -7,6 +7,7 @@ from jinja2 import Environment
|
|
|
7
7
|
from .import_serializer import FileImportSerializer
|
|
8
8
|
from ..models import CodeModel, FileImport, ImportType, TypingSection
|
|
9
9
|
|
|
10
|
+
|
|
10
11
|
class PatchSerializer:
|
|
11
12
|
def __init__(self, env: Environment, code_model: CodeModel) -> None:
|
|
12
13
|
self.env = env
|
|
@@ -15,7 +16,9 @@ class PatchSerializer:
|
|
|
15
16
|
def serialize(self) -> str:
|
|
16
17
|
template = self.env.get_template("patch.py.jinja2")
|
|
17
18
|
imports = FileImport()
|
|
18
|
-
imports.add_submodule_import(
|
|
19
|
+
imports.add_submodule_import(
|
|
20
|
+
"typing", "List", ImportType.STDLIB, TypingSection.CONDITIONAL
|
|
21
|
+
)
|
|
19
22
|
is_python3_file = self.code_model.options["python3_only"]
|
|
20
23
|
return template.render(
|
|
21
24
|
code_model=self.code_model,
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# -------------------------------------------------------------------------
|
|
2
|
+
# Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
+
# Licensed under the MIT License. See License.txt in the project root for
|
|
4
|
+
# license information.
|
|
5
|
+
# --------------------------------------------------------------------------
|
|
6
|
+
from typing import List
|
|
7
|
+
from jinja2 import Environment
|
|
8
|
+
|
|
9
|
+
from ..models import FileImport
|
|
10
|
+
from .import_serializer import FileImportSerializer
|
|
11
|
+
from ..models import CodeModel, RequestBuilderType
|
|
12
|
+
from .builder_serializer import RequestBuilderSerializer
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class RequestBuildersSerializer:
|
|
16
|
+
def __init__(
|
|
17
|
+
self,
|
|
18
|
+
code_model: CodeModel,
|
|
19
|
+
env: Environment,
|
|
20
|
+
request_builders: List[RequestBuilderType],
|
|
21
|
+
is_python3_file: bool,
|
|
22
|
+
) -> None:
|
|
23
|
+
self.code_model = code_model
|
|
24
|
+
self.env = env
|
|
25
|
+
self.request_builders = request_builders
|
|
26
|
+
self.group_name = request_builders[0].group_name
|
|
27
|
+
self.is_python3_file = is_python3_file
|
|
28
|
+
|
|
29
|
+
@property
|
|
30
|
+
def imports(self) -> FileImport:
|
|
31
|
+
file_import = FileImport()
|
|
32
|
+
for request_builder in self.request_builders:
|
|
33
|
+
if request_builder.group_name == self.group_name:
|
|
34
|
+
file_import.merge(request_builder.imports())
|
|
35
|
+
return file_import
|
|
36
|
+
|
|
37
|
+
def serialize_init(self) -> str:
|
|
38
|
+
template = self.env.get_template("rest_init.py.jinja2")
|
|
39
|
+
return template.render(
|
|
40
|
+
code_model=self.code_model,
|
|
41
|
+
request_builders=[r for r in self.request_builders if not r.is_overload],
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
def serialize_request_builders(self) -> str:
|
|
45
|
+
template = self.env.get_template("request_builders.py.jinja2")
|
|
46
|
+
|
|
47
|
+
return template.render(
|
|
48
|
+
code_model=self.code_model,
|
|
49
|
+
request_builders=self.request_builders,
|
|
50
|
+
imports=FileImportSerializer(
|
|
51
|
+
self.imports,
|
|
52
|
+
is_python3_file=True,
|
|
53
|
+
),
|
|
54
|
+
request_builder_serializer=RequestBuilderSerializer(
|
|
55
|
+
self.code_model, async_mode=False, is_python3_file=self.is_python3_file
|
|
56
|
+
),
|
|
57
|
+
)
|
|
@@ -3,96 +3,8 @@
|
|
|
3
3
|
# Licensed under the MIT License. See License.txt in the project root for
|
|
4
4
|
# license information.
|
|
5
5
|
# --------------------------------------------------------------------------
|
|
6
|
-
from enum import Enum, auto
|
|
7
|
-
from typing import List
|
|
8
|
-
from ..models import ParameterStyle, ListSchema, Parameter, ParameterLocation
|
|
9
6
|
|
|
10
7
|
|
|
11
|
-
def serialize_method(
|
|
12
|
-
*,
|
|
13
|
-
function_def: str,
|
|
14
|
-
method_name: str,
|
|
15
|
-
is_in_class: bool,
|
|
16
|
-
method_param_signatures: List[str],
|
|
17
|
-
ignore_inconsistent_return_statements: bool = False,
|
|
18
|
-
):
|
|
19
|
-
lines: List[str] = []
|
|
20
|
-
first_line = f"{function_def} {method_name}("
|
|
21
|
-
if ignore_inconsistent_return_statements:
|
|
22
|
-
first_line += " # pylint: disable=inconsistent-return-statements"
|
|
23
|
-
lines.append(first_line)
|
|
24
|
-
if is_in_class:
|
|
25
|
-
lines.append(" self,")
|
|
26
|
-
lines.extend([
|
|
27
|
-
(" " + line)
|
|
28
|
-
for line in method_param_signatures
|
|
29
|
-
])
|
|
30
|
-
lines.append(")")
|
|
31
|
-
return "\n".join(lines)
|
|
32
|
-
|
|
33
|
-
def build_serialize_data_call(
|
|
34
|
-
parameter: Parameter, function_name: str, serializer_name: str
|
|
35
|
-
) -> str:
|
|
36
|
-
|
|
37
|
-
optional_parameters = []
|
|
38
|
-
|
|
39
|
-
if parameter.skip_url_encoding:
|
|
40
|
-
optional_parameters.append("skip_quote=True")
|
|
41
|
-
|
|
42
|
-
if parameter.style and not parameter.explode:
|
|
43
|
-
if parameter.style in [ParameterStyle.simple, ParameterStyle.form]:
|
|
44
|
-
div_char = ","
|
|
45
|
-
elif parameter.style in [ParameterStyle.spaceDelimited]:
|
|
46
|
-
div_char = " "
|
|
47
|
-
elif parameter.style in [ParameterStyle.pipeDelimited]:
|
|
48
|
-
div_char = "|"
|
|
49
|
-
elif parameter.style in [ParameterStyle.tabDelimited]:
|
|
50
|
-
div_char = "\t"
|
|
51
|
-
else:
|
|
52
|
-
raise ValueError(f"Do not support {parameter.style} yet")
|
|
53
|
-
optional_parameters.append(f"div='{div_char}'")
|
|
54
|
-
|
|
55
|
-
if parameter.explode:
|
|
56
|
-
if not isinstance(parameter.schema, ListSchema):
|
|
57
|
-
raise ValueError("Got a explode boolean on a non-array schema")
|
|
58
|
-
serialization_schema = parameter.schema.element_type
|
|
59
|
-
else:
|
|
60
|
-
serialization_schema = parameter.schema
|
|
61
|
-
|
|
62
|
-
serialization_constraints = serialization_schema.serialization_constraints
|
|
63
|
-
if serialization_constraints:
|
|
64
|
-
optional_parameters += serialization_constraints
|
|
65
|
-
|
|
66
|
-
origin_name = parameter.full_serialized_name
|
|
67
|
-
|
|
68
|
-
parameters = [
|
|
69
|
-
f'"{origin_name.lstrip("_")}"',
|
|
70
|
-
"q" if parameter.explode else origin_name,
|
|
71
|
-
f"'{serialization_schema.serialization_type}'",
|
|
72
|
-
*optional_parameters
|
|
73
|
-
]
|
|
74
|
-
parameters_line = ', '.join(parameters)
|
|
75
|
-
|
|
76
|
-
serialize_line = f'{serializer_name}.{function_name}({parameters_line})'
|
|
77
|
-
|
|
78
|
-
if parameter.explode:
|
|
79
|
-
return f"[{serialize_line} if q is not None else '' for q in {origin_name}]"
|
|
80
|
-
return serialize_line
|
|
81
|
-
|
|
82
|
-
def serialize_path(
|
|
83
|
-
parameters: List[Parameter], serializer_name: str
|
|
84
|
-
) -> List[str]:
|
|
85
|
-
retval = ["path_format_arguments = {"]
|
|
86
|
-
retval.extend([
|
|
87
|
-
" \"{}\": {},".format(
|
|
88
|
-
path_parameter.rest_api_name,
|
|
89
|
-
build_serialize_data_call(path_parameter, "url", serializer_name)
|
|
90
|
-
)
|
|
91
|
-
for path_parameter in parameters
|
|
92
|
-
])
|
|
93
|
-
retval.append("}")
|
|
94
|
-
return retval
|
|
95
|
-
|
|
96
8
|
def method_signature_and_response_type_annotation_template(
|
|
97
9
|
*,
|
|
98
10
|
is_python3_file: bool,
|
|
@@ -102,41 +14,3 @@ def method_signature_and_response_type_annotation_template(
|
|
|
102
14
|
if is_python3_file:
|
|
103
15
|
return f"{method_signature} -> {response_type_annotation}:"
|
|
104
16
|
return f"{method_signature}:\n # type: (...) -> {response_type_annotation}"
|
|
105
|
-
|
|
106
|
-
class PopKwargType(Enum):
|
|
107
|
-
NO = auto()
|
|
108
|
-
SIMPLE = auto()
|
|
109
|
-
CASE_INSENSITIVE = auto()
|
|
110
|
-
|
|
111
|
-
def pop_kwargs_from_signature(
|
|
112
|
-
kwargs_to_pop: List[Parameter],
|
|
113
|
-
check_kwarg_dict: bool,
|
|
114
|
-
pop_headers_kwarg: PopKwargType,
|
|
115
|
-
pop_params_kwarg: PopKwargType,
|
|
116
|
-
) -> List[str]:
|
|
117
|
-
retval = []
|
|
118
|
-
def append_pop_kwarg(key: str, pop_type: PopKwargType) -> None:
|
|
119
|
-
if PopKwargType.CASE_INSENSITIVE == pop_type:
|
|
120
|
-
retval.append(f'_{key} = case_insensitive_dict(kwargs.pop("{key}", {{}}) or {{}})')
|
|
121
|
-
elif PopKwargType.SIMPLE == pop_type:
|
|
122
|
-
retval.append(f'_{key} = kwargs.pop("{key}", {{}}) or {{}}')
|
|
123
|
-
append_pop_kwarg("headers", pop_headers_kwarg)
|
|
124
|
-
append_pop_kwarg("params", pop_params_kwarg)
|
|
125
|
-
if pop_headers_kwarg != PopKwargType.NO or pop_params_kwarg != PopKwargType.NO:
|
|
126
|
-
retval.append("")
|
|
127
|
-
for kwarg in kwargs_to_pop:
|
|
128
|
-
if kwarg.has_default_value:
|
|
129
|
-
default_value = kwarg.default_value_declaration
|
|
130
|
-
if check_kwarg_dict and (kwarg.location in [ParameterLocation.Header, ParameterLocation.Query]):
|
|
131
|
-
kwarg_dict = "headers" if kwarg.location == ParameterLocation.Header else "params"
|
|
132
|
-
default_value = f"_{kwarg_dict}.pop('{kwarg.rest_api_name}', {default_value})"
|
|
133
|
-
retval.append(
|
|
134
|
-
f"{kwarg.serialized_name} = kwargs.pop('{kwarg.serialized_name}', "
|
|
135
|
-
+ f"{default_value}) # type: {kwarg.type_annotation(is_operation_file=True)}"
|
|
136
|
-
)
|
|
137
|
-
else:
|
|
138
|
-
type_annot = kwarg.type_annotation(is_operation_file=True)
|
|
139
|
-
retval.append(
|
|
140
|
-
f"{kwarg.serialized_name} = kwargs.pop('{kwarg.serialized_name}') # type: {type_annot}"
|
|
141
|
-
)
|
|
142
|
-
return retval
|
|
@@ -7,15 +7,15 @@
|
|
|
7
7
|
{{ imports }}
|
|
8
8
|
|
|
9
9
|
{{ serializer.class_definition(async_mode) }}
|
|
10
|
-
"""{{ op_tools.wrap_string(code_model.description, "\n") | indent }}
|
|
10
|
+
"""{{ op_tools.wrap_string(code_model.client.description, "\n") | indent }}
|
|
11
11
|
|
|
12
12
|
{{ op_tools.serialize_with_wrap(serializer.property_descriptions(async_mode), "\n ") | indent }}
|
|
13
13
|
{{ serializer.init_signature_and_response_type_annotation(async_mode) | indent }}
|
|
14
|
-
{% if code_model.
|
|
14
|
+
{% if code_model.client.parameters.kwargs_to_pop(async_mode) %}
|
|
15
15
|
{{ op_tools.serialize(serializer.pop_kwargs_from_signature(async_mode)) | indent(8) }}
|
|
16
16
|
{% endif %}
|
|
17
|
-
{% if code_model.
|
|
18
|
-
|
|
17
|
+
{% if code_model.client.has_parameterized_host %}
|
|
18
|
+
{{ serializer.host_variable_name }} = {{ keywords.escape_str(code_model.client.url) }}
|
|
19
19
|
{% endif %}
|
|
20
20
|
{{ serializer.initialize_config() }}
|
|
21
21
|
{{ serializer.initialize_pipeline_client(async_mode) }}
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
{{ serializer.send_request_signature_and_response_type_annotation(async_mode) | indent }}
|
|
27
27
|
{{ op_tools.serialize(serializer.send_request_description(async_mode)) | indent(8) }}
|
|
28
28
|
request_copy = deepcopy(request)
|
|
29
|
-
{% if code_model.
|
|
29
|
+
{% if code_model.client.parameters.path %}
|
|
30
30
|
{{ op_tools.serialize(serializer.serialize_path()) | indent(8) }}
|
|
31
31
|
request_copy.url = self._client.format_url(request_copy.url, **path_format_arguments)
|
|
32
32
|
{% else %}
|
|
@@ -40,9 +40,9 @@
|
|
|
40
40
|
{% endif %}
|
|
41
41
|
{{ keywords.await }}self._client.close()
|
|
42
42
|
|
|
43
|
-
{{ keywords.def }} __{{ keywords.async_prefix }}enter__(self){{ (" -> \"" + code_model.
|
|
43
|
+
{{ keywords.def }} __{{ keywords.async_prefix }}enter__(self){{ (" -> \"" + code_model.client.name + "\"") if async_mode else "" }}:
|
|
44
44
|
{% if not async_mode %}
|
|
45
|
-
# type: () -> {{ code_model.
|
|
45
|
+
# type: () -> {{ code_model.client.name }}
|
|
46
46
|
{% endif %}
|
|
47
47
|
{{ keywords.await }}self._client.__{{ keywords.async_prefix }}enter__()
|
|
48
48
|
return self
|