@autorest/python 5.13.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.
Files changed (101) hide show
  1. package/ChangeLog.md +67 -0
  2. package/autorest/__init__.py +1 -2
  3. package/autorest/black/__init__.py +12 -5
  4. package/autorest/codegen/__init__.py +239 -105
  5. package/autorest/codegen/models/__init__.py +29 -18
  6. package/autorest/codegen/models/base_builder.py +48 -11
  7. package/autorest/codegen/models/base_model.py +6 -4
  8. package/autorest/codegen/models/base_schema.py +21 -24
  9. package/autorest/codegen/models/client.py +70 -20
  10. package/autorest/codegen/models/code_model.py +144 -129
  11. package/autorest/codegen/models/constant_schema.py +32 -16
  12. package/autorest/codegen/models/credential_model.py +55 -0
  13. package/autorest/codegen/models/credential_schema.py +21 -16
  14. package/autorest/codegen/models/credential_schema_policy.py +11 -15
  15. package/autorest/codegen/models/dictionary_schema.py +27 -24
  16. package/autorest/codegen/models/enum_schema.py +41 -62
  17. package/autorest/codegen/models/imports.py +72 -41
  18. package/autorest/codegen/models/list_schema.py +40 -18
  19. package/autorest/codegen/models/lro_operation.py +61 -25
  20. package/autorest/codegen/models/lro_paging_operation.py +5 -6
  21. package/autorest/codegen/models/object_schema.py +113 -59
  22. package/autorest/codegen/models/operation.py +251 -111
  23. package/autorest/codegen/models/operation_group.py +67 -32
  24. package/autorest/codegen/models/paging_operation.py +48 -21
  25. package/autorest/codegen/models/parameter.py +182 -90
  26. package/autorest/codegen/models/parameter_list.py +184 -163
  27. package/autorest/codegen/models/primitive_schemas.py +89 -70
  28. package/autorest/codegen/models/property.py +49 -31
  29. package/autorest/codegen/models/request_builder.py +67 -32
  30. package/autorest/codegen/models/request_builder_parameter.py +54 -23
  31. package/autorest/codegen/models/request_builder_parameter_list.py +77 -108
  32. package/autorest/codegen/models/schema_request.py +16 -6
  33. package/autorest/codegen/models/schema_response.py +35 -17
  34. package/autorest/codegen/models/utils.py +24 -1
  35. package/autorest/codegen/serializers/__init__.py +273 -89
  36. package/autorest/codegen/serializers/builder_serializer.py +711 -333
  37. package/autorest/codegen/serializers/client_serializer.py +114 -43
  38. package/autorest/codegen/serializers/general_serializer.py +84 -25
  39. package/autorest/codegen/serializers/import_serializer.py +93 -31
  40. package/autorest/codegen/serializers/metadata_serializer.py +73 -24
  41. package/autorest/codegen/serializers/model_base_serializer.py +42 -14
  42. package/autorest/codegen/serializers/model_generic_serializer.py +1 -4
  43. package/autorest/codegen/serializers/model_init_serializer.py +5 -1
  44. package/autorest/codegen/serializers/model_python3_serializer.py +9 -8
  45. package/autorest/codegen/serializers/operation_groups_serializer.py +20 -8
  46. package/autorest/codegen/serializers/operations_init_serializer.py +23 -11
  47. package/autorest/codegen/serializers/patch_serializer.py +14 -2
  48. package/autorest/codegen/serializers/{rest_serializer.py → request_builders_serializer.py} +29 -12
  49. package/autorest/codegen/serializers/utils.py +60 -21
  50. package/autorest/codegen/templates/CHANGELOG.md.jinja2 +6 -0
  51. package/autorest/codegen/templates/LICENSE.jinja2 +21 -0
  52. package/autorest/codegen/templates/MANIFEST.in.jinja2 +7 -0
  53. package/autorest/codegen/templates/README.md.jinja2 +105 -0
  54. package/autorest/codegen/templates/config.py.jinja2 +4 -4
  55. package/autorest/codegen/templates/dev_requirements.txt.jinja2 +10 -0
  56. package/autorest/codegen/templates/enum.py.jinja2 +1 -1
  57. package/autorest/codegen/templates/enum_container.py.jinja2 +0 -1
  58. package/autorest/codegen/templates/init.py.jinja2 +9 -6
  59. package/autorest/codegen/templates/keywords.jinja2 +14 -1
  60. package/autorest/codegen/templates/lro_operation.py.jinja2 +5 -7
  61. package/autorest/codegen/templates/lro_paging_operation.py.jinja2 +5 -7
  62. package/autorest/codegen/templates/metadata.json.jinja2 +10 -9
  63. package/autorest/codegen/templates/model.py.jinja2 +1 -6
  64. package/autorest/codegen/templates/model_init.py.jinja2 +7 -4
  65. package/autorest/codegen/templates/operation.py.jinja2 +8 -11
  66. package/autorest/codegen/templates/operation_group.py.jinja2 +15 -18
  67. package/autorest/codegen/templates/operation_groups_container.py.jinja2 +1 -2
  68. package/autorest/codegen/templates/operations_folder_init.py.jinja2 +4 -0
  69. package/autorest/codegen/templates/paging_operation.py.jinja2 +7 -8
  70. package/autorest/codegen/templates/patch.py.jinja2 +18 -29
  71. package/autorest/codegen/templates/request_builder.py.jinja2 +19 -14
  72. package/autorest/codegen/templates/setup.py.jinja2 +79 -20
  73. package/autorest/codegen/templates/vendor.py.jinja2 +12 -2
  74. package/autorest/jsonrpc/__init__.py +7 -12
  75. package/autorest/jsonrpc/localapi.py +4 -3
  76. package/autorest/jsonrpc/server.py +13 -6
  77. package/autorest/jsonrpc/stdstream.py +13 -6
  78. package/autorest/m2r/__init__.py +5 -8
  79. package/autorest/multiapi/__init__.py +24 -14
  80. package/autorest/multiapi/models/client.py +21 -11
  81. package/autorest/multiapi/models/code_model.py +23 -10
  82. package/autorest/multiapi/models/config.py +4 -1
  83. package/autorest/multiapi/models/constant_global_parameter.py +1 -0
  84. package/autorest/multiapi/models/global_parameter.py +2 -1
  85. package/autorest/multiapi/models/global_parameters.py +14 -8
  86. package/autorest/multiapi/models/imports.py +35 -18
  87. package/autorest/multiapi/models/mixin_operation.py +5 -5
  88. package/autorest/multiapi/models/operation_group.py +2 -1
  89. package/autorest/multiapi/models/operation_mixin_group.py +21 -10
  90. package/autorest/multiapi/serializers/__init__.py +18 -23
  91. package/autorest/multiapi/serializers/import_serializer.py +47 -15
  92. package/autorest/multiapi/serializers/multiapi_serializer.py +17 -17
  93. package/autorest/multiapi/templates/multiapi_operations_mixin.py.jinja2 +1 -1
  94. package/autorest/multiapi/utils.py +3 -3
  95. package/autorest/namer/__init__.py +2 -4
  96. package/autorest/namer/name_converter.py +200 -103
  97. package/autorest/namer/python_mappings.py +10 -22
  98. package/package.json +3 -3
  99. package/run-python3.js +2 -3
  100. package/venvtools.py +1 -1
  101. package/autorest/codegen/models/rest.py +0 -42
