@autorest/python 5.15.0 → 5.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ChangeLog.md +20 -0
- package/autorest/__init__.py +1 -2
- package/autorest/black/__init__.py +12 -5
- package/autorest/codegen/__init__.py +145 -73
- package/autorest/codegen/models/__init__.py +29 -18
- package/autorest/codegen/models/base_builder.py +48 -11
- package/autorest/codegen/models/base_model.py +6 -4
- package/autorest/codegen/models/base_schema.py +19 -18
- package/autorest/codegen/models/client.py +65 -21
- package/autorest/codegen/models/code_model.py +107 -61
- package/autorest/codegen/models/constant_schema.py +25 -13
- package/autorest/codegen/models/credential_model.py +23 -15
- package/autorest/codegen/models/credential_schema.py +18 -14
- package/autorest/codegen/models/credential_schema_policy.py +11 -15
- package/autorest/codegen/models/dictionary_schema.py +20 -17
- package/autorest/codegen/models/enum_schema.py +35 -25
- package/autorest/codegen/models/imports.py +70 -41
- package/autorest/codegen/models/list_schema.py +25 -13
- package/autorest/codegen/models/lro_operation.py +58 -22
- package/autorest/codegen/models/lro_paging_operation.py +2 -3
- package/autorest/codegen/models/object_schema.py +99 -49
- package/autorest/codegen/models/operation.py +236 -117
- package/autorest/codegen/models/operation_group.py +64 -34
- package/autorest/codegen/models/paging_operation.py +45 -18
- package/autorest/codegen/models/parameter.py +151 -83
- package/autorest/codegen/models/parameter_list.py +183 -162
- package/autorest/codegen/models/primitive_schemas.py +84 -55
- package/autorest/codegen/models/property.py +44 -26
- package/autorest/codegen/models/request_builder.py +65 -30
- package/autorest/codegen/models/request_builder_parameter.py +47 -23
- package/autorest/codegen/models/request_builder_parameter_list.py +77 -108
- package/autorest/codegen/models/schema_request.py +16 -6
- package/autorest/codegen/models/schema_response.py +18 -13
- package/autorest/codegen/models/utils.py +5 -2
- package/autorest/codegen/serializers/__init__.py +182 -91
- package/autorest/codegen/serializers/builder_serializer.py +667 -331
- package/autorest/codegen/serializers/client_serializer.py +98 -37
- package/autorest/codegen/serializers/general_serializer.py +61 -26
- package/autorest/codegen/serializers/import_serializer.py +93 -31
- package/autorest/codegen/serializers/metadata_serializer.py +73 -24
- package/autorest/codegen/serializers/model_base_serializer.py +35 -15
- package/autorest/codegen/serializers/model_generic_serializer.py +1 -4
- package/autorest/codegen/serializers/model_init_serializer.py +5 -1
- package/autorest/codegen/serializers/model_python3_serializer.py +7 -6
- package/autorest/codegen/serializers/operation_groups_serializer.py +20 -9
- package/autorest/codegen/serializers/operations_init_serializer.py +23 -11
- package/autorest/codegen/serializers/patch_serializer.py +4 -1
- package/autorest/codegen/serializers/{rest_serializer.py → request_builders_serializer.py} +29 -12
- package/autorest/codegen/serializers/utils.py +35 -21
- package/autorest/codegen/templates/init.py.jinja2 +2 -2
- package/autorest/codegen/templates/lro_operation.py.jinja2 +5 -7
- package/autorest/codegen/templates/lro_paging_operation.py.jinja2 +5 -7
- package/autorest/codegen/templates/metadata.json.jinja2 +7 -6
- package/autorest/codegen/templates/operation.py.jinja2 +7 -9
- package/autorest/codegen/templates/operation_group.py.jinja2 +2 -8
- package/autorest/codegen/templates/operation_groups_container.py.jinja2 +1 -1
- package/autorest/codegen/templates/paging_operation.py.jinja2 +7 -8
- package/autorest/codegen/templates/request_builder.py.jinja2 +18 -11
- package/autorest/jsonrpc/__init__.py +7 -12
- package/autorest/jsonrpc/localapi.py +4 -3
- package/autorest/jsonrpc/server.py +13 -6
- package/autorest/jsonrpc/stdstream.py +13 -6
- package/autorest/m2r/__init__.py +5 -8
- package/autorest/multiapi/__init__.py +24 -14
- package/autorest/multiapi/models/client.py +21 -11
- package/autorest/multiapi/models/code_model.py +23 -10
- package/autorest/multiapi/models/config.py +4 -1
- package/autorest/multiapi/models/constant_global_parameter.py +1 -0
- package/autorest/multiapi/models/global_parameter.py +2 -1
- package/autorest/multiapi/models/global_parameters.py +14 -8
- package/autorest/multiapi/models/imports.py +24 -17
- package/autorest/multiapi/models/mixin_operation.py +5 -5
- package/autorest/multiapi/models/operation_group.py +2 -1
- package/autorest/multiapi/models/operation_mixin_group.py +21 -10
- package/autorest/multiapi/serializers/__init__.py +18 -23
- package/autorest/multiapi/serializers/import_serializer.py +47 -17
- package/autorest/multiapi/serializers/multiapi_serializer.py +17 -17
- package/autorest/multiapi/templates/multiapi_operations_mixin.py.jinja2 +1 -1
- package/autorest/multiapi/utils.py +3 -3
- package/autorest/namer/__init__.py +2 -4
- package/autorest/namer/name_converter.py +200 -103
- package/autorest/namer/python_mappings.py +10 -22
- package/package.json +2 -2
- package/run-python3.js +2 -3
- package/venvtools.py +1 -1
- package/autorest/codegen/models/rest.py +0 -42
|
@@ -23,13 +23,11 @@ def serialize_method(
|
|
|
23
23
|
lines.append(first_line)
|
|
24
24
|
if is_in_class:
|
|
25
25
|
lines.append(" self,")
|
|
26
|
-
lines.extend([
|
|
27
|
-
(" " + line)
|
|
28
|
-
for line in method_param_signatures
|
|
29
|
-
])
|
|
26
|
+
lines.extend([(" " + line) for line in method_param_signatures])
|
|
30
27
|
lines.append(")")
|
|
31
28
|
return "\n".join(lines)
|
|
32
29
|
|
|
30
|
+
|
|
33
31
|
def build_serialize_data_call(
|
|
34
32
|
parameter: Parameter, function_name: str, serializer_name: str
|
|
35
33
|
) -> str:
|
|
@@ -69,30 +67,32 @@ def build_serialize_data_call(
|
|
|
69
67
|
f'"{origin_name.lstrip("_")}"',
|
|
70
68
|
"q" if parameter.explode else origin_name,
|
|
71
69
|
f"'{serialization_schema.serialization_type}'",
|
|
72
|
-
*optional_parameters
|
|
70
|
+
*optional_parameters,
|
|
73
71
|
]
|
|
74
|
-
parameters_line =
|
|
72
|
+
parameters_line = ", ".join(parameters)
|
|
75
73
|
|
|
76
|
-
serialize_line = f
|
|
74
|
+
serialize_line = f"{serializer_name}.{function_name}({parameters_line})"
|
|
77
75
|
|
|
78
76
|
if parameter.explode:
|
|
79
77
|
return f"[{serialize_line} if q is not None else '' for q in {origin_name}]"
|
|
80
78
|
return serialize_line
|
|
81
79
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
) -> List[str]:
|
|
80
|
+
|
|
81
|
+
def serialize_path(parameters: List[Parameter], serializer_name: str) -> List[str]:
|
|
85
82
|
retval = ["path_format_arguments = {"]
|
|
86
|
-
retval.extend(
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
83
|
+
retval.extend(
|
|
84
|
+
[
|
|
85
|
+
' "{}": {},'.format(
|
|
86
|
+
path_parameter.rest_api_name,
|
|
87
|
+
build_serialize_data_call(path_parameter, "url", serializer_name),
|
|
88
|
+
)
|
|
89
|
+
for path_parameter in parameters
|
|
90
|
+
]
|
|
91
|
+
)
|
|
93
92
|
retval.append("}")
|
|
94
93
|
return retval
|
|
95
94
|
|
|
95
|
+
|
|
96
96
|
def method_signature_and_response_type_annotation_template(
|
|
97
97
|
*,
|
|
98
98
|
is_python3_file: bool,
|
|
@@ -103,11 +103,13 @@ def method_signature_and_response_type_annotation_template(
|
|
|
103
103
|
return f"{method_signature} -> {response_type_annotation}:"
|
|
104
104
|
return f"{method_signature}:\n # type: (...) -> {response_type_annotation}"
|
|
105
105
|
|
|
106
|
+
|
|
106
107
|
class PopKwargType(Enum):
|
|
107
108
|
NO = auto()
|
|
108
109
|
SIMPLE = auto()
|
|
109
110
|
CASE_INSENSITIVE = auto()
|
|
110
111
|
|
|
112
|
+
|
|
111
113
|
def pop_kwargs_from_signature(
|
|
112
114
|
kwargs_to_pop: List[Parameter],
|
|
113
115
|
check_kwarg_dict: bool,
|
|
@@ -115,11 +117,15 @@ def pop_kwargs_from_signature(
|
|
|
115
117
|
pop_params_kwarg: PopKwargType,
|
|
116
118
|
) -> List[str]:
|
|
117
119
|
retval = []
|
|
120
|
+
|
|
118
121
|
def append_pop_kwarg(key: str, pop_type: PopKwargType) -> None:
|
|
119
122
|
if PopKwargType.CASE_INSENSITIVE == pop_type:
|
|
120
|
-
retval.append(
|
|
123
|
+
retval.append(
|
|
124
|
+
f'_{key} = case_insensitive_dict(kwargs.pop("{key}", {{}}) or {{}})'
|
|
125
|
+
)
|
|
121
126
|
elif PopKwargType.SIMPLE == pop_type:
|
|
122
127
|
retval.append(f'_{key} = kwargs.pop("{key}", {{}}) or {{}}')
|
|
128
|
+
|
|
123
129
|
append_pop_kwarg("headers", pop_headers_kwarg)
|
|
124
130
|
append_pop_kwarg("params", pop_params_kwarg)
|
|
125
131
|
if pop_headers_kwarg != PopKwargType.NO or pop_params_kwarg != PopKwargType.NO:
|
|
@@ -127,9 +133,17 @@ def pop_kwargs_from_signature(
|
|
|
127
133
|
for kwarg in kwargs_to_pop:
|
|
128
134
|
if kwarg.has_default_value:
|
|
129
135
|
default_value = kwarg.default_value_declaration
|
|
130
|
-
if check_kwarg_dict and (
|
|
131
|
-
|
|
132
|
-
|
|
136
|
+
if check_kwarg_dict and (
|
|
137
|
+
kwarg.location in [ParameterLocation.Header, ParameterLocation.Query]
|
|
138
|
+
):
|
|
139
|
+
kwarg_dict = (
|
|
140
|
+
"headers"
|
|
141
|
+
if kwarg.location == ParameterLocation.Header
|
|
142
|
+
else "params"
|
|
143
|
+
)
|
|
144
|
+
default_value = (
|
|
145
|
+
f"_{kwarg_dict}.pop('{kwarg.rest_api_name}', {default_value})"
|
|
146
|
+
)
|
|
133
147
|
retval.append(
|
|
134
148
|
f"{kwarg.serialized_name} = kwargs.pop('{kwarg.serialized_name}', "
|
|
135
149
|
+ f"{default_value}) # type: {kwarg.type_annotation(is_operation_file=True)}"
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
# coding=utf-8
|
|
3
3
|
{{ code_model.options['license_header'] }}
|
|
4
4
|
|
|
5
|
-
{% if code_model.
|
|
5
|
+
{% if code_model.request_builders %}
|
|
6
6
|
from .{{ code_model.service_client.filename }} import {{ code_model.class_name }}
|
|
7
7
|
{% endif %}
|
|
8
8
|
{% if not async_mode and code_model.options['package_version']%}
|
|
@@ -12,7 +12,7 @@ __version__ = VERSION
|
|
|
12
12
|
{% endif %}
|
|
13
13
|
|
|
14
14
|
{{ keywords.patch_imports(try_except=True) }}
|
|
15
|
-
__all__ = [{{("'" + code_model.class_name + "'") if code_model.
|
|
15
|
+
__all__ = [{{("'" + code_model.class_name + "'") if code_model.request_builders else ""}}]
|
|
16
16
|
{{ keywords.extend_all }}
|
|
17
17
|
|
|
18
18
|
_patch_sdk()
|
|
@@ -1,18 +1,16 @@
|
|
|
1
1
|
{% import 'operation_tools.jinja2' as op_tools with context %}
|
|
2
|
-
{% set trace_decorator = "@distributed_trace_async" if async_mode else "@distributed_trace" %}
|
|
3
2
|
{# actual template starts here #}
|
|
4
|
-
{
|
|
5
|
-
{{ trace_decorator }}
|
|
6
|
-
{% endif %}
|
|
7
|
-
{{ operation_serializer.method_signature_and_response_type_annotation(operation) }}
|
|
3
|
+
{{ operation_serializer.method_signature_and_response_type_annotation(operation, async_mode) }}
|
|
8
4
|
{{ op_tools.description(operation, operation_serializer) | indent -}}
|
|
9
|
-
{% if
|
|
5
|
+
{% if not operation.abstract %}
|
|
6
|
+
{% if operation_serializer.pop_kwargs_from_signature(operation) %}
|
|
10
7
|
{{ op_tools.serialize(operation_serializer.pop_kwargs_from_signature(operation)) | indent }}
|
|
11
|
-
|
|
8
|
+
{%- endif %}
|
|
12
9
|
{{ op_tools.serialize(operation_serializer.initial_call(operation)) | indent }}
|
|
13
10
|
{{ op_tools.serialize(operation_serializer.get_long_running_output(operation)) | indent }}
|
|
14
11
|
|
|
15
12
|
{{ op_tools.serialize(operation_serializer.return_lro_poller(operation)) | indent }}
|
|
13
|
+
{% endif %}
|
|
16
14
|
{% if not code_model.options["version_tolerant"] %}
|
|
17
15
|
{{ operation_serializer.get_metadata_url(operation) -}}
|
|
18
16
|
{% endif %}
|
|
@@ -1,20 +1,18 @@
|
|
|
1
1
|
{% import 'operation_tools.jinja2' as op_tools with context %}
|
|
2
2
|
{% import 'keywords.jinja2' as keywords with context %}
|
|
3
|
-
{% set trace_decorator = "@distributed_trace_async" if async_mode else "@distributed_trace" %}
|
|
4
3
|
{# actual template starts here #}
|
|
5
|
-
{
|
|
6
|
-
{{ trace_decorator }}
|
|
7
|
-
{% endif %}
|
|
8
|
-
{{ operation_serializer.method_signature_and_response_type_annotation(operation) }}
|
|
4
|
+
{{ operation_serializer.method_signature_and_response_type_annotation(operation, async_mode) }}
|
|
9
5
|
{{ op_tools.description(operation, operation_serializer) | indent }}
|
|
10
|
-
{% if
|
|
6
|
+
{% if not operation.abstract %}
|
|
7
|
+
{% if operation_serializer.pop_kwargs_from_signature(operation) %}
|
|
11
8
|
{{ op_tools.serialize(operation_serializer.pop_kwargs_from_signature(operation)) | indent }}
|
|
12
|
-
|
|
9
|
+
{% endif %}
|
|
13
10
|
{{ op_tools.serialize(operation_serializer.set_up_params_for_pager(operation)) | indent }}
|
|
14
11
|
|
|
15
12
|
{{ op_tools.serialize(operation_serializer.initial_call(operation)) | indent }}
|
|
16
13
|
{{ op_tools.serialize(operation_serializer.get_long_running_output(operation)) | indent }}
|
|
17
14
|
{{ op_tools.serialize(operation_serializer.return_lro_poller(operation)) | indent }}
|
|
15
|
+
{% endif %}
|
|
18
16
|
{% if not code_model.options["version_tolerant"] %}
|
|
19
17
|
{{ operation_serializer.get_metadata_url(operation) }}
|
|
20
18
|
{% endif %}
|
|
@@ -126,8 +126,9 @@
|
|
|
126
126
|
{% from "operation.py.jinja2" import operation_docstring with context %}
|
|
127
127
|
{% set sync_return_type_wrapper = "" %}
|
|
128
128
|
{% endif %}
|
|
129
|
-
"signature": {{ (operation_serializer.method_signature_and_response_type_annotation(operation) + "\n") | tojson }},
|
|
130
|
-
"doc": {{ op_tools.description(operation, operation_serializer).rstrip("\n") | tojson }}
|
|
129
|
+
"signature": {{ (operation_serializer.method_signature_and_response_type_annotation(operation, False, want_decorators=False) + "\n") | tojson }},
|
|
130
|
+
"doc": {{ op_tools.description(operation, operation_serializer).rstrip("\n") | tojson }},
|
|
131
|
+
"call": {{ operation.parameters.call(is_python3_file=False) | join(', ') | tojson }}
|
|
131
132
|
},
|
|
132
133
|
"async": {
|
|
133
134
|
{% set coroutine = False if (is_paging(operation) and not is_lro(operation)) else True %}
|
|
@@ -146,10 +147,10 @@
|
|
|
146
147
|
{% from "operation.py.jinja2" import operation_docstring with context %}
|
|
147
148
|
{% set async_return_type_wrapper = "" %}
|
|
148
149
|
{% endif %}
|
|
149
|
-
"signature": {{ (operation_serializer.method_signature_and_response_type_annotation(operation) + "\n") | tojson }},
|
|
150
|
-
"doc": {{ op_tools.description(operation, operation_serializer).rstrip("\n") | tojson }}
|
|
151
|
-
|
|
152
|
-
|
|
150
|
+
"signature": {{ (operation_serializer.method_signature_and_response_type_annotation(operation, True, want_decorators=False) + "\n") | tojson }},
|
|
151
|
+
"doc": {{ op_tools.description(operation, operation_serializer).rstrip("\n") | tojson }},
|
|
152
|
+
"call": {{ operation.parameters.call(is_python3_file=True) | join(', ') | tojson }}
|
|
153
|
+
}
|
|
153
154
|
}{{ "," if not loop.last else "" }}
|
|
154
155
|
{% endfor %}
|
|
155
156
|
}
|
|
@@ -1,21 +1,18 @@
|
|
|
1
1
|
{% import 'keywords.jinja2' as keywords with context %}
|
|
2
2
|
{% import 'operation_tools.jinja2' as op_tools %}
|
|
3
|
-
{% set trace_decorator = "@distributed_trace_async" if async_mode else "@distributed_trace" %}
|
|
4
3
|
{% set stream_request_parameter = "stream=" ~ ("True" if operation.is_stream_response else "False") %}
|
|
5
4
|
{# actual template starts here #}
|
|
6
|
-
{
|
|
7
|
-
{{ trace_decorator }}
|
|
8
|
-
{% endif %}
|
|
9
|
-
{{ operation_serializer.method_signature_and_response_type_annotation(operation) }}
|
|
5
|
+
{{ operation_serializer.method_signature_and_response_type_annotation(operation, async_mode) }}
|
|
10
6
|
{% if operation.want_description_docstring %}
|
|
11
7
|
{{ op_tools.description(operation, operation_serializer) | indent }}{% endif %}
|
|
12
|
-
{% if operation.
|
|
8
|
+
{% if not operation.abstract %}
|
|
9
|
+
{% if operation.deprecated %}
|
|
13
10
|
warnings.warn('Method {{operation.name}} is deprecated', DeprecationWarning)
|
|
14
|
-
{% endif %}
|
|
11
|
+
{% endif %}
|
|
15
12
|
{{ op_tools.serialize(operation_serializer.error_map(operation)) | indent }}
|
|
16
|
-
|
|
13
|
+
{% if operation_serializer.pop_kwargs_from_signature(operation) %}
|
|
17
14
|
{{ op_tools.serialize(operation_serializer.pop_kwargs_from_signature(operation)) | indent }}
|
|
18
|
-
|
|
15
|
+
{% endif %}
|
|
19
16
|
{{ op_tools.serialize(operation_serializer.call_request_builder(operation)) | indent }}
|
|
20
17
|
pipeline_response = {{ keywords.await }}self._client._pipeline.run( # type: ignore # pylint: disable=protected-access
|
|
21
18
|
request,
|
|
@@ -23,6 +20,7 @@
|
|
|
23
20
|
**kwargs
|
|
24
21
|
)
|
|
25
22
|
{{ op_tools.serialize(operation_serializer.handle_response(operation)) | indent }}
|
|
23
|
+
{% endif %}
|
|
26
24
|
{% if not code_model.options["version_tolerant"] %}
|
|
27
25
|
{{ operation_serializer.get_metadata_url(operation) }}
|
|
28
26
|
{% endif %}
|
|
@@ -1,12 +1,6 @@
|
|
|
1
1
|
{% set disable = " # pylint: disable=too-many-public-methods" if operation_group.operations | length > 20 else "" %}
|
|
2
|
-
{%
|
|
3
|
-
|
|
4
|
-
{% elif not (async_mode or code_model.options["python3_only"]) %}
|
|
5
|
-
{% set object_base_class = "(object)" %}
|
|
6
|
-
{% else %}
|
|
7
|
-
{% set object_base_class = "" %}
|
|
8
|
-
{% endif %}
|
|
9
|
-
class {{ operation_group.class_name }}{{ object_base_class }}:{{ disable }}
|
|
2
|
+
{% set base_class = ("(" + operation_group.base_class(async_mode) + ")") if operation_group.base_class(async_mode) else "" %}
|
|
3
|
+
class {{ operation_group.class_name }}{{ base_class }}:{{ disable }}
|
|
10
4
|
{% if not operation_group.is_empty_operation_group %}
|
|
11
5
|
"""
|
|
12
6
|
.. warning::
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
# fmt: off
|
|
13
13
|
{% endif %}
|
|
14
14
|
{% for operation_group in operation_groups %}
|
|
15
|
-
{% for request_builder in code_model.
|
|
15
|
+
{% for request_builder in code_model.request_builders | selectattr("operation_group_name", "equalto", operation_group.name) %}
|
|
16
16
|
|
|
17
17
|
{% include "request_builder.py.jinja2" %}
|
|
18
18
|
{% endfor %}
|
|
@@ -1,22 +1,21 @@
|
|
|
1
1
|
{% import 'operation_tools.jinja2' as op_tools with context %}
|
|
2
2
|
{# actual template starts here #}
|
|
3
|
-
{
|
|
4
|
-
@distributed_trace
|
|
5
|
-
{% endif %}
|
|
6
|
-
{{ operation_serializer.method_signature_and_response_type_annotation(operation) }}
|
|
3
|
+
{{ operation_serializer.method_signature_and_response_type_annotation(operation, async_mode) }}
|
|
7
4
|
{% if operation.want_description_docstring %}
|
|
8
5
|
{{ op_tools.description(operation, operation_serializer) | indent }}{% endif %}
|
|
9
|
-
{% if operation.
|
|
6
|
+
{% if not operation.abstract %}
|
|
7
|
+
{% if operation.deprecated %}
|
|
10
8
|
warnings.warn('Method {{operation.name}} is deprecated', DeprecationWarning)
|
|
11
|
-
{% endif %}
|
|
12
|
-
|
|
9
|
+
{% endif %}
|
|
10
|
+
{% if operation_serializer.pop_kwargs_from_signature(operation) %}
|
|
13
11
|
{{ op_tools.serialize(operation_serializer.pop_kwargs_from_signature(operation)) | indent }}
|
|
14
|
-
|
|
12
|
+
{% endif %}
|
|
15
13
|
{{ op_tools.serialize(operation_serializer.set_up_params_for_pager(operation)) | indent }}
|
|
16
14
|
|
|
17
15
|
return {{ operation.get_pager(async_mode) }}(
|
|
18
16
|
get_next, extract_data
|
|
19
17
|
)
|
|
18
|
+
{% endif %}
|
|
20
19
|
{% if not code_model.options["version_tolerant"] %}
|
|
21
20
|
{{ operation_serializer.get_metadata_url(operation) -}}
|
|
22
21
|
{% endif %}
|
|
@@ -1,26 +1,33 @@
|
|
|
1
1
|
{% import 'keywords.jinja2' as keywords with context %}
|
|
2
2
|
{% import 'operation_tools.jinja2' as op_tools with context %}
|
|
3
|
-
{{ request_builder_serializer.method_signature_and_response_type_annotation(request_builder) }}
|
|
3
|
+
{{ request_builder_serializer.method_signature_and_response_type_annotation(request_builder, False) }}
|
|
4
4
|
{% if code_model.options["builders_visibility"] == "public" %}
|
|
5
5
|
{{ op_tools.description(request_builder, request_builder_serializer) | indent }}
|
|
6
6
|
{% endif %}
|
|
7
|
-
{% if
|
|
7
|
+
{% if request_builder.abstract %}
|
|
8
|
+
raise NotImplementedError(
|
|
9
|
+
"You need to write a custom operation for '{{ request_builder.name }}'. "
|
|
10
|
+
"Please refer to https://aka.ms/azsdk/python/dpcodegen/python/customize to learn how to customize."
|
|
11
|
+
)
|
|
12
|
+
{% else %}
|
|
13
|
+
{% if request_builder_serializer.pop_kwargs_from_signature(request_builder) %}
|
|
8
14
|
{{ op_tools.serialize(request_builder_serializer.pop_kwargs_from_signature(request_builder)) | indent }}
|
|
9
|
-
{%- endif -%}
|
|
10
|
-
{% if request_builder_serializer.declare_non_inputtable_constants(request_builder) %}
|
|
15
|
+
{%- endif -%}
|
|
16
|
+
{% if request_builder_serializer.declare_non_inputtable_constants(request_builder) %}
|
|
11
17
|
{{ op_tools.serialize(request_builder_serializer.declare_non_inputtable_constants(request_builder)) | indent }}
|
|
12
|
-
{% endif %}
|
|
18
|
+
{% endif %}
|
|
13
19
|
# Construct URL
|
|
14
20
|
{{ request_builder_serializer.construct_url(request_builder) }}
|
|
15
|
-
{% if request_builder.parameters.path %}
|
|
21
|
+
{% if request_builder.parameters.path %}
|
|
16
22
|
{{ op_tools.serialize(request_builder_serializer.serialize_path(request_builder)) | indent }}
|
|
17
23
|
_url = _format_url_section(_url, **path_format_arguments)
|
|
18
|
-
{% endif %}
|
|
24
|
+
{% endif %}
|
|
19
25
|
|
|
20
|
-
{% if request_builder.parameters.query %}
|
|
26
|
+
{% if request_builder.parameters.query %}
|
|
21
27
|
{{ op_tools.serialize(request_builder_serializer.serialize_query(request_builder)) | indent }}
|
|
22
|
-
{% endif %}
|
|
23
|
-
{% if request_builder.parameters.headers %}
|
|
28
|
+
{% endif %}
|
|
29
|
+
{% if request_builder.parameters.headers %}
|
|
24
30
|
{{ op_tools.serialize(request_builder_serializer.serialize_headers(request_builder)) | indent }}
|
|
25
|
-
{% endif %}
|
|
31
|
+
{% endif %}
|
|
26
32
|
{{ op_tools.serialize(request_builder_serializer.create_http_request(request_builder)) | indent }}
|
|
33
|
+
{% endif %}
|
|
@@ -7,7 +7,7 @@ from abc import ABC, abstractmethod
|
|
|
7
7
|
from enum import Enum
|
|
8
8
|
from typing import Any, List, Optional, Union
|
|
9
9
|
import logging
|
|
10
|
-
import logging.config
|
|
10
|
+
import logging.config # need to include this extra import so mypy doesn't throw logging module has no config
|
|
11
11
|
from pathlib import Path
|
|
12
12
|
|
|
13
13
|
|
|
@@ -45,13 +45,12 @@ class AutorestHandler(logging.Handler):
|
|
|
45
45
|
# Initialize this handler with the max loglevel, since
|
|
46
46
|
# autorest is deciding what to show, not us
|
|
47
47
|
# so we want to log everything and let autorest filters.
|
|
48
|
-
super(
|
|
48
|
+
super().__init__(logging.DEBUG)
|
|
49
49
|
self._autorest_api = autorest_api
|
|
50
50
|
|
|
51
51
|
@staticmethod
|
|
52
52
|
def _get_log_level(level: int) -> Channel:
|
|
53
|
-
"""Convert Python log levels to Autorest Channel.
|
|
54
|
-
"""
|
|
53
|
+
"""Convert Python log levels to Autorest Channel."""
|
|
55
54
|
return _LEVEL_MAPPING.get(level, Channel.Warning)
|
|
56
55
|
|
|
57
56
|
def emit(self, record: logging.LogRecord) -> None:
|
|
@@ -65,8 +64,7 @@ class AutorestHandler(logging.Handler):
|
|
|
65
64
|
|
|
66
65
|
|
|
67
66
|
class AutorestAPI(ABC):
|
|
68
|
-
"""Defines the base interface of communication to Autorest from the plugin.
|
|
69
|
-
"""
|
|
67
|
+
"""Defines the base interface of communication to Autorest from the plugin."""
|
|
70
68
|
|
|
71
69
|
def __init__(self) -> None:
|
|
72
70
|
if Path("logging.conf").exists():
|
|
@@ -106,18 +104,15 @@ class AutorestAPI(ABC):
|
|
|
106
104
|
|
|
107
105
|
@abstractmethod
|
|
108
106
|
def list_inputs(self) -> List[str]:
|
|
109
|
-
"""List possible inputs for this plugin.
|
|
110
|
-
"""
|
|
107
|
+
"""List possible inputs for this plugin."""
|
|
111
108
|
|
|
112
109
|
@abstractmethod
|
|
113
110
|
def get_value(self, key: str) -> Any:
|
|
114
|
-
"""Get a value from configuration.
|
|
115
|
-
"""
|
|
111
|
+
"""Get a value from configuration."""
|
|
116
112
|
|
|
117
113
|
@abstractmethod
|
|
118
114
|
def message(self, channel: Channel, text: str) -> None:
|
|
119
|
-
"""Send a log message to autorest.
|
|
120
|
-
"""
|
|
115
|
+
"""Send a log message to autorest."""
|
|
121
116
|
|
|
122
117
|
def get_boolean_value(self, key: str, default: bool = None) -> Optional[bool]:
|
|
123
118
|
"""Check if value is present on the line, and interpret it as bool if it was.
|
|
@@ -14,10 +14,11 @@ _LOGGER = logging.getLogger(__name__)
|
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
class LocalAutorestAPI(AutorestAPI):
|
|
17
|
-
"""A local API that will write on local disk.
|
|
18
|
-
"""
|
|
17
|
+
"""A local API that will write on local disk."""
|
|
19
18
|
|
|
20
|
-
def __init__(
|
|
19
|
+
def __init__(
|
|
20
|
+
self, reachable_files: List[str] = None, output_folder: str = "generated"
|
|
21
|
+
) -> None:
|
|
21
22
|
super().__init__()
|
|
22
23
|
if reachable_files is None:
|
|
23
24
|
reachable_files = []
|
|
@@ -24,13 +24,16 @@ def GetPluginNames():
|
|
|
24
24
|
@dispatcher.add_method
|
|
25
25
|
def Process(plugin_name: str, session_id: str) -> bool:
|
|
26
26
|
# pylint: disable=import-outside-toplevel
|
|
27
|
-
"""JSON-RPC process call.
|
|
28
|
-
"""
|
|
27
|
+
"""JSON-RPC process call."""
|
|
29
28
|
from .stdstream import StdStreamAutorestAPI
|
|
30
29
|
|
|
31
30
|
with contextlib.closing(StdStreamAutorestAPI(session_id)) as stdstream_connection:
|
|
32
31
|
|
|
33
|
-
_LOGGER.debug(
|
|
32
|
+
_LOGGER.debug(
|
|
33
|
+
"Autorest called process with plugin_name '%s' and session_id: '%s'",
|
|
34
|
+
plugin_name,
|
|
35
|
+
session_id,
|
|
36
|
+
)
|
|
34
37
|
if plugin_name == "m2r":
|
|
35
38
|
from ..m2r import M2R as PluginToLoad
|
|
36
39
|
elif plugin_name == "namer":
|
|
@@ -38,7 +41,7 @@ def Process(plugin_name: str, session_id: str) -> bool:
|
|
|
38
41
|
elif plugin_name == "codegen":
|
|
39
42
|
from ..codegen import CodeGenerator as PluginToLoad # type: ignore
|
|
40
43
|
elif plugin_name == "black":
|
|
41
|
-
from ..black import BlackScriptPlugin
|
|
44
|
+
from ..black import BlackScriptPlugin as PluginToLoad # type: ignore
|
|
42
45
|
elif plugin_name == "multiapiscript":
|
|
43
46
|
from ..multiapi import MultiApiScriptPlugin as PluginToLoad # type: ignore
|
|
44
47
|
else:
|
|
@@ -58,11 +61,15 @@ def Process(plugin_name: str, session_id: str) -> bool:
|
|
|
58
61
|
def main() -> None:
|
|
59
62
|
# If --python.debugger is specified on the command line, we call the server.py file internally
|
|
60
63
|
# with flag --debug.
|
|
61
|
-
if
|
|
64
|
+
if "--debug" in sys.argv or os.environ.get(
|
|
65
|
+
"AUTOREST_PYTHON_ATTACH_VSCODE_DEBUG", False
|
|
66
|
+
):
|
|
62
67
|
try:
|
|
63
68
|
import ptvsd # pylint: disable=import-outside-toplevel
|
|
64
69
|
except ImportError:
|
|
65
|
-
raise SystemExit(
|
|
70
|
+
raise SystemExit(
|
|
71
|
+
"Please pip install ptvsd in order to use VSCode debugging"
|
|
72
|
+
)
|
|
66
73
|
|
|
67
74
|
# 5678 is the default attach port in the VS Code debug configurations
|
|
68
75
|
ptvsd.enable_attach(address=("localhost", 5678), redirect_output=True)
|
|
@@ -53,8 +53,7 @@ def write_message(message: str, stream: BinaryIO = sys.stdout.buffer) -> None:
|
|
|
53
53
|
|
|
54
54
|
|
|
55
55
|
class StdStreamAutorestAPI(AutorestAPI):
|
|
56
|
-
"""The stream API with Autorest
|
|
57
|
-
"""
|
|
56
|
+
"""The stream API with Autorest"""
|
|
58
57
|
|
|
59
58
|
def __init__(self, session_id: str) -> None:
|
|
60
59
|
super().__init__()
|
|
@@ -73,19 +72,25 @@ class StdStreamAutorestAPI(AutorestAPI):
|
|
|
73
72
|
def read_file(self, filename: Union[str, Path]) -> str:
|
|
74
73
|
_LOGGER.debug("Asking content for file %s", filename)
|
|
75
74
|
filename = os.fspath(filename)
|
|
76
|
-
request = JSONRPC20Request(
|
|
75
|
+
request = JSONRPC20Request(
|
|
76
|
+
method="ReadFile", params=[self.session_id, filename], _id=42
|
|
77
|
+
)
|
|
77
78
|
write_message(request.json)
|
|
78
79
|
return json.loads(read_message())["result"]
|
|
79
80
|
|
|
80
81
|
def list_inputs(self) -> List[str]:
|
|
81
82
|
_LOGGER.debug("Calling list inputs to Autorest")
|
|
82
|
-
request = JSONRPC20Request(
|
|
83
|
+
request = JSONRPC20Request(
|
|
84
|
+
method="ListInputs", params=[self.session_id, None], _id=42
|
|
85
|
+
)
|
|
83
86
|
write_message(request.json)
|
|
84
87
|
return json.loads(read_message())["result"]
|
|
85
88
|
|
|
86
89
|
def get_value(self, key: str) -> Any:
|
|
87
90
|
_LOGGER.debug("Calling get value to Autorest: %s", key)
|
|
88
|
-
request = JSONRPC20Request(
|
|
91
|
+
request = JSONRPC20Request(
|
|
92
|
+
method="GetValue", params=[self.session_id, key], _id=42
|
|
93
|
+
)
|
|
89
94
|
write_message(request.json)
|
|
90
95
|
return json.loads(read_message())["result"]
|
|
91
96
|
|
|
@@ -96,5 +101,7 @@ class StdStreamAutorestAPI(AutorestAPI):
|
|
|
96
101
|
"Channel": channel.value,
|
|
97
102
|
"Text": text,
|
|
98
103
|
}
|
|
99
|
-
request = JSONRPC20Request(
|
|
104
|
+
request = JSONRPC20Request(
|
|
105
|
+
method="Message", params=[self.session_id, message], is_notification=True
|
|
106
|
+
)
|
|
100
107
|
write_message(request.json)
|
package/autorest/m2r/__init__.py
CHANGED
|
@@ -27,18 +27,16 @@ class AutorestRender(m2r.RestRenderer):
|
|
|
27
27
|
|
|
28
28
|
|
|
29
29
|
class M2R(YamlUpdatePlugin):
|
|
30
|
-
"""A plugin to convert any description and summary from MD to RST.
|
|
31
|
-
|
|
30
|
+
"""A plugin to convert any description and summary from MD to RST."""
|
|
31
|
+
|
|
32
32
|
def update_yaml(self, yaml_data: Dict[str, Any]) -> None:
|
|
33
|
-
"""Convert in place the YAML str.
|
|
34
|
-
"""
|
|
33
|
+
"""Convert in place the YAML str."""
|
|
35
34
|
self._convert_docstring_no_cycles(yaml_data, set())
|
|
36
35
|
|
|
37
36
|
def _convert_docstring_no_cycles(
|
|
38
37
|
self, yaml_data: Dict[str, Any], node_list: Set[int]
|
|
39
38
|
) -> None:
|
|
40
|
-
"""Walk the YAML tree to convert MD to RST.
|
|
41
|
-
"""
|
|
39
|
+
"""Walk the YAML tree to convert MD to RST."""
|
|
42
40
|
if id(yaml_data) in node_list:
|
|
43
41
|
return
|
|
44
42
|
node_list.add(id(yaml_data))
|
|
@@ -55,8 +53,7 @@ class M2R(YamlUpdatePlugin):
|
|
|
55
53
|
|
|
56
54
|
@staticmethod
|
|
57
55
|
def convert_to_rst(string_to_convert: str) -> str:
|
|
58
|
-
"""Convert that string from MD to RST.
|
|
59
|
-
"""
|
|
56
|
+
"""Convert that string from MD to RST."""
|
|
60
57
|
try:
|
|
61
58
|
return m2r.convert(string_to_convert, renderer=AutorestRender()).strip()
|
|
62
59
|
except Exception: # pylint: disable=broad-except
|
|
@@ -32,7 +32,7 @@ class MultiApiScriptPlugin(Plugin):
|
|
|
32
32
|
output_folder,
|
|
33
33
|
self._autorestapi,
|
|
34
34
|
no_async,
|
|
35
|
-
user_specified_default_api
|
|
35
|
+
user_specified_default_api,
|
|
36
36
|
)
|
|
37
37
|
return generator.process()
|
|
38
38
|
|
|
@@ -44,10 +44,12 @@ class MultiAPI:
|
|
|
44
44
|
output_folder: str,
|
|
45
45
|
autorestapi: AutorestAPI,
|
|
46
46
|
no_async: Optional[bool] = False,
|
|
47
|
-
user_specified_default_api: Optional[str] = None
|
|
47
|
+
user_specified_default_api: Optional[str] = None,
|
|
48
48
|
) -> None:
|
|
49
49
|
if input_package_name is None:
|
|
50
|
-
raise ValueError(
|
|
50
|
+
raise ValueError(
|
|
51
|
+
"package-name is required, either provide it as args or check your readme configuration"
|
|
52
|
+
)
|
|
51
53
|
self.input_package_name = input_package_name
|
|
52
54
|
_LOGGER.debug("Received package name %s", input_package_name)
|
|
53
55
|
|
|
@@ -64,7 +66,7 @@ class MultiAPI:
|
|
|
64
66
|
self.mod_to_api_version,
|
|
65
67
|
[p.name for p in self.paths_to_versions],
|
|
66
68
|
self.preview_mode,
|
|
67
|
-
self.user_specified_default_api
|
|
69
|
+
self.user_specified_default_api,
|
|
68
70
|
)
|
|
69
71
|
|
|
70
72
|
@property
|
|
@@ -75,7 +77,9 @@ class MultiAPI:
|
|
|
75
77
|
if self.default_api_version.replace("-", "_") == path_to_version.stem:
|
|
76
78
|
path_to_default_version = path_to_version
|
|
77
79
|
break
|
|
78
|
-
return json.loads(
|
|
80
|
+
return json.loads(
|
|
81
|
+
self._autorestapi.read_file(path_to_default_version / "_metadata.json")
|
|
82
|
+
)
|
|
79
83
|
|
|
80
84
|
@property
|
|
81
85
|
def module_name(self) -> str:
|
|
@@ -96,7 +100,11 @@ class MultiAPI:
|
|
|
96
100
|
def preview_mode(self) -> bool:
|
|
97
101
|
# If True, means the auto-profile will consider preview versions.
|
|
98
102
|
# If not, if it exists a stable API version for a global or RT, will always be used
|
|
99
|
-
return cast(
|
|
103
|
+
return cast(
|
|
104
|
+
bool,
|
|
105
|
+
self.user_specified_default_api
|
|
106
|
+
and "preview" in self.user_specified_default_api,
|
|
107
|
+
)
|
|
100
108
|
|
|
101
109
|
@property
|
|
102
110
|
def paths_to_versions(self) -> List[Path]:
|
|
@@ -105,14 +113,16 @@ class MultiAPI:
|
|
|
105
113
|
directory.sort()
|
|
106
114
|
for child in directory:
|
|
107
115
|
child_dir = (self.output_folder / child).resolve()
|
|
108
|
-
if Path(child_dir /
|
|
116
|
+
if Path(child_dir / "_metadata.json") in child_dir.iterdir():
|
|
109
117
|
paths_to_versions.append(Path(child.stem))
|
|
110
118
|
return paths_to_versions
|
|
111
119
|
|
|
112
120
|
@property
|
|
113
121
|
def version_path_to_metadata(self) -> Dict[Path, Dict[str, Any]]:
|
|
114
122
|
return {
|
|
115
|
-
version_path: json.loads(
|
|
123
|
+
version_path: json.loads(
|
|
124
|
+
self._autorestapi.read_file(version_path / "_metadata.json")
|
|
125
|
+
)
|
|
116
126
|
for version_path in self.paths_to_versions
|
|
117
127
|
}
|
|
118
128
|
|
|
@@ -120,18 +130,18 @@ class MultiAPI:
|
|
|
120
130
|
def mod_to_api_version(self) -> Dict[str, str]:
|
|
121
131
|
mod_to_api_version: Dict[str, str] = defaultdict(str)
|
|
122
132
|
for version_path in self.paths_to_versions:
|
|
123
|
-
metadata_json = json.loads(
|
|
124
|
-
|
|
125
|
-
|
|
133
|
+
metadata_json = json.loads(
|
|
134
|
+
self._autorestapi.read_file(version_path / "_metadata.json")
|
|
135
|
+
)
|
|
136
|
+
version = metadata_json["chosen_version"]
|
|
137
|
+
total_api_version_list = metadata_json["total_api_version_list"]
|
|
126
138
|
if not version:
|
|
127
139
|
if total_api_version_list:
|
|
128
140
|
sys.exit(
|
|
129
141
|
f"Unable to match {total_api_version_list} to label {version_path.stem}"
|
|
130
142
|
)
|
|
131
143
|
else:
|
|
132
|
-
sys.exit(
|
|
133
|
-
f"Unable to extract api version of {version_path.stem}"
|
|
134
|
-
)
|
|
144
|
+
sys.exit(f"Unable to extract api version of {version_path.stem}")
|
|
135
145
|
mod_to_api_version[version_path.name] = version
|
|
136
146
|
return mod_to_api_version
|
|
137
147
|
|