@typespec/http-client-python 0.4.3 → 0.5.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 (139) hide show
  1. package/dist/emitter/emitter.d.ts.map +1 -1
  2. package/dist/emitter/emitter.js +85 -24
  3. package/dist/emitter/emitter.js.map +1 -1
  4. package/dist/emitter/lib.d.ts +1 -0
  5. package/dist/emitter/lib.d.ts.map +1 -1
  6. package/dist/emitter/lib.js +1 -0
  7. package/dist/emitter/lib.js.map +1 -1
  8. package/dist/emitter/run-python3.d.ts +2 -0
  9. package/dist/emitter/run-python3.d.ts.map +1 -0
  10. package/dist/emitter/run-python3.js +19 -0
  11. package/dist/emitter/run-python3.js.map +1 -0
  12. package/dist/emitter/system-requirements.d.ts +17 -0
  13. package/dist/emitter/system-requirements.d.ts.map +1 -0
  14. package/dist/emitter/system-requirements.js +167 -0
  15. package/dist/emitter/system-requirements.js.map +1 -0
  16. package/emitter/src/emitter.ts +88 -23
  17. package/emitter/src/lib.ts +2 -0
  18. package/emitter/src/run-python3.ts +20 -0
  19. package/emitter/src/system-requirements.ts +261 -0
  20. package/emitter/temp/tsconfig.tsbuildinfo +1 -1
  21. package/eng/scripts/ci/regenerate.ts +16 -4
  22. package/eng/scripts/setup/__pycache__/venvtools.cpython-38.pyc +0 -0
  23. package/eng/scripts/setup/build.ts +16 -0
  24. package/eng/scripts/setup/build_pygen_wheel.py +40 -0
  25. package/eng/scripts/setup/install.py +9 -3
  26. package/eng/scripts/setup/install.ts +32 -0
  27. package/eng/scripts/setup/prepare.py +3 -1
  28. package/eng/scripts/setup/prepare.ts +11 -0
  29. package/eng/scripts/setup/run-python3.ts +1 -6
  30. package/generator/build/lib/pygen/__init__.py +107 -0
  31. package/generator/build/lib/pygen/_version.py +7 -0
  32. package/generator/build/lib/pygen/black.py +71 -0
  33. package/generator/build/lib/pygen/codegen/__init__.py +357 -0
  34. package/generator/build/lib/pygen/codegen/_utils.py +17 -0
  35. package/generator/build/lib/pygen/codegen/models/__init__.py +204 -0
  36. package/generator/build/lib/pygen/codegen/models/base.py +186 -0
  37. package/generator/build/lib/pygen/codegen/models/base_builder.py +118 -0
  38. package/generator/build/lib/pygen/codegen/models/client.py +435 -0
  39. package/generator/build/lib/pygen/codegen/models/code_model.py +237 -0
  40. package/generator/build/lib/pygen/codegen/models/combined_type.py +149 -0
  41. package/generator/build/lib/pygen/codegen/models/constant_type.py +129 -0
  42. package/generator/build/lib/pygen/codegen/models/credential_types.py +214 -0
  43. package/generator/build/lib/pygen/codegen/models/dictionary_type.py +127 -0
  44. package/generator/build/lib/pygen/codegen/models/enum_type.py +238 -0
  45. package/generator/build/lib/pygen/codegen/models/imports.py +291 -0
  46. package/generator/build/lib/pygen/codegen/models/list_type.py +143 -0
  47. package/generator/build/lib/pygen/codegen/models/lro_operation.py +142 -0
  48. package/generator/build/lib/pygen/codegen/models/lro_paging_operation.py +32 -0
  49. package/generator/build/lib/pygen/codegen/models/model_type.py +357 -0
  50. package/generator/build/lib/pygen/codegen/models/operation.py +509 -0
  51. package/generator/build/lib/pygen/codegen/models/operation_group.py +184 -0
  52. package/generator/build/lib/pygen/codegen/models/paging_operation.py +155 -0
  53. package/generator/build/lib/pygen/codegen/models/parameter.py +412 -0
  54. package/generator/build/lib/pygen/codegen/models/parameter_list.py +387 -0
  55. package/generator/build/lib/pygen/codegen/models/primitive_types.py +659 -0
  56. package/generator/build/lib/pygen/codegen/models/property.py +170 -0
  57. package/generator/build/lib/pygen/codegen/models/request_builder.py +189 -0
  58. package/generator/build/lib/pygen/codegen/models/request_builder_parameter.py +115 -0
  59. package/generator/build/lib/pygen/codegen/models/response.py +348 -0
  60. package/generator/build/lib/pygen/codegen/models/utils.py +21 -0
  61. package/generator/build/lib/pygen/codegen/serializers/__init__.py +574 -0
  62. package/generator/build/lib/pygen/codegen/serializers/base_serializer.py +21 -0
  63. package/generator/build/lib/pygen/codegen/serializers/builder_serializer.py +1533 -0
  64. package/generator/build/lib/pygen/codegen/serializers/client_serializer.py +294 -0
  65. package/generator/build/lib/pygen/codegen/serializers/enum_serializer.py +15 -0
  66. package/generator/build/lib/pygen/codegen/serializers/general_serializer.py +213 -0
  67. package/generator/build/lib/pygen/codegen/serializers/import_serializer.py +126 -0
  68. package/generator/build/lib/pygen/codegen/serializers/metadata_serializer.py +198 -0
  69. package/generator/build/lib/pygen/codegen/serializers/model_init_serializer.py +33 -0
  70. package/generator/build/lib/pygen/codegen/serializers/model_serializer.py +335 -0
  71. package/generator/build/lib/pygen/codegen/serializers/operation_groups_serializer.py +89 -0
  72. package/generator/build/lib/pygen/codegen/serializers/operations_init_serializer.py +44 -0
  73. package/generator/build/lib/pygen/codegen/serializers/parameter_serializer.py +221 -0
  74. package/generator/build/lib/pygen/codegen/serializers/patch_serializer.py +19 -0
  75. package/generator/build/lib/pygen/codegen/serializers/request_builders_serializer.py +52 -0
  76. package/generator/build/lib/pygen/codegen/serializers/sample_serializer.py +168 -0
  77. package/generator/build/lib/pygen/codegen/serializers/test_serializer.py +292 -0
  78. package/generator/build/lib/pygen/codegen/serializers/types_serializer.py +31 -0
  79. package/generator/build/lib/pygen/codegen/serializers/utils.py +68 -0
  80. package/generator/build/lib/pygen/codegen/templates/client.py.jinja2 +37 -0
  81. package/generator/build/lib/pygen/codegen/templates/client_container.py.jinja2 +12 -0
  82. package/generator/build/lib/pygen/codegen/templates/config.py.jinja2 +73 -0
  83. package/generator/build/lib/pygen/codegen/templates/config_container.py.jinja2 +16 -0
  84. package/generator/build/lib/pygen/codegen/templates/conftest.py.jinja2 +28 -0
  85. package/generator/build/lib/pygen/codegen/templates/enum.py.jinja2 +13 -0
  86. package/generator/build/lib/pygen/codegen/templates/enum_container.py.jinja2 +10 -0
  87. package/generator/build/lib/pygen/codegen/templates/init.py.jinja2 +24 -0
  88. package/generator/build/lib/pygen/codegen/templates/keywords.jinja2 +27 -0
  89. package/generator/build/lib/pygen/codegen/templates/lro_operation.py.jinja2 +16 -0
  90. package/generator/build/lib/pygen/codegen/templates/lro_paging_operation.py.jinja2 +18 -0
  91. package/generator/build/lib/pygen/codegen/templates/macros.jinja2 +12 -0
  92. package/generator/build/lib/pygen/codegen/templates/metadata.json.jinja2 +167 -0
  93. package/generator/build/lib/pygen/codegen/templates/model_base.py.jinja2 +1174 -0
  94. package/generator/build/lib/pygen/codegen/templates/model_container.py.jinja2 +15 -0
  95. package/generator/build/lib/pygen/codegen/templates/model_dpg.py.jinja2 +97 -0
  96. package/generator/build/lib/pygen/codegen/templates/model_init.py.jinja2 +33 -0
  97. package/generator/build/lib/pygen/codegen/templates/model_msrest.py.jinja2 +92 -0
  98. package/generator/build/lib/pygen/codegen/templates/operation.py.jinja2 +21 -0
  99. package/generator/build/lib/pygen/codegen/templates/operation_group.py.jinja2 +75 -0
  100. package/generator/build/lib/pygen/codegen/templates/operation_groups_container.py.jinja2 +19 -0
  101. package/generator/build/lib/pygen/codegen/templates/operation_tools.jinja2 +81 -0
  102. package/generator/build/lib/pygen/codegen/templates/operations_folder_init.py.jinja2 +17 -0
  103. package/generator/build/lib/pygen/codegen/templates/packaging_templates/CHANGELOG.md.jinja2 +6 -0
  104. package/generator/build/lib/pygen/codegen/templates/packaging_templates/LICENSE.jinja2 +21 -0
  105. package/generator/build/lib/pygen/codegen/templates/packaging_templates/MANIFEST.in.jinja2 +8 -0
  106. package/generator/build/lib/pygen/codegen/templates/packaging_templates/README.md.jinja2 +107 -0
  107. package/generator/build/lib/pygen/codegen/templates/packaging_templates/dev_requirements.txt.jinja2 +9 -0
  108. package/generator/build/lib/pygen/codegen/templates/packaging_templates/setup.py.jinja2 +108 -0
  109. package/generator/build/lib/pygen/codegen/templates/paging_operation.py.jinja2 +21 -0
  110. package/generator/build/lib/pygen/codegen/templates/patch.py.jinja2 +19 -0
  111. package/generator/build/lib/pygen/codegen/templates/pkgutil_init.py.jinja2 +1 -0
  112. package/generator/build/lib/pygen/codegen/templates/request_builder.py.jinja2 +28 -0
  113. package/generator/build/lib/pygen/codegen/templates/request_builders.py.jinja2 +10 -0
  114. package/generator/build/lib/pygen/codegen/templates/rest_init.py.jinja2 +12 -0
  115. package/generator/build/lib/pygen/codegen/templates/sample.py.jinja2 +44 -0
  116. package/generator/build/lib/pygen/codegen/templates/serialization.py.jinja2 +2117 -0
  117. package/generator/build/lib/pygen/codegen/templates/test.py.jinja2 +50 -0
  118. package/generator/build/lib/pygen/codegen/templates/testpreparer.py.jinja2 +26 -0
  119. package/generator/build/lib/pygen/codegen/templates/types.py.jinja2 +7 -0
  120. package/generator/build/lib/pygen/codegen/templates/validation.py.jinja2 +38 -0
  121. package/generator/build/lib/pygen/codegen/templates/vendor.py.jinja2 +96 -0
  122. package/generator/build/lib/pygen/codegen/templates/version.py.jinja2 +4 -0
  123. package/generator/build/lib/pygen/m2r.py +65 -0
  124. package/generator/build/lib/pygen/preprocess/__init__.py +515 -0
  125. package/generator/build/lib/pygen/preprocess/helpers.py +27 -0
  126. package/generator/build/lib/pygen/preprocess/python_mappings.py +226 -0
  127. package/generator/build/lib/pygen/utils.py +163 -0
  128. package/generator/component-detection-pip-report.json +134 -0
  129. package/generator/dev_requirements.txt +0 -1
  130. package/generator/dist/pygen-0.1.0-py3-none-any.whl +0 -0
  131. package/generator/pygen/m2r.py +1 -1
  132. package/generator/pygen.egg-info/PKG-INFO +7 -4
  133. package/generator/pygen.egg-info/requires.txt +7 -4
  134. package/generator/requirements.txt +5 -10
  135. package/generator/setup.py +7 -4
  136. package/generator/test/azure/requirements.txt +2 -0
  137. package/generator/test/generic_mock_api_tests/unittests/test_m2r.py +10 -0
  138. package/generator/test/unbranded/requirements.txt +2 -0
  139. package/package.json +6 -5
