@autorest/python 5.14.0 → 5.17.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.
Files changed (120) hide show
  1. package/ChangeLog.md +91 -2
  2. package/README.md +30 -4
  3. package/autorest/__init__.py +2 -3
  4. package/autorest/black/__init__.py +12 -5
  5. package/autorest/codegen/__init__.py +130 -179
  6. package/autorest/codegen/models/__init__.py +122 -78
  7. package/autorest/codegen/models/base_builder.py +70 -72
  8. package/autorest/codegen/models/base_model.py +7 -5
  9. package/autorest/codegen/models/{base_schema.py → base_type.py} +62 -49
  10. package/autorest/codegen/models/client.py +195 -36
  11. package/autorest/codegen/models/code_model.py +165 -299
  12. package/autorest/codegen/models/combined_type.py +107 -0
  13. package/autorest/codegen/models/constant_type.py +122 -0
  14. package/autorest/codegen/models/credential_types.py +224 -0
  15. package/autorest/codegen/models/dictionary_type.py +116 -0
  16. package/autorest/codegen/models/enum_type.py +195 -0
  17. package/autorest/codegen/models/imports.py +95 -41
  18. package/autorest/codegen/models/list_type.py +134 -0
  19. package/autorest/codegen/models/lro_operation.py +90 -133
  20. package/autorest/codegen/models/lro_paging_operation.py +28 -12
  21. package/autorest/codegen/models/model_type.py +239 -0
  22. package/autorest/codegen/models/operation.py +415 -241
  23. package/autorest/codegen/models/operation_group.py +82 -88
  24. package/autorest/codegen/models/paging_operation.py +101 -117
  25. package/autorest/codegen/models/parameter.py +307 -322
  26. package/autorest/codegen/models/parameter_list.py +366 -357
  27. package/autorest/codegen/models/primitive_types.py +544 -0
  28. package/autorest/codegen/models/property.py +122 -134
  29. package/autorest/codegen/models/request_builder.py +138 -86
  30. package/autorest/codegen/models/request_builder_parameter.py +122 -79
  31. package/autorest/codegen/models/response.py +325 -0
  32. package/autorest/codegen/models/utils.py +17 -1
  33. package/autorest/codegen/serializers/__init__.py +242 -118
  34. package/autorest/codegen/serializers/builder_serializer.py +863 -1027
  35. package/autorest/codegen/serializers/client_serializer.py +148 -82
  36. package/autorest/codegen/serializers/general_serializer.py +44 -47
  37. package/autorest/codegen/serializers/import_serializer.py +96 -31
  38. package/autorest/codegen/serializers/metadata_serializer.py +39 -79
  39. package/autorest/codegen/serializers/model_base_serializer.py +65 -29
  40. package/autorest/codegen/serializers/model_generic_serializer.py +9 -10
  41. package/autorest/codegen/serializers/model_init_serializer.py +4 -2
  42. package/autorest/codegen/serializers/model_python3_serializer.py +29 -22
  43. package/autorest/codegen/serializers/operation_groups_serializer.py +21 -18
  44. package/autorest/codegen/serializers/operations_init_serializer.py +23 -11
  45. package/autorest/codegen/serializers/parameter_serializer.py +174 -0
  46. package/autorest/codegen/serializers/patch_serializer.py +14 -2
  47. package/autorest/codegen/serializers/request_builders_serializer.py +57 -0
  48. package/autorest/codegen/serializers/utils.py +0 -103
  49. package/autorest/codegen/templates/MANIFEST.in.jinja2 +1 -0
  50. package/autorest/codegen/templates/{service_client.py.jinja2 → client.py.jinja2} +7 -7
  51. package/autorest/codegen/templates/config.py.jinja2 +13 -13
  52. package/autorest/codegen/templates/enum.py.jinja2 +4 -4
  53. package/autorest/codegen/templates/enum_container.py.jinja2 +1 -2
  54. package/autorest/codegen/templates/init.py.jinja2 +9 -6
  55. package/autorest/codegen/templates/keywords.jinja2 +14 -1
  56. package/autorest/codegen/templates/lro_operation.py.jinja2 +6 -5
  57. package/autorest/codegen/templates/lro_paging_operation.py.jinja2 +6 -5
  58. package/autorest/codegen/templates/metadata.json.jinja2 +36 -35
  59. package/autorest/codegen/templates/model.py.jinja2 +23 -29
  60. package/autorest/codegen/templates/model_container.py.jinja2 +2 -1
  61. package/autorest/codegen/templates/model_init.py.jinja2 +9 -8
  62. package/autorest/codegen/templates/operation.py.jinja2 +10 -15
  63. package/autorest/codegen/templates/operation_group.py.jinja2 +14 -13
  64. package/autorest/codegen/templates/operation_groups_container.py.jinja2 +1 -2
  65. package/autorest/codegen/templates/operation_tools.jinja2 +8 -2
  66. package/autorest/codegen/templates/operations_folder_init.py.jinja2 +4 -0
  67. package/autorest/codegen/templates/paging_operation.py.jinja2 +7 -8
  68. package/autorest/codegen/templates/patch.py.jinja2 +18 -29
  69. package/autorest/codegen/templates/request_builder.py.jinja2 +20 -13
  70. package/autorest/codegen/templates/setup.py.jinja2 +9 -3
  71. package/autorest/codegen/templates/vendor.py.jinja2 +12 -2
  72. package/autorest/jsonrpc/__init__.py +7 -12
  73. package/autorest/jsonrpc/localapi.py +4 -3
  74. package/autorest/jsonrpc/server.py +28 -9
  75. package/autorest/jsonrpc/stdstream.py +13 -6
  76. package/autorest/m2r/__init__.py +5 -8
  77. package/autorest/m4reformatter/__init__.py +1108 -0
  78. package/autorest/multiapi/__init__.py +24 -14
  79. package/autorest/multiapi/models/client.py +21 -11
  80. package/autorest/multiapi/models/code_model.py +23 -10
  81. package/autorest/multiapi/models/config.py +4 -1
  82. package/autorest/multiapi/models/constant_global_parameter.py +1 -0
  83. package/autorest/multiapi/models/global_parameter.py +2 -1
  84. package/autorest/multiapi/models/global_parameters.py +14 -8
  85. package/autorest/multiapi/models/imports.py +35 -18
  86. package/autorest/multiapi/models/mixin_operation.py +5 -5
  87. package/autorest/multiapi/models/operation_group.py +2 -1
  88. package/autorest/multiapi/models/operation_mixin_group.py +21 -10
  89. package/autorest/multiapi/serializers/__init__.py +20 -25
  90. package/autorest/multiapi/serializers/import_serializer.py +47 -15
  91. package/autorest/multiapi/serializers/multiapi_serializer.py +17 -17
  92. package/autorest/multiapi/templates/multiapi_config.py.jinja2 +3 -3
  93. package/autorest/multiapi/templates/multiapi_init.py.jinja2 +2 -2
  94. package/autorest/multiapi/templates/multiapi_operations_mixin.py.jinja2 +4 -4
  95. package/autorest/multiapi/templates/multiapi_service_client.py.jinja2 +9 -9
  96. package/autorest/multiapi/utils.py +3 -3
  97. package/autorest/postprocess/__init__.py +202 -0
  98. package/autorest/postprocess/get_all.py +19 -0
  99. package/autorest/postprocess/venvtools.py +73 -0
  100. package/autorest/preprocess/__init__.py +209 -0
  101. package/autorest/preprocess/helpers.py +54 -0
  102. package/autorest/{namer → preprocess}/python_mappings.py +25 -32
  103. package/package.json +3 -3
  104. package/run-python3.js +2 -3
  105. package/venvtools.py +1 -1
  106. package/autorest/codegen/models/constant_schema.py +0 -97
  107. package/autorest/codegen/models/credential_schema.py +0 -90
  108. package/autorest/codegen/models/credential_schema_policy.py +0 -77
  109. package/autorest/codegen/models/dictionary_schema.py +0 -103
  110. package/autorest/codegen/models/enum_schema.py +0 -246
  111. package/autorest/codegen/models/list_schema.py +0 -113
  112. package/autorest/codegen/models/object_schema.py +0 -249
  113. package/autorest/codegen/models/primitive_schemas.py +0 -476
  114. package/autorest/codegen/models/request_builder_parameter_list.py +0 -280
  115. package/autorest/codegen/models/rest.py +0 -42
  116. package/autorest/codegen/models/schema_request.py +0 -45
  117. package/autorest/codegen/models/schema_response.py +0 -123
  118. package/autorest/codegen/serializers/rest_serializer.py +0 -57
  119. package/autorest/namer/__init__.py +0 -25
  120. package/autorest/namer/name_converter.py +0 -412