package/ChangeLog.md CHANGED
@@ -1,5 +1,72 @@
1
1
  # Change Log
2
2
 
3
+ ### 2022-04-18 - 5.16.0
4
+
5
+ | Library | Min Version |
6
+ | ----------------------------------------------------------------------- | ----------- |
7
+ | `@autorest/core` | `3.6.2` |
8
+ | `@autorest/modelerfour` | `4.19.1` |
9
+ | `azure-core` dep of generated code | `1.23.0` |
10
+ | `msrest` dep of generated code | `0.6.21` |
11
+ | `azure-mgmt-core` dep of generated code (If generating mgmt plane code) | `1.3.0` |
12
+
13
+ **Breaking Changes in Version Tolerant Generation**
14
+
15
+ - We no longer generate operations for operations with multipart or urlencoded bodies. SDK writers must implement these operations in their customized patch file. See https://aka.ms/azsdk/python/dpcodegen/python/customize for how to customize generated code #1223
16
+
17
+ **Bug Fixes**
18
+
19
+ - Drop package dependency on "@azure-tools/extension", switch to "@autorest/system-requirements" #1229
20
+ - Fix `content_type` generation in multiapi SDKs with multiple content types for bodies #1232
21
+
22
+ ### 2022-04-07 - 5.15.0
23
+
24
+ | Library | Min Version |
25
+ | ----------------------------------------------------------------------- | ----------- |
26
+ | `@autorest/core` | `3.6.2` |
27
+ | `@autorest/modelerfour` | `4.19.1` |
28
+ | `azure-core` dep of generated code | `1.23.0` |
29
+ | `msrest` dep of generated code | `0.6.21` |
30
+ | `azure-mgmt-core` dep of generated code (If generating mgmt plane code) | `1.3.0` |
31
+
32
+ **New Features**
33
+
34
+ - Add support for security configurations in the swagger. For more information, see https://github.com/Azure/autorest/blob/main/docs/generate/authentication.md #1161
35
+ - Add support for handwritten customizations of generated code. For more information, see https://aka.ms/azsdk/python/dpcodegen/python/customize #1153
36
+ - Allow `header` and `params` as kwargs in operation and request-build function to hand over REST Header and Query parameters case insensitively #1183
37
+ - Typing operation parameters as JSON, Primitives or Any for `--version-tolerant` #1210
38
+
39
+ **Bug Fixes**
40
+
41
+ - Make `--version-tolerant` generated code mypy compatible in the `azure-sdk-for-python` repo. Tested only with the `--black` flag #1185
42
+ - Remove unnecessary vendored code in the `_vendor` file if the SDK has no operations #1196
43
+ - Fix the generation of the root `__init__` files for packages with only models #1195
44
+ - Add pylint and mypy support for `--version-tolerant` generations with `--models-mode=msrest` #1202
45
+
46
+ **Breaking Changes in Version Tolerant Generation**
47
+
48
+ - Change client filenames to `_client.py` #1206
49
+ - Change the models filename from `_models_py3.py` to `_models.py` #1204
50
+ - Change the enums filename to `_enums.py` #1204
51
+
52
+ ### 2022-03-08 - 5.14.0
53
+
54
+ | Library | Min Version |
55
+ | ----------------------------------------------------------------------- | ----------- |
56
+ | `@autorest/core` | `3.6.2` |
57
+ | `@autorest/modelerfour` | `4.19.1` |
58
+ | `azure-core` dep of generated code | `1.20.1` |
59
+ | `msrest` dep of generated code | `0.6.21` |
60
+ | `azure-mgmt-core` dep of generated code (If generating mgmt plane code) | `1.3.0` |
61
+
62
+ **New Features**
63
+
64
+ - Add flag `--package-mode=mgmtplane|dataplane|<custom package template folder>` to generate necessary files for package #1154
65
+
66
+ **Bug Fixes**
67
+
68
+ - Improve operation group documentation to prevent users from initializing operation groups themselves #1179
69
+
3
70
  ### 2022-03-03 - 5.13.0
