@autorest/python 5.16.0 → 5.19.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 +79 -4
- package/README.md +30 -4
- package/autorest/__init__.py +1 -1
- package/autorest/codegen/__init__.py +55 -211
- package/autorest/codegen/models/__init__.py +116 -83
- package/autorest/codegen/models/base_builder.py +49 -88
- package/autorest/codegen/models/base_model.py +1 -1
- package/autorest/codegen/models/{base_schema.py → base_type.py} +61 -39
- package/autorest/codegen/models/client.py +165 -53
- package/autorest/codegen/models/code_model.py +122 -257
- package/autorest/codegen/models/combined_type.py +107 -0
- package/autorest/codegen/models/{constant_schema.py → constant_type.py} +49 -40
- 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 +80 -2
- package/autorest/codegen/models/list_type.py +149 -0
- package/autorest/codegen/models/lro_operation.py +79 -156
- package/autorest/codegen/models/lro_paging_operation.py +28 -11
- package/autorest/codegen/models/model_type.py +262 -0
- package/autorest/codegen/models/operation.py +331 -298
- package/autorest/codegen/models/operation_group.py +54 -91
- package/autorest/codegen/models/paging_operation.py +82 -123
- package/autorest/codegen/models/parameter.py +289 -396
- package/autorest/codegen/models/parameter_list.py +355 -360
- package/autorest/codegen/models/primitive_types.py +544 -0
- package/autorest/codegen/models/property.py +123 -139
- package/autorest/codegen/models/request_builder.py +130 -102
- package/autorest/codegen/models/request_builder_parameter.py +112 -100
- package/autorest/codegen/models/response.py +325 -0
- package/autorest/codegen/models/utils.py +12 -19
- package/autorest/codegen/serializers/__init__.py +55 -37
- package/autorest/codegen/serializers/builder_serializer.py +695 -1144
- package/autorest/codegen/serializers/client_serializer.py +92 -89
- package/autorest/codegen/serializers/general_serializer.py +15 -69
- package/autorest/codegen/serializers/import_serializer.py +7 -4
- package/autorest/codegen/serializers/metadata_serializer.py +15 -104
- package/autorest/codegen/serializers/model_base_serializer.py +49 -36
- package/autorest/codegen/serializers/model_generic_serializer.py +8 -6
- package/autorest/codegen/serializers/model_init_serializer.py +2 -4
- package/autorest/codegen/serializers/model_python3_serializer.py +22 -16
- package/autorest/codegen/serializers/operation_groups_serializer.py +7 -13
- package/autorest/codegen/serializers/parameter_serializer.py +174 -0
- package/autorest/codegen/serializers/request_builders_serializer.py +13 -30
- package/autorest/codegen/serializers/utils.py +0 -140
- package/autorest/codegen/templates/MANIFEST.in.jinja2 +1 -0
- package/autorest/codegen/templates/{service_client.py.jinja2 → client.py.jinja2} +10 -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 +2 -2
- package/autorest/codegen/templates/lro_operation.py.jinja2 +4 -1
- package/autorest/codegen/templates/lro_paging_operation.py.jinja2 +4 -1
- package/autorest/codegen/templates/metadata.json.jinja2 +33 -33
- 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 +6 -8
- package/autorest/codegen/templates/operation_group.py.jinja2 +21 -8
- package/autorest/codegen/templates/operation_groups_container.py.jinja2 +2 -2
- package/autorest/codegen/templates/operation_tools.jinja2 +11 -3
- package/autorest/codegen/templates/paging_operation.py.jinja2 +2 -2
- package/autorest/codegen/templates/request_builder.py.jinja2 +10 -15
- package/autorest/codegen/templates/request_builders.py.jinja2 +1 -1
- package/autorest/codegen/templates/serialization.py.jinja2 +2006 -0
- package/autorest/codegen/templates/setup.py.jinja2 +13 -3
- package/autorest/codegen/templates/vendor.py.jinja2 +11 -1
- package/autorest/jsonrpc/server.py +15 -3
- package/autorest/m4reformatter/__init__.py +1126 -0
- package/autorest/multiapi/models/client.py +12 -2
- package/autorest/multiapi/models/code_model.py +1 -1
- package/autorest/multiapi/serializers/__init__.py +18 -4
- 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/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 +21 -16
- package/package.json +2 -2
- package/autorest/codegen/models/credential_model.py +0 -55
- package/autorest/codegen/models/credential_schema.py +0 -95
- package/autorest/codegen/models/credential_schema_policy.py +0 -73
- package/autorest/codegen/models/dictionary_schema.py +0 -106
- package/autorest/codegen/models/enum_schema.py +0 -225
- package/autorest/codegen/models/list_schema.py +0 -135
- package/autorest/codegen/models/object_schema.py +0 -303
- package/autorest/codegen/models/primitive_schemas.py +0 -495
- package/autorest/codegen/models/request_builder_parameter_list.py +0 -249
- package/autorest/codegen/models/schema_request.py +0 -55
- package/autorest/codegen/models/schema_response.py +0 -141
- package/autorest/namer/__init__.py +0 -23
- package/autorest/namer/name_converter.py +0 -509
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
from abc import abstractmethod
|
|
7
7
|
from typing import cast, List
|
|
8
8
|
from jinja2 import Environment
|
|
9
|
-
from ..models import
|
|
10
|
-
from ..models.imports import FileImport,
|
|
9
|
+
from ..models import ModelType, CodeModel, Property
|
|
10
|
+
from ..models.imports import FileImport, TypingSection, MsrestImportType
|
|
11
11
|
from .import_serializer import FileImportSerializer
|
|
12
12
|
|
|
13
13
|
|
|
@@ -15,12 +15,14 @@ def _documentation_string(
|
|
|
15
15
|
prop: Property, description_keyword: str, docstring_type_keyword: str
|
|
16
16
|
) -> List[str]:
|
|
17
17
|
retval: List[str] = []
|
|
18
|
-
sphinx_prefix = f":{description_keyword} {prop.
|
|
18
|
+
sphinx_prefix = f":{description_keyword} {prop.client_name}:"
|
|
19
19
|
retval.append(
|
|
20
|
-
f"{sphinx_prefix} {prop.description}"
|
|
20
|
+
f"{sphinx_prefix} {prop.description(is_operation_file=False)}"
|
|
21
|
+
if prop.description(is_operation_file=False)
|
|
22
|
+
else sphinx_prefix
|
|
21
23
|
)
|
|
22
24
|
retval.append(
|
|
23
|
-
f":{docstring_type_keyword} {prop.
|
|
25
|
+
f":{docstring_type_keyword} {prop.client_name}: {prop.type.docstring_type()}"
|
|
24
26
|
)
|
|
25
27
|
return retval
|
|
26
28
|
|
|
@@ -42,29 +44,27 @@ class ModelBaseSerializer:
|
|
|
42
44
|
self.imports(), is_python3_file=self.is_python3_file
|
|
43
45
|
),
|
|
44
46
|
str=str,
|
|
45
|
-
|
|
46
|
-
init_args=self.init_args,
|
|
47
|
-
input_documentation_string=ModelBaseSerializer.input_documentation_string,
|
|
48
|
-
variable_documentation_string=ModelBaseSerializer.variable_documentation_string,
|
|
49
|
-
declare_model=ModelBaseSerializer.declare_model,
|
|
47
|
+
serializer=self,
|
|
50
48
|
)
|
|
51
49
|
|
|
52
50
|
def imports(self) -> FileImport:
|
|
53
51
|
file_import = FileImport()
|
|
54
|
-
file_import.
|
|
55
|
-
|
|
56
|
-
|
|
52
|
+
file_import.add_msrest_import(
|
|
53
|
+
self.code_model, "..", MsrestImportType.Module, TypingSection.REGULAR
|
|
54
|
+
)
|
|
55
|
+
for model in self.code_model.model_types:
|
|
56
|
+
file_import.merge(model.imports(is_operation_file=False))
|
|
57
57
|
return file_import
|
|
58
58
|
|
|
59
59
|
@staticmethod
|
|
60
|
-
def get_properties_to_initialize(model:
|
|
61
|
-
if model.
|
|
60
|
+
def get_properties_to_initialize(model: ModelType) -> List[Property]:
|
|
61
|
+
if model.parents:
|
|
62
62
|
properties_to_initialize = list(
|
|
63
63
|
{
|
|
64
|
-
p.
|
|
65
|
-
for bm in model.
|
|
64
|
+
p.client_name: p
|
|
65
|
+
for bm in model.parents
|
|
66
66
|
for p in model.properties
|
|
67
|
-
if p not in cast(
|
|
67
|
+
if p not in cast(ModelType, bm).properties
|
|
68
68
|
or p.is_discriminator
|
|
69
69
|
or p.constant
|
|
70
70
|
}.values()
|
|
@@ -73,14 +73,15 @@ class ModelBaseSerializer:
|
|
|
73
73
|
properties_to_initialize = model.properties
|
|
74
74
|
return properties_to_initialize
|
|
75
75
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
76
|
+
def declare_model(self, model: ModelType) -> str:
|
|
77
|
+
basename = (
|
|
78
|
+
"msrest.serialization.Model"
|
|
79
|
+
if self.code_model.options["client_side_validation"]
|
|
80
|
+
else "_serialization.Model"
|
|
81
|
+
)
|
|
82
|
+
if model.parents:
|
|
83
|
+
basename = ", ".join([cast(ModelType, m).name for m in model.parents])
|
|
84
|
+
return f"class {model.name}({basename}):{model.pylint_disable}"
|
|
84
85
|
|
|
85
86
|
@staticmethod
|
|
86
87
|
def input_documentation_string(prop: Property) -> List[str]:
|
|
@@ -91,12 +92,17 @@ class ModelBaseSerializer:
|
|
|
91
92
|
def variable_documentation_string(prop: Property) -> List[str]:
|
|
92
93
|
return _documentation_string(prop, "ivar", "vartype")
|
|
93
94
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
95
|
+
@abstractmethod
|
|
96
|
+
def super_call_template(self, model: ModelType) -> str:
|
|
97
|
+
...
|
|
98
|
+
|
|
99
|
+
def super_call(self, model: ModelType):
|
|
100
|
+
return self.super_call_template(model).format(
|
|
101
|
+
self.properties_to_pass_to_super(model)
|
|
99
102
|
)
|
|
103
|
+
|
|
104
|
+
def initialize_properties(self, model: ModelType) -> List[str]:
|
|
105
|
+
init_args = []
|
|
100
106
|
for prop in ModelBaseSerializer.get_properties_to_initialize(model):
|
|
101
107
|
if prop.is_discriminator:
|
|
102
108
|
discriminator_value = (
|
|
@@ -109,25 +115,32 @@ class ModelBaseSerializer:
|
|
|
109
115
|
else:
|
|
110
116
|
typing = "str"
|
|
111
117
|
init_args.append(
|
|
112
|
-
f"self.{prop.
|
|
118
|
+
f"self.{prop.client_name} = {discriminator_value} # type: {typing}"
|
|
113
119
|
)
|
|
114
120
|
elif prop.readonly:
|
|
115
|
-
init_args.append(f"self.{prop.
|
|
121
|
+
init_args.append(f"self.{prop.client_name} = None")
|
|
116
122
|
elif not prop.constant:
|
|
117
123
|
init_args.append(self.initialize_standard_arg(prop))
|
|
118
124
|
return init_args
|
|
119
125
|
|
|
120
126
|
def initialize_standard_property(self, prop: Property):
|
|
121
|
-
if prop.
|
|
127
|
+
if not (prop.optional or prop.client_default_value is not None):
|
|
122
128
|
return self.required_property_no_default_init(prop)
|
|
123
129
|
return self.optional_property_init(prop)
|
|
124
130
|
|
|
131
|
+
@staticmethod
|
|
132
|
+
def discriminator_docstring(model: ModelType) -> str:
|
|
133
|
+
return (
|
|
134
|
+
"You probably want to use the sub-classes and not this class directly. "
|
|
135
|
+
f"Known sub-classes are: {', '.join(v.name for v in model.discriminated_subtypes.values())}"
|
|
136
|
+
)
|
|
137
|
+
|
|
125
138
|
@abstractmethod
|
|
126
|
-
def init_line(self, model:
|
|
139
|
+
def init_line(self, model: ModelType) -> List[str]:
|
|
127
140
|
...
|
|
128
141
|
|
|
129
142
|
@abstractmethod
|
|
130
|
-
def properties_to_pass_to_super(self, model:
|
|
143
|
+
def properties_to_pass_to_super(self, model: ModelType) -> str:
|
|
131
144
|
...
|
|
132
145
|
|
|
133
146
|
@abstractmethod
|
|
@@ -6,25 +6,27 @@
|
|
|
6
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
|
|
|
11
11
|
|
|
12
12
|
class ModelGenericSerializer(ModelBaseSerializer):
|
|
13
13
|
def __init__(self, code_model: CodeModel, env: Environment) -> None:
|
|
14
14
|
super().__init__(code_model=code_model, env=env, is_python3_file=False)
|
|
15
15
|
|
|
16
|
-
def init_line(self, model:
|
|
16
|
+
def init_line(self, model: ModelType) -> List[str]:
|
|
17
17
|
return []
|
|
18
18
|
|
|
19
|
-
def properties_to_pass_to_super(self, model:
|
|
19
|
+
def properties_to_pass_to_super(self, model: ModelType) -> str:
|
|
20
20
|
return "**kwargs"
|
|
21
21
|
|
|
22
22
|
def required_property_no_default_init(self, prop: Property) -> str:
|
|
23
|
-
return f"self.{prop.
|
|
23
|
+
return f"self.{prop.client_name} = kwargs['{prop.client_name}']"
|
|
24
24
|
|
|
25
25
|
def optional_property_init(self, prop: Property) -> str:
|
|
26
|
-
|
|
27
|
-
return f"self.{prop.name} = kwargs.get('{prop.name}', {default})"
|
|
26
|
+
return f"self.{prop.client_name} = kwargs.get('{prop.client_name}', {prop.client_default_value_declaration})"
|
|
28
27
|
|
|
29
28
|
def initialize_standard_arg(self, prop: Property) -> str:
|
|
30
29
|
return self.initialize_standard_property(prop)
|
|
30
|
+
|
|
31
|
+
def super_call_template(self, model: ModelType) -> str:
|
|
32
|
+
return "super(" + model.name + ", self).__init__({})"
|
|
@@ -13,12 +13,10 @@ class ModelInitSerializer:
|
|
|
13
13
|
self.env = env
|
|
14
14
|
|
|
15
15
|
def serialize(self) -> str:
|
|
16
|
-
schemas = [s.name for s in self.code_model.
|
|
16
|
+
schemas = [s.name for s in self.code_model.public_model_types]
|
|
17
17
|
schemas.sort()
|
|
18
18
|
enums = (
|
|
19
|
-
[e.name for e in self.code_model.enums.
|
|
20
|
-
if self.code_model.enums
|
|
21
|
-
else None
|
|
19
|
+
[e.name for e in self.code_model.enums] if self.code_model.enums else None
|
|
22
20
|
)
|
|
23
21
|
|
|
24
22
|
if enums:
|
|
@@ -3,10 +3,10 @@
|
|
|
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
|
|
|
@@ -14,53 +14,59 @@ class ModelPython3Serializer(ModelBaseSerializer):
|
|
|
14
14
|
def __init__(self, code_model: CodeModel, env: Environment) -> None:
|
|
15
15
|
super().__init__(code_model=code_model, env=env, is_python3_file=True)
|
|
16
16
|
|
|
17
|
-
def init_line(self, model:
|
|
17
|
+
def init_line(self, model: ModelType) -> List[str]:
|
|
18
18
|
init_properties_declaration = []
|
|
19
19
|
init_line_parameters = [
|
|
20
20
|
p
|
|
21
21
|
for p in model.properties
|
|
22
22
|
if not p.readonly and not p.is_discriminator and not p.constant
|
|
23
23
|
]
|
|
24
|
-
init_line_parameters.sort(key=lambda x: x.
|
|
24
|
+
init_line_parameters.sort(key=lambda x: x.optional)
|
|
25
25
|
if init_line_parameters:
|
|
26
|
-
init_properties_declaration.append("
|
|
26
|
+
init_properties_declaration.append("*,")
|
|
27
27
|
for param in init_line_parameters:
|
|
28
28
|
init_properties_declaration.append(self.initialize_standard_property(param))
|
|
29
29
|
|
|
30
30
|
return init_properties_declaration
|
|
31
31
|
|
|
32
|
-
def properties_to_pass_to_super(self, model:
|
|
32
|
+
def properties_to_pass_to_super(self, model: ModelType) -> str:
|
|
33
33
|
properties_to_pass_to_super = []
|
|
34
|
-
for
|
|
35
|
-
base_model = cast(ObjectSchema, uncast_base_model)
|
|
34
|
+
for parent in model.parents:
|
|
36
35
|
for prop in model.properties:
|
|
37
36
|
if (
|
|
38
|
-
prop in
|
|
37
|
+
prop in parent.properties
|
|
39
38
|
and not prop.is_discriminator
|
|
40
39
|
and not prop.constant
|
|
41
40
|
and not prop.readonly
|
|
42
41
|
):
|
|
43
|
-
properties_to_pass_to_super.append(
|
|
42
|
+
properties_to_pass_to_super.append(
|
|
43
|
+
f"{prop.client_name}={prop.client_name}"
|
|
44
|
+
)
|
|
44
45
|
properties_to_pass_to_super.append("**kwargs")
|
|
45
46
|
return ", ".join(properties_to_pass_to_super)
|
|
46
47
|
|
|
47
48
|
def required_property_no_default_init(self, prop: Property) -> str:
|
|
48
|
-
return f"{prop.
|
|
49
|
+
return f"{prop.client_name}: {prop.type_annotation()},{prop.pylint_disable}"
|
|
49
50
|
|
|
50
51
|
def optional_property_init(self, prop: Property) -> str:
|
|
51
|
-
|
|
52
|
-
|
|
52
|
+
return (
|
|
53
|
+
f"{prop.client_name}: {prop.type_annotation()} = "
|
|
54
|
+
f"{prop.client_default_value_declaration},{prop.pylint_disable}"
|
|
55
|
+
)
|
|
53
56
|
|
|
54
57
|
def initialize_standard_arg(self, prop: Property) -> str:
|
|
55
|
-
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__({})"
|
|
56
62
|
|
|
57
63
|
def imports(self) -> FileImport:
|
|
58
64
|
file_import = super(ModelPython3Serializer, self).imports()
|
|
59
|
-
for model in self.code_model.
|
|
65
|
+
for model in self.code_model.model_types:
|
|
60
66
|
init_line_parameters = [
|
|
61
67
|
p for p in model.properties if not p.readonly and not p.is_discriminator
|
|
62
68
|
]
|
|
63
69
|
for param in init_line_parameters:
|
|
64
|
-
file_import.merge(param.
|
|
70
|
+
file_import.merge(param.imports())
|
|
65
71
|
|
|
66
72
|
return file_import
|
|
@@ -11,11 +11,9 @@ 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
|
|
19
17
|
|
|
20
18
|
|
|
21
19
|
class OperationGroupsSerializer:
|
|
@@ -34,12 +32,6 @@ class OperationGroupsSerializer:
|
|
|
34
32
|
self.operation_group = operation_group
|
|
35
33
|
|
|
36
34
|
def serialize(self) -> str:
|
|
37
|
-
def _is_lro(operation):
|
|
38
|
-
return isinstance(operation, LROOperation)
|
|
39
|
-
|
|
40
|
-
def _is_paging(operation):
|
|
41
|
-
return isinstance(operation, PagingOperation)
|
|
42
|
-
|
|
43
35
|
operation_groups = (
|
|
44
36
|
[self.operation_group]
|
|
45
37
|
if self.operation_group
|
|
@@ -67,16 +59,18 @@ class OperationGroupsSerializer:
|
|
|
67
59
|
),
|
|
68
60
|
async_mode=self.async_mode,
|
|
69
61
|
is_python3_file=self.is_python3_file,
|
|
70
|
-
is_lro=_is_lro,
|
|
71
|
-
is_paging=_is_paging,
|
|
72
62
|
get_operation_serializer=functools.partial(
|
|
73
63
|
get_operation_serializer,
|
|
74
64
|
code_model=self.code_model,
|
|
75
65
|
async_mode=self.async_mode,
|
|
76
66
|
is_python3_file=self.is_python3_file,
|
|
77
67
|
),
|
|
78
|
-
request_builder_serializer=
|
|
68
|
+
request_builder_serializer=RequestBuilderSerializer(
|
|
79
69
|
self.code_model,
|
|
80
|
-
|
|
70
|
+
async_mode=False,
|
|
71
|
+
is_python3_file=self.is_python3_file,
|
|
81
72
|
),
|
|
73
|
+
request_builders=[
|
|
74
|
+
rb for rb in self.code_model.request_builders if not rb.abstract
|
|
75
|
+
],
|
|
82
76
|
)
|
|
@@ -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)
|
|
@@ -6,13 +6,10 @@
|
|
|
6
6
|
from typing import List
|
|
7
7
|
from jinja2 import Environment
|
|
8
8
|
|
|
9
|
-
from ..models import
|
|
9
|
+
from ..models import FileImport
|
|
10
10
|
from .import_serializer import FileImportSerializer
|
|
11
|
-
from ..models import CodeModel
|
|
12
|
-
from .builder_serializer import
|
|
13
|
-
RequestBuilderGenericSerializer,
|
|
14
|
-
RequestBuilderPython3Serializer,
|
|
15
|
-
)
|
|
11
|
+
from ..models import CodeModel, RequestBuilderType
|
|
12
|
+
from .builder_serializer import RequestBuilderSerializer
|
|
16
13
|
|
|
17
14
|
|
|
18
15
|
class RequestBuildersSerializer:
|
|
@@ -20,55 +17,41 @@ class RequestBuildersSerializer:
|
|
|
20
17
|
self,
|
|
21
18
|
code_model: CodeModel,
|
|
22
19
|
env: Environment,
|
|
23
|
-
request_builders: List[
|
|
20
|
+
request_builders: List[RequestBuilderType],
|
|
21
|
+
is_python3_file: bool,
|
|
24
22
|
) -> None:
|
|
25
23
|
self.code_model = code_model
|
|
26
24
|
self.env = env
|
|
27
25
|
self.request_builders = request_builders
|
|
28
|
-
self.
|
|
26
|
+
self.group_name = request_builders[0].group_name
|
|
27
|
+
self.is_python3_file = is_python3_file
|
|
29
28
|
|
|
30
29
|
@property
|
|
31
30
|
def imports(self) -> FileImport:
|
|
32
31
|
file_import = FileImport()
|
|
33
32
|
for request_builder in self.request_builders:
|
|
34
|
-
if request_builder.
|
|
33
|
+
if request_builder.group_name == self.group_name:
|
|
35
34
|
file_import.merge(request_builder.imports())
|
|
36
35
|
return file_import
|
|
37
36
|
|
|
38
37
|
def serialize_init(self) -> str:
|
|
39
38
|
template = self.env.get_template("rest_init.py.jinja2")
|
|
40
39
|
return template.render(
|
|
41
|
-
code_model=self.code_model,
|
|
40
|
+
code_model=self.code_model,
|
|
41
|
+
request_builders=[r for r in self.request_builders if not r.is_overload],
|
|
42
42
|
)
|
|
43
43
|
|
|
44
|
-
|
|
45
|
-
class RequestBuildersPython3Serializer(RequestBuildersSerializer):
|
|
46
44
|
def serialize_request_builders(self) -> str:
|
|
47
45
|
template = self.env.get_template("request_builders.py.jinja2")
|
|
48
46
|
|
|
49
47
|
return template.render(
|
|
50
48
|
code_model=self.code_model,
|
|
51
|
-
request_builders=self.request_builders,
|
|
49
|
+
request_builders=[rb for rb in self.request_builders if not rb.abstract],
|
|
52
50
|
imports=FileImportSerializer(
|
|
53
51
|
self.imports,
|
|
54
52
|
is_python3_file=True,
|
|
55
53
|
),
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
)
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
class RequestBuildersGenericSerializer(RequestBuildersSerializer):
|
|
62
|
-
def serialize_request_builders(self) -> str:
|
|
63
|
-
template = self.env.get_template("request_builders.py.jinja2")
|
|
64
|
-
|
|
65
|
-
return template.render(
|
|
66
|
-
code_model=self.code_model,
|
|
67
|
-
request_builders=self.request_builders,
|
|
68
|
-
imports=FileImportSerializer(
|
|
69
|
-
self.imports,
|
|
70
|
-
is_python3_file=False,
|
|
54
|
+
request_builder_serializer=RequestBuilderSerializer(
|
|
55
|
+
self.code_model, async_mode=False, is_python3_file=self.is_python3_file
|
|
71
56
|
),
|
|
72
|
-
is_python3_file=False,
|
|
73
|
-
request_builder_serializer=RequestBuilderGenericSerializer(self.code_model),
|
|
74
57
|
)
|