@@ -3,23 +3,48 @@
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
7
- from .parameter_list import GlobalParameterList
6
+ from typing import Any, Dict, TYPE_CHECKING, TypeVar, Generic, Union
7
+
8
+ from .base_model import BaseModel
9
+ from .parameter_list import ClientGlobalParameterList, ConfigGlobalParameterList
8
10
  from .imports import FileImport, ImportType, TypingSection
11
+ from .utils import add_to_pylint_disable
12
+
13
+ ParameterListType = TypeVar(
14
+ "ParameterListType",
15
+ bound=Union[ClientGlobalParameterList, ConfigGlobalParameterList],
16
+ )
17
+
18
+ if TYPE_CHECKING:
19
+ from .code_model import CodeModel
9
20
 
10
- class Client:
11
- """A service client.
12
- """
13
21
 
14
- def __init__(self, code_model, parameters: GlobalParameterList):
15
- self.code_model = code_model
22
+ class _ClientConfigBase(Generic[ParameterListType], BaseModel):
23
+ """The service client base. Shared across our Client and Config type"""
24
+
25
+ def __init__(
26
+ self,
27
+ yaml_data: Dict[str, Any],
28
+ code_model: "CodeModel",
29
+ parameters: ParameterListType,
30
+ ):
31
+ super().__init__(yaml_data, code_model)
16
32
  self.parameters = parameters