4
71
 
5
72
  | Library | Min Version |
@@ -38,8 +38,7 @@ class Plugin(ABC):
38
38
 
39
39
 
40
40
  class YamlUpdatePlugin(Plugin):
41
- """A plugin that update the YAML as input.
42
- """
41
+ """A plugin that update the YAML as input."""
43
42
 
44
43
  def process(self) -> bool:
45
44
  # List the input file, should be only one
@@ -15,20 +15,25 @@ _LOGGER = logging.getLogger(__name__)
15
15
  _BLACK_MODE = black.Mode()
16
16
  _BLACK_MODE.line_length = 120
17
17
 
18
- class BlackScriptPlugin(Plugin):
19
18
 
19
+ class BlackScriptPlugin(Plugin):
20
20
  def __init__(self, autorestapi):
21
- super(BlackScriptPlugin, self).__init__(autorestapi)
21
+ super().__init__(autorestapi)
22
22
  output_folder_uri = self._autorestapi.get_value("outputFolderUri")
23
23
  if output_folder_uri.startswith("file:"):
24
24
  output_folder_uri = output_folder_uri[5:]
25
- if os.name == 'nt' and output_folder_uri.startswith("///"):
25
+ if os.name == "nt" and output_folder_uri.startswith("///"):
26
26
  output_folder_uri = output_folder_uri[3:]
27
27
  self.output_folder = Path(output_folder_uri)
28
28
 
29
29
  def process(self) -> bool:
30
30
  # apply format_file on every file in the output folder
31
- list(map(self.format_file, [f for f in self.output_folder.glob('**/*') if f.is_file()]))
31
+ list(
32
+ map(
33
+ self.format_file,
34
+ [f for f in self.output_folder.glob("**/*") if f.is_file()],
35
+ )
36
+ )
32
37
  return True
33
38
 
34
39
  def format_file(self, full_path) -> None:
@@ -38,7 +43,9 @@ class BlackScriptPlugin(Plugin):
38
43
  self._autorestapi.write_file(file, file_content)
39
44
  return
40
45
  try:
41
- file_content = black.format_file_contents(file_content, fast=True, mode=_BLACK_MODE)
46
+ file_content = black.format_file_contents(
47
+ file_content, fast=True, mode=_BLACK_MODE
48
+ )
42
49
  except black.NothingChanged:
43
50
  pass
44
51
  self._autorestapi.write_file(file, file_content)
@@ -5,25 +5,37 @@
5
5
  # --------------------------------------------------------------------------
6
6
  import logging
7
7
  import sys
8
- from typing import Dict, Any, Set, Union, List, Type
8
+ from typing import Dict, Any, Union, Type
9
+ from pathlib import Path
9
10
  import yaml
10
11
 
11
12
  from .. import Plugin
12
13
  from .models.code_model import CodeModel
13
- from .models import build_schema
14
+ from .models import build_schema, RequestBuilder
14
15
  from .models.operation_group import OperationGroup
15
16
  from .models.parameter import Parameter
16
17
  from .models.parameter_list import GlobalParameterList