@@ -0,0 +1,149 @@
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, List, Optional, TYPE_CHECKING, Type, Tuple, Union
7
+ import re
8
+ from .imports import FileImport, ImportType, TypingSection
9
+ from .base import BaseType
10
+ from .model_type import ModelType
11
+
12
+ if TYPE_CHECKING:
13
+ from .code_model import CodeModel
14
+
15
+
16
+ class CombinedType(BaseType):
17
+ """A type that consists of multiple different types.
18
+
19
+ Used by body parameters that have multiple types, i.e. one that can be
20
+ a stream body or a JSON body.
21
+ """
22
+
23
+ def __init__(
24
+ self,
25
+ yaml_data: Dict[str, Any],
26
+ code_model: "CodeModel",
27
+ types: List[BaseType],
28
+ ) -> None:
29
+ super().__init__(yaml_data, code_model)
30
+ self.types = types # the types that this type is combining
31
+ self.name = yaml_data.get("name")
32
+ self._is_union_of_literals = all(i.type == "constant" for i in self.types)
33
+
34
+ @property
35
+ def serialization_type(self) -> str:
36
+ """The tag recognized by 'msrest' as a serialization/deserialization.
37
+
38
+ 'str', 'int', 'float', 'bool' or
39
+ https://github.com/Azure/msrest-for-python/blob/b505e3627b547bd8fdc38327e86c70bdb16df061/msrest/serialization.py#L407-L416
40
+
41
+ or the object schema name (e.g. DotSalmon).
42
+
43
+ If list: '[str]'
44
+ If dict: '{str}'
45
+ """
46
+ if not all(t for t in self.types if t.type == "constant"):
47
+ raise ValueError("Shouldn't get serialization type of a combinedtype")
48
+ return self.types[0].serialization_type
49
+
50
+ @property
51
+ def client_default_value(self) -> Any:
52
+ return self.yaml_data.get("clientDefaultValue")
53
+
54
+ def description(self, *, is_operation_file: bool) -> str:
55
+ if len(self.types) == 2:
56
+ return f"Is either a {self.types[0].type_description} type or a {self.types[1].type_description} type."
57
+ return f"Is one of the following types: {', '.join([t.type_description for t in self.types])}"
58
+
59
+ def docstring_text(self, **kwargs: Any) -> str:
60
+ return " or ".join(t.docstring_text(**kwargs) for t in self.types)
61
+
62
+ def docstring_type(self, **kwargs: Any) -> str:
63
+ return " or ".join(t.docstring_type(**kwargs) for t in self.types)
64
+
65
+ def type_annotation(self, **kwargs: Any) -> str:
66
+ if self.name:
67
+ return f'"_types.{self.name}"'
68
+ return self.type_definition(**kwargs)
69
+
70
+ def type_definition(self, **kwargs: Any) -> str:
71
+ """The python type used for type annotation
72
+
73
+ Special case for enum, for instance: Union[str, "EnumName"]
74
+ """
75
+ # remove duplicates
76
+ inside_types = list(dict.fromkeys([type.type_annotation(**kwargs) for type in self.types]))
77
+ if len(inside_types) == 1:
78
+ return inside_types[0]
79
+ if self._is_union_of_literals:
80
+ parsed_values = []
81
+ for entry in inside_types:
82
+ match = re.search(r"Literal\[(.*)\]", entry)
83
+ if match is not None:
84
+ parsed_values.append(match.group(1))
85
+ join_string = ", ".join(parsed_values)
86
+ return f"Literal[{join_string}]"
87
+
88
+ # If the inside types has been a Union, peel first and then re-union
89
+ pattern = re.compile(r"Union\[.*\]")
90
+ return f'Union[{", ".join(map(lambda x: x[6: -1] if pattern.match(x) else x, inside_types))}]'
91
+
92
+ @property
93
+ def is_form_data(self) -> bool:
94
+ return any(t.is_form_data for t in self.types)
95
+
96
+ def get_json_template_representation(
97
+ self,
98
+ *,
99
+ client_default_value_declaration: Optional[str] = None,
100
+ ) -> Any:
101
+ return self.types[0].get_json_template_representation(
102
+ client_default_value_declaration=client_default_value_declaration,
103
+ )
104
+
105
+ def get_polymorphic_subtypes(self, polymorphic_subtypes: List["ModelType"]) -> None:
106
+ raise ValueError("You shouldn't get polymorphic subtypes of multiple types")
107
+
108
+ @property
109
+ def instance_check_template(self) -> str:
110
+ """Template of what an instance check of a variable for this type would look like"""
111
+ raise ValueError("You shouldn't do instance checks on a multiple type")
112
+
113
+ def imports(self, **kwargs: Any) -> FileImport:
114
+ file_import = FileImport(self.code_model)
115
+ if self.name and not kwargs.get("is_types_file"):
116
+ file_import.add_submodule_import(
117
+ kwargs.pop("relative_path"),
118
+ "_types",
119
+ ImportType.LOCAL,
120
+ TypingSection.TYPING,
121
+ )
122
+ return file_import
123
+ for type in self.types:
124
+ file_import.merge(type.imports(**kwargs))
125
+ if not self._is_union_of_literals:
126
+ file_import.add_submodule_import("typing", "Union", ImportType.STDLIB)
127
+ return file_import
128
+
129
+ @classmethod
130
+ def from_yaml(cls, yaml_data: Dict[str, Any], code_model: "CodeModel") -> "BaseType":
131
+ from . import build_type
132
+
133
+ return cls(
134
+ yaml_data,
135
+ code_model,
136
+ [build_type(t, code_model) for t in yaml_data["types"]],
137
+ )
138
+
139
+ def target_model_subtype(
140
+ self,
141
+ target_types: Union[
142
+ Tuple[Type[ModelType]],
143
+ Tuple[Type[ModelType], Type[ModelType]],
144
+ ],
145
+ ) -> Optional[ModelType]:
146
+ for sub_t in self.types:
147
+ if isinstance(sub_t, target_types):
148
+ return sub_t # type: ignore
149
+ return None
@@ -0,0 +1,129 @@
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
+ import logging
7
+ from typing import Dict, Any, Optional, TYPE_CHECKING, Union
8
+ from .base import BaseType
9
+ from .imports import FileImport, ImportType, TypingSection
10
+ from .primitive_types import IntegerType, BinaryType, StringType, BooleanType
11
+ from .utils import add_to_description
12
+
13
+ if TYPE_CHECKING:
14
+ from .code_model import CodeModel
15
+
16
+ _LOGGER = logging.getLogger(__name__)
17
+
18
+
19
+ class ConstantType(BaseType):
20
+ """Schema for constants that will be serialized.
21
+
22
+ :param yaml_data: the yaml data for this schema
23
+ :type yaml_data: dict[str, Any]
24
+ :param str value: The actual value of this constant.
25
+ :param schema: The schema for the value of this constant.
26
+ :type schema: ~autorest.models.PrimitiveType
27
+ """
28
+
29
+ def __init__(
30
+ self,
31
+ yaml_data: Dict[str, Any],
32
+ code_model: "CodeModel",
33
+ value_type: BaseType,
34
+ value: Optional[Union[str, int, float]],
35
+ ) -> None:
36
+ super().__init__(yaml_data=yaml_data, code_model=code_model)
37
+ self.value_type = value_type
38
+ self.value = value
39
+
40
+ def get_declaration(self, value=None):
41
+ if value and value != self.value:
42
+ _LOGGER.warning(
43
+ "Passed in value of %s differs from constant value of %s. Choosing constant value",
44
+ str(value),
45
+ str(self.value),
46
+ )
47
+ if self.value is None:
48
+ return "None"
49
+ return self.value_type.get_declaration(self.value)
50
+
51
+ def description(self, *, is_operation_file: bool) -> str:
52
+ if is_operation_file:
53
+ return ""
54
+ return add_to_description(
55
+ self.yaml_data.get("description", ""),
56
+ f"Default value is {self.get_declaration()}.",
57
+ )
58
+
59
+ @property
60
+ def serialization_type(self) -> str:
61
+ """Returns the serialization value for msrest.
62
+
63
+ :return: The serialization value for msrest
64
+ :rtype: str
65
+ """
66
+ return self.value_type.serialization_type
67
+
68
+ def docstring_text(self, **kwargs: Any) -> str:
69
+ return "constant"
70
+
71
+ def docstring_type(self, **kwargs: Any) -> str:
72
+ """The python type used for RST syntax input and type annotation.
73
+
74
+ :param str namespace: Optional. The namespace for the models.
75
+ """
76
+ return self.value_type.docstring_type(**kwargs)
77
+
78
+ def type_annotation(self, **kwargs: Any) -> str:
79
+ return f"Literal[{self.get_declaration()}]" if self._is_literal else self.value_type.type_annotation(**kwargs)
80
+
81
+ @property
82
+ def _is_literal(self) -> bool:
83
+ return isinstance(self.value_type, (IntegerType, BinaryType, StringType, BooleanType))
84
+
85
+ @classmethod
86
+ def from_yaml(cls, yaml_data: Dict[str, Any], code_model: "CodeModel") -> "ConstantType":
87
+ """Constructs a ConstantType from yaml data.
88
+
89
+ :param yaml_data: the yaml data from which we will construct this schema
90
+ :type yaml_data: dict[str, Any]
91
+
92
+ :return: A created ConstantType
93
+ :rtype: ~autorest.models.ConstantType
94
+ """
95
+ from . import build_type
96
+
97
+ return cls(
98
+ yaml_data=yaml_data,
99
+ code_model=code_model,
100
+ value_type=build_type(yaml_data["valueType"], code_model),
101
+ value=yaml_data["value"],
102
+ )
103
+
104
+ def get_json_template_representation(
105
+ self,
106
+ *,
107
+ client_default_value_declaration: Optional[str] = None,
108
+ ) -> Any:
109
+ return self.value_type.get_json_template_representation(
110
+ client_default_value_declaration=self.get_declaration(),
111
+ )
112
+
113
+ def _imports_shared(self, **kwargs: Any):
114
+ file_import = super().imports(**kwargs)
115
+ file_import.merge(self.value_type.imports(**kwargs))
116
+ return file_import
117
+
118
+ def imports_for_multiapi(self, **kwargs: Any) -> FileImport:
119
+ return self._imports_shared(**kwargs)
120
+
121
+ def imports(self, **kwargs: Any) -> FileImport:
122
+ file_import = self._imports_shared(**kwargs)
123
+ if self._is_literal:
124
+ file_import.add_submodule_import("typing", "Literal", ImportType.STDLIB, TypingSection.REGULAR)
125
+ return file_import
126
+
127
+ @property
128
+ def instance_check_template(self) -> str:
129
+ return self.value_type.instance_check_template
@@ -0,0 +1,214 @@
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 (
8
+ Optional,
9
+ Any,
10
+ Dict,
11
+ TYPE_CHECKING,
12
+ List,
13
+ Generic,
14
+ TypeVar,
15
+ Union,
16
+ cast,
17
+ )
18
+
19
+ from .imports import FileImport, ImportType, TypingSection
20
+ from .base import BaseType
21
+
22
+ if TYPE_CHECKING:
23
+ from .code_model import CodeModel
24
+
25
+
26
+ class _CredentialPolicyBaseType:
27
+ """Base class for our different credential policy types.
28
+
29
+ Inherited by our BearerTokenCredentialPolicy and KeyCredentialPolicy types.
30
+ """
31
+
32
+ def __init__(self, yaml_data: Dict[str, Any], code_model: "CodeModel") -> None:
33
+ self.yaml_data = yaml_data
34
+ self.code_model = code_model
35
+
36
+ @abstractmethod
37
+ def call(self, async_mode: bool) -> str:
38
+ """
39
+ How to call this credential policy. Used to initialize the credential policy in the config file.
40
+ """
41
+
42
+
43
+ class BearerTokenCredentialPolicyType(_CredentialPolicyBaseType):
44
+ """Credential policy type representing BearerTokenCredentialPolicy"""
45
+
46
+ def __init__(
47
+ self,
48
+ yaml_data: Dict[str, Any],
49
+ code_model: "CodeModel",
50
+ credential_scopes: List[str],
51
+ ) -> None:
52
+ super().__init__(yaml_data, code_model)
53
+ self.credential_scopes = credential_scopes
54
+
55
+ def call(self, async_mode: bool) -> str:
56
+ policy_name = f"{'Async' if async_mode else ''}BearerTokenCredentialPolicy"
57
+ return f"policies.{policy_name}(self.credential, *self.credential_scopes, **kwargs)"
58
+
59
+ @classmethod
60
+ def from_yaml(cls, yaml_data: Dict[str, Any], code_model: "CodeModel") -> "BearerTokenCredentialPolicyType":
61
+ return cls(yaml_data, code_model, yaml_data["credentialScopes"])
62
+
63
+
64
+ class ARMChallengeAuthenticationPolicyType(BearerTokenCredentialPolicyType):
65
+ """Credential policy type representing ARMChallengeAuthenticationPolicy"""
66
+
67
+ def call(self, async_mode: bool) -> str:
68
+ policy_name = f"{'Async' if async_mode else ''}ARMChallengeAuthenticationPolicy"
69
+ return f"{policy_name}(self.credential, *self.credential_scopes, **kwargs)"
70
+
71
+
72
+ class KeyCredentialPolicyType(_CredentialPolicyBaseType):
73
+ def __init__(
74
+ self,
75
+ yaml_data: Dict[str, Any],
76
+ code_model: "CodeModel",
77
+ key: str,
78
+ scheme: Optional[str] = None,
79
+ ) -> None:
80
+ super().__init__(yaml_data, code_model)
81
+ self.key = key
82
+ self.scheme = scheme
83
+
84
+ @property
85
+ def credential_name(self) -> str:
86
+ return "AzureKeyCredential" if self.code_model.is_azure_flavor else "ServiceKeyCredential"
87
+
88
+ def call(self, async_mode: bool) -> str:
89
+ params = f'"{self.key}", '
90
+ if self.scheme:
91
+ params += f'prefix="{self.scheme}", '
92
+ return f"policies.{self.credential_name}Policy(self.credential, {params}**kwargs)"
93
+
94
+ @classmethod
95
+ def from_yaml(cls, yaml_data: Dict[str, Any], code_model: "CodeModel") -> "KeyCredentialPolicyType":
96
+ return cls(yaml_data, code_model, yaml_data["key"], yaml_data.get("scheme", None))
97
+
98
+
99
+ CredentialPolicyType = TypeVar(
100
+ "CredentialPolicyType",
101
+ bound=Union[
102
+ BearerTokenCredentialPolicyType,
103
+ ARMChallengeAuthenticationPolicyType,
104
+ KeyCredentialPolicyType,
105
+ ],
106
+ )
107
+
108
+
109
+ class CredentialType(Generic[CredentialPolicyType], BaseType):
110
+ """Store info about the type of the credential. Can be either an KeyCredential or a TokenCredential"""
111
+
112
+ def __init__(
113
+ self,
114
+ yaml_data: Dict[str, Any],
115
+ code_model: "CodeModel",
116
+ policy: CredentialPolicyType,
117
+ ) -> None:
118
+ super().__init__(yaml_data, code_model)
119
+ self.policy = policy
120
+
121
+ def description(self, *, is_operation_file: bool) -> str:
122
+ return ""
123
+
124
+ def get_json_template_representation(
125
+ self,
126
+ *,
127
+ client_default_value_declaration: Optional[str] = None,
128
+ ) -> Any:
129
+ raise TypeError("You should not try to get a JSON template representation of a CredentialSchema")
130
+
131
+ def docstring_text(self, **kwargs: Any) -> str:
132
+ return "credential"
133
+
134
+ @property
135
+ def serialization_type(self) -> str:
136
+ return self.docstring_type()
137
+
138
+ @classmethod
139
+ def from_yaml(cls, yaml_data: Dict[str, Any], code_model: "CodeModel") -> "CredentialType":
140
+ from . import build_type
141
+
142
+ return cls(
143
+ yaml_data,
144
+ code_model,
145
+ policy=cast(CredentialPolicyType, build_type(yaml_data["policy"], code_model)),
146
+ )
147
+
148
+
149
+ class TokenCredentialType(CredentialType[Union[BearerTokenCredentialPolicyType, ARMChallengeAuthenticationPolicyType]]):
150
+ """Type of a token credential. Used by BearerAuth and ARMChallenge policies"""
151
+
152
+ def type_annotation(self, **kwargs: Any) -> str:
153
+ if kwargs.get("async_mode"):
154
+ return '"AsyncTokenCredential"'
155
+ return '"TokenCredential"'
156
+
157
+ @property
158
+ def type_description(self) -> str:
159
+ return "TokenCredential"
160
+
161
+ @property
162
+ def credentials_subfolder(self) -> str:
163
+ return "credentials_async" if self.code_model.is_azure_flavor else "credentials"
164
+
165
+ def docstring_type(self, **kwargs: Any) -> str:
166
+ if kwargs.get("async_mode"):
167
+ return f"~{self.code_model.core_library}.{self.credentials_subfolder}.AsyncTokenCredential"
168
+ return f"~{self.code_model.core_library}.credentials.TokenCredential"
169
+
170
+ def imports(self, **kwargs: Any) -> FileImport:
171
+ file_import = super().imports(**kwargs)
172
+ if kwargs.get("async_mode"):
173
+ file_import.add_submodule_import(
174
+ self.credentials_subfolder,
175
+ "AsyncTokenCredential",
176
+ ImportType.SDKCORE,
177
+ typing_section=TypingSection.TYPING,
178
+ )
179
+ else:
180
+ file_import.add_submodule_import(
181
+ "credentials",
182
+ "TokenCredential",
183
+ ImportType.SDKCORE,
184
+ typing_section=TypingSection.TYPING,
185
+ )
186
+ return file_import
187
+
188
+ @property
189
+ def instance_check_template(self) -> str:
190
+ return "hasattr({}, 'get_token')"
191
+
192
+
193
+ class KeyCredentialType(CredentialType[KeyCredentialPolicyType]):
194
+ """Type for an KeyCredential"""
195
+
196
+ def docstring_type(self, **kwargs: Any) -> str:
197
+ return f"~{self.code_model.core_library}.credentials.{self.policy.credential_name}"
198
+
199
+ def type_annotation(self, **kwargs: Any) -> str:
200
+ return self.policy.credential_name
201
+
202
+ @property
203
+ def instance_check_template(self) -> str:
204
+ return "isinstance({}, " + f"{self.policy.credential_name})"
205
+
206
+ def imports(self, **kwargs: Any) -> FileImport:
207
+ file_import = super().imports(**kwargs)
208
+ file_import.add_submodule_import(
209
+ "credentials",
210
+ self.policy.credential_name,
211
+ ImportType.SDKCORE,
212
+ typing_section=TypingSection.CONDITIONAL,
213
+ )
214
+ return file_import
@@ -0,0 +1,127 @@
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, List
7
+ from .base import BaseType
8
+ from .imports import FileImport, ImportType, TypingSection
9
+
10
+ if TYPE_CHECKING:
11
+ from .code_model import CodeModel
12
+ from .model_type import ModelType
13
+
14
+
15
+ class DictionaryType(BaseType):
16
+ """Schema for dictionaries that will be serialized.
17
+
18
+ :param yaml_data: the yaml data for this schema
19
+ :type yaml_data: dict[str, Any]
20
+ :param element_type: The type of the value for the dictionary
21
+ :type element_type: ~autorest.models.BaseType
22
+ """
23
+
24
+ def __init__(
25
+ self,
26
+ yaml_data: Dict[str, Any],
27
+ code_model: "CodeModel",
28
+ element_type: BaseType,
29
+ ) -> None:
30
+ super().__init__(yaml_data=yaml_data, code_model=code_model)
31
+ self.element_type = element_type
32
+
33
+ @property
34
+ def encode(self) -> Optional[str]:
35
+ return self.element_type.encode if hasattr(self.element_type, "encode") else None # type: ignore
36
+
37
+ @property
38
+ def serialization_type(self) -> str:
39
+ """Returns the serialization value for msrest.
40
+
41
+ :return: The serialization value for msrest
42
+ :rtype: str
43
+ """
44
+ return f"{{{self.element_type.serialization_type}}}"
45
+
46
+ def type_annotation(self, **kwargs: Any) -> str:
47
+ """The python type used for type annotation
48
+
49
+ :return: The type annotation for this schema
50
+ :rtype: str
51
+ """
52
+ return f"Dict[str, {self.element_type.type_annotation(**kwargs)}]"
53
+
54
+ def description(self, *, is_operation_file: bool) -> str:
55
+ return "" if is_operation_file else self.yaml_data.get("description", "")
56
+
57
+ def docstring_text(self, **kwargs: Any) -> str:
58
+ return f"dict mapping str to {self.element_type.docstring_text(**kwargs)}"
59
+
60
+ @property
61
+ def xml_serialization_ctxt(self) -> Optional[str]:
62
+ """No serialization ctxt for dictionaries"""
63
+ return None
64
+
65
+ def docstring_type(self, **kwargs: Any) -> str:
66
+ """The python type used for RST syntax input and type annotation.
67
+
68
+ :param str namespace: Optional. The namespace for the models.
69
+ """
70
+ return f"dict[str, {self.element_type.docstring_type(**kwargs)}]"
71
+
72
+ def get_json_template_representation(
73
+ self,
74
+ *,
75
+ client_default_value_declaration: Optional[str] = None,
76
+ ) -> Any:
77
+ return {
78
+ '"str"': self.element_type.get_json_template_representation(
79
+ client_default_value_declaration=client_default_value_declaration,
80
+ )
81
+ }
82
+
83
+ def get_polymorphic_subtypes(self, polymorphic_subtypes: List["ModelType"]) -> None:
84
+ from .model_type import ModelType
85
+
86
+ if isinstance(self.element_type, ModelType):
87
+ is_polymorphic_subtype = (
88
+ self.element_type.discriminator_value and not self.element_type.discriminated_subtypes
89
+ )
90
+ if self.element_type.name not in (m.name for m in polymorphic_subtypes) and is_polymorphic_subtype:
91
+ polymorphic_subtypes.append(self.element_type)
92
+
93
+ @classmethod
94
+ def from_yaml(cls, yaml_data: Dict[str, Any], code_model: "CodeModel") -> "DictionaryType":
95
+ """Constructs a DictionaryType from yaml data.
96
+
97
+ :param yaml_data: the yaml data from which we will construct this schema
98
+ :type yaml_data: dict[str, Any]
99
+
100
+ :return: A created DictionaryType
101
+ :rtype: ~autorest.models.DictionaryType
102
+ """
103
+ element_schema: Dict[str, Any] = yaml_data["elementType"]
104
+
105
+ from . import build_type # pylint: disable=import-outside-toplevel
106
+
107
+ element_type = build_type(yaml_data=element_schema, code_model=code_model)
108
+
109
+ return cls(
110
+ yaml_data=yaml_data,
111
+ code_model=code_model,
112
+ element_type=element_type,
113
+ )
114
+
115
+ def imports(self, **kwargs: Any) -> FileImport:
116
+ file_import = FileImport(self.code_model)
117
+ file_import.add_submodule_import("typing", "Dict", ImportType.STDLIB, TypingSection.CONDITIONAL)
118
+ file_import.merge(self.element_type.imports(**kwargs))
119
+ return file_import
120
+
121
+ @property
122
+ def instance_check_template(self) -> str:
123
+ return "isinstance({}, dict)"
124
+
125
+ @property
126
+ def type_description(self) -> str:
127
+ return f"{{str: {self.element_type.type_description}}}"