@autorest/python 5.15.0 → 5.18.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 (118) hide show
  1. package/ChangeLog.md +98 -4
  2. package/README.md +30 -4
  3. package/autorest/__init__.py +2 -3
  4. package/autorest/black/__init__.py +12 -5
  5. package/autorest/codegen/__init__.py +122 -211
  6. package/autorest/codegen/models/__init__.py +122 -78
  7. package/autorest/codegen/models/base_builder.py +70 -72
  8. package/autorest/codegen/models/base_model.py +7 -5
  9. package/autorest/codegen/models/{base_schema.py → base_type.py} +68 -45
  10. package/autorest/codegen/models/client.py +193 -40
  11. package/autorest/codegen/models/code_model.py +145 -245
  12. package/autorest/codegen/models/combined_type.py +107 -0
  13. package/autorest/codegen/models/constant_type.py +122 -0
  14. package/autorest/codegen/models/credential_types.py +224 -0
  15. package/autorest/codegen/models/dictionary_type.py +131 -0
  16. package/autorest/codegen/models/enum_type.py +195 -0
  17. package/autorest/codegen/models/imports.py +93 -41
  18. package/autorest/codegen/models/list_type.py +149 -0
  19. package/autorest/codegen/models/lro_operation.py +90 -133
  20. package/autorest/codegen/models/lro_paging_operation.py +28 -12
  21. package/autorest/codegen/models/model_type.py +262 -0
  22. package/autorest/codegen/models/operation.py +412 -259
  23. package/autorest/codegen/models/operation_group.py +80 -91
  24. package/autorest/codegen/models/paging_operation.py +101 -117
  25. package/autorest/codegen/models/parameter.py +302 -341
  26. package/autorest/codegen/models/parameter_list.py +373 -357
  27. package/autorest/codegen/models/primitive_types.py +544 -0
  28. package/autorest/codegen/models/property.py +136 -134
  29. package/autorest/codegen/models/request_builder.py +138 -86
  30. package/autorest/codegen/models/request_builder_parameter.py +122 -86
  31. package/autorest/codegen/models/response.py +325 -0
  32. package/autorest/codegen/models/utils.py +13 -17
  33. package/autorest/codegen/serializers/__init__.py +212 -112
  34. package/autorest/codegen/serializers/builder_serializer.py +931 -1040
  35. package/autorest/codegen/serializers/client_serializer.py +140 -84
  36. package/autorest/codegen/serializers/general_serializer.py +26 -50
  37. package/autorest/codegen/serializers/import_serializer.py +96 -31
  38. package/autorest/codegen/serializers/metadata_serializer.py +39 -79
  39. package/autorest/codegen/serializers/model_base_serializer.py +62 -34
  40. package/autorest/codegen/serializers/model_generic_serializer.py +9 -10
  41. package/autorest/codegen/serializers/model_init_serializer.py +4 -2
  42. package/autorest/codegen/serializers/model_python3_serializer.py +29 -22
  43. package/autorest/codegen/serializers/operation_groups_serializer.py +21 -19
  44. package/autorest/codegen/serializers/operations_init_serializer.py +23 -11
  45. package/autorest/codegen/serializers/parameter_serializer.py +174 -0
  46. package/autorest/codegen/serializers/patch_serializer.py +4 -1
  47. package/autorest/codegen/serializers/request_builders_serializer.py +57 -0
  48. package/autorest/codegen/serializers/utils.py +0 -126
  49. package/autorest/codegen/templates/MANIFEST.in.jinja2 +1 -0
  50. package/autorest/codegen/templates/{service_client.py.jinja2 → client.py.jinja2} +7 -7
  51. package/autorest/codegen/templates/config.py.jinja2 +13 -13
  52. package/autorest/codegen/templates/enum.py.jinja2 +4 -4
  53. package/autorest/codegen/templates/enum_container.py.jinja2 +1 -1
  54. package/autorest/codegen/templates/init.py.jinja2 +3 -3
  55. package/autorest/codegen/templates/lro_operation.py.jinja2 +6 -5
  56. package/autorest/codegen/templates/lro_paging_operation.py.jinja2 +6 -5
  57. package/autorest/codegen/templates/metadata.json.jinja2 +36 -35
  58. package/autorest/codegen/templates/model.py.jinja2 +23 -24
  59. package/autorest/codegen/templates/model_container.py.jinja2 +2 -1
  60. package/autorest/codegen/templates/model_init.py.jinja2 +3 -5
  61. package/autorest/codegen/templates/operation.py.jinja2 +10 -14
  62. package/autorest/codegen/templates/operation_group.py.jinja2 +9 -15
  63. package/autorest/codegen/templates/operation_groups_container.py.jinja2 +1 -1
  64. package/autorest/codegen/templates/operation_tools.jinja2 +8 -2
  65. package/autorest/codegen/templates/paging_operation.py.jinja2 +7 -8
  66. package/autorest/codegen/templates/request_builder.py.jinja2 +19 -10
  67. package/autorest/codegen/templates/setup.py.jinja2 +9 -3
  68. package/autorest/codegen/templates/vendor.py.jinja2 +1 -1
  69. package/autorest/jsonrpc/__init__.py +7 -12
  70. package/autorest/jsonrpc/localapi.py +4 -3
  71. package/autorest/jsonrpc/server.py +28 -9
  72. package/autorest/jsonrpc/stdstream.py +13 -6
  73. package/autorest/m2r/__init__.py +5 -8
  74. package/autorest/m4reformatter/__init__.py +1126 -0
  75. package/autorest/multiapi/__init__.py +24 -14
  76. package/autorest/multiapi/models/client.py +21 -11
  77. package/autorest/multiapi/models/code_model.py +23 -10
  78. package/autorest/multiapi/models/config.py +4 -1
  79. package/autorest/multiapi/models/constant_global_parameter.py +1 -0
  80. package/autorest/multiapi/models/global_parameter.py +2 -1
  81. package/autorest/multiapi/models/global_parameters.py +14 -8
  82. package/autorest/multiapi/models/imports.py +24 -17
  83. package/autorest/multiapi/models/mixin_operation.py +5 -5
  84. package/autorest/multiapi/models/operation_group.py +2 -1
  85. package/autorest/multiapi/models/operation_mixin_group.py +21 -10
  86. package/autorest/multiapi/serializers/__init__.py +20 -25
  87. package/autorest/multiapi/serializers/import_serializer.py +47 -17
  88. package/autorest/multiapi/serializers/multiapi_serializer.py +17 -17
  89. package/autorest/multiapi/templates/multiapi_config.py.jinja2 +3 -3
  90. package/autorest/multiapi/templates/multiapi_init.py.jinja2 +2 -2
  91. package/autorest/multiapi/templates/multiapi_operations_mixin.py.jinja2 +4 -4
  92. package/autorest/multiapi/templates/multiapi_service_client.py.jinja2 +9 -9
  93. package/autorest/multiapi/utils.py +3 -3
  94. package/autorest/postprocess/__init__.py +202 -0
  95. package/autorest/postprocess/get_all.py +19 -0
  96. package/autorest/postprocess/venvtools.py +73 -0
  97. package/autorest/preprocess/__init__.py +210 -0
  98. package/autorest/preprocess/helpers.py +54 -0
  99. package/autorest/{namer → preprocess}/python_mappings.py +25 -32
  100. package/package.json +3 -3
  101. package/run-python3.js +2 -3
  102. package/venvtools.py +1 -1
  103. package/autorest/codegen/models/constant_schema.py +0 -101
  104. package/autorest/codegen/models/credential_model.py +0 -47
  105. package/autorest/codegen/models/credential_schema.py +0 -91
  106. package/autorest/codegen/models/credential_schema_policy.py +0 -77
  107. package/autorest/codegen/models/dictionary_schema.py +0 -103
  108. package/autorest/codegen/models/enum_schema.py +0 -215
  109. package/autorest/codegen/models/list_schema.py +0 -123
  110. package/autorest/codegen/models/object_schema.py +0 -253
  111. package/autorest/codegen/models/primitive_schemas.py +0 -466
  112. package/autorest/codegen/models/request_builder_parameter_list.py +0 -280
  113. package/autorest/codegen/models/rest.py +0 -42
  114. package/autorest/codegen/models/schema_request.py +0 -45
  115. package/autorest/codegen/models/schema_response.py +0 -136
  116. package/autorest/codegen/serializers/rest_serializer.py +0 -57
  117. package/autorest/namer/__init__.py +0 -25
  118. package/autorest/namer/name_converter.py +0 -412