17
- from .models.rest import Rest
18
18
  from .serializers import JinjaSerializer
19
- from .models.credential_schema_policy import CredentialSchemaPolicy, get_credential_schema_policy_type
20
- from .models.credential_schema import AzureKeyCredentialSchema, TokenCredentialSchema
19
+ from .models.credential_schema_policy import (
20
+ CredentialSchemaPolicy,
21
+ get_credential_schema_policy_type,
22
+ )
23
+ from .models.credential_schema_policy import (
24
+ BearerTokenCredentialPolicy,
25
+ AzureKeyCredentialPolicy,
26
+ )
27
+ from .models.credential_model import CredentialModel
28
+
29
+ _AAD_TYPE = "AADToken"
30
+ _KEY_TYPE = "AzureKey"
31
+
21
32
 
22
33
  def _build_convenience_layer(yaml_data: Dict[str, Any], code_model: CodeModel) -> None:
23
34
  # Create operations
24
35
  if code_model.options["show_operations"] and yaml_data.get("operationGroups"):
25
36
  code_model.operation_groups = [
26
- OperationGroup.from_yaml(code_model, op_group) for op_group in yaml_data["operationGroups"]
37
+ OperationGroup.from_yaml(op_group, code_model)
38
+ for op_group in yaml_data["operationGroups"]
27
39
  ]
28
40
  if yaml_data.get("schemas"):
29
41
  code_model.add_inheritance_to_models()
@@ -31,13 +43,13 @@ def _build_convenience_layer(yaml_data: Dict[str, Any], code_model: CodeModel) -
31
43
  code_model.sort_schemas()
32
44
 
33
45
  if code_model.options["show_operations"]:
34
- code_model.add_schema_link_to_operation()
35
46
  code_model.generate_single_parameter_from_multiple_content_types_operation()
36
47
  code_model.link_operation_to_request_builder()
37
48
  # LRO operation
38
49
  code_model.format_lro_operations()
39
50
  code_model.remove_next_operation()
40
51
 
52
+
41
53
  def _validate_code_model_options(options: Dict[str, Any]) -> None:
42
54
 
43
55
  if options["builders_visibility"] not in ["public", "hidden", "embedded"]:
@@ -70,19 +82,40 @@ def _validate_code_model_options(options: Dict[str, Any]) -> None:
70
82
  if options["basic_setup_py"] and not options["package_version"]:
71
83
  raise ValueError("--basic-setup-py must be used with --package-version")
72
84
 
85
+ if options["package_mode"] and not options["package_version"]:
86
+ raise ValueError("--package-mode must be used with --package-version")
87
+
73
88
  if not options["show_operations"] and options["combine_operation_files"]:
74
89
  raise ValueError(
75
90
  "Can not combine operation files if you are not showing operations. "
76
91
  "If you want operation files, pass in flag --show-operations"
77
92
  )
78
93
 
94
+ if options["package_mode"]:
95
+ if (
96
+ options["package_mode"] not in ("mgmtplane", "dataplane")
97
+ and not Path(options["package_mode"]).exists()
98
+ ):
99
+ raise ValueError(
100
+ "--package-mode can only be 'mgmtplane' or 'dataplane' or directory which contains template files"
101
+ )
102
+
79
103
  if options["reformat_next_link"] and options["version_tolerant"]:
80
104
  raise ValueError(
81
105
  "--reformat-next-link can not be true for version tolerant generations. "
82
106
  "Please remove --reformat-next-link from your call for version tolerant generations."
83
107
  )
84
108
 
109
+ if options["multiapi"] and options["version_tolerant"]:
110
+ raise ValueError(
111
+ "Can not currently generate version tolerant multiapi SDKs. "
112
+ "We are working on creating a new multiapi SDK for version tolerant and it is not available yet."
113
+ )
114
+
115
+
85
116
  _LOGGER = logging.getLogger(__name__)
117
+
118
+
86
119
  class CodeGenerator(Plugin):
87
120
  @staticmethod
88
121
  def remove_cloud_errors(yaml_data: Dict[str, Any]) -> None:
@@ -93,7 +126,11 @@ class CodeGenerator(Plugin):
93
126
  i = 0
94
127
  while i < len(operation["exceptions"]):
95
128
  exception = operation["exceptions"][i]
96
- if exception.get("schema") and exception["schema"]["language"]["default"]["name"] == "CloudError":
129
+ if (
130
+ exception.get("schema")
131
+ and exception["schema"]["language"]["default"]["name"]
132
+ == "CloudError"
133
+ ):
97
134
  del operation["exceptions"][i]
98
135
  i -= 1
99
136
  i += 1
@@ -105,40 +142,66 @@ class CodeGenerator(Plugin):
105
142
  break
106
143
 
107
144
  @staticmethod
