@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.
Files changed (96) hide show
  1. package/ChangeLog.md +79 -4
  2. package/README.md +30 -4
  3. package/autorest/__init__.py +1 -1
  4. package/autorest/codegen/__init__.py +55 -211
  5. package/autorest/codegen/models/__init__.py +116 -83
  6. package/autorest/codegen/models/base_builder.py +49 -88
  7. package/autorest/codegen/models/base_model.py +1 -1
  8. package/autorest/codegen/models/{base_schema.py → base_type.py} +61 -39
  9. package/autorest/codegen/models/client.py +165 -53
  10. package/autorest/codegen/models/code_model.py +122 -257
  11. package/autorest/codegen/models/combined_type.py +107 -0
  12. package/autorest/codegen/models/{constant_schema.py → constant_type.py} +49 -40
  13. package/autorest/codegen/models/credential_types.py +224 -0
  14. package/autorest/codegen/models/dictionary_type.py +131 -0
  15. package/autorest/codegen/models/enum_type.py +195 -0
  16. package/autorest/codegen/models/imports.py +80 -2
  17. package/autorest/codegen/models/list_type.py +149 -0
  18. package/autorest/codegen/models/lro_operation.py +79 -156
  19. package/autorest/codegen/models/lro_paging_operation.py +28 -11
  20. package/autorest/codegen/models/model_type.py +262 -0
  21. package/autorest/codegen/models/operation.py +331 -298
  22. package/autorest/codegen/models/operation_group.py +54 -91
  23. package/autorest/codegen/models/paging_operation.py +82 -123
  24. package/autorest/codegen/models/parameter.py +289 -396
  25. package/autorest/codegen/models/parameter_list.py +355 -360
  26. package/autorest/codegen/models/primitive_types.py +544 -0
  27. package/autorest/codegen/models/property.py +123 -139
  28. package/autorest/codegen/models/request_builder.py +130 -102
  29. package/autorest/codegen/models/request_builder_parameter.py +112 -100
  30. package/autorest/codegen/models/response.py +325 -0
  31. package/autorest/codegen/models/utils.py +12 -19
  32. package/autorest/codegen/serializers/__init__.py +55 -37
  33. package/autorest/codegen/serializers/builder_serializer.py +695 -1144
  34. package/autorest/codegen/serializers/client_serializer.py +92 -89
  35. package/autorest/codegen/serializers/general_serializer.py +15 -69
  36. package/autorest/codegen/serializers/import_serializer.py +7 -4
  37. package/autorest/codegen/serializers/metadata_serializer.py +15 -104
  38. package/autorest/codegen/serializers/model_base_serializer.py +49 -36
  39. package/autorest/codegen/serializers/model_generic_serializer.py +8 -6
  40. package/autorest/codegen/serializers/model_init_serializer.py +2 -4
  41. package/autorest/codegen/serializers/model_python3_serializer.py +22 -16
  42. package/autorest/codegen/serializers/operation_groups_serializer.py +7 -13
  43. package/autorest/codegen/serializers/parameter_serializer.py +174 -0
  44. package/autorest/codegen/serializers/request_builders_serializer.py +13 -30
  45. package/autorest/codegen/serializers/utils.py +0 -140
  46. package/autorest/codegen/templates/MANIFEST.in.jinja2 +1 -0
  47. package/autorest/codegen/templates/{service_client.py.jinja2 → client.py.jinja2} +10 -7
  48. package/autorest/codegen/templates/config.py.jinja2 +13 -13
  49. package/autorest/codegen/templates/enum.py.jinja2 +4 -4
  50. package/autorest/codegen/templates/enum_container.py.jinja2 +1 -1
  51. package/autorest/codegen/templates/init.py.jinja2 +2 -2
  52. package/autorest/codegen/templates/lro_operation.py.jinja2 +4 -1
  53. package/autorest/codegen/templates/lro_paging_operation.py.jinja2 +4 -1
  54. package/autorest/codegen/templates/metadata.json.jinja2 +33 -33
  55. package/autorest/codegen/templates/model.py.jinja2 +23 -24
  56. package/autorest/codegen/templates/model_container.py.jinja2 +2 -1
  57. package/autorest/codegen/templates/model_init.py.jinja2 +3 -5
  58. package/autorest/codegen/templates/operation.py.jinja2 +6 -8
  59. package/autorest/codegen/templates/operation_group.py.jinja2 +21 -8
  60. package/autorest/codegen/templates/operation_groups_container.py.jinja2 +2 -2
  61. package/autorest/codegen/templates/operation_tools.jinja2 +11 -3
  62. package/autorest/codegen/templates/paging_operation.py.jinja2 +2 -2
  63. package/autorest/codegen/templates/request_builder.py.jinja2 +10 -15
  64. package/autorest/codegen/templates/request_builders.py.jinja2 +1 -1
  65. package/autorest/codegen/templates/serialization.py.jinja2 +2006 -0
  66. package/autorest/codegen/templates/setup.py.jinja2 +13 -3
  67. package/autorest/codegen/templates/vendor.py.jinja2 +11 -1
  68. package/autorest/jsonrpc/server.py +15 -3
  69. package/autorest/m4reformatter/__init__.py +1126 -0
  70. package/autorest/multiapi/models/client.py +12 -2
  71. package/autorest/multiapi/models/code_model.py +1 -1
  72. package/autorest/multiapi/serializers/__init__.py +18 -4
  73. package/autorest/multiapi/templates/multiapi_config.py.jinja2 +3 -3
  74. package/autorest/multiapi/templates/multiapi_init.py.jinja2 +2 -2
  75. package/autorest/multiapi/templates/multiapi_operations_mixin.py.jinja2 +4 -4
  76. package/autorest/multiapi/templates/multiapi_service_client.py.jinja2 +9 -9
  77. package/autorest/postprocess/__init__.py +202 -0
  78. package/autorest/postprocess/get_all.py +19 -0
  79. package/autorest/postprocess/venvtools.py +73 -0
  80. package/autorest/preprocess/__init__.py +210 -0
  81. package/autorest/preprocess/helpers.py +54 -0
  82. package/autorest/{namer → preprocess}/python_mappings.py +21 -16
  83. package/package.json +2 -2
  84. package/autorest/codegen/models/credential_model.py +0 -55
  85. package/autorest/codegen/models/credential_schema.py +0 -95
  86. package/autorest/codegen/models/credential_schema_policy.py +0 -73
  87. package/autorest/codegen/models/dictionary_schema.py +0 -106
  88. package/autorest/codegen/models/enum_schema.py +0 -225
  89. package/autorest/codegen/models/list_schema.py +0 -135
  90. package/autorest/codegen/models/object_schema.py +0 -303
  91. package/autorest/codegen/models/primitive_schemas.py +0 -495
  92. package/autorest/codegen/models/request_builder_parameter_list.py +0 -249
  93. package/autorest/codegen/models/schema_request.py +0 -55
  94. package/autorest/codegen/models/schema_response.py +0 -141
  95. package/autorest/namer/__init__.py +0 -23
  96. package/autorest/namer/name_converter.py +0 -509