@@ -3,63 +3,70 @@
3
3
  # Licensed under the MIT License. See License.txt in the project root for
4
4
  # license information.
5
5
  # --------------------------------------------------------------------------
6
- from typing import cast, List
6
+ from typing import List
7
7
  from jinja2 import Environment
8
8
  from .model_base_serializer import ModelBaseSerializer
9
- from ..models import ObjectSchema, CodeModel, Property
9
+ from ..models import ModelType, CodeModel, Property
10
10
  from ..models.imports import FileImport
11
11
 
12
12
 
13
13
  class ModelPython3Serializer(ModelBaseSerializer):
14
-
15
14
  def __init__(self, code_model: CodeModel, env: Environment) -> None:
16
- super(ModelPython3Serializer, self).__init__(
17
- code_model=code_model, env=env, is_python3_file=True
18
- )
15
+ super().__init__(code_model=code_model, env=env, is_python3_file=True)
19
16
 
20
- def init_line(self, model: ObjectSchema) -> List[str]:
17
+ def init_line(self, model: ModelType) -> List[str]:
21
18
  init_properties_declaration = []
22
19
  init_line_parameters = [
23
- p for p in model.properties if not p.readonly and not p.is_discriminator and not p.constant
20
+ p
21
+ for p in model.properties
22
+ if not p.readonly and not p.is_discriminator and not p.constant
24
23
  ]