108
- def _build_exceptions_set(yaml_data: List[Dict[str, Any]]) -> Set[int]:
109
- exceptions_set = set()
110
- for group in yaml_data:
111
- for operation in group["operations"]:
112
- if not operation.get("exceptions"):
113
- continue
114
- for exception in operation["exceptions"]:
115
- if not exception.get("schema"):
116
- continue
117
- exceptions_set.add(id(exception["schema"]))
118
- return exceptions_set
145
+ def _build_package_dependency() -> Dict[str, str]:
146
+ return {
147
+ "dependency_azure_mgmt_core": "azure-mgmt-core<2.0.0,>=1.3.0",
148
+ "dependency_azure_core": "azure-core<2.0.0,>=1.23.0",
149
+ "dependency_msrest": "msrest>=0.6.21",
150
+ }
119
151
 
120
- def _create_code_model(self, yaml_data: Dict[str, Any], options: Dict[str, Union[str, bool]]) -> CodeModel:
152
+ @staticmethod
153
+ def _build_with_security_definition(
154
+ yaml_data: Dict[str, Any], credential_model: CredentialModel
155
+ ):
156
+ security_yaml = yaml_data.get("security", {})
157
+ if security_yaml.get("authenticationRequired"):
158
+ for scheme in security_yaml.get("schemes"):
159
+ if _AAD_TYPE == scheme["type"]:
160
+ credential_model.credential_scopes.update(scheme["scopes"])
161
+ elif _KEY_TYPE == scheme["type"]:
162
+ # only accept the last one
163
+ credential_model.key_header_name = scheme["headerName"]
164
+
165
+ if credential_model.credential_scopes:
166
+ credential_model.policy_type = BearerTokenCredentialPolicy
167
+ elif credential_model.key_header_name:
168
+ credential_model.policy_type = AzureKeyCredentialPolicy
169
+
170
+ @staticmethod
171
+ def _build_credential_model(
172
+ code_model: CodeModel, credential_model: CredentialModel
173
+ ):
174
+ if credential_model.policy_type:
175
+ code_model.options["credential"] = True
176
+ credential_model.build_authentication_policy()
177
+ code_model.credential_model = credential_model
178
+
179
+ def _handle_credential_model(
180
+ self, yaml_data: Dict[str, Any], code_model: CodeModel
181
+ ):
182
+ credential_model = CredentialModel(code_model.options["azure_arm"])
183
+
184
+ # credential info with security definition will be overridded by credential flags
185
+ self._build_with_security_definition(yaml_data, credential_model)
186
+ self._build_with_credential_flags(code_model, credential_model)
187
+
188
+ self._build_credential_model(code_model, credential_model)
189
+
190
+ def _create_code_model(
191
+ self, yaml_data: Dict[str, Any], options: Dict[str, Union[str, bool]]
192
+ ) -> CodeModel:
121
193
  # Create a code model
122
194
 
123
- code_model = CodeModel(options=options)
124
- if code_model.options['credential']:
125
- self._handle_default_authentication_policy(code_model)
195
+ code_model = CodeModel(yaml_data, options=options)
196
+ self._handle_credential_model(yaml_data, code_model)
126
197
  code_model.module_name = yaml_data["info"]["python_title"]
127
198
  code_model.class_name = yaml_data["info"]["pascal_case_title"]
128
199
  code_model.description = (
129
- yaml_data["info"]["description"] if yaml_data["info"].get("description") else ""
200
+ yaml_data["info"]["description"]
201
+ if yaml_data["info"].get("description")
202
+ else ""
130
203
  )
131
204
 
132
- # Global parameters
133
- code_model.global_parameters = GlobalParameterList(
134
- code_model,
135
- [Parameter.from_yaml(param, code_model=code_model) for param in yaml_data.get("globalParameters", [])],
136
- )
137
- code_model.global_parameters.code_model = code_model
138
-
139
- # Custom URL
140
- code_model.setup_client_input_parameters(yaml_data)
141
-
142
205
  # Get my namespace
143
206
  namespace = self._autorestapi.get_value("namespace")
144
207
  _LOGGER.debug("Namespace parameter was %s", namespace)
@@ -146,44 +209,74 @@ class CodeGenerator(Plugin):
146
209
  namespace = yaml_data["info"]["python_title"]
147
210
  code_model.namespace = namespace
148
211
 
149
- code_model.rest = Rest.from_yaml(yaml_data, code_model=code_model)
150
212
  if yaml_data.get("schemas"):
151
- exceptions_set = CodeGenerator._build_exceptions_set(yaml_data=yaml_data["operationGroups"])
152
-
153
213
  for type_list in yaml_data["schemas"].values():
154
214
  for schema in type_list:
155
- build_schema(yaml_data=schema, exceptions_set=exceptions_set, code_model=code_model)
156
- code_model.add_schema_link_to_request_builder()
157
- code_model.add_schema_link_to_global_parameters()
215
+ build_schema(yaml_data=schema, code_model=code_model)
216
+
217
+ # Global parameters
218
+ code_model.global_parameters = GlobalParameterList(
219
+ code_model,
220
+ [
221
+ Parameter.from_yaml(param, code_model=code_model)
222
+ for param in yaml_data.get("globalParameters", [])
223
+ ],
224
+ )
158
225
 
226
+ # Custom URL
227
+ code_model.setup_client_input_parameters(yaml_data)
228
+
229
+ # Build request builders
230
+ if yaml_data.get("operationGroups"):
231
+ code_model.request_builders = [
232
+ RequestBuilder.from_yaml(operation_yaml, code_model=code_model)
233
+ for og_group in yaml_data["operationGroups"]
234
+ for operation_yaml in og_group["operations"]
235
+ ]
159
236
  _build_convenience_layer(yaml_data=yaml_data, code_model=code_model)
160
237
 
161
238
  if options["credential"]:
162
239
  code_model.global_parameters.add_credential_global_parameter()
163
240
 
241
+ code_model.package_dependency = self._build_package_dependency()
164
242
  return code_model
165
243
 
166
244
  def _get_credential_scopes(self, credential):
167
245
  credential_scopes_temp = self._autorestapi.get_value("credential-scopes")
168
- credential_scopes = credential_scopes_temp.split(",") if credential_scopes_temp else None
246
+ credential_scopes = (
247
+ credential_scopes_temp.split(",") if credential_scopes_temp else None
248
+ )
169
249
  if credential_scopes and not credential:
170
- raise ValueError("--credential-scopes must be used with the --add-credential flag")
250
+ raise ValueError(
251
+ "--credential-scopes must be used with the --add-credential flag"
252
+ )
171
253
 
172
254
  # check to see if user just passes in --credential-scopes with no value
173
- if self._autorestapi.get_boolean_value("credential-scopes", False) and not credential_scopes:
255
+ if (
256
+ self._autorestapi.get_boolean_value("credential-scopes", False)
257
+ and not credential_scopes
258
+ ):
174
259
  raise ValueError(
175
260
  "--credential-scopes takes a list of scopes in comma separated format. "
176
261
  "For example: --credential-scopes=https://cognitiveservices.azure.com/.default"
177
262
  )
178
263
  return credential_scopes
179
264
 
180
- def _initialize_credential_schema_policy(
181
- self, code_model: CodeModel, credential_schema_policy: Type[CredentialSchemaPolicy]
182
- ) -> CredentialSchemaPolicy:
183
- credential_scopes = self._get_credential_scopes(code_model.options['credential'])
184
- credential_key_header_name = self._autorestapi.get_value('credential-key-header-name')
185
- azure_arm = code_model.options['azure_arm']
186
- credential = code_model.options['credential']
265
+ def _update_with_credential_flags(
266
+ self,
267
+ code_model: CodeModel,
268
+ credential_schema_policy: Type[CredentialSchemaPolicy],
269
+ credential_model: CredentialModel,
270
+ ):
271
+ credential_model.policy_type = credential_schema_policy
272
+ credential_scopes = self._get_credential_scopes(
273
+ code_model.options["credential"]
274
+ )
275
+ credential_key_header_name = self._autorestapi.get_value(
276
+ "credential-key-header-name"
277
+ )
278
+ azure_arm = code_model.options["azure_arm"]
279
+ credential = code_model.options["credential"]
187
280
 
188
281
  if hasattr(credential_schema_policy, "credential_scopes"):
189
282
  if not credential_scopes:
@@ -197,7 +290,7 @@ class CodeGenerator(Plugin):
197
290
  "but not the --credential-scopes flag set while generating non-management plane code. "
198
291
  "This is not recommend because it forces the customer to pass credential scopes "
199
292
  "through kwargs if they want to authenticate.",
200
- credential_schema_policy.name()
293
+ credential_schema_policy.name(),
201
294
  )
202
295
  credential_scopes = []
203
296
 
@@ -208,101 +301,138 @@ class CodeGenerator(Plugin):
208
301
  "name is tied with AzureKeyCredentialPolicy. Instead, with this policy it is recommend you "
209
302
  "pass in --credential-scopes."
210
303
  )
