@autorest/python 5.14.0 → 5.17.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 (120) hide show
  1. package/ChangeLog.md +91 -2
  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 +130 -179
  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} +62 -49
  10. package/autorest/codegen/models/client.py +195 -36
  11. package/autorest/codegen/models/code_model.py +165 -299
  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 +116 -0
  16. package/autorest/codegen/models/enum_type.py +195 -0
  17. package/autorest/codegen/models/imports.py +95 -41
  18. package/autorest/codegen/models/list_type.py +134 -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 +239 -0
  22. package/autorest/codegen/models/operation.py +415 -241
  23. package/autorest/codegen/models/operation_group.py +82 -88
  24. package/autorest/codegen/models/paging_operation.py +101 -117
  25. package/autorest/codegen/models/parameter.py +307 -322
  26. package/autorest/codegen/models/parameter_list.py +366 -357
  27. package/autorest/codegen/models/primitive_types.py +544 -0
  28. package/autorest/codegen/models/property.py +122 -134
  29. package/autorest/codegen/models/request_builder.py +138 -86
  30. package/autorest/codegen/models/request_builder_parameter.py +122 -79
  31. package/autorest/codegen/models/response.py +325 -0
  32. package/autorest/codegen/models/utils.py +17 -1
  33. package/autorest/codegen/serializers/__init__.py +242 -118
  34. package/autorest/codegen/serializers/builder_serializer.py +863 -1027
  35. package/autorest/codegen/serializers/client_serializer.py +148 -82
  36. package/autorest/codegen/serializers/general_serializer.py +44 -47
  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 +65 -29
  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 -18
  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 +14 -2
  47. package/autorest/codegen/serializers/request_builders_serializer.py +57 -0
  48. package/autorest/codegen/serializers/utils.py +0 -103
  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 -2
  54. package/autorest/codegen/templates/init.py.jinja2 +9 -6
  55. package/autorest/codegen/templates/keywords.jinja2 +14 -1
  56. package/autorest/codegen/templates/lro_operation.py.jinja2 +6 -5
  57. package/autorest/codegen/templates/lro_paging_operation.py.jinja2 +6 -5
  58. package/autorest/codegen/templates/metadata.json.jinja2 +36 -35
  59. package/autorest/codegen/templates/model.py.jinja2 +23 -29
  60. package/autorest/codegen/templates/model_container.py.jinja2 +2 -1
  61. package/autorest/codegen/templates/model_init.py.jinja2 +9 -8
  62. package/autorest/codegen/templates/operation.py.jinja2 +10 -15
  63. package/autorest/codegen/templates/operation_group.py.jinja2 +14 -13
  64. package/autorest/codegen/templates/operation_groups_container.py.jinja2 +1 -2
  65. package/autorest/codegen/templates/operation_tools.jinja2 +8 -2
  66. package/autorest/codegen/templates/operations_folder_init.py.jinja2 +4 -0
  67. package/autorest/codegen/templates/paging_operation.py.jinja2 +7 -8
  68. package/autorest/codegen/templates/patch.py.jinja2 +18 -29
  69. package/autorest/codegen/templates/request_builder.py.jinja2 +20 -13
  70. package/autorest/codegen/templates/setup.py.jinja2 +9 -3
  71. package/autorest/codegen/templates/vendor.py.jinja2 +12 -2
  72. package/autorest/jsonrpc/__init__.py +7 -12
  73. package/autorest/jsonrpc/localapi.py +4 -3
  74. package/autorest/jsonrpc/server.py +28 -9
  75. package/autorest/jsonrpc/stdstream.py +13 -6
  76. package/autorest/m2r/__init__.py +5 -8
  77. package/autorest/m4reformatter/__init__.py +1108 -0
  78. package/autorest/multiapi/__init__.py +24 -14
  79. package/autorest/multiapi/models/client.py +21 -11
  80. package/autorest/multiapi/models/code_model.py +23 -10
  81. package/autorest/multiapi/models/config.py +4 -1
  82. package/autorest/multiapi/models/constant_global_parameter.py +1 -0
  83. package/autorest/multiapi/models/global_parameter.py +2 -1
  84. package/autorest/multiapi/models/global_parameters.py +14 -8
  85. package/autorest/multiapi/models/imports.py +35 -18
  86. package/autorest/multiapi/models/mixin_operation.py +5 -5
  87. package/autorest/multiapi/models/operation_group.py +2 -1
  88. package/autorest/multiapi/models/operation_mixin_group.py +21 -10
  89. package/autorest/multiapi/serializers/__init__.py +20 -25
  90. package/autorest/multiapi/serializers/import_serializer.py +47 -15
  91. package/autorest/multiapi/serializers/multiapi_serializer.py +17 -17
  92. package/autorest/multiapi/templates/multiapi_config.py.jinja2 +3 -3
  93. package/autorest/multiapi/templates/multiapi_init.py.jinja2 +2 -2
  94. package/autorest/multiapi/templates/multiapi_operations_mixin.py.jinja2 +4 -4
  95. package/autorest/multiapi/templates/multiapi_service_client.py.jinja2 +9 -9
  96. package/autorest/multiapi/utils.py +3 -3
  97. package/autorest/postprocess/__init__.py +202 -0
  98. package/autorest/postprocess/get_all.py +19 -0
  99. package/autorest/postprocess/venvtools.py +73 -0
  100. package/autorest/preprocess/__init__.py +209 -0
  101. package/autorest/preprocess/helpers.py +54 -0
  102. package/autorest/{namer → preprocess}/python_mappings.py +25 -32
  103. package/package.json +3 -3
  104. package/run-python3.js +2 -3
  105. package/venvtools.py +1 -1
  106. package/autorest/codegen/models/constant_schema.py +0 -97
  107. package/autorest/codegen/models/credential_schema.py +0 -90
  108. package/autorest/codegen/models/credential_schema_policy.py +0 -77
  109. package/autorest/codegen/models/dictionary_schema.py +0 -103
  110. package/autorest/codegen/models/enum_schema.py +0 -246
  111. package/autorest/codegen/models/list_schema.py +0 -113
  112. package/autorest/codegen/models/object_schema.py +0 -249
  113. package/autorest/codegen/models/primitive_schemas.py +0 -476
  114. package/autorest/codegen/models/request_builder_parameter_list.py +0 -280
  115. package/autorest/codegen/models/rest.py +0 -42
  116. package/autorest/codegen/models/schema_request.py +0 -45
  117. package/autorest/codegen/models/schema_response.py +0 -123
  118. package/autorest/codegen/serializers/rest_serializer.py +0 -57
  119. package/autorest/namer/__init__.py +0 -25
  120. 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,38 +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
