@typespec/http-client-python 0.4.4 → 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.
- package/dist/emitter/emitter.d.ts.map +1 -1
- package/dist/emitter/emitter.js +85 -24
- package/dist/emitter/emitter.js.map +1 -1
- package/dist/emitter/lib.d.ts +1 -0
- package/dist/emitter/lib.d.ts.map +1 -1
- package/dist/emitter/lib.js +1 -0
- package/dist/emitter/lib.js.map +1 -1
- package/dist/emitter/run-python3.d.ts +2 -0
- package/dist/emitter/run-python3.d.ts.map +1 -0
- package/dist/emitter/run-python3.js +19 -0
- package/dist/emitter/run-python3.js.map +1 -0
- package/dist/emitter/system-requirements.d.ts +17 -0
- package/dist/emitter/system-requirements.d.ts.map +1 -0
- package/dist/emitter/system-requirements.js +167 -0
- package/dist/emitter/system-requirements.js.map +1 -0
- package/emitter/src/emitter.ts +88 -23
- package/emitter/src/lib.ts +2 -0
- package/emitter/src/run-python3.ts +20 -0
- package/emitter/src/system-requirements.ts +261 -0
- package/emitter/temp/tsconfig.tsbuildinfo +1 -1
- package/eng/scripts/ci/regenerate.ts +16 -4
- package/eng/scripts/setup/__pycache__/venvtools.cpython-38.pyc +0 -0
- package/eng/scripts/setup/build.ts +16 -0
- package/eng/scripts/setup/build_pygen_wheel.py +40 -0
- package/eng/scripts/setup/install.py +9 -3
- package/eng/scripts/setup/install.ts +32 -0
- package/eng/scripts/setup/prepare.py +3 -1
- package/eng/scripts/setup/prepare.ts +11 -0
- package/eng/scripts/setup/run-python3.ts +1 -6
- package/generator/build/lib/pygen/__init__.py +107 -0
- package/generator/build/lib/pygen/_version.py +7 -0
- package/generator/build/lib/pygen/black.py +71 -0
- package/generator/build/lib/pygen/codegen/__init__.py +357 -0
- package/generator/build/lib/pygen/codegen/_utils.py +17 -0
- package/generator/build/lib/pygen/codegen/models/__init__.py +204 -0
- package/generator/build/lib/pygen/codegen/models/base.py +186 -0
- package/generator/build/lib/pygen/codegen/models/base_builder.py +118 -0
- package/generator/build/lib/pygen/codegen/models/client.py +435 -0
- package/generator/build/lib/pygen/codegen/models/code_model.py +237 -0
- package/generator/build/lib/pygen/codegen/models/combined_type.py +149 -0
- package/generator/build/lib/pygen/codegen/models/constant_type.py +129 -0
- package/generator/build/lib/pygen/codegen/models/credential_types.py +214 -0
- package/generator/build/lib/pygen/codegen/models/dictionary_type.py +127 -0
- package/generator/build/lib/pygen/codegen/models/enum_type.py +238 -0
- package/generator/build/lib/pygen/codegen/models/imports.py +291 -0
- package/generator/build/lib/pygen/codegen/models/list_type.py +143 -0
- package/generator/build/lib/pygen/codegen/models/lro_operation.py +142 -0
- package/generator/build/lib/pygen/codegen/models/lro_paging_operation.py +32 -0
- package/generator/build/lib/pygen/codegen/models/model_type.py +357 -0
- package/generator/build/lib/pygen/codegen/models/operation.py +509 -0
- package/generator/build/lib/pygen/codegen/models/operation_group.py +184 -0
- package/generator/build/lib/pygen/codegen/models/paging_operation.py +155 -0
- package/generator/build/lib/pygen/codegen/models/parameter.py +412 -0
- package/generator/build/lib/pygen/codegen/models/parameter_list.py +387 -0
- package/generator/build/lib/pygen/codegen/models/primitive_types.py +659 -0
- package/generator/build/lib/pygen/codegen/models/property.py +170 -0
- package/generator/build/lib/pygen/codegen/models/request_builder.py +189 -0
- package/generator/build/lib/pygen/codegen/models/request_builder_parameter.py +115 -0
- package/generator/build/lib/pygen/codegen/models/response.py +348 -0
- package/generator/build/lib/pygen/codegen/models/utils.py +21 -0
- package/generator/build/lib/pygen/codegen/serializers/__init__.py +574 -0
- package/generator/build/lib/pygen/codegen/serializers/base_serializer.py +21 -0
- package/generator/build/lib/pygen/codegen/serializers/builder_serializer.py +1533 -0
- package/generator/build/lib/pygen/codegen/serializers/client_serializer.py +294 -0
- package/generator/build/lib/pygen/codegen/serializers/enum_serializer.py +15 -0
- package/generator/build/lib/pygen/codegen/serializers/general_serializer.py +213 -0
- package/generator/build/lib/pygen/codegen/serializers/import_serializer.py +126 -0
- package/generator/build/lib/pygen/codegen/serializers/metadata_serializer.py +198 -0
- package/generator/build/lib/pygen/codegen/serializers/model_init_serializer.py +33 -0
- package/generator/build/lib/pygen/codegen/serializers/model_serializer.py +335 -0
- package/generator/build/lib/pygen/codegen/serializers/operation_groups_serializer.py +89 -0
- package/generator/build/lib/pygen/codegen/serializers/operations_init_serializer.py +44 -0
- package/generator/build/lib/pygen/codegen/serializers/parameter_serializer.py +221 -0
- package/generator/build/lib/pygen/codegen/serializers/patch_serializer.py +19 -0
- package/generator/build/lib/pygen/codegen/serializers/request_builders_serializer.py +52 -0
- package/generator/build/lib/pygen/codegen/serializers/sample_serializer.py +168 -0
- package/generator/build/lib/pygen/codegen/serializers/test_serializer.py +292 -0
- package/generator/build/lib/pygen/codegen/serializers/types_serializer.py +31 -0
- package/generator/build/lib/pygen/codegen/serializers/utils.py +68 -0
- package/generator/build/lib/pygen/codegen/templates/client.py.jinja2 +37 -0
- package/generator/build/lib/pygen/codegen/templates/client_container.py.jinja2 +12 -0
- package/generator/build/lib/pygen/codegen/templates/config.py.jinja2 +73 -0
- package/generator/build/lib/pygen/codegen/templates/config_container.py.jinja2 +16 -0
- package/generator/build/lib/pygen/codegen/templates/conftest.py.jinja2 +28 -0
- package/generator/build/lib/pygen/codegen/templates/enum.py.jinja2 +13 -0
- package/generator/build/lib/pygen/codegen/templates/enum_container.py.jinja2 +10 -0
- package/generator/build/lib/pygen/codegen/templates/init.py.jinja2 +24 -0
- package/generator/build/lib/pygen/codegen/templates/keywords.jinja2 +27 -0
- package/generator/build/lib/pygen/codegen/templates/lro_operation.py.jinja2 +16 -0
- package/generator/build/lib/pygen/codegen/templates/lro_paging_operation.py.jinja2 +18 -0
- package/generator/build/lib/pygen/codegen/templates/macros.jinja2 +12 -0
- package/generator/build/lib/pygen/codegen/templates/metadata.json.jinja2 +167 -0
- package/generator/build/lib/pygen/codegen/templates/model_base.py.jinja2 +1174 -0
- package/generator/build/lib/pygen/codegen/templates/model_container.py.jinja2 +15 -0
- package/generator/build/lib/pygen/codegen/templates/model_dpg.py.jinja2 +97 -0
- package/generator/build/lib/pygen/codegen/templates/model_init.py.jinja2 +33 -0
- package/generator/build/lib/pygen/codegen/templates/model_msrest.py.jinja2 +92 -0
- package/generator/build/lib/pygen/codegen/templates/operation.py.jinja2 +21 -0
- package/generator/build/lib/pygen/codegen/templates/operation_group.py.jinja2 +75 -0
- package/generator/build/lib/pygen/codegen/templates/operation_groups_container.py.jinja2 +19 -0
- package/generator/build/lib/pygen/codegen/templates/operation_tools.jinja2 +81 -0
- package/generator/build/lib/pygen/codegen/templates/operations_folder_init.py.jinja2 +17 -0
- package/generator/build/lib/pygen/codegen/templates/packaging_templates/CHANGELOG.md.jinja2 +6 -0
- package/generator/build/lib/pygen/codegen/templates/packaging_templates/LICENSE.jinja2 +21 -0
- package/generator/build/lib/pygen/codegen/templates/packaging_templates/MANIFEST.in.jinja2 +8 -0
- package/generator/build/lib/pygen/codegen/templates/packaging_templates/README.md.jinja2 +107 -0
- package/generator/build/lib/pygen/codegen/templates/packaging_templates/dev_requirements.txt.jinja2 +9 -0
- package/generator/build/lib/pygen/codegen/templates/packaging_templates/setup.py.jinja2 +108 -0
- package/generator/build/lib/pygen/codegen/templates/paging_operation.py.jinja2 +21 -0
- package/generator/build/lib/pygen/codegen/templates/patch.py.jinja2 +19 -0
- package/generator/build/lib/pygen/codegen/templates/pkgutil_init.py.jinja2 +1 -0
- package/generator/build/lib/pygen/codegen/templates/request_builder.py.jinja2 +28 -0
- package/generator/build/lib/pygen/codegen/templates/request_builders.py.jinja2 +10 -0
- package/generator/build/lib/pygen/codegen/templates/rest_init.py.jinja2 +12 -0
- package/generator/build/lib/pygen/codegen/templates/sample.py.jinja2 +44 -0
- package/generator/build/lib/pygen/codegen/templates/serialization.py.jinja2 +2117 -0
- package/generator/build/lib/pygen/codegen/templates/test.py.jinja2 +50 -0
- package/generator/build/lib/pygen/codegen/templates/testpreparer.py.jinja2 +26 -0
- package/generator/build/lib/pygen/codegen/templates/types.py.jinja2 +7 -0
- package/generator/build/lib/pygen/codegen/templates/validation.py.jinja2 +38 -0
- package/generator/build/lib/pygen/codegen/templates/vendor.py.jinja2 +96 -0
- package/generator/build/lib/pygen/codegen/templates/version.py.jinja2 +4 -0
- package/generator/build/lib/pygen/m2r.py +65 -0
- package/generator/build/lib/pygen/preprocess/__init__.py +515 -0
- package/generator/build/lib/pygen/preprocess/helpers.py +27 -0
- package/generator/build/lib/pygen/preprocess/python_mappings.py +226 -0
- package/generator/build/lib/pygen/utils.py +163 -0
- package/generator/component-detection-pip-report.json +134 -0
- package/generator/dev_requirements.txt +0 -1
- package/generator/dist/pygen-0.1.0-py3-none-any.whl +0 -0
- package/generator/pygen.egg-info/PKG-INFO +7 -4
- package/generator/pygen.egg-info/requires.txt +7 -4
- package/generator/requirements.txt +5 -10
- package/generator/setup.py +7 -4
- package/generator/test/azure/requirements.txt +1 -1
- package/generator/test/unbranded/requirements.txt +1 -1
- 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}}}"
|