17
- self.parameterized_host_template: Optional[str] = None
18
- self._config_parameters = parameters
33
+ self.url: str = self.yaml_data[
34
+ "url"
35
+ ] # the base endpoint of the client. Can be parameterized or not
19
36
 
20
37
  @property
21
- def has_parameterized_host(self) -> bool:
22
- return bool(self.parameterized_host_template)
38
+ def description(self) -> str:
39
+ return self.yaml_data["description"]
40
+
41
+ @property
42
+ def name(self) -> str:
43
+ return self.yaml_data["name"]
44
+
45
+
46
+ class Client(_ClientConfigBase[ClientGlobalParameterList]):
47
+ """Model representing our service client"""
23
48
 
24
49
  def pipeline_class(self, async_mode: bool) -> str:
25
50
  if self.code_model.options["azure_arm"]:
@@ -30,19 +55,47 @@ class Client:
30
55
  return "AsyncPipelineClient"
31
56
  return "PipelineClient"
32
57
 
33
- def _imports_shared(self, async_mode: bool) -> FileImport:
34
- file_import = FileImport()
58
+ @property
59
+ def send_request_name(self) -> str:
60
+ """Name of the send request function"""
61
+ return (
62
+ "send_request"
63
+ if self.code_model.options["show_send_request"]
64
+ else "_send_request"
65
+ )
35
66
 
36
- file_import.add_submodule_import("msrest", "Serializer", ImportType.THIRDPARTY)
37
- file_import.add_submodule_import("msrest", "Deserializer", ImportType.THIRDPARTY)
38
- file_import.add_submodule_import("typing", "Any", ImportType.STDLIB, TypingSection.CONDITIONAL)
67
+ @property
68
+ def has_parameterized_host(self) -> bool:
69
+ """Whether the base url is parameterized or not"""
70
+ return not any(p for p in self.parameters if p.is_host)
71
+
72
+ @property
73
+ def pylint_disable(self) -> str:
74
+ retval = add_to_pylint_disable("", "client-accepts-api-version-keyword")
75
+ if len(self.code_model.operation_groups) > 6:
76
+ retval = add_to_pylint_disable(retval, "too-many-instance-attributes")
77
+ return retval
39
78
 
40
- any_optional_gp = any(not gp.required for gp in self.parameters)
79
+ @property
80
+ def filename(self) -> str:
81
+ """Name of the file for the client"""
82
+ if (
83
+ self.code_model.options["version_tolerant"]
84
+ or self.code_model.options["low_level_client"]
85
+ ):
86
+ return "_client"
87
+ return f"_{self.code_model.module_name}"
41
88
 
42
- legacy = not any(g for g in ["low_level_client", "version_tolerant"] if g in self.code_model.options)
43
- if any_optional_gp or (legacy and self.code_model.service_client.parameters.host):
44
- file_import.add_submodule_import("typing", "Optional", ImportType.STDLIB, TypingSection.CONDITIONAL)
89
+ def _imports_shared(self, async_mode: bool) -> FileImport:
90
+ file_import = FileImport()
45
91
 