- ))
42
+ imports.merge(
43
+ operation_group.imports(
44
+ async_mode=self.async_mode,
45
+ is_python3_file=self.is_python3_file,
46
+ )
47
+ )
47
48
 
48
- 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
+ )
49
52
  return template.render(
50
53
  code_model=self.code_model,
51
54
  operation_groups=operation_groups,
52
55
  imports=FileImportSerializer(
53
56
  imports,
54
57
  is_python3_file=self.is_python3_file,
55
- async_mode=self.async_mode
58
+ async_mode=self.async_mode,
56
59
  ),
57
60
  async_mode=self.async_mode,
58
61
  is_python3_file=self.is_python3_file,
59
- is_lro=_is_lro,
60
- is_paging=_is_paging,
61
62
  get_operation_serializer=functools.partial(
62
63
  get_operation_serializer,
63
64
  code_model=self.code_model,
64
65
  async_mode=self.async_mode,
65
66
  is_python3_file=self.is_python3_file,
66
67
  ),
67
- request_builder_serializer=get_request_builder_serializer(
68
- 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,
69
72
  ),
70
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)
@@ -4,12 +4,24 @@
4
4
  # license information.
5
5
  # --------------------------------------------------------------------------
6
6
  from jinja2 import Environment
7
+ from .import_serializer import FileImportSerializer
8
+ from ..models import CodeModel, FileImport, ImportType, TypingSection
7
9
 
8
10
 
9
11
  class PatchSerializer:
10
- def __init__(self, env: Environment) -> None:
12
+ def __init__(self, env: Environment, code_model: CodeModel) -> None:
11
13
  self.env = env
14
+ self.code_model = code_model
12
15
 
13
16
  def serialize(self) -> str:
14
17
  template = self.env.get_template("patch.py.jinja2")