25
- init_line_parameters.sort(key=lambda x: x.required, reverse=True)
24
+ init_line_parameters.sort(key=lambda x: x.optional)
26
25
  if init_line_parameters:
27
- init_properties_declaration.append("*")
26
+ init_properties_declaration.append("*,")
28
27
  for param in init_line_parameters:
29
28
  init_properties_declaration.append(self.initialize_standard_property(param))
30
29
 
31
30
  return init_properties_declaration
32
31
 
33
- def properties_to_pass_to_super(self, model: ObjectSchema) -> str:
32
+ def properties_to_pass_to_super(self, model: ModelType) -> str:
34
33
  properties_to_pass_to_super = []
35
- for uncast_base_model in model.base_models:
36
- base_model = cast(ObjectSchema, uncast_base_model)
34
+ for parent in model.parents:
37
35
  for prop in model.properties:
38
36
  if (
39
- prop in base_model.properties
37
+ prop in parent.properties
40
38
  and not prop.is_discriminator
41
39
  and not prop.constant
42
40
  and not prop.readonly
43
41
  ):
44
- properties_to_pass_to_super.append(f"{prop.name}={prop.name}")
42
+ properties_to_pass_to_super.append(
43
+ f"{prop.client_name}={prop.client_name}"
44
+ )
45
45
  properties_to_pass_to_super.append("**kwargs")
46
46
  return ", ".join(properties_to_pass_to_super)
47
47
 
48
48
  def required_property_no_default_init(self, prop: Property) -> str:
49
- return f"{prop.name}: {prop.type_annotation()}"
49
+ return f"{prop.client_name}: {prop.type_annotation()},{prop.pylint_disable}"
50
50
 
51
51
  def optional_property_init(self, prop: Property) -> str:
52
- default = prop.default_value_declaration
53
- return f"{prop.name}: {prop.type_annotation()} = {default}"
52
+ return (
53
+ f"{prop.client_name}: {prop.type_annotation()} = "
54
+ f"{prop.client_default_value_declaration},{prop.pylint_disable}"
55
+ )
54
56
 
55
57
  def initialize_standard_arg(self, prop: Property) -> str:
56
- return f"self.{prop.name} = {prop.name}"
58
+ return f"self.{prop.client_name} = {prop.client_name}"
59
+
60
+ def super_call_template(self, model: ModelType) -> str:
61
+ return "super().__init__({})"
57
62
 
58
63
  def imports(self) -> FileImport:
59
64
  file_import = super(ModelPython3Serializer, self).imports()
60
- for model in self.code_model.sorted_schemas:
61
- init_line_parameters = [p for p in model.properties if not p.readonly and not p.is_discriminator]
65
+ for model in self.code_model.model_types:
66
+ init_line_parameters = [
67
+ p for p in model.properties if not p.readonly and not p.is_discriminator
68
+ ]
62
69
  for param in init_line_parameters:
63
- file_import.merge(param.model_file_imports())
70
+ file_import.merge(param.imports())
64
71
 
65
72
  return file_import
@@ -11,11 +11,10 @@ from ..models import (
11
11
  CodeModel,
12
12
  OperationGroup,
13
13
  FileImport,
14
- LROOperation,
15
- PagingOperation
16
14
  )
17
15
  from .import_serializer import FileImportSerializer
18
- from .builder_serializer import get_operation_serializer, get_request_builder_serializer
16
+ from .builder_serializer import get_operation_serializer, RequestBuilderSerializer
17
+
19
18
 
20
19
  class OperationGroupsSerializer:
21
20
  def __init__(
@@ -33,39 +32,42 @@ class OperationGroupsSerializer:
33
32
  self.operation_group = operation_group
34
33
 
35
34
  def serialize(self) -> str:
36
- def _is_lro(operation):
37
- return isinstance(operation, LROOperation)
38
-
39
- def _is_paging(operation):
40
- return isinstance(operation, PagingOperation)
41
- operation_groups = [self.operation_group] if self.operation_group else self.code_model.operation_groups
35
+ operation_groups = (
36
+ [self.operation_group]
37
+ if self.operation_group
38
+ else self.code_model.operation_groups
39
+ )
42
40
  imports = FileImport()
43
41
  for operation_group in operation_groups:
44
- imports.merge(operation_group.imports(
45
- async_mode=self.async_mode,
46
- is_python3_file=self.is_python3_file,
47
- ))
42
+ imports.merge(
43
+ operation_group.imports(
44
+ async_mode=self.async_mode,
45
+ is_python3_file=self.is_python3_file,
46
+ )
47
+ )
48
48
 
49
- template = self.env.get_or_select_template("operation_groups_container.py.jinja2")
49
+ template = self.env.get_or_select_template(
50
+ "operation_groups_container.py.jinja2"
51
+ )
50
52
  return template.render(
51
53
  code_model=self.code_model,
52
54
  operation_groups=operation_groups,
53
55
  imports=FileImportSerializer(
54
56
  imports,
55
57
  is_python3_file=self.is_python3_file,
56
- async_mode=self.async_mode
58
+ async_mode=self.async_mode,
57
59
  ),
58
60
  async_mode=self.async_mode,
59
61
  is_python3_file=self.is_python3_file,
60
- is_lro=_is_lro,
61
- is_paging=_is_paging,
62
62
  get_operation_serializer=functools.partial(
63
63
  get_operation_serializer,
64
64
  code_model=self.code_model,
65
65
  async_mode=self.async_mode,
66
66
  is_python3_file=self.is_python3_file,
67
67
  ),
68
- request_builder_serializer=get_request_builder_serializer(
69
- self.code_model, self.is_python3_file,
68
+ request_builder_serializer=RequestBuilderSerializer(
69
+ self.code_model,
70
+ async_mode=False,
71
+ is_python3_file=self.is_python3_file,
70
72
  ),
71
73
  )
@@ -11,15 +11,22 @@ from ..models import CodeModel
11
11
 
12
12
 
13
13
  class OperationsInitSerializer:
14
- def __init__(self, code_model: CodeModel, env: Environment, async_mode: bool) -> None:
14
+ def __init__(
15
+ self, code_model: CodeModel, env: Environment, async_mode: bool
16
+ ) -> None:
15
17
  self.code_model = code_model
16
18
  self.env = env
17
19
  self.async_mode = async_mode
18
20
 
19
21
  def _operation_group_imports_helper(self, filename_suffix: str = "") -> List[str]:
20
22
  def _get_filename(operation_group: OperationGroup) -> str:
21
- prefix = "_operations" if self.code_model.options["combine_operation_files"] else operation_group.filename
23
+ prefix = (
24
+ "_operations"
25
+ if self.code_model.options["combine_operation_files"]
26
+ else operation_group.filename
27
+ )
22
28
  return prefix + filename_suffix
29
+
23
30
  return [
24
31
  f"from .{_get_filename(og)} import {og.class_name}"
25
32
  for og in self.code_model.operation_groups
@@ -30,20 +37,25 @@ class OperationsInitSerializer:
30
37
  py3_only = self.code_model.options["python3_only"]
31
38
  if typed_py3_files and not py3_only and not self.async_mode:
32
39
  retval: List[str] = ["try:"]
33
- retval.extend([
34
- f" {line}"
35
- for line in self._operation_group_imports_helper(filename_suffix="_py3")
36
- ])
40
+ retval.extend(
41
+ [
42
+ f" {line}"
43
+ for line in self._operation_group_imports_helper(
44
+ filename_suffix="_py3"
45
+ )
46
+ ]
47
+ )
37
48
  retval.append("except (SyntaxError, ImportError):")
38
- retval.extend([
39
- f" {line}"
40
- for line in self._operation_group_imports_helper()
41
- ])
49
+ retval.extend(
50
+ [f" {line}" for line in self._operation_group_imports_helper()]
51
+ )
42
52
  return retval
43
53
  return self._operation_group_imports_helper()
44
54
 
45
55
  def serialize(self) -> str:
46
- operation_group_init_template = self.env.get_template("operations_folder_init.py.jinja2")
56
+ operation_group_init_template = self.env.get_template(
57
+ "operations_folder_init.py.jinja2"
58
+ )
47
59
 
48
60
  return operation_group_init_template.render(
49
61
  code_model=self.code_model,
@@ -0,0 +1,174 @@
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 List, Sequence, Union
7
+ from enum import Enum, auto
8
+
9
+
10
+ from ..models import (
11
+ Parameter,
12
+ ParameterLocation,
13
+ ListType,
14
+ ParameterDelimeter,
15
+ RequestBuilderParameter,
16
+ ClientParameter,
17
+ ConfigParameter,
18
+ ParameterType,
19
+ )
20
+ from ..models.parameter import _ParameterBase
21
+
22
+
23
+ class PopKwargType(Enum):
24
+ NO = auto()
25
+ SIMPLE = auto()
26
+ CASE_INSENSITIVE = auto()
27
+
28
+
29
+ class ParameterSerializer:
30
+ @staticmethod
31
+ def serialize_parameter(parameter: ParameterType, serializer_name: str) -> str:
32
+ optional_parameters = []
33
+
34
+ if parameter.skip_url_encoding:
35
+ optional_parameters.append("skip_quote=True")
36
+
37
+ if parameter.delimiter and not parameter.explode:
38
+ if parameter.delimiter == ParameterDelimeter.COMMA:
39
+ div_char = ","
40
+ elif parameter.delimiter == ParameterDelimeter.SPACE:
41
+ div_char = " "
42
+ elif parameter.delimiter == ParameterDelimeter.PIPE:
43
+ div_char = "|"
44
+ elif parameter.delimiter == ParameterDelimeter.TAB:
45
+ div_char = "\t"
46
+ else:
47
+ raise ValueError(f"We do not support {parameter.delimiter} yet")
48
+ optional_parameters.append(f"div='{div_char}'")
49
+
50
+ if parameter.explode:
51
+ if not isinstance(parameter.type, ListType):
52
+ raise ValueError("Got a explode boolean on a non-array schema")
53
+ type = parameter.type.element_type
54
+ else:
55
+ type = parameter.type
56
+
57
+ serialization_constraints = type.serialization_constraints
58
+ if serialization_constraints:
59
+ optional_parameters += serialization_constraints
60
+
61
+ origin_name = parameter.full_client_name
62
+
63
+ parameters = [
64
+ f'"{origin_name.lstrip("_")}"',
65
+ "q" if parameter.explode else origin_name,
66
+ f"'{type.serialization_type}'",
67
+ *optional_parameters,
68
+ ]
69
+ parameters_line = ", ".join(parameters)
70
+
71
+ msrest_function_name = {
72
+ ParameterLocation.PATH: "url",
73
+ ParameterLocation.ENDPOINT_PATH: "url",
74
+ ParameterLocation.HEADER: "header",
75
+ ParameterLocation.QUERY: "query",
76
+ }[parameter.location]
77
+
78
+ serialize_line = f"{serializer_name}.{msrest_function_name}({parameters_line})"
79
+
80
+ if parameter.explode:
81
+ return f"[{serialize_line} if q is not None else '' for q in {origin_name}]"
82
+ return serialize_line
83
+
84
+ def serialize_path(
85
+ self,
86
+ parameters: Union[
87
+ List[Parameter],
88
+ List[RequestBuilderParameter],
89
+ List[ClientParameter],
90
+ List[ConfigParameter],
91
+ ],
92
+ serializer_name: str,
93
+ ) -> List[str]:
94
+ retval = ["path_format_arguments = {"]
95
+ retval.extend(
96
+ [
97
+ ' "{}": {},'.format(
98
+ path_parameter.rest_api_name,
99
+ self.serialize_parameter(path_parameter, serializer_name),
100
+ )
101
+ for path_parameter in parameters
102
+ ]
103
+ )
104
+ retval.append("}")
105
+ return retval
106
+
107
+ @staticmethod
108
+ def pop_kwargs_from_signature(
109
+ parameters: Sequence[_ParameterBase],
110
+ check_kwarg_dict: bool,
111
+ pop_headers_kwarg: PopKwargType,
112
+ pop_params_kwarg: PopKwargType,
113
+ check_client_input: bool = False,
114
+ ) -> List[str]:
115
+ retval = []
116
+
117
+ def append_pop_kwarg(key: str, pop_type: PopKwargType) -> None:
118
+ if PopKwargType.CASE_INSENSITIVE == pop_type:
119
+ retval.append(
120
+ f'_{key} = case_insensitive_dict(kwargs.pop("{key}", {{}}) or {{}})'
121
+ )
122
+ elif PopKwargType.SIMPLE == pop_type:
123
+ retval.append(f'_{key} = kwargs.pop("{key}", {{}}) or {{}}')
124
+
125
+ append_pop_kwarg("headers", pop_headers_kwarg)
126
+ append_pop_kwarg("params", pop_params_kwarg)
127
+ if pop_headers_kwarg != PopKwargType.NO or pop_params_kwarg != PopKwargType.NO:
128
+ retval.append("")
129
+ for kwarg in parameters:
130
+ if kwarg.client_default_value is not None or kwarg.optional:
131
+ if check_client_input and kwarg.check_client_input:
132
+ default_value = f"self._config.{kwarg.client_name}"
133
+ else:
134
+ default_value = kwarg.client_default_value_declaration
135
+ if check_kwarg_dict and (
136
+ kwarg.location
137
+ 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
+ )
147
+ retval.append(
148
+ f"{kwarg.client_name} = kwargs.pop('{kwarg.client_name}', "
149
+ + f"{default_value}) # type: {kwarg.type_annotation()}"
150
+ )
151
+ else:
152
+ type_annot = kwarg.type_annotation()
153
+ retval.append(
154
+ f"{kwarg.client_name} = kwargs.pop('{kwarg.client_name}') # type: {type_annot}"
155
+ )
156
+ return retval
157
+
158
+ @staticmethod
159
+ def serialize_method(
160
+ *,
161
+ function_def: str,
162
+ method_name: str,
163
+ need_self_param: bool,
164
+ method_param_signatures: List[str],
165
+ pylint_disable: str = "",
166
+ ):
167
+ lines: List[str] = []
168
+ first_line = f"{function_def} {method_name}({pylint_disable}"
169
+ lines.append(first_line)
170
+ if need_self_param:
171
+ lines.append(" self,")
172
+ lines.extend([(" " + line) for line in method_param_signatures])
173
+ lines.append(")")
174
+ return "\n".join(lines)
@@ -7,6 +7,7 @@ from jinja2 import Environment
7
7
  from .import_serializer import FileImportSerializer
8
8
  from ..models import CodeModel, FileImport, ImportType, TypingSection
9
9
 
10
+
10
11
  class PatchSerializer:
11
12
  def __init__(self, env: Environment, code_model: CodeModel) -> None:
12
13
  self.env = env
@@ -15,7 +16,9 @@ class PatchSerializer:
15
16
  def serialize(self) -> str:
16
17
  template = self.env.get_template("patch.py.jinja2")
17
18
  imports = FileImport()
18
- imports.add_submodule_import("typing", "List", ImportType.STDLIB, TypingSection.CONDITIONAL)
19
+ imports.add_submodule_import(
20
+ "typing", "List", ImportType.STDLIB, TypingSection.CONDITIONAL
21
+ )
19
22
  is_python3_file = self.code_model.options["python3_only"]
20
23
  return template.render(
21
24
  code_model=self.code_model,
@@ -0,0 +1,57 @@
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 List
7
+ from jinja2 import Environment
8
+
9
+ from ..models import FileImport
10
+ from .import_serializer import FileImportSerializer
11
+ from ..models import CodeModel, RequestBuilderType
12
+ from .builder_serializer import RequestBuilderSerializer
13
+
14
+
15
+ class RequestBuildersSerializer:
16
+ def __init__(
17
+ self,
18
+ code_model: CodeModel,
19
+ env: Environment,
20
+ request_builders: List[RequestBuilderType],
21
+ is_python3_file: bool,
22
+ ) -> None:
23
+ self.code_model = code_model
24
+ self.env = env
25
+ self.request_builders = request_builders
26
+ self.group_name = request_builders[0].group_name
27
+ self.is_python3_file = is_python3_file
28
+
29
+ @property
30
+ def imports(self) -> FileImport:
31
+ file_import = FileImport()
32
+ for request_builder in self.request_builders:
33
+ if request_builder.group_name == self.group_name:
34
+ file_import.merge(request_builder.imports())
35
+ return file_import
36
+
37
+ def serialize_init(self) -> str:
38
+ template = self.env.get_template("rest_init.py.jinja2")
39
+ return template.render(
40
+ code_model=self.code_model,
41
+ request_builders=[r for r in self.request_builders if not r.is_overload],
42
+ )
43
+
44
+ def serialize_request_builders(self) -> str:
45
+ template = self.env.get_template("request_builders.py.jinja2")
46
+
47
+ return template.render(
48
+ code_model=self.code_model,
49
+ request_builders=self.request_builders,
50
+ imports=FileImportSerializer(
51
+ self.imports,
52
+ is_python3_file=True,
53
+ ),
54
+ request_builder_serializer=RequestBuilderSerializer(
55
+ self.code_model, async_mode=False, is_python3_file=self.is_python3_file
56
+ ),
57
+ )
@@ -3,96 +3,8 @@
3
3
  # Licensed under the MIT License. See License.txt in the project root for
4
4
  # license information.
5
5
  # --------------------------------------------------------------------------
6
- from enum import Enum, auto
7
- from typing import List
8
- from ..models import ParameterStyle, ListSchema, Parameter, ParameterLocation
9
6
 
10
7
 
11
- def serialize_method(
12
- *,
13
- function_def: str,
14
- method_name: str,
15
- is_in_class: bool,
16
- method_param_signatures: List[str],
17
- ignore_inconsistent_return_statements: bool = False,
18
- ):
19
- lines: List[str] = []
20
- first_line = f"{function_def} {method_name}("
21
- if ignore_inconsistent_return_statements:
22
- first_line += " # pylint: disable=inconsistent-return-statements"
23
- lines.append(first_line)
24
- if is_in_class:
25
- lines.append(" self,")
26
- lines.extend([
27
- (" " + line)
28
- for line in method_param_signatures
29
- ])
30
- lines.append(")")
31
- return "\n".join(lines)
32
-
33
- def build_serialize_data_call(
34
- parameter: Parameter, function_name: str, serializer_name: str
35
- ) -> str:
36
-
37
- optional_parameters = []
38
-
39
- if parameter.skip_url_encoding:
40
- optional_parameters.append("skip_quote=True")
41
-
42
- if parameter.style and not parameter.explode:
43
- if parameter.style in [ParameterStyle.simple, ParameterStyle.form]:
44
- div_char = ","
45
- elif parameter.style in [ParameterStyle.spaceDelimited]:
46
- div_char = " "
47
- elif parameter.style in [ParameterStyle.pipeDelimited]:
48
- div_char = "|"
49
- elif parameter.style in [ParameterStyle.tabDelimited]:
50
- div_char = "\t"
51
- else:
52
- raise ValueError(f"Do not support {parameter.style} yet")
53
- optional_parameters.append(f"div='{div_char}'")
54
-
55
- if parameter.explode:
56
- if not isinstance(parameter.schema, ListSchema):
57
- raise ValueError("Got a explode boolean on a non-array schema")
58
- serialization_schema = parameter.schema.element_type
59
- else:
60
- serialization_schema = parameter.schema
61
-
62
- serialization_constraints = serialization_schema.serialization_constraints
63
- if serialization_constraints:
64
- optional_parameters += serialization_constraints
65
-
66
- origin_name = parameter.full_serialized_name
67
-
68
- parameters = [
69
- f'"{origin_name.lstrip("_")}"',
70
- "q" if parameter.explode else origin_name,
71
- f"'{serialization_schema.serialization_type}'",
72
- *optional_parameters
73
- ]
74
- parameters_line = ', '.join(parameters)
75
-
76
- serialize_line = f'{serializer_name}.{function_name}({parameters_line})'
77
-
78
- if parameter.explode:
79
- return f"[{serialize_line} if q is not None else '' for q in {origin_name}]"
80
- return serialize_line
81
-
82
- def serialize_path(
83
- parameters: List[Parameter], serializer_name: str
84
- ) -> List[str]:
85
- retval = ["path_format_arguments = {"]
86
- retval.extend([
87
- " \"{}\": {},".format(
88
- path_parameter.rest_api_name,
89
- build_serialize_data_call(path_parameter, "url", serializer_name)
90
- )
91
- for path_parameter in parameters
92
- ])
93
- retval.append("}")
94
- return retval
95
-
96
8
  def method_signature_and_response_type_annotation_template(
97
9
  *,
98
10
  is_python3_file: bool,
@@ -102,41 +14,3 @@ def method_signature_and_response_type_annotation_template(
102
14
  if is_python3_file:
103
15
  return f"{method_signature} -> {response_type_annotation}:"
104
16
  return f"{method_signature}:\n # type: (...) -> {response_type_annotation}"
105
-
106
- class PopKwargType(Enum):
107
- NO = auto()
108
- SIMPLE = auto()
109
- CASE_INSENSITIVE = auto()
110
-
111
- def pop_kwargs_from_signature(
112
- kwargs_to_pop: List[Parameter],
113
- check_kwarg_dict: bool,
114
- pop_headers_kwarg: PopKwargType,
115
- pop_params_kwarg: PopKwargType,
116
- ) -> List[str]:
117
- retval = []
118
- def append_pop_kwarg(key: str, pop_type: PopKwargType) -> None:
119
- if PopKwargType.CASE_INSENSITIVE == pop_type:
120
- retval.append(f'_{key} = case_insensitive_dict(kwargs.pop("{key}", {{}}) or {{}})')
121
- elif PopKwargType.SIMPLE == pop_type:
122
- retval.append(f'_{key} = kwargs.pop("{key}", {{}}) or {{}}')
123
- append_pop_kwarg("headers", pop_headers_kwarg)
124
- append_pop_kwarg("params", pop_params_kwarg)
125
- if pop_headers_kwarg != PopKwargType.NO or pop_params_kwarg != PopKwargType.NO:
126
- retval.append("")
127
- for kwarg in kwargs_to_pop:
128
- if kwarg.has_default_value:
129
- default_value = kwarg.default_value_declaration
130
- if check_kwarg_dict and (kwarg.location in [ParameterLocation.Header, ParameterLocation.Query]):
131
- kwarg_dict = "headers" if kwarg.location == ParameterLocation.Header else "params"
132
- default_value = f"_{kwarg_dict}.pop('{kwarg.rest_api_name}', {default_value})"
133
- retval.append(
134
- f"{kwarg.serialized_name} = kwargs.pop('{kwarg.serialized_name}', "
135
- + f"{default_value}) # type: {kwarg.type_annotation(is_operation_file=True)}"
136
- )
137
- else:
138
- type_annot = kwarg.type_annotation(is_operation_file=True)
139
- retval.append(
140
- f"{kwarg.serialized_name} = kwargs.pop('{kwarg.serialized_name}') # type: {type_annot}"
141
- )
142
- return retval
@@ -1,5 +1,6 @@
1
1
  include *.md
2
2
  include LICENSE
3
+ include {{ package_name.replace('-', '/') }}/py.typed
3
4
  recursive-include tests *.py
4
5
  recursive-include samples *.py *.md
5
6
  {%- for init_name in init_names %}
@@ -7,15 +7,15 @@
7
7
  {{ imports }}
8
8
 
9
9
  {{ serializer.class_definition(async_mode) }}
10
- """{{ op_tools.wrap_string(code_model.description, "\n") | indent }}
10
+ """{{ op_tools.wrap_string(code_model.client.description, "\n") | indent }}
11
11
 
12
12
  {{ op_tools.serialize_with_wrap(serializer.property_descriptions(async_mode), "\n ") | indent }}
13
13
  {{ serializer.init_signature_and_response_type_annotation(async_mode) | indent }}
14
- {% if code_model.service_client.parameters.kwargs_to_pop(async_mode) %}
14
+ {% if code_model.client.parameters.kwargs_to_pop(async_mode) %}
15
15
  {{ op_tools.serialize(serializer.pop_kwargs_from_signature(async_mode)) | indent(8) }}
16
16
  {% endif %}
17
- {% if code_model.service_client.has_parameterized_host %}
18
- _{{ code_model.service_client.parameters.host_variable_name }} = {{ keywords.escape_str(code_model.service_client.parameterized_host_template) }}
17
+ {% if code_model.client.has_parameterized_host %}
18
+ {{ serializer.host_variable_name }} = {{ keywords.escape_str(code_model.client.url) }}
19
19
  {% endif %}
20
20
  {{ serializer.initialize_config() }}
21
21
  {{ serializer.initialize_pipeline_client(async_mode) }}
@@ -26,7 +26,7 @@
26
26
  {{ serializer.send_request_signature_and_response_type_annotation(async_mode) | indent }}
27
27
  {{ op_tools.serialize(serializer.send_request_description(async_mode)) | indent(8) }}
28
28
  request_copy = deepcopy(request)
29
- {% if code_model.global_parameters.path %}
29
+ {% if code_model.client.parameters.path %}
30
30
  {{ op_tools.serialize(serializer.serialize_path()) | indent(8) }}
31
31
  request_copy.url = self._client.format_url(request_copy.url, **path_format_arguments)
32
32
  {% else %}
@@ -40,9 +40,9 @@
40
40
  {% endif %}
41
41
  {{ keywords.await }}self._client.close()
42
42
 
43
- {{ keywords.def }} __{{ keywords.async_prefix }}enter__(self){{ (" -> \"" + code_model.class_name + "\"") if async_mode else "" }}:
43
+ {{ keywords.def }} __{{ keywords.async_prefix }}enter__(self){{ (" -> \"" + code_model.client.name + "\"") if async_mode else "" }}:
44
44
  {% if not async_mode %}
45
- # type: () -> {{ code_model.class_name }}
45
+ # type: () -> {{ code_model.client.name }}
46
46
  {% endif %}
47
47
  {{ keywords.await }}self._client.__{{ keywords.async_prefix }}enter__()
48
48
  return self