211
- return credential_schema_policy(
212
- credential=TokenCredentialSchema(async_mode=False),
213
- credential_scopes=credential_scopes,
214
- )
215
- # currently the only other credential policy is AzureKeyCredentialPolicy
216
- if credential_scopes:
217
- raise ValueError(
218
- "You have passed in credential scopes with default credential policy type "
219
- "AzureKeyCredentialPolicy. This is not allowed, since credential scopes is tied with "
220
- f"{code_model.default_authentication_policy.name()}. Instead, with this policy you must pass in "
221
- "--credential-key-header-name."
222
- )
223
- if not credential_key_header_name:
224
- credential_key_header_name = "api-key"
225
- _LOGGER.info(
226
- "Defaulting the AzureKeyCredentialPolicy header's name to 'api-key'"
227
- )
228
- return credential_schema_policy(
229
- credential=AzureKeyCredentialSchema(),
230
- credential_key_header_name=credential_key_header_name,
231
- )
304
+ credential_model.credential_scopes = set(credential_scopes)
305
+ else:
306
+ # currently the only other credential policy is AzureKeyCredentialPolicy
307
+ if credential_scopes:
308
+ raise ValueError(
309
+ "You have passed in credential scopes with default credential policy type "
310
+ "AzureKeyCredentialPolicy. This is not allowed, since credential scopes is tied with "
311
+ f"{credential_model.default_authentication_policy.name()}. Instead, with this policy "
312
+ "you must pass in --credential-key-header-name."
313
+ )
314
+ if not credential_key_header_name:
315
+ credential_key_header_name = "api-key"
316
+ _LOGGER.info(
317
+ "Defaulting the AzureKeyCredentialPolicy header's name to 'api-key'"
318
+ )
319
+
320
+ credential_model.key_header_name = credential_key_header_name
321
+
322
+ def _build_with_credential_flags(
323
+ self, code_model: CodeModel, credential_model: CredentialModel
324
+ ):
325
+ if not code_model.options["credential"]:
326
+ return
232
327
 
233
- def _handle_default_authentication_policy(self, code_model: CodeModel):
234
328
  credential_schema_policy_name = (
235
- self._autorestapi.get_value("credential-default-policy-type") or
236
- code_model.default_authentication_policy.name()
329
+ self._autorestapi.get_value("credential-default-policy-type")
330
+ or credential_model.default_authentication_policy.name()
331
+ )
332
+ credential_schema_policy_type = get_credential_schema_policy_type(
333
+ credential_schema_policy_name
237
334
  )