92
+ file_import.add_submodule_import("msrest", "Serializer", ImportType.THIRDPARTY)
93
+ file_import.add_submodule_import(
94
+ "msrest", "Deserializer", ImportType.THIRDPARTY
95
+ )
96
+ file_import.add_submodule_import(
97
+ "typing", "Any", ImportType.STDLIB, TypingSection.CONDITIONAL
98
+ )
46
99
  if self.code_model.options["azure_arm"]:
47
100
  file_import.add_submodule_import(
48
101
  "azure.mgmt.core", self.pipeline_class(async_mode), ImportType.AZURECORE
@@ -52,11 +105,12 @@ class Client:
52
105
  "azure.core", self.pipeline_class(async_mode), ImportType.AZURECORE
53
106
  )
54
107
 
55
- for gp in self.code_model.global_parameters:
56
- file_import.merge(gp.imports())
108
+ for gp in self.parameters:
109
+ file_import.merge(gp.imports(async_mode))
57
110
  file_import.add_submodule_import(
58
- "._configuration", f"{self.code_model.class_name}Configuration",
59
- ImportType.LOCAL
111
+ "._configuration",
112
+ f"{self.code_model.client.name}Configuration",
113
+ ImportType.LOCAL,
60
114
  )
61
115
 
62
116
  return file_import
@@ -66,39 +120,144 @@ class Client:
66
120
  if async_mode:
67
121
  file_import.add_submodule_import("typing", "Awaitable", ImportType.STDLIB)
68
122
  file_import.add_submodule_import(
69
- "azure.core.rest", "AsyncHttpResponse", ImportType.AZURECORE, TypingSection.CONDITIONAL
123
+ "azure.core.rest",
124
+ "AsyncHttpResponse",
125
+ ImportType.AZURECORE,
126
+ TypingSection.CONDITIONAL,
70
127
  )
71
128
  else:
72
129
  file_import.add_submodule_import(
73
- "azure.core.rest", "HttpResponse", ImportType.AZURECORE, TypingSection.CONDITIONAL
130
+ "azure.core.rest",
131
+ "HttpResponse",
132
+ ImportType.AZURECORE,
133
+ TypingSection.CONDITIONAL,
74
134
  )
75
135
  file_import.add_submodule_import(
76
- "azure.core.rest", "HttpRequest", ImportType.AZURECORE, TypingSection.CONDITIONAL
136
+ "azure.core.rest",
137
+ "HttpRequest",
138
+ ImportType.AZURECORE,
139
+ TypingSection.CONDITIONAL,
77
140
  )
78
141
  for og in self.code_model.operation_groups:
79
142
  file_import.add_submodule_import(
80
- f".{self.code_model.operations_folder_name}", og.class_name, ImportType.LOCAL
143
+ f".{self.code_model.operations_folder_name}",
144
+ og.class_name,
145
+ ImportType.LOCAL,
81
146
  )
82
147
 
83
- if self.code_model.sorted_schemas:
148
+ if self.code_model.model_types and self.code_model.options["models_mode"]:
84
149
  path_to_models = ".." if async_mode else "."
85
- file_import.add_submodule_import(path_to_models, "models", ImportType.LOCAL)
150
+ if len(self.code_model.model_types) != len(
151
+ self.code_model.public_model_types
152
+ ):
153
+ # this means we have hidden models. In that case, we import directly from the models
154
+ # file, not the module, bc we don't expose the hidden models in the models module
155
+
156
+ # Also in this case, we're in version tolerant, so python3 only is true
157
+ file_import.add_submodule_import(
158
+ f"{path_to_models}models",
159
+ f"{self.code_model.get_models_filename(is_python3_file=True)}",
160
+ ImportType.LOCAL,
161
+ alias="models",
162
+ )
163
+ else:
164
+ file_import.add_submodule_import(
165
+ path_to_models, "models", ImportType.LOCAL
166
+ )
86
167
  else:
87
168
  # in this case, we have client_models = {} in the service client, which needs a type annotation
88
169
  # this import will always be commented, so will always add it to the typing section
89
- file_import.add_submodule_import("typing", "Dict", ImportType.STDLIB, TypingSection.TYPING)
170
+ file_import.add_submodule_import(
171
+ "typing", "Dict", ImportType.STDLIB, TypingSection.TYPING
172
+ )
90
173
  file_import.add_submodule_import("copy", "deepcopy", ImportType.STDLIB)