15
- return template.render()
18
+ imports = FileImport()
19
+ imports.add_submodule_import(
20
+ "typing", "List", ImportType.STDLIB, TypingSection.CONDITIONAL
21
+ )
22
+ is_python3_file = self.code_model.options["python3_only"]
23
+ return template.render(
24
+ code_model=self.code_model,
25
+ imports=FileImportSerializer(imports, is_python3_file=is_python3_file),
26
+ is_python3_file=is_python3_file,
27
+ )
@@ -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,95 +3,6 @@
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 List
7
- from ..models import ParameterStyle, ListSchema, Parameter
8
-
9
-
10
- def serialize_method(
11
- *,
12
- function_def: str,
13
- method_name: str,
14
- is_in_class: bool,
15
- method_param_signatures: List[str],
16
- ignore_inconsistent_return_statements: bool = False,
17
- ):
18
- lines: List[str] = []
19
- first_line = f"{function_def} {method_name}("
20
- if ignore_inconsistent_return_statements:
21
- first_line += " # pylint: disable=inconsistent-return-statements"
22
- lines.append(first_line)
23
- if is_in_class:
24
- lines.append(" self,")
25
- lines.extend([
26
- (" " + line)
27
- for line in method_param_signatures
28
- ])
29
- lines.append(")")
30
- return "\n".join(lines)
31
-
32
- def build_serialize_data_call(
33
- parameter: Parameter, function_name: str, serializer_name: str
34
- ) -> str:
35
-
36
- optional_parameters = []
37
-
38
- if parameter.skip_url_encoding:
39
- optional_parameters.append("skip_quote=True")
40
-
41
- if parameter.style and not parameter.explode:
42
- if parameter.style in [ParameterStyle.simple, ParameterStyle.form]:
43
- div_char = ","
44
- elif parameter.style in [ParameterStyle.spaceDelimited]:
45
- div_char = " "
46
- elif parameter.style in [ParameterStyle.pipeDelimited]:
47
- div_char = "|"
48
- elif parameter.style in [ParameterStyle.tabDelimited]:
49
- div_char = "\t"
50
- else:
51
- raise ValueError(f"Do not support {parameter.style} yet")
52
- optional_parameters.append(f"div='{div_char}'")
53
-
54
- if parameter.explode:
55
- if not isinstance(parameter.schema, ListSchema):
56
- raise ValueError("Got a explode boolean on a non-array schema")
57
- serialization_schema = parameter.schema.element_type
58
- else:
59
- serialization_schema = parameter.schema
60
-
61
- serialization_constraints = serialization_schema.serialization_constraints
62
- if serialization_constraints:
63
- optional_parameters += serialization_constraints
64
-
65
- origin_name = parameter.full_serialized_name
66
-
67
- parameters = [
68
- f'"{origin_name.lstrip("_")}"',
69
- "q" if parameter.explode else origin_name,
70
- f"'{serialization_schema.serialization_type}'",
71
- *optional_parameters
72
- ]
73
- parameters_line = ', '.join(parameters)
74
-
75
- serialize_line = f'{serializer_name}.{function_name}({parameters_line})'
76
-
77
- if parameter.explode:
78
- return f"[{serialize_line} if q is not None else '' for q in {origin_name}]"
79
- return serialize_line
80
-
81
- def serialize_path(
82
- parameters: List[Parameter], serializer_name: str
83
- ) -> List[str]:
84
- retval = ["path_format_arguments = {"]
85
- retval.extend([
86
- " \"{}\": {},".format(
87
- path_parameter.rest_api_name,
88
- build_serialize_data_call(path_parameter, "url", serializer_name)
89
- )
90
- for path_parameter in parameters
91
- ])
92
- retval.append("}")
93
- return retval
94
-
95
6
  def method_signature_and_response_type_annotation_template(
96
7
  *,
97
8
  is_python3_file: bool,
@@ -101,17 +12,3 @@ def method_signature_and_response_type_annotation_template(
101
12
  if is_python3_file:
102
13
  return f"{method_signature} -> {response_type_annotation}:"
103
14
  return f"{method_signature}:\n # type: (...) -> {response_type_annotation}"
104
-
105
- def pop_kwargs_from_signature(kwargs_to_pop: List[Parameter]) -> List[str]:
106
- retval = []
107
- for kwarg in kwargs_to_pop:
108
- if kwarg.has_default_value:
109
- retval.append(
110
- f"{kwarg.serialized_name} = kwargs.pop('{kwarg.serialized_name}', "
111
- + f"{kwarg.default_value_declaration}) # type: {kwarg.type_annotation}"
112
- )
113
- else:
114
- retval.append(
115
- f"{kwarg.serialized_name} = kwargs.pop('{kwarg.serialized_name}') # type: {kwarg.type_annotation}"
116
- )
117
- 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