238
- credential_schema_policy_type = get_credential_schema_policy_type(credential_schema_policy_name)
239
- credential_schema_policy = self._initialize_credential_schema_policy(
240
- code_model, credential_schema_policy_type
335
+ self._update_with_credential_flags(
336
+ code_model, credential_schema_policy_type, credential_model
241
337
  )
242
- code_model.credential_schema_policy = credential_schema_policy
243
338
 
244
339
  def _build_code_model_options(self) -> Dict[str, Any]:
245
- """Build en options dict from the user input while running autorest.
246
- """
340
+ """Build en options dict from the user input while running autorest."""
247
341
  azure_arm = self._autorestapi.get_boolean_value("azure-arm", False)
248
- credential = (
249
- self._autorestapi.get_boolean_value("add-credentials", False) or
250
- self._autorestapi.get_boolean_value("add-credential", False)
251
- )
342
+ credential = self._autorestapi.get_boolean_value(
343
+ "add-credentials", False
344
+ ) or self._autorestapi.get_boolean_value("add-credential", False)
252
345
 
253
346
  license_header = self._autorestapi.get_value("header-text")
254
347
  if license_header:
255
348
  license_header = license_header.replace("\n", "\n# ")
256
349
  license_header = (
257
- "# --------------------------------------------------------------------------\n# " + license_header
350
+ "# --------------------------------------------------------------------------\n# "
351
+ + license_header
258
352
  )
259
353
  license_header += "\n# --------------------------------------------------------------------------"
260
354
 
261
- low_level_client = self._autorestapi.get_boolean_value("low-level-client", False)
262
- version_tolerant = self._autorestapi.get_boolean_value("version-tolerant", False)
263
- show_operations = self._autorestapi.get_boolean_value("show-operations", not low_level_client)
264
- models_mode_default = "none" if low_level_client or version_tolerant else "msrest"
265
- python3_only = self._autorestapi.get_boolean_value("python3-only", low_level_client or version_tolerant)
355
+ low_level_client = self._autorestapi.get_boolean_value(
356
+ "low-level-client", False
357
+ )
358
+ version_tolerant = self._autorestapi.get_boolean_value(
359
+ "version-tolerant", False
360
+ )
361
+ show_operations = self._autorestapi.get_boolean_value(
362
+ "show-operations", not low_level_client
363
+ )
364
+ models_mode_default = (
365
+ "none" if low_level_client or version_tolerant else "msrest"
366
+ )
367
+ python3_only = self._autorestapi.get_boolean_value(
368
+ "python3-only", low_level_client or version_tolerant
369
+ )
266
370
 
267
371
  options: Dict[str, Any] = {
268
372
  "azure_arm": azure_arm,
269
373
  "credential": credential,
270
- "head_as_boolean": self._autorestapi.get_boolean_value("head-as-boolean", False),
374
+ "head_as_boolean": self._autorestapi.get_boolean_value(
375
+ "head-as-boolean", False
376
+ ),
271
377
  "license_header": license_header,
272
- "keep_version_file": self._autorestapi.get_boolean_value("keep-version-file", False),
378
+ "keep_version_file": self._autorestapi.get_boolean_value(
379
+ "keep-version-file", False
380
+ ),
273
381
  "no_async": self._autorestapi.get_boolean_value("no-async", False),
274
- "no_namespace_folders": self._autorestapi.get_boolean_value("no-namespace-folders", False),
275
- "basic_setup_py": self._autorestapi.get_boolean_value("basic-setup-py", False),
382
+ "no_namespace_folders": self._autorestapi.get_boolean_value(
383
+ "no-namespace-folders", False
384
+ ),
385
+ "basic_setup_py": self._autorestapi.get_boolean_value(
386
+ "basic-setup-py", False
387
+ ),
276
388
  "package_name": self._autorestapi.get_value("package-name"),
277
389
  "package_version": self._autorestapi.get_value("package-version"),
278
- "client_side_validation": self._autorestapi.get_boolean_value("client-side-validation", False),
390
+ "client_side_validation": self._autorestapi.get_boolean_value(
391
+ "client-side-validation", False
392
+ ),
279
393
  "tracing": self._autorestapi.get_boolean_value("trace", show_operations),
280
394
  "multiapi": self._autorestapi.get_boolean_value("multiapi", False),
281
- "polymorphic_examples": self._autorestapi.get_value("polymorphic-examples") or 5,
282
- "models_mode": (self._autorestapi.get_value("models-mode") or models_mode_default).lower(),
395
+ "polymorphic_examples": self._autorestapi.get_value("polymorphic-examples")
396
+ or 5,
397
+ "models_mode": (
398
+ self._autorestapi.get_value("models-mode") or models_mode_default
399
+ ).lower(),
283
400
  "builders_visibility": self._autorestapi.get_value("builders-visibility"),
284
401
  "show_operations": show_operations,
285
402
  "show_send_request": self._autorestapi.get_boolean_value(
286
403
  "show-send-request", low_level_client or version_tolerant
287
404
  ),
288
405
  "only_path_and_body_params_positional": self._autorestapi.get_boolean_value(
289
- "only-path-and-body-params-positional", low_level_client or version_tolerant
406
+ "only-path-and-body-params-positional",
407
+ low_level_client or version_tolerant,
290
408
  ),
291
409
  "add_python3_operation_files": self._autorestapi.get_boolean_value(
292
410
  "add-python3-operation-files", python3_only and not low_level_client
293
411
  ),
294
412
  "version_tolerant": version_tolerant,
295
413
  "low_level_client": low_level_client,
296
- "combine_operation_files": self._autorestapi.get_boolean_value("combine-operation-files", version_tolerant),
414
+ "combine_operation_files": self._autorestapi.get_boolean_value(
415
+ "combine-operation-files", version_tolerant
416
+ ),
297
417
  "python3_only": python3_only,
418
+ "package_mode": self._autorestapi.get_value("package-mode"),
419
+ "package_pprint_name": self._autorestapi.get_value("package-pprint-name"),
420
+ "package_configuration": self._autorestapi.get_value(
421
+ "package-configuration"
422
+ ),
298
423
  "default_optional_constants_to_none": self._autorestapi.get_boolean_value(
299
- "default-optional-constants-to-none", low_level_client or version_tolerant
424
+ "default-optional-constants-to-none",
425
+ low_level_client or version_tolerant,
426
+ ),
427
+ "reformat_next_link": self._autorestapi.get_boolean_value(
428
+ "reformat-next-link", not version_tolerant
300
429
  ),
301
- "reformat_next_link": self._autorestapi.get_boolean_value("reformat-next-link", not version_tolerant)
302
430
  }
303
431
 
304
432
  if options["builders_visibility"] is None:
305
- options["builders_visibility"] = "public" if low_level_client else "embedded"
433
+ options["builders_visibility"] = (
434
+ "public" if low_level_client else "embedded"
435
+ )
306
436
  else:
307
437
  options["builders_visibility"] = options["builders_visibility"].lower()
308
438
 
@@ -344,9 +474,13 @@ class CodeGenerator(Plugin):
344
474
 
345
475
 
346
476
  def main(yaml_model_file: str) -> None:
347
- from ..jsonrpc.localapi import LocalAutorestAPI # pylint: disable=import-outside-toplevel
477
+ from ..jsonrpc.localapi import ( # pylint: disable=import-outside-toplevel
478
+ LocalAutorestAPI,
479
+ )
348
480
 
349
- code_generator = CodeGenerator(autorestapi=LocalAutorestAPI(reachable_files=[yaml_model_file]))
481
+ code_generator = CodeGenerator(
482
+ autorestapi=LocalAutorestAPI(reachable_files=[yaml_model_file])
483
+ )
350
484
  if not code_generator.process():
351
485
  raise SystemExit("Process didn't finish gracefully")
352
486