91
174
  return file_import
92
175
 
93
176
  def imports_for_multiapi(self, async_mode: bool) -> FileImport:
94
177
  file_import = self._imports_shared(async_mode)
178
+ file_import.add_submodule_import(
179
+ "typing", "Optional", ImportType.STDLIB, TypingSection.CONDITIONAL
180
+ )
95
181
  try:
96
- mixin_operation = next(og for og in self.code_model.operation_groups if og.is_empty_operation_group)
97
- file_import.add_submodule_import("._operations_mixin", mixin_operation.class_name, ImportType.LOCAL)
182
+ mixin_operation = next(
183
+ og for og in self.code_model.operation_groups if og.is_mixin
184
+ )
185
+ file_import.add_submodule_import(
186
+ "._operations_mixin", mixin_operation.class_name, ImportType.LOCAL
187
+ )
98
188
  except StopIteration:
99
189
  pass
190
+ file_import.add_submodule_import(
191
+ "azure.profiles", "KnownProfiles", import_type=ImportType.AZURECORE
192
+ )
193
+ file_import.add_submodule_import(
194
+ "azure.profiles", "ProfileDefinition", import_type=ImportType.AZURECORE
195
+ )
196
+ file_import.add_submodule_import(
197
+ "azure.profiles.multiapiclient",
198
+ "MultiApiClientMixin",
199
+ import_type=ImportType.AZURECORE,
200
+ )
201
+ return file_import
202
+
203
+ @classmethod
204
+ def from_yaml(cls, yaml_data: Dict[str, Any], code_model: "CodeModel") -> "Client":
205
+ return cls(
206
+ yaml_data=yaml_data,
207
+ code_model=code_model,
208
+ parameters=ClientGlobalParameterList.from_yaml(yaml_data, code_model),
209
+ )
210
+
211
+
212
+ class Config(_ClientConfigBase[ConfigGlobalParameterList]):
213
+ """Model representing our Config type."""
214
+
215
+ @property
216
+ def description(self) -> str:
217
+ return (
218
+ f"Configuration for {self.yaml_data['name']}.\n\n."
219
+ "Note that all parameters used to create this instance are saved as instance attributes."
220
+ )
221
+
222
+ @property
223
+ def name(self) -> str:
224
+ return f"{super().name}Configuration"
225
+
226
+ def imports(self, async_mode: bool) -> FileImport:
227
+ file_import = FileImport()
228
+ file_import.add_submodule_import(
229
+ "azure.core.configuration", "Configuration", ImportType.AZURECORE
230
+ )
231
+ file_import.add_submodule_import(
232
+ "azure.core.pipeline", "policies", ImportType.AZURECORE
233
+ )
234
+ file_import.add_submodule_import(
235
+ "typing", "Any", ImportType.STDLIB, TypingSection.CONDITIONAL
236
+ )
237
+ if self.code_model.options["package_version"]:
238
+ file_import.add_submodule_import(
239
+ ".._version" if async_mode else "._version", "VERSION", ImportType.LOCAL
240
+ )
241
+ for gp in self.parameters:
242
+ file_import.merge(gp.imports(async_mode=async_mode))
243
+ if self.code_model.options["azure_arm"]:
244
+ policy = (
245
+ "AsyncARMChallengeAuthenticationPolicy"
246
+ if async_mode
247
+ else "ARMChallengeAuthenticationPolicy"
248
+ )
249
+ file_import.add_submodule_import(
250
+ "azure.mgmt.core.policies", "ARMHttpLoggingPolicy", ImportType.AZURECORE
251
+ )
252
+ file_import.add_submodule_import(
253
+ "azure.mgmt.core.policies", policy, ImportType.AZURECORE
254
+ )
100
255
  return file_import
101
256
 
102
- def send_request_signature(self, is_python3_file: bool) -> List[str]:
103
- request_signature = ["request: HttpRequest," if is_python3_file else "request, # type: HttpRequest"]
104
- return request_signature + self.parameters.method_signature_kwargs(is_python3_file)
257
+ @classmethod
258
+ def from_yaml(cls, yaml_data: Dict[str, Any], code_model: "CodeModel") -> "Config":
259
+ return cls(
260
+ yaml_data=yaml_data,
261
+ code_model=code_model,
262
+ parameters=ConfigGlobalParameterList.from_yaml(yaml_data, code_model),
263
+ )