@autorest/python 5.15.0 → 5.16.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 +20 -0
- package/autorest/__init__.py +1 -2
- package/autorest/black/__init__.py +12 -5
- package/autorest/codegen/__init__.py +145 -73
- package/autorest/codegen/models/__init__.py +29 -18
- package/autorest/codegen/models/base_builder.py +48 -11
- package/autorest/codegen/models/base_model.py +6 -4
- package/autorest/codegen/models/base_schema.py +19 -18
- package/autorest/codegen/models/client.py +65 -21
- package/autorest/codegen/models/code_model.py +107 -61
- package/autorest/codegen/models/constant_schema.py +25 -13
- package/autorest/codegen/models/credential_model.py +23 -15
- package/autorest/codegen/models/credential_schema.py +18 -14
- package/autorest/codegen/models/credential_schema_policy.py +11 -15
- package/autorest/codegen/models/dictionary_schema.py +20 -17
- package/autorest/codegen/models/enum_schema.py +35 -25
- package/autorest/codegen/models/imports.py +70 -41
- package/autorest/codegen/models/list_schema.py +25 -13
- package/autorest/codegen/models/lro_operation.py +58 -22
- package/autorest/codegen/models/lro_paging_operation.py +2 -3
- package/autorest/codegen/models/object_schema.py +99 -49
- package/autorest/codegen/models/operation.py +236 -117
- package/autorest/codegen/models/operation_group.py +64 -34
- package/autorest/codegen/models/paging_operation.py +45 -18
- package/autorest/codegen/models/parameter.py +151 -83
- package/autorest/codegen/models/parameter_list.py +183 -162
- package/autorest/codegen/models/primitive_schemas.py +84 -55
- package/autorest/codegen/models/property.py +44 -26
- package/autorest/codegen/models/request_builder.py +65 -30
- package/autorest/codegen/models/request_builder_parameter.py +47 -23
- package/autorest/codegen/models/request_builder_parameter_list.py +77 -108
- package/autorest/codegen/models/schema_request.py +16 -6
- package/autorest/codegen/models/schema_response.py +18 -13
- package/autorest/codegen/models/utils.py +5 -2
- package/autorest/codegen/serializers/__init__.py +182 -91
- package/autorest/codegen/serializers/builder_serializer.py +667 -331
- package/autorest/codegen/serializers/client_serializer.py +98 -37
- package/autorest/codegen/serializers/general_serializer.py +61 -26
- package/autorest/codegen/serializers/import_serializer.py +93 -31
- package/autorest/codegen/serializers/metadata_serializer.py +73 -24
- package/autorest/codegen/serializers/model_base_serializer.py +35 -15
- package/autorest/codegen/serializers/model_generic_serializer.py +1 -4
- package/autorest/codegen/serializers/model_init_serializer.py +5 -1
- package/autorest/codegen/serializers/model_python3_serializer.py +7 -6
- package/autorest/codegen/serializers/operation_groups_serializer.py +20 -9
- package/autorest/codegen/serializers/operations_init_serializer.py +23 -11
- package/autorest/codegen/serializers/patch_serializer.py +4 -1
- package/autorest/codegen/serializers/{rest_serializer.py → request_builders_serializer.py} +29 -12
- package/autorest/codegen/serializers/utils.py +35 -21
- package/autorest/codegen/templates/init.py.jinja2 +2 -2
- package/autorest/codegen/templates/lro_operation.py.jinja2 +5 -7
- package/autorest/codegen/templates/lro_paging_operation.py.jinja2 +5 -7
- package/autorest/codegen/templates/metadata.json.jinja2 +7 -6
- package/autorest/codegen/templates/operation.py.jinja2 +7 -9
- package/autorest/codegen/templates/operation_group.py.jinja2 +2 -8
- package/autorest/codegen/templates/operation_groups_container.py.jinja2 +1 -1
- package/autorest/codegen/templates/paging_operation.py.jinja2 +7 -8
- package/autorest/codegen/templates/request_builder.py.jinja2 +18 -11
- package/autorest/jsonrpc/__init__.py +7 -12
- package/autorest/jsonrpc/localapi.py +4 -3
- package/autorest/jsonrpc/server.py +13 -6
- package/autorest/jsonrpc/stdstream.py +13 -6
- package/autorest/m2r/__init__.py +5 -8
- 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 +18 -23
- package/autorest/multiapi/serializers/import_serializer.py +47 -17
- package/autorest/multiapi/serializers/multiapi_serializer.py +17 -17
- package/autorest/multiapi/templates/multiapi_operations_mixin.py.jinja2 +1 -1
- package/autorest/multiapi/utils.py +3 -3
- package/autorest/namer/__init__.py +2 -4
- package/autorest/namer/name_converter.py +200 -103
- package/autorest/namer/python_mappings.py +10 -22
- package/package.json +2 -2
- package/run-python3.js +2 -3
- package/venvtools.py +1 -1
- package/autorest/codegen/models/rest.py +0 -42
|
@@ -3,14 +3,18 @@
|
|
|
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 Any, Callable, Dict, List, Optional, Union
|
|
6
|
+
from typing import Any, Callable, Dict, List, Optional, Union, TYPE_CHECKING
|
|
7
7
|
from .base_model import BaseModel
|
|
8
8
|
from .schema_response import SchemaResponse
|
|
9
9
|
from .schema_request import SchemaRequest
|
|
10
10
|
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
from .code_model import CodeModel
|
|
13
|
+
|
|
11
14
|
|
|
12
15
|
_M4_HEADER_PARAMETERS = ["content_type", "accept"]
|
|
13
16
|
|
|
17
|
+
|
|
14
18
|
def create_parameters(
|
|
15
19
|
yaml_data: Dict[str, Any], code_model, parameter_creator: Callable
|
|
16
20
|
):
|
|
@@ -40,9 +44,8 @@ def create_parameters(
|
|
|
40
44
|
)
|
|
41
45
|
if len(body_parameters_name_set) > 1:
|
|
42
46
|
raise ValueError(
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
47
|
+
f"The body parameter with multiple media types has different names: {body_parameters_name_set}"
|
|
48
|
+
)
|
|
46
49
|
|
|
47
50
|
parameters_index = {id(parameter.yaml_data): parameter for parameter in parameters}
|
|
48
51
|
|
|
@@ -58,34 +61,58 @@ def create_parameters(
|
|
|
58
61
|
|
|
59
62
|
return parameters, multiple_content_type_parameters
|
|
60
63
|
|
|
64
|
+
|
|
61
65
|
class BaseBuilder(BaseModel):
|
|
62
66
|
"""Base class for Operations and Request Builders"""
|
|
63
67
|
|
|
64
68
|
def __init__(
|
|
65
69
|
self,
|
|
66
|
-
code_model,
|
|
67
70
|
yaml_data: Dict[str, Any],
|
|
71
|
+
code_model: "CodeModel",
|
|
68
72
|
name: str,
|
|
69
73
|
description: str,
|
|
70
74
|
parameters,
|
|
71
75
|
schema_requests: List[SchemaRequest],
|
|
72
76
|
responses: Optional[List[SchemaResponse]] = None,
|
|
73
77
|
summary: Optional[str] = None,
|
|
78
|
+
*,
|
|
79
|
+
abstract: bool = False,
|
|
80
|
+
want_tracing: bool = True,
|
|
74
81
|
) -> None:
|
|
75
|
-
super().__init__(yaml_data=yaml_data)
|
|
76
|
-
self.code_model = code_model
|
|
82
|
+
super().__init__(yaml_data=yaml_data, code_model=code_model)
|
|
77
83
|
self.name = name
|
|
78
|
-
self.
|
|
84
|
+
self._description = description
|
|
79
85
|
self.parameters = parameters
|
|
80
86
|
self.responses = responses or []
|
|
81
|
-
self.
|
|
87
|
+
self._summary = summary
|
|
82
88
|
self.schema_requests = schema_requests
|
|
89
|
+
# for operations where we don't know what to do, we mark them as abstract so users implement
|
|
90
|
+
# in patch.py
|
|
91
|
+
self.abstract = abstract
|
|
92
|
+
self.want_tracing = want_tracing
|
|
93
|
+
|
|
94
|
+
@property
|
|
95
|
+
def summary(self) -> Optional[str]:
|
|
96
|
+
if self.abstract:
|
|
97
|
+
return None
|
|
98
|
+
return self._summary
|
|
99
|
+
|
|
100
|
+
@property
|
|
101
|
+
def description(self) -> str:
|
|
102
|
+
if self.abstract:
|
|
103
|
+
return (
|
|
104
|
+
f'You need to write a custom operation for "{self.name}". Please refer to '
|
|
105
|
+
"https://aka.ms/azsdk/python/dpcodegen/python/customize to learn how to customize."
|
|
106
|
+
)
|
|
107
|
+
return self._description
|
|
83
108
|
|
|
84
109
|
@property
|
|
85
110
|
def default_content_type_declaration(self) -> str:
|
|
86
111
|
return f'"{self.parameters.default_content_type}"'
|
|
87
112
|
|
|
88
|
-
def get_response_from_status(
|
|
113
|
+
def get_response_from_status(
|
|
114
|
+
self, status_code: Optional[Union[str, int]]
|
|
115
|
+
) -> SchemaResponse:
|
|
89
116
|
for response in self.responses:
|
|
90
117
|
if status_code in response.status_codes:
|
|
91
118
|
return response
|
|
@@ -94,4 +121,14 @@ class BaseBuilder(BaseModel):
|
|
|
94
121
|
@property
|
|
95
122
|
def success_status_code(self) -> List[Union[str, int]]:
|
|
96
123
|
"""The list of all successfull status code."""
|
|
97
|
-
return [
|
|
124
|
+
return [
|
|
125
|
+
code
|
|
126
|
+
for response in self.responses
|
|
127
|
+
for code in response.status_codes
|
|
128
|
+
if code != "default"
|
|
129
|
+
]
|
|
130
|
+
|
|
131
|
+
def method_signature(self, is_python3_file: bool) -> List[str]:
|
|
132
|
+
if self.abstract:
|
|
133
|
+
return ["*args,", "**kwargs"]
|
|
134
|
+
return self.parameters.method_signature(is_python3_file)
|
|
@@ -3,7 +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 Any, Dict
|
|
6
|
+
from typing import Any, Dict, TYPE_CHECKING
|
|
7
|
+
|
|
8
|
+
if TYPE_CHECKING:
|
|
9
|
+
from .code_model import CodeModel
|
|
7
10
|
|
|
8
11
|
|
|
9
12
|
class BaseModel:
|
|
@@ -13,10 +16,9 @@ class BaseModel:
|
|
|
13
16
|
:type yaml_data: dict[str, Any]
|
|
14
17
|
"""
|
|
15
18
|
|
|
16
|
-
def __init__(
|
|
17
|
-
self, yaml_data: Dict[str, Any],
|
|
18
|
-
) -> None:
|
|
19
|
+
def __init__(self, yaml_data: Dict[str, Any], code_model: "CodeModel") -> None:
|
|
19
20
|
self.yaml_data = yaml_data
|
|
21
|
+
self.code_model = code_model
|
|
20
22
|
|
|
21
23
|
@property
|
|
22
24
|
def id(self) -> int:
|
|
@@ -4,11 +4,14 @@
|
|
|
4
4
|
# license information.
|
|
5
5
|
# --------------------------------------------------------------------------
|
|
6
6
|
from abc import ABC, abstractmethod
|
|
7
|
-
from typing import Any, Dict, List, Optional, Union
|
|
7
|
+
from typing import Any, Dict, List, Optional, Union, TYPE_CHECKING
|
|
8
8
|
|
|
9
9
|
from .base_model import BaseModel
|
|
10
10
|
from .imports import FileImport
|
|
11
11
|
|
|
12
|
+
if TYPE_CHECKING:
|
|
13
|
+
from .code_model import CodeModel
|
|
14
|
+
|
|
12
15
|
|
|
13
16
|
class BaseSchema(BaseModel, ABC):
|
|
14
17
|
"""This is the base class for all schema models.
|
|
@@ -17,18 +20,19 @@ class BaseSchema(BaseModel, ABC):
|
|
|
17
20
|
:type yaml_data: dict[str, Any]
|
|
18
21
|
"""
|
|
19
22
|
|
|
20
|
-
def __init__(self,
|
|
21
|
-
super().__init__(yaml_data)
|
|
22
|
-
self.namespace = namespace
|
|
23
|
+
def __init__(self, yaml_data: Dict[str, Any], code_model: "CodeModel") -> None:
|
|
24
|
+
super().__init__(yaml_data, code_model)
|
|
23
25
|
self.default_value = yaml_data.get("defaultValue", None)
|
|
24
26
|
self.xml_metadata = yaml_data.get("serialization", {}).get("xml", {})
|
|
25
|
-
self.api_versions = set(
|
|
27
|
+
self.api_versions = set(
|
|
28
|
+
value_dict["version"] for value_dict in yaml_data.get("apiVersions", [])
|
|
29
|
+
)
|
|
26
30
|
|
|
27
31
|
@classmethod
|
|
28
32
|
def from_yaml(
|
|
29
|
-
cls,
|
|
33
|
+
cls, yaml_data: Dict[str, Any], code_model: "CodeModel"
|
|
30
34
|
) -> "BaseSchema":
|
|
31
|
-
return cls(
|
|
35
|
+
return cls(yaml_data=yaml_data, code_model=code_model)
|
|
32
36
|
|
|
33
37
|
@property
|
|
34
38
|
def extra_description_information(self) -> str:
|
|
@@ -77,8 +81,7 @@ class BaseSchema(BaseModel, ABC):
|
|
|
77
81
|
@property
|
|
78
82
|
@abstractmethod
|
|
79
83
|
def docstring_text(self) -> str:
|
|
80
|
-
"""The names used in rtype documentation
|
|
81
|
-
"""
|
|
84
|
+
"""The names used in rtype documentation"""
|
|
82
85
|
...
|
|
83
86
|
|
|
84
87
|
@property
|
|
@@ -113,26 +116,24 @@ class BaseSchema(BaseModel, ABC):
|
|
|
113
116
|
|
|
114
117
|
@property
|
|
115
118
|
def default_value_declaration(self) -> str:
|
|
116
|
-
"""Return the default value as string using get_declaration.
|
|
117
|
-
"""
|
|
119
|
+
"""Return the default value as string using get_declaration."""
|
|
118
120
|
if self.default_value is None:
|
|
119
121
|
return "None"
|
|
120
122
|
return self.get_declaration(self.default_value)
|
|
121
123
|
|
|
122
124
|
@property
|
|
123
|
-
def validation_map(
|
|
125
|
+
def validation_map(
|
|
126
|
+
self,
|
|
127
|
+
) -> Optional[Dict[str, Union[bool, int, str]]]: # pylint: disable=no-self-use
|
|
124
128
|
return None
|
|
125
129
|
|
|
126
130
|
@property
|
|
127
|
-
def serialization_constraints(
|
|
131
|
+
def serialization_constraints(
|
|
132
|
+
self,
|
|
133
|
+
) -> Optional[List[str]]: # pylint: disable=no-self-use
|
|
128
134
|
return None
|
|
129
135
|
|
|
130
136
|
@abstractmethod
|
|
131
137
|
def get_json_template_representation(self, **kwargs: Any) -> Any:
|
|
132
138
|
"""Template of what this schema would look like as JSON input"""
|
|
133
139
|
...
|
|
134
|
-
|
|
135
|
-
@abstractmethod
|
|
136
|
-
def get_files_and_data_template_representation(self, **kwargs: Any) -> Any:
|
|
137
|
-
"""Template of what this schema would look like as files input"""
|
|
138
|
-
...
|
|
@@ -3,15 +3,18 @@
|
|
|
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, Optional
|
|
6
|
+
from typing import List, Optional, TYPE_CHECKING
|
|
7
7
|
from .parameter_list import GlobalParameterList
|
|
8
8
|
from .imports import FileImport, ImportType, TypingSection
|
|
9
9
|
|
|
10
|
+
if TYPE_CHECKING:
|
|
11
|
+
from .code_model import CodeModel
|
|
12
|
+
|
|
13
|
+
|
|
10
14
|
class Client:
|
|
11
|
-
"""A service client.
|
|
12
|
-
"""
|
|
15
|
+
"""A service client."""
|
|
13
16
|
|
|
14
|
-
def __init__(self, code_model, parameters: GlobalParameterList):
|
|
17
|
+
def __init__(self, code_model: "CodeModel", parameters: GlobalParameterList):
|
|
15
18
|
self.code_model = code_model
|
|
16
19
|
self.parameters = parameters
|
|
17
20
|
self.parameterized_host_template: Optional[str] = None
|
|
@@ -34,14 +37,26 @@ class Client:
|
|
|
34
37
|
file_import = FileImport()
|
|
35
38
|
|
|
36
39
|
file_import.add_submodule_import("msrest", "Serializer", ImportType.THIRDPARTY)
|
|
37
|
-
file_import.add_submodule_import(
|
|
38
|
-
|
|
40
|
+
file_import.add_submodule_import(
|
|
41
|
+
"msrest", "Deserializer", ImportType.THIRDPARTY
|
|
42
|
+
)
|
|
43
|
+
file_import.add_submodule_import(
|
|
44
|
+
"typing", "Any", ImportType.STDLIB, TypingSection.CONDITIONAL
|
|
45
|
+
)
|
|
39
46
|
|
|
40
47
|
any_optional_gp = any(not gp.required for gp in self.parameters)
|
|
41
48
|
|
|
42
|
-
legacy = not any(
|
|
43
|
-
|
|
44
|
-
|
|
49
|
+
legacy = not any(
|
|
50
|
+
g
|
|
51
|
+
for g in ["low_level_client", "version_tolerant"]
|
|
52
|
+
if g in self.code_model.options
|
|
53
|
+
)
|
|
54
|
+
if any_optional_gp or (
|
|
55
|
+
legacy and self.code_model.service_client.parameters.host
|
|
56
|
+
):
|
|
57
|
+
file_import.add_submodule_import(
|
|
58
|
+
"typing", "Optional", ImportType.STDLIB, TypingSection.CONDITIONAL
|
|
59
|
+
)
|
|
45
60
|
|
|
46
61
|
if self.code_model.options["azure_arm"]:
|
|
47
62
|
file_import.add_submodule_import(
|
|
@@ -55,8 +70,9 @@ class Client:
|
|
|
55
70
|
for gp in self.code_model.global_parameters:
|
|
56
71
|
file_import.merge(gp.imports())
|
|
57
72
|
file_import.add_submodule_import(
|
|
58
|
-
"._configuration",
|
|
59
|
-
|
|
73
|
+
"._configuration",
|
|
74
|
+
f"{self.code_model.class_name}Configuration",
|
|
75
|
+
ImportType.LOCAL,
|
|
60
76
|
)
|
|
61
77
|
|
|
62
78
|
return file_import
|
|
@@ -66,18 +82,29 @@ class Client:
|
|
|
66
82
|
if async_mode:
|
|
67
83
|
file_import.add_submodule_import("typing", "Awaitable", ImportType.STDLIB)
|
|
68
84
|
file_import.add_submodule_import(
|
|
69
|
-
"azure.core.rest",
|
|
85
|
+
"azure.core.rest",
|
|
86
|
+
"AsyncHttpResponse",
|
|
87
|
+
ImportType.AZURECORE,
|
|
88
|
+
TypingSection.CONDITIONAL,
|
|
70
89
|
)
|
|
71
90
|
else:
|
|
72
91
|
file_import.add_submodule_import(
|
|
73
|
-
"azure.core.rest",
|
|
92
|
+
"azure.core.rest",
|
|
93
|
+
"HttpResponse",
|
|
94
|
+
ImportType.AZURECORE,
|
|
95
|
+
TypingSection.CONDITIONAL,
|
|
74
96
|
)
|
|
75
97
|
file_import.add_submodule_import(
|
|
76
|
-
"azure.core.rest",
|
|
98
|
+
"azure.core.rest",
|
|
99
|
+
"HttpRequest",
|
|
100
|
+
ImportType.AZURECORE,
|
|
101
|
+
TypingSection.CONDITIONAL,
|
|
77
102
|
)
|
|
78
103
|
for og in self.code_model.operation_groups:
|
|
79
104
|
file_import.add_submodule_import(
|
|
80
|
-
f".{self.code_model.operations_folder_name}",
|
|
105
|
+
f".{self.code_model.operations_folder_name}",
|
|
106
|
+
og.class_name,
|
|
107
|
+
ImportType.LOCAL,
|
|
81
108
|
)
|
|
82
109
|
|
|
83
110
|
if self.code_model.sorted_schemas:
|
|
@@ -86,25 +113,42 @@ class Client:
|
|
|
86
113
|
else:
|
|
87
114
|
# in this case, we have client_models = {} in the service client, which needs a type annotation
|
|
88
115
|
# this import will always be commented, so will always add it to the typing section
|
|
89
|
-
file_import.add_submodule_import(
|
|
116
|
+
file_import.add_submodule_import(
|
|
117
|
+
"typing", "Dict", ImportType.STDLIB, TypingSection.TYPING
|
|
118
|
+
)
|
|
90
119
|
file_import.add_submodule_import("copy", "deepcopy", ImportType.STDLIB)
|
|
91
120
|
return file_import
|
|
92
121
|
|
|
93
122
|
def imports_for_multiapi(self, async_mode: bool) -> FileImport:
|
|
94
123
|
file_import = self._imports_shared(async_mode)
|
|
95
124
|
try:
|
|
96
|
-
mixin_operation = next(
|
|
97
|
-
|
|
125
|
+
mixin_operation = next(
|
|
126
|
+
og
|
|
127
|
+
for og in self.code_model.operation_groups
|
|
128
|
+
if og.is_empty_operation_group
|
|
129
|
+
)
|
|
130
|
+
file_import.add_submodule_import(
|
|
131
|
+
"._operations_mixin", mixin_operation.class_name, ImportType.LOCAL
|
|
132
|
+
)
|
|
98
133
|
except StopIteration:
|
|
99
134
|
pass
|
|
100
135
|
return file_import
|
|
101
136
|
|
|
102
137
|
def send_request_signature(self, is_python3_file: bool) -> List[str]:
|
|
103
|
-
request_signature = [
|
|
104
|
-
|
|
138
|
+
request_signature = [
|
|
139
|
+
"request: HttpRequest,"
|
|
140
|
+
if is_python3_file
|
|
141
|
+
else "request, # type: HttpRequest"
|
|
142
|
+
]
|
|
143
|
+
return request_signature + self.parameters.method_signature_kwargs(
|
|
144
|
+
is_python3_file
|
|
145
|
+
)
|
|
105
146
|
|
|
106
147
|
@property
|
|
107
148
|
def filename(self) -> str:
|
|
108
|
-
if
|
|
149
|
+
if (
|
|
150
|
+
self.code_model.options["version_tolerant"]
|
|
151
|
+
or self.code_model.options["low_level_client"]
|
|
152
|
+
):
|
|
109
153
|
return "_client"
|
|
110
154
|
return f"_{self.code_model.module_name}"
|