@@ -0,0 +1,210 @@
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
+ """The preprocessing autorest plugin.
7
+ """
8
+ from typing import Callable, Dict, Any, List, Optional
9
+ from .helpers import to_snake_case, pad_reserved_words, add_redefined_builtin_info
10
+ from .python_mappings import PadType
11
+
12
+ from .. import YamlUpdatePlugin
13
+
14
+
15
+ def update_description(
16
+ description: Optional[str], default_description: str = ""
17
+ ) -> str:
18
+ if not description:
19
+ description = default_description
20
+ description.rstrip(" ")
21
+ if description and description[-1] != ".":
22
+ description += "."
23
+ return description
24
+
25
+
26
+ def update_operation_group_class_name(
27
+ yaml_data: Dict[str, Any], class_name: str
28
+ ) -> str:
29
+ if class_name == "":
30
+ return yaml_data["client"]["name"] + "OperationsMixin"
31
+ if class_name == "Operations":
32
+ return "Operations"
33
+ return class_name + "Operations"
34
+
35
+
36
+ def update_parameter(yaml_data: Dict[str, Any]) -> None:
37
+ yaml_data["description"] = update_description(yaml_data["description"])
38
+ if not (
39
+ yaml_data["location"] == "header"
40
+ and yaml_data["clientName"] in ("content_type", "accept")
41
+ ):
42
+ yaml_data["clientName"] = pad_reserved_words(
43
+ yaml_data["clientName"].lower(), PadType.PARAMETER
44
+ )
45
+ if yaml_data.get("propertyToParameterName"):
46
+ # need to create a new one with padded keys and values
47
+ yaml_data["propertyToParameterName"] = {
48
+ pad_reserved_words(prop, PadType.PROPERTY)
49
+ .lower(): pad_reserved_words(param_name, PadType.PARAMETER)
50
+ .lower()
51
+ for prop, param_name in yaml_data["propertyToParameterName"].items()
52
+ }
53
+
54
+
55
+ def update_types(yaml_data: List[Dict[str, Any]]) -> None:
56
+ for type in yaml_data:
57
+ for property in type.get("properties", []):
58
+ property["description"] = update_description(property["description"])
59
+ property["clientName"] = pad_reserved_words(
60
+ property["clientName"].lower(), PadType.PROPERTY
61
+ )
62
+ add_redefined_builtin_info(property["clientName"], property)
63
+ if type.get("name"):
64
+ type["description"] = update_description(type["description"], type["name"])
65
+ type["snakeCaseName"] = to_snake_case(type["name"])
66
+
67
+
68
+ def update_client(yaml_data: Dict[str, Any]) -> None:
69
+ yaml_data["description"] = update_description(
70
+ yaml_data["description"], default_description=yaml_data["name"]
71
+ )
72
+ yaml_data["moduleName"] = to_snake_case(yaml_data["name"].replace(" ", "_"))
73
+ for parameter in yaml_data["parameters"]:
74
+ update_parameter(parameter)
75
+
76
+
77
+ def update_paging_response(yaml_data: Dict[str, Any]) -> None:
78
+ yaml_data["discriminator"] = "paging"
79
+ yaml_data["pagerSync"] = yaml_data.get("pagerSync") or "azure.core.paging.ItemPaged"
80
+ yaml_data["pagerAsync"] = (
81
+ yaml_data.get("pagerAsync") or "azure.core.async_paging.AsyncItemPaged"
82
+ )
83
+
84
+
85
+ class PreProcessPlugin(YamlUpdatePlugin):
86
+ """Add Python naming information."""
87
+
88
+ def get_operation_updater(
89
+ self, yaml_data: Dict[str, Any]
90
+ ) -> Callable[[Dict[str, Any]], None]:
91
+ if yaml_data["discriminator"] == "lropaging":
92
+ return self.update_lro_paging_operation
93
+ if yaml_data["discriminator"] == "lro":
94
+ return self.update_lro_operation
95
+ if yaml_data["discriminator"] == "paging":
96
+ return self.update_paging_operation
97
+ return self.update_operation
98
+
99
+ def update_operation(self, yaml_data: Dict[str, Any]) -> None:
100
+ yaml_data["groupName"] = pad_reserved_words(
101
+ yaml_data["groupName"], PadType.OPERATION_GROUP
102
+ )
103
+ yaml_data["groupName"] = to_snake_case(yaml_data["groupName"])
104
+ yaml_data["name"] = yaml_data["name"].lower()
105
+ yaml_data["name"] = pad_reserved_words(yaml_data["name"], PadType.METHOD)
106
+ yaml_data["description"] = update_description(
107
+ yaml_data["description"], yaml_data["name"]
108
+ )
109
+ yaml_data["summary"] = update_description(yaml_data.get("summary", ""))
110
+ for parameter in yaml_data["parameters"]:
111
+ update_parameter(parameter)
112
+ if yaml_data.get("bodyParameter"):
113
+ update_parameter(yaml_data["bodyParameter"])
114
+ for entry in yaml_data["bodyParameter"].get("entries", []):
115
+ update_parameter(entry)
116
+ for overload in yaml_data.get("overloads", []):
117
+ self.update_operation(overload)
118
+ for response in yaml_data.get("responses", []):
119
+ response["discriminator"] = "operation"
120
+
121
+ def _update_lro_operation_helper(self, yaml_data: Dict[str, Any]) -> None:
122
+ azure_arm = self._autorestapi.get_boolean_value("azure-arm", False)
123
+ for response in yaml_data.get("responses", []):
124
+ response["discriminator"] = "lro"
125
+ response["pollerSync"] = (
126
+ response.get("pollerSync") or "azure.core.polling.LROPoller"
127
+ )
128
+ response["pollerAsync"] = (
129
+ response.get("pollerAsync") or "azure.core.polling.AsyncLROPoller"
130
+ )
131
+ if not response.get("pollingMethodSync"):
132
+ response["pollingMethodSync"] = (
133
+ "azure.mgmt.core.polling.arm_polling.ARMPolling"
134
+ if azure_arm
135
+ else "azure.core.polling.base_polling.LROBasePolling"
136
+ )
137
+ if not response.get("pollingMethodAsync"):
138
+ response["pollingMethodAsync"] = (
139
+ "azure.mgmt.core.polling.async_arm_polling.AsyncARMPolling"
140
+ if azure_arm
141
+ else "azure.core.polling.async_base_polling.AsyncLROBasePolling"
142
+ )
143
+
144
+ def update_lro_paging_operation(self, yaml_data: Dict[str, Any]) -> None:
145
+ self.update_lro_operation(yaml_data)
146
+ self.update_paging_operation(yaml_data)
147
+ for response in yaml_data.get("responses", []):
148
+ response["discriminator"] = "lropaging"
149
+
150
+ def update_lro_operation(self, yaml_data: Dict[str, Any]) -> None:
151
+ self.update_operation(yaml_data)
152
+ self._update_lro_operation_helper(yaml_data)
153
+ for overload in yaml_data["overloads"]:
154
+ self._update_lro_operation_helper(overload)
155
+
156
+ def update_paging_operation(self, yaml_data: Dict[str, Any]) -> None:
157
+ self.update_operation(yaml_data)
158
+ if not yaml_data.get("pagerSync"):
159
+ yaml_data["pagerSync"] = "azure.core.paging.ItemPaged"
160
+ if not yaml_data.get("pagerAsync"):
161
+ yaml_data["pagerAsync"] = "azure.core.async_paging.AsyncItemPaged"
162
+ returned_response_object = (
163
+ yaml_data["nextOperation"]["responses"][0]
164
+ if yaml_data.get("nextOperation")
165
+ else yaml_data["responses"][0]
166
+ )
167
+ # if we're in version tolerant, hide the paging model
168
+ if self._autorestapi.get_boolean_value("version-tolerant"):
169
+ returned_response_object["type"]["isPublic"] = False
170
+ item_type = next(
171
+ p["type"]["elementType"]
172
+ for p in returned_response_object["type"]["properties"]
173
+ if p["restApiName"] == yaml_data["itemName"]
174
+ )
175
+ if yaml_data.get("nextOperation"):
176
+ yaml_data["nextOperation"]["groupName"] = pad_reserved_words(
177
+ yaml_data["nextOperation"]["groupName"], PadType.OPERATION_GROUP
178
+ )
179
+ yaml_data["nextOperation"]["groupName"] = to_snake_case(
180
+ yaml_data["nextOperation"]["groupName"]
181
+ )
182
+ for response in yaml_data["nextOperation"].get("responses", []):
183
+ update_paging_response(response)
184
+ response["itemType"] = item_type
185
+ for response in yaml_data.get("responses", []):
186
+ update_paging_response(response)
187
+ response["itemType"] = item_type
188
+ for overload in yaml_data.get("overloads", []):
189
+ self.update_paging_operation(overload)
190
+
191
+ def update_operation_groups(self, yaml_data: Dict[str, Any]) -> None:
192
+ operation_groups_yaml_data = yaml_data["operationGroups"]
193
+ for operation_group in operation_groups_yaml_data:
194
+ operation_group["propertyName"] = pad_reserved_words(
195
+ operation_group["propertyName"], PadType.OPERATION_GROUP
196
+ )
197
+ operation_group["propertyName"] = to_snake_case(
198
+ operation_group["propertyName"]
199
+ )
200
+ operation_group["className"] = update_operation_group_class_name(
201
+ yaml_data, operation_group["className"]
202
+ )
203
+ for operation in operation_group["operations"]:
204
+ self.get_operation_updater(operation)(operation)
205
+
206
+ def update_yaml(self, yaml_data: Dict[str, Any]) -> None:
207
+ """Convert in place the YAML str."""
208
+ update_client(yaml_data["client"])
209
+ update_types(yaml_data["types"])
210
+ self.update_operation_groups(yaml_data)
@@ -0,0 +1,54 @@
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 Any, Dict
7
+ import re
8
+ from .python_mappings import PadType, RESERVED_WORDS, REDEFINED_BUILTINS
9
+
10
+
11
+ def to_snake_case(name: str) -> str:
12
+ def replace_upper_characters(m) -> str:
13
+ match_str = m.group().lower()
14
+ if m.start() > 0 and name[m.start() - 1] == "_":
15
+ # we are good if a '_' already exists
16
+ return match_str
17
+ # the first letter should not have _
18
+ prefix = "_" if m.start() > 0 else ""
19
+
20
+ # we will add an extra _ if there are multiple upper case chars together
21
+ next_non_upper_case_char_location = m.start() + len(match_str)
22
+ if (
23
+ len(match_str) > 2
24
+ and len(name) - next_non_upper_case_char_location > 1
25
+ and name[next_non_upper_case_char_location].isalpha()
26
+ ):
27
+
28
+ return (
29
+ prefix
30
+ + match_str[: len(match_str) - 1]
31
+ + "_"
32
+ + match_str[len(match_str) - 1]
33
+ )
34
+
35
+ return prefix + match_str
36
+
37
+ return re.sub("[A-Z]+", replace_upper_characters, name)
38
+
39
+
40
+ def pad_reserved_words(name: str, pad_type: PadType):
41
+ # we want to pad hidden variables as well
42
+ if not name:
43
+ # we'll pass in empty operation groups sometime etc.
44
+ return name
45
+ name_prefix = "_" if name[0] == "_" else ""
46
+ name = name[1:] if name[0] == "_" else name
47
+ if name.lower() in RESERVED_WORDS[pad_type]:
48
+ return name_prefix + name + pad_type
49
+ return name_prefix + name
50
+
51
+
52
+ def add_redefined_builtin_info(name: str, yaml_data: Dict[str, Any]) -> None:
53
+ if name in REDEFINED_BUILTINS:
54
+ yaml_data["pylintDisable"] = "redefined-builtin"
@@ -51,14 +51,13 @@ basic_latin_chars = {
51
51
  }
52
52
 
53
53
 
54
- class PadType(Enum):
55
- Model = "Model"
56
- Method = "Method"
57
- Parameter = "Parameter"
58
- Enum = "Enum"
59
- Property = "Property"
60
- OperationGroup = "Operations"
61
- BuilderGroup = "Builders"
54
+ class PadType(str, Enum):
55
+ MODEL = "Model"
56
+ METHOD = "_method"
57
+ PARAMETER = "_parameter"
58
+ ENUM = "_enum"
59
+ PROPERTY = "_property"
60
+ OPERATION_GROUP = "Operations"
62
61
 
63
62
 
64
63
  _always_reserved = [
@@ -96,9 +95,9 @@ _always_reserved = [
96
95
  "await",
97
96
  ]
98
97
 
99
- reserved_words = {
100
- PadType.Method: [*_always_reserved],
101
- PadType.Parameter: [
98
+ RESERVED_WORDS = {
99
+ PadType.METHOD: [*_always_reserved],
100
+ PadType.PARAMETER: [
102
101
  "self",
103
102
  # these are kwargs we've reserved for our autorest generated operations
104
103
  "content_type",
@@ -163,9 +162,15 @@ reserved_words = {
163
162
  "retry_on_status_codes",
164
163
  *_always_reserved,
165
164
  ],
166
- PadType.Model: [*_always_reserved],
167
- PadType.Property: ["self", *_always_reserved],
168
- PadType.Enum: ["mro", *_always_reserved],
169
- PadType.OperationGroup: [*_always_reserved],
170
- PadType.BuilderGroup: [*_always_reserved],
165
+ PadType.MODEL: [*_always_reserved],
166
+ PadType.PROPERTY: ["self", *_always_reserved],
167
+ PadType.ENUM: ["mro", *_always_reserved],
168
+ PadType.OPERATION_GROUP: [*_always_reserved],
171
169
  }
170
+
171
+ REDEFINED_BUILTINS = [ # we don't pad, but we need to do lint ignores
172
+ "id",
173
+ "min",
174
+ "max",
175
+ "filter",
176
+ ]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@autorest/python",
3
- "version": "5.16.0",
3
+ "version": "5.19.0",
4
4
  "description": "The Python extension for generators in AutoRest.",
5
5
  "scripts": {
6
6
  "prepare": "node run-python3.js prepare.py",
@@ -27,7 +27,7 @@
27
27
  "@autorest/system-requirements": "~1.0.0"
28
28
  },
29
29
  "devDependencies": {
30
- "@microsoft.azure/autorest.testserver": "3.3.23"
30
+ "@microsoft.azure/autorest.testserver": "^3.3.28"
31
31
  },
32
32
  "files": [
33
33
  "autorest/**/*.py",
@@ -1,55 +0,0 @@
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 Set, Optional, Type
7
- from .credential_schema_policy import (
8
- CredentialSchemaPolicy,
9
- BearerTokenCredentialPolicy,
10
- )
11
- from .credential_schema_policy import ARMChallengeAuthenticationPolicy
12
- from .credential_schema import TokenCredentialSchema, AzureKeyCredentialSchema
13
-
14
-
15
- class CredentialModel:
16
- """Store info about credential."""
17
-
18
- def __init__(self, azure_arm: bool) -> None:
19
- self.azure_arm: bool = azure_arm
20
- self.credential_scopes: Set[str] = set()
21
- self.key_header_name: str = ""
22
- self.policy_type: Optional[Type[CredentialSchemaPolicy]] = None
23
- self._credential_schema_policy: Optional[CredentialSchemaPolicy] = None
24
-
25
- @property
26
- def default_authentication_policy(self) -> Type[CredentialSchemaPolicy]:
27
- return (
28
- ARMChallengeAuthenticationPolicy
29
- if self.azure_arm
30
- else BearerTokenCredentialPolicy
31
- )
32
-
33
- @property
34
- def credential_schema_policy(self) -> CredentialSchemaPolicy:
35
- if not self._credential_schema_policy:
36
- raise ValueError(
37
- "You want to find the Credential Schema Policy, but have not given a value"
38
- )
39
- return self._credential_schema_policy
40
-
41
- def build_authentication_policy(self):
42
- if hasattr(self.policy_type, "credential_scopes"):
43
- self._credential_schema_policy = (
44
- self.policy_type( # pylint: disable=not-callable
45
- credential=TokenCredentialSchema(async_mode=False),
46
- credential_scopes=list(self.credential_scopes),
47
- )
48
- )
49
- elif hasattr(self.policy_type, "credential_key_header_name"):
50
- self._credential_schema_policy = (
51
- self.policy_type( # pylint: disable=not-callable
52
- credential=AzureKeyCredentialSchema(),
53
- credential_key_header_name=self.key_header_name,
54
- )
55
- )
@@ -1,95 +0,0 @@
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 Any
7
- from .base_schema import BaseSchema
8
- from .imports import FileImport, ImportType, TypingSection
9
-
10
-
11
- class CredentialSchema(BaseSchema):
12
- def __init__(self) -> None: # pylint: disable=super-init-not-called
13
- self.default_value = None
14
-
15
- def type_annotation(self, *, is_operation_file: bool = False) -> str:
16
- raise ValueError("Children classes should set their own type annotation")
17
-
18
- @property
19
- def docstring_type(self) -> str:
20
- return self.serialization_type
21
-
22
- @property
23
- def docstring_text(self) -> str:
24
- return "credential"
25
-
26
- @property
27
- def serialization_type(self) -> str:
28
- # this property is added, because otherwise pylint says that
29
- # abstract serialization_type in BaseSchema is not overridden
30
- pass
31
-
32
- def get_json_template_representation(self, **kwargs: Any) -> Any:
33
- raise TypeError(
34
- "You should not try to get a JSON template representation of a CredentialSchema"
35
- )
36
-
37
-
38
- class AzureKeyCredentialSchema(CredentialSchema):
39
- @property
40
- def serialization_type(self) -> str:
41
- return "~azure.core.credentials.AzureKeyCredential"
42
-
43
- def type_annotation(
44
- self, *, is_operation_file: bool = False # pylint: disable=unused-argument
45
- ) -> str:
46
- return "AzureKeyCredential"
47
-
48
- def imports(self) -> FileImport:
49
- file_import = FileImport()
50
- file_import.add_submodule_import(
51
- "azure.core.credentials",
52
- "AzureKeyCredential",
53
- ImportType.AZURECORE,
54
- typing_section=TypingSection.CONDITIONAL,
55
- )
56
- return file_import
57
-
58
-
59
- class TokenCredentialSchema(CredentialSchema):
60
- def __init__(self, async_mode) -> None:
61
- super().__init__()
62
- self.async_mode = async_mode
63
- self.async_type = "~azure.core.credentials_async.AsyncTokenCredential"
64
- self.sync_type = "~azure.core.credentials.TokenCredential"
65
-
66
- @property
67
- def serialization_type(self) -> str:
68
- if self.async_mode:
69
- return self.async_type
70
- return self.sync_type
71
-
72
- def type_annotation(
73
- self, *, is_operation_file: bool = False # pylint: disable=unused-argument
74
- ) -> str:
75
- if self.async_mode:
76
- return '"AsyncTokenCredential"'
77
- return '"TokenCredential"'
78
-
79
- def imports(self) -> FileImport:
80
- file_import = FileImport()
81
- if self.async_mode:
82
- file_import.add_submodule_import(
83
- "azure.core.credentials_async",
84
- "AsyncTokenCredential",
85
- ImportType.AZURECORE,
86
- typing_section=TypingSection.TYPING,
87
- )
88
- else:
89
- file_import.add_submodule_import(
90
- "azure.core.credentials",
91
- "TokenCredential",
92
- ImportType.AZURECORE,
93
- typing_section=TypingSection.TYPING,
94
- )
95
- return file_import
@@ -1,73 +0,0 @@
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 abc import abstractmethod
7
- from typing import List
8
- from .credential_schema import CredentialSchema
9
-
10
-
11
- class CredentialSchemaPolicy:
12
- def __init__(self, credential: CredentialSchema) -> None:
13
- self.credential = credential
14
-
15
- @abstractmethod
16
- def call(self, async_mode: bool) -> str:
17
- ...
18
-
19
- @classmethod
20
- def name(cls):
21
- return cls.__name__
22
-
23
-
24
- class BearerTokenCredentialPolicy(CredentialSchemaPolicy):
25
- def __init__(
26
- self, credential: CredentialSchema, credential_scopes: List[str]
27
- ) -> None:
28
- super().__init__(credential)
29
- self._credential_scopes = credential_scopes
30
-
31
- @property
32
- def credential_scopes(self):
33
- return self._credential_scopes
34
-
35
- def call(self, async_mode: bool) -> str:
36
- policy_name = f"Async{self.name()}" if async_mode else self.name()
37
- return f"policies.{policy_name}(self.credential, *self.credential_scopes, **kwargs)"
38
-
39
-
40
- class ARMChallengeAuthenticationPolicy(BearerTokenCredentialPolicy):
41
- def call(self, async_mode: bool) -> str:
42
- policy_name = f"Async{self.name()}" if async_mode else self.name()
43
- return f"{policy_name}(self.credential, *self.credential_scopes, **kwargs)"
44
-
45
-
46
- class AzureKeyCredentialPolicy(CredentialSchemaPolicy):
47
- def __init__(
48
- self, credential: CredentialSchema, credential_key_header_name: str
49
- ) -> None:
50
- super().__init__(credential)
51
- self._credential_key_header_name = credential_key_header_name
52
-
53
- @property
54
- def credential_key_header_name(self):
55
- return self._credential_key_header_name
56
-
57
- def call(self, async_mode: bool) -> str:
58
- return f'policies.AzureKeyCredentialPolicy(self.credential, "{self.credential_key_header_name}", **kwargs)'
59
-
60
-
61
- def get_credential_schema_policy_type(name):
62
- policies = [
63
- ARMChallengeAuthenticationPolicy,
64
- BearerTokenCredentialPolicy,
65
- AzureKeyCredentialPolicy,
66
- ]
67
- try:
68
- return next(p for p in policies if p.name().lower() == name.lower())
69
- except StopIteration:
70
- raise ValueError(
71
- "The credential policy you pass in with --credential-default-policy-type must be either "
72
- "{}".format(" or ".join([p.name() for p in policies]))
73
- )
@@ -1,106 +0,0 @@
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 Any, Dict, Optional, TYPE_CHECKING
7
- from .base_schema import BaseSchema
8
- from .imports import FileImport, ImportType, TypingSection
9
-
10
- if TYPE_CHECKING:
11
- from .code_model import CodeModel
12
-
13
-
14
- class DictionarySchema(BaseSchema):
15
- """Schema for dictionaries that will be serialized.
16
-
17
- :param yaml_data: the yaml data for this schema
18
- :type yaml_data: dict[str, Any]
19
- :param element_type: The type of the value for the dictionary
20
- :type element_type: ~autorest.models.BaseSchema
21
- """
22
-
23
- def __init__(
24
- self,
25
- yaml_data: Dict[str, Any],
26
- code_model: "CodeModel",
27
- element_type: "BaseSchema",
28
- ) -> None:
29
- super().__init__(yaml_data=yaml_data, code_model=code_model)
30
- self.element_type = element_type
31
-
32
- @property
33
- def serialization_type(self) -> str:
34
- """Returns the serialization value for msrest.
35
-
36
- :return: The serialization value for msrest
37
- :rtype: str
38
- """
39
- return f"{{{self.element_type.serialization_type}}}"
40
-
41
- def type_annotation(self, *, is_operation_file: bool = False) -> str:
42
- """The python type used for type annotation
43
-
44
- :return: The type annotation for this schema
45
- :rtype: str
46
- """
47
- return f"Dict[str, {self.element_type.type_annotation(is_operation_file=is_operation_file)}]"
48
-
49
- @property
50
- def docstring_text(self) -> str:
51
- return f"dict mapping str to {self.element_type.docstring_text}"
52
-
53
- @property
54
- def docstring_type(self) -> str:
55
- """The python type used for RST syntax input and type annotation.
56
-
57
- :param str namespace: Optional. The namespace for the models.
58
- """
59
- return f"dict[str, {self.element_type.docstring_type}]"
60
-
61
- def xml_serialization_ctxt(self) -> Optional[str]:
62
- raise NotImplementedError(
63
- "Dictionary schema does not support XML serialization."
64
- )
65
-
66
- def get_json_template_representation(self, **kwargs: Any) -> Any:
67
- return {
68
- f'"{"str"}"': self.element_type.get_json_template_representation(**kwargs)
69
- }
70
-
71
- @classmethod
72
- def from_yaml(
73
- cls, yaml_data: Dict[str, Any], code_model: "CodeModel"
74
- ) -> "DictionarySchema":
75
- """Constructs a DictionarySchema from yaml data.
76
-
77
- :param yaml_data: the yaml data from which we will construct this schema
78
- :type yaml_data: dict[str, Any]
79
-
80
- :return: A created DictionarySchema
81
- :rtype: ~autorest.models.DictionarySchema
82
- """
83
- element_schema = yaml_data["elementType"]
84
-
85
- from . import build_schema # pylint: disable=import-outside-toplevel
86
-
87
- element_type = build_schema(yaml_data=element_schema, code_model=code_model)
88
-
89
- return cls(
90
- yaml_data=yaml_data,
91
- code_model=code_model,
92
- element_type=element_type,
93
- )
94
-
95
- def imports(self) -> FileImport:
96
- file_import = FileImport()
97
- file_import.add_submodule_import(
98
- "typing", "Dict", ImportType.STDLIB, TypingSection.CONDITIONAL
99
- )
100
- file_import.merge(self.element_type.imports())
101
- return file_import
102
-
103
- def model_file_imports(self) -> FileImport:
104
- file_import = self.imports()
105
- file_import.merge(self.element_type.model_file_imports())
106
- return file_import