@autorest/python 5.14.0 → 5.15.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 (58) hide show
  1. package/ChangeLog.md +29 -0
  2. package/autorest/codegen/__init__.py +87 -47
  3. package/autorest/codegen/models/base_schema.py +2 -6
  4. package/autorest/codegen/models/client.py +6 -0
  5. package/autorest/codegen/models/code_model.py +40 -74
  6. package/autorest/codegen/models/constant_schema.py +7 -3
  7. package/autorest/codegen/models/credential_model.py +47 -0
  8. package/autorest/codegen/models/credential_schema.py +5 -4
  9. package/autorest/codegen/models/dictionary_schema.py +7 -7
  10. package/autorest/codegen/models/enum_schema.py +8 -39
  11. package/autorest/codegen/models/imports.py +3 -1
  12. package/autorest/codegen/models/list_schema.py +18 -8
  13. package/autorest/codegen/models/lro_operation.py +3 -3
  14. package/autorest/codegen/models/lro_paging_operation.py +3 -3
  15. package/autorest/codegen/models/object_schema.py +17 -13
  16. package/autorest/codegen/models/operation.py +27 -6
  17. package/autorest/codegen/models/operation_group.py +7 -2
  18. package/autorest/codegen/models/paging_operation.py +3 -3
  19. package/autorest/codegen/models/parameter.py +39 -15
  20. package/autorest/codegen/models/parameter_list.py +1 -1
  21. package/autorest/codegen/models/primitive_schemas.py +15 -25
  22. package/autorest/codegen/models/property.py +5 -5
  23. package/autorest/codegen/models/request_builder.py +4 -4
  24. package/autorest/codegen/models/request_builder_parameter.py +12 -5
  25. package/autorest/codegen/models/schema_response.py +23 -10
  26. package/autorest/codegen/models/utils.py +20 -0
  27. package/autorest/codegen/serializers/__init__.py +49 -25
  28. package/autorest/codegen/serializers/builder_serializer.py +79 -37
  29. package/autorest/codegen/serializers/client_serializer.py +16 -6
  30. package/autorest/codegen/serializers/general_serializer.py +24 -3
  31. package/autorest/codegen/serializers/import_serializer.py +1 -1
  32. package/autorest/codegen/serializers/metadata_serializer.py +1 -1
  33. package/autorest/codegen/serializers/model_base_serializer.py +8 -0
  34. package/autorest/codegen/serializers/model_python3_serializer.py +2 -2
  35. package/autorest/codegen/serializers/operation_groups_serializer.py +1 -0
  36. package/autorest/codegen/serializers/patch_serializer.py +12 -3
  37. package/autorest/codegen/serializers/utils.py +29 -4
  38. package/autorest/codegen/templates/config.py.jinja2 +4 -4
  39. package/autorest/codegen/templates/enum.py.jinja2 +1 -1
  40. package/autorest/codegen/templates/enum_container.py.jinja2 +0 -1
  41. package/autorest/codegen/templates/init.py.jinja2 +9 -6
  42. package/autorest/codegen/templates/keywords.jinja2 +14 -1
  43. package/autorest/codegen/templates/lro_operation.py.jinja2 +1 -1
  44. package/autorest/codegen/templates/lro_paging_operation.py.jinja2 +1 -1
  45. package/autorest/codegen/templates/metadata.json.jinja2 +3 -3
  46. package/autorest/codegen/templates/model.py.jinja2 +1 -6
  47. package/autorest/codegen/templates/model_init.py.jinja2 +7 -4
  48. package/autorest/codegen/templates/operation.py.jinja2 +2 -3
  49. package/autorest/codegen/templates/operation_group.py.jinja2 +12 -5
  50. package/autorest/codegen/templates/operation_groups_container.py.jinja2 +0 -1
  51. package/autorest/codegen/templates/operations_folder_init.py.jinja2 +4 -0
  52. package/autorest/codegen/templates/paging_operation.py.jinja2 +1 -1
  53. package/autorest/codegen/templates/patch.py.jinja2 +18 -29
  54. package/autorest/codegen/templates/request_builder.py.jinja2 +4 -6
  55. package/autorest/codegen/templates/vendor.py.jinja2 +12 -2
  56. package/autorest/multiapi/models/imports.py +21 -11
  57. package/autorest/multiapi/serializers/import_serializer.py +3 -1
  58. package/package.json +2 -2
@@ -39,8 +39,7 @@ class PrimitiveSchema(BaseSchema):
39
39
  def docstring_type(self) -> str:
40
40
  return self._to_python_type()
41
41
 
42
- @property
43
- def type_annotation(self) -> str:
42
+ def type_annotation(self, *, is_operation_file: bool = False) -> str: # pylint: disable=unused-argument
44
43
  return self.docstring_type
45
44
 
46
45
  @property
@@ -102,8 +101,7 @@ class IOSchema(PrimitiveSchema):
102
101
  def docstring_type(self) -> str:
103
102
  return self.type
104
103
 
105
- @property
106
- def type_annotation(self) -> str:
104
+ def type_annotation(self, *, is_operation_file: bool = False) -> str: # pylint: disable=unused-argument
107
105
  return self.docstring_type
108
106
 
109
107
  @property
@@ -128,8 +126,7 @@ class AnySchema(PrimitiveSchema):
128
126
  def docstring_type(self) -> str:
129
127
  return "any"
130
128
 
131
- @property
132
- def type_annotation(self) -> str:
129
+ def type_annotation(self, *, is_operation_file: bool = False) -> str: # pylint: disable=unused-argument
133
130
  return "Any"
134
131
 
135
132
  @property
@@ -147,8 +144,7 @@ class JSONSchema(AnySchema):
147
144
  def docstring_type(self) -> str:
148
145
  return "JSONType"
149
146
 
150
- @property
151
- def type_annotation(self) -> str:
147
+ def type_annotation(self, *, is_operation_file: bool = False) -> str: # pylint: disable=unused-argument
152
148
  return "JSONType"
153
149
 
154
150
 
@@ -206,8 +202,7 @@ class NumberSchema(PrimitiveSchema):
206
202
  return "int"
207
203
  return "float"
208
204
 
209
- @property
210
- def type_annotation(self) -> str:
205
+ def type_annotation(self, *, is_operation_file: bool = False) -> str: # pylint: disable=unused-argument
211
206
  python_type = self.docstring_type
212
207
  if python_type == "long":
213
208
  return "int"
@@ -269,10 +264,9 @@ class DatetimeSchema(PrimitiveSchema):
269
264
 
270
265
  @property
271
266
  def docstring_type(self) -> str:
272
- return "~" + self.type_annotation
267
+ return "~" + self.type_annotation()
273
268
 
274
- @property
275
- def type_annotation(self) -> str:
269
+ def type_annotation(self, *, is_operation_file: bool = False) -> str: # pylint: disable=unused-argument
276
270
  return "datetime.datetime"
277
271
 
278
272
  @property
@@ -301,10 +295,9 @@ class TimeSchema(PrimitiveSchema):
301
295
 
302
296
  @property
303
297
  def docstring_type(self) -> str:
304
- return "~" + self.type_annotation
298
+ return "~" + self.type_annotation()
305
299
 
306
- @property
307
- def type_annotation(self) -> str:
300
+ def type_annotation(self, *, is_operation_file: bool = False) -> str: # pylint: disable=unused-argument
308
301
  return "datetime.time"
309
302
 
310
303
  @property
@@ -334,10 +327,9 @@ class UnixTimeSchema(PrimitiveSchema):
334
327
 
335
328
  @property
336
329
  def docstring_type(self) -> str:
337
- return "~" + self.type_annotation
330
+ return "~" + self.type_annotation()
338
331
 
339
- @property
340
- def type_annotation(self) -> str:
332
+ def type_annotation(self, *, is_operation_file: bool = False) -> str: # pylint: disable=unused-argument
341
333
  return "datetime.datetime"
342
334
 
343
335
  @property
@@ -367,10 +359,9 @@ class DateSchema(PrimitiveSchema):
367
359
 
368
360
  @property
369
361
  def docstring_type(self) -> str:
370
- return "~" + self.type_annotation
362
+ return "~" + self.type_annotation()
371
363
 
372
- @property
373
- def type_annotation(self) -> str:
364
+ def type_annotation(self, *, is_operation_file: bool = False) -> str: # pylint: disable=unused-argument
374
365
  return "datetime.date"
375
366
 
376
367
  @property
@@ -400,10 +391,9 @@ class DurationSchema(PrimitiveSchema):
400
391
 
401
392
  @property
402
393
  def docstring_type(self) -> str:
403
- return "~" + self.type_annotation
394
+ return "~" + self.type_annotation()
404
395
 
405
- @property
406
- def type_annotation(self) -> str:
396
+ def type_annotation(self, *, is_operation_file: bool = False) -> str: # pylint: disable=unused-argument
407
397
  return "datetime.timedelta"
408
398
 
409
399
  @property
@@ -60,7 +60,7 @@ class Property(BaseModel): # pylint: disable=too-many-instance-attributes
60
60
  values = [self.schema.enum_type.get_declaration(v.value) for v in self.schema.values]
61
61
  if description and description[-1] != " ":
62
62
  description += " "
63
- description += "Possible values include: {}.".format(", ".join(values))
63
+ description += "Known values are: {}.".format(", ".join(values))
64
64
  if self.schema.default_value:
65
65
  description += f' Default value: "{self.schema.default_value}".'
66
66
  return description
@@ -149,11 +149,10 @@ class Property(BaseModel): # pylint: disable=too-many-instance-attributes
149
149
  return self.schema.get_declaration(self.client_default_value)
150
150
  return self.schema.default_value_declaration
151
151
 
152
- @property
153
- def type_annotation(self) -> str:
152
+ def type_annotation(self, *, is_operation_file: bool = False) -> str:
154
153
  if self.required:
155
- return self.schema.type_annotation
156
- return f"Optional[{self.schema.type_annotation}]"
154
+ return self.schema.type_annotation(is_operation_file=is_operation_file)
155
+ return f"Optional[{self.schema.type_annotation(is_operation_file=is_operation_file)}]"
157
156
 
158
157
  def get_json_template_representation(self, **kwargs: Any) -> Any:
159
158
  kwargs["optional"] = not self.required
@@ -171,4 +170,5 @@ class Property(BaseModel): # pylint: disable=too-many-instance-attributes
171
170
  file_import = self.schema.model_file_imports()
172
171
  if not self.required:
173
172
  file_import.add_submodule_import("typing", "Optional", ImportType.STDLIB, TypingSection.CONDITIONAL)
173
+ file_import.merge(self.schema.model_file_imports())
174
174
  return file_import
@@ -82,9 +82,7 @@ class RequestBuilder(BaseBuilder):
82
82
  f"{relative_path}_vendor", "_format_url_section", ImportType.LOCAL
83
83
  )
84
84
  if self.parameters.headers or self.parameters.query:
85
- file_import.add_submodule_import(
86
- "typing", "Dict", ImportType.STDLIB, typing_section=TypingSection.CONDITIONAL
87
- )
85
+ file_import.add_submodule_import("azure.core.utils", "case_insensitive_dict", ImportType.AZURECORE)
88
86
  file_import.add_submodule_import(
89
87
  "typing", "Any", ImportType.STDLIB, typing_section=TypingSection.CONDITIONAL
90
88
  )
@@ -130,7 +128,9 @@ class RequestBuilder(BaseBuilder):
130
128
  schema_requests=schema_requests,
131
129
  parameters=parameter_list,
132
130
  description=yaml_data["language"]["python"]["description"],
133
- responses=[SchemaResponse.from_yaml(yaml) for yaml in yaml_data.get("responses", [])],
131
+ responses=[
132
+ SchemaResponse.from_yaml(yaml, code_model=code_model) for yaml in yaml_data.get("responses", [])
133
+ ],
134
134
  summary=yaml_data["language"]["python"].get("summary"),
135
135
  )
136
136
  code_model.request_builder_ids[id(yaml_data)] = request_builder_class
@@ -4,7 +4,8 @@
4
4
  # license information.
5
5
  # --------------------------------------------------------------------------
6
6
  from typing import Any, Dict, List, Optional
7
- from .parameter import ParameterOnlyPathAndBodyPositional, ParameterLocation, ParameterStyle
7
+ from .parameter import ParameterOnlyPathAndBodyPositional, ParameterLocation, ParameterStyle, get_target_property_name
8
+ from .utils import get_schema
8
9
 
9
10
  def _make_public(name):
10
11
  if name[0] == "_":
@@ -16,8 +17,8 @@ class RequestBuilderParameter(ParameterOnlyPathAndBodyPositional):
16
17
  @property
17
18
  def in_method_signature(self) -> bool:
18
19
  return not(
19
- # don't put accept in method signature
20
- self.rest_api_name == "Accept"
20
+ # if not inputtable, don't put in signature
21
+ not self.inputtable_by_user
21
22
  # If i'm not in the method code, no point in being in signature
22
23
  or not self.in_method_code
23
24
  # If I'm a flattened property of a body, don't want me, want the body param
@@ -78,10 +79,16 @@ class RequestBuilderParameter(ParameterOnlyPathAndBodyPositional):
78
79
  http_protocol = yaml_data["protocol"].get("http", {"in": ParameterLocation.Other})
79
80
  name = yaml_data["language"]["python"]["name"]
80
81
  location = ParameterLocation(http_protocol["in"])
82
+ serialized_name = yaml_data["language"]["python"]["name"]
83
+ schema = get_schema(
84
+ code_model, yaml_data.get("schema"), serialized_name
85
+ )
86
+ target_property = yaml_data.get("targetProperty")
87
+ target_property_name = get_target_property_name(code_model, id(target_property)) if target_property else None
81
88
  return cls(
82
89
  code_model=code_model,
83
90
  yaml_data=yaml_data,
84
- schema=yaml_data.get("schema", None), # FIXME replace by operation model
91
+ schema=schema,
85
92
  # See also https://github.com/Azure/autorest.modelerfour/issues/80
86
93
  rest_api_name=yaml_data["language"]["default"].get(
87
94
  "serializedName", yaml_data["language"]["default"]["name"]
@@ -93,7 +100,7 @@ class RequestBuilderParameter(ParameterOnlyPathAndBodyPositional):
93
100
  location=location,
94
101
  skip_url_encoding=yaml_data.get("extensions", {}).get("x-ms-skip-url-encoding", False),
95
102
  constraints=[], # FIXME constraints
96
- target_property_name=id(yaml_data["targetProperty"]) if yaml_data.get("targetProperty") else None,
103
+ target_property_name=target_property_name,
97
104
  style=ParameterStyle(http_protocol["style"]) if "style" in http_protocol else None,
98
105
  explode=http_protocol.get("explode", False),
99
106
  grouped_by=yaml_data.get("groupedBy", None),
@@ -3,12 +3,17 @@
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 Dict, Optional, List, Union, Any, cast
6
+ from typing import Dict, Optional, List, Union, Any, cast, TYPE_CHECKING
7
7
 
8
8
  from .base_model import BaseModel
9
9
  from .base_schema import BaseSchema
10
10
  from .object_schema import ObjectSchema
11
11
  from .imports import FileImport, ImportType
12
+ from .utils import get_schema
13
+ from .primitive_schemas import IOSchema
14
+
15
+ if TYPE_CHECKING:
16
+ from .code_model import CodeModel
12
17
 
13
18
 
14
19
  class HeaderResponse:
@@ -24,6 +29,7 @@ class HeaderResponse:
24
29
  class SchemaResponse(BaseModel):
25
30
  def __init__(
26
31
  self,
32
+ code_model: "CodeModel",
27
33
  yaml_data: Dict[str, Any],
28
34
  schema: Optional[BaseSchema],
29
35
  content_types: List[str],
@@ -32,6 +38,7 @@ class SchemaResponse(BaseModel):
32
38
  binary: bool,
33
39
  ) -> None:
34
40
  super().__init__(yaml_data)
41
+ self.code_model = code_model
35
42
  self.schema = schema
36
43
  self.content_types = content_types
37
44
  self.status_codes = status_codes
@@ -57,13 +64,12 @@ class SchemaResponse(BaseModel):
57
64
  return self.schema.serialization_type
58
65
  return "None"
59
66
 
60
- @property
61
- def operation_type_annotation(self) -> str:
67
+ def type_annotation(self, *, is_operation_file: bool = False) -> str:
62
68
  if not self.schema:
63
69
  return "None"
64
70
  if self.nullable:
65
- return f"Optional[{self.schema.operation_type_annotation}]"
66
- return self.schema.operation_type_annotation
71
+ return f"Optional[{self.schema.type_annotation(is_operation_file=is_operation_file)}]"
72
+ return self.schema.type_annotation(is_operation_file=is_operation_file)
67
73
 
68
74
  @property
69
75
  def docstring_text(self) -> str:
@@ -103,20 +109,27 @@ class SchemaResponse(BaseModel):
103
109
  return file_import
104
110
 
105
111
  @classmethod
106
- def from_yaml(cls, yaml_data: Dict[str, Any]) -> "SchemaResponse":
107
-
112
+ def from_yaml(cls, yaml_data: Dict[str, Any], *, code_model: "CodeModel") -> "SchemaResponse":
113
+ binary = yaml_data.get("binary", False)
114
+ if binary:
115
+ schema: BaseSchema = IOSchema(namespace=None, yaml_data={})
116
+ else:
117
+ schema = get_schema(code_model, yaml_data.get("schema"))
108
118
  return cls(
119
+ code_model=code_model,
109
120
  yaml_data=yaml_data,
110
- schema=yaml_data.get("schema", None), # FIXME replace by operation model
121
+ schema=schema,
111
122
  content_types=yaml_data["protocol"]["http"].get("mediaTypes", []),
112
123
  status_codes=[
113
124
  int(code) if code != "default" else "default" for code in yaml_data["protocol"]["http"]["statusCodes"]
114
125
  ],
115
126
  headers=[
116
- HeaderResponse(header_prop["header"], header_prop["schema"])
127
+ HeaderResponse(
128
+ header_prop["header"], get_schema(code_model, header_prop["schema"], header_prop["header"])
129
+ )
117
130
  for header_prop in yaml_data["protocol"]["http"].get("headers", [])
118
131
  ],
119
- binary=yaml_data.get("binary", False),
132
+ binary=binary,
120
133
  )
121
134
 
122
135
  def __repr__(self) -> str:
@@ -4,5 +4,25 @@
4
4
  # license information.
5
5
  # --------------------------------------------------------------------------
6
6
  import re
7
+ from typing import Any, TYPE_CHECKING
8
+ import logging
9
+ from .base_schema import BaseSchema
10
+
11
+ if TYPE_CHECKING:
12
+ from .code_model import CodeModel
13
+
14
+
15
+ _LOGGER = logging.getLogger(__name__)
7
16
 
8
17
  JSON_REGEXP = re.compile(r'^(application|text)/(.+\+)?json$')
18
+
19
+ def get_schema(code_model: "CodeModel", schema: Any, serialized_name: str = "unknown") -> BaseSchema:
20
+ if not isinstance(schema, dict):
21
+ return schema
22
+ schema_id = id(schema)
23
+ _LOGGER.debug("Looking for id %s for member %s", schema_id, serialized_name)
24
+ try:
25
+ return code_model.lookup_schema(schema_id)
26
+ except KeyError:
27
+ _LOGGER.critical("Unable to ref the object")
28
+ raise
@@ -49,6 +49,10 @@ class JinjaSerializer:
49
49
  self._autorestapi = autorestapi
50
50
  self.code_model = code_model
51
51
 
52
+ @property
53
+ def has_aio_folder(self) -> bool:
54
+ return not self.code_model.options["no_async"] and bool(self.code_model.rest.request_builders)
55
+
52
56
  def serialize(self) -> None:
53
57
  env = Environment(
54
58
  loader=PackageLoader("autorest.codegen", "templates"),
@@ -64,17 +68,28 @@ class JinjaSerializer:
64
68
  if self.code_model.options["no_namespace_folders"]
65
69
  else Path(*(self.code_model.namespace.split(".")))
66
70
  )
67
-
68
71
  # if there was a patch file before, we keep it
69
72
  self._keep_patch_file(namespace_path / Path("_patch.py"), env)
70
- self._keep_patch_file(namespace_path / Path("aio") / Path("_patch.py"), env)
73
+ if self.has_aio_folder:
74
+ self._keep_patch_file(namespace_path / Path("aio") / Path("_patch.py"), env)
75
+
76
+ if self.code_model.options["models_mode"] and (self.code_model.schemas or self.code_model.enums):
77
+ self._keep_patch_file(namespace_path / Path("models") / Path("_patch.py"), env)
78
+ if self.code_model.options["show_operations"] and self.code_model.operation_groups:
79
+ self._keep_patch_file(
80
+ namespace_path / Path(self.code_model.operations_folder_name) / Path("_patch.py"), env
81
+ )
82
+ if self.has_aio_folder:
83
+ self._keep_patch_file(
84
+ namespace_path / Path("aio") / Path(self.code_model.operations_folder_name) / Path("_patch.py"), env
85
+ )
71
86
 
72
87
  self._serialize_and_write_top_level_folder(env=env, namespace_path=namespace_path)
73
88
 
74
89
  if self.code_model.rest.request_builders:
75
90
  if self.code_model.options["builders_visibility"] != "embedded":
76
91
  self._serialize_and_write_rest_layer(env=env, namespace_path=namespace_path)
77
- if not self.code_model.options["no_async"]:
92
+ if self.has_aio_folder:
78
93
  self._serialize_and_write_aio_top_level_folder(
79
94
  env=env, namespace_path=namespace_path,
80
95
  )
@@ -88,6 +103,12 @@ class JinjaSerializer:
88
103
 
89
104
  if self.code_model.options["models_mode"] and (self.code_model.schemas or self.code_model.enums):
90
105
  self._serialize_and_write_models_folder(env=env, namespace_path=namespace_path)
106
+ if not self.code_model.options["models_mode"]:
107
+ # keep models file if users ended up just writing a models file
108
+ if self._autorestapi.read_file(namespace_path / Path("models.py")):
109
+ self._autorestapi.write_file(
110
+ namespace_path / Path("models.py"), self._autorestapi.read_file(namespace_path / Path("models.py"))
111
+ )
91
112
 
92
113
  if self.code_model.options["package_mode"]:
93
114
  self._serialize_and_write_package_files(out_path=namespace_path)
@@ -106,7 +127,10 @@ class JinjaSerializer:
106
127
  def _prepare_params() -> Dict[Any, Any]:
107
128
  package_parts = self.code_model.options["package_name"].split("-")[:-1]
108
129
  try:
109
- token_cred = isinstance(self.code_model.credential_schema_policy.credential, TokenCredentialSchema)
130
+ token_cred = isinstance(
131
+ self.code_model.credential_model.credential_schema_policy.credential,
132
+ TokenCredentialSchema
133
+ )
110
134
  except ValueError:
111
135
  token_cred = False
112
136
  version = self.code_model.options["package_version"]
@@ -149,8 +173,7 @@ class JinjaSerializer:
149
173
  if self._autorestapi.read_file(path_file):
150
174
  self._autorestapi.write_file(path_file, self._autorestapi.read_file(path_file))
151
175
  else:
152
- self._autorestapi.write_file(path_file, PatchSerializer(env=env).serialize())
153
-
176
+ self._autorestapi.write_file(path_file, PatchSerializer(env=env, code_model=self.code_model).serialize())
154
177
 
155
178
  def _serialize_and_write_models_folder(self, env: Environment, namespace_path: Path) -> None:
156
179
  # Write the models folder
@@ -158,16 +181,16 @@ class JinjaSerializer:
158
181
  if self.code_model.schemas:
159
182
  if not self.code_model.options['python3_only']:
160
183
  self._autorestapi.write_file(
161
- models_path / Path("_models.py"),
184
+ models_path / Path(f"{self.code_model.get_models_filename(is_python3_file=False)}.py"),
162
185
  ModelGenericSerializer(code_model=self.code_model, env=env).serialize()
163
186
  )
164
187
  self._autorestapi.write_file(
165
- models_path / Path("_models_py3.py"),
188
+ models_path / Path(f"{self.code_model.get_models_filename(is_python3_file=True)}.py"),
166
189
  ModelPython3Serializer(code_model=self.code_model, env=env).serialize()
167
190
  )
168
191
  if self.code_model.enums:
169
192
  self._autorestapi.write_file(
170
- models_path / Path(f"_{self.code_model.module_name}_enums.py"),
193
+ models_path / Path(f"{self.code_model.enums_filename}.py"),
171
194
  EnumSerializer(code_model=self.code_model, env=env).serialize(),
172
195
  )
173
196
  self._autorestapi.write_file(
@@ -257,7 +280,7 @@ class JinjaSerializer:
257
280
  operation_group_serializer.serialize(),
258
281
  )
259
282
 
260
- if not self.code_model.options["no_async"]:
283
+ if self.has_aio_folder:
261
284
  # write async operation group and operation files
262
285
  operation_group_async_serializer = OperationGroupsSerializer(
263
286
  code_model=self.code_model,
@@ -287,7 +310,7 @@ class JinjaSerializer:
287
310
  )
288
311
 
289
312
  # write async operations init file
290
- if not self.code_model.options["no_async"]:
313
+ if self.has_aio_folder:
291
314
  operations_async_init_serializer = OperationsInitSerializer(
292
315
  code_model=self.code_model, env=env, async_mode=True
293
316
  )
@@ -336,14 +359,9 @@ class JinjaSerializer:
336
359
  ) -> None:
337
360
  general_serializer = GeneralSerializer(code_model=self.code_model, env=env, async_mode=False)
338
361
 
339
- if self.code_model.rest.request_builders:
340
- self._autorestapi.write_file(
341
- namespace_path / Path("__init__.py"), general_serializer.serialize_init_file()
342
- )
343
- else:
344
- self._autorestapi.write_file(
345
- namespace_path / Path("__init__.py"), general_serializer.serialize_pkgutil_init_file()
346
- )
362
+ self._autorestapi.write_file(
363
+ namespace_path / Path("__init__.py"), general_serializer.serialize_init_file()
364
+ )
347
365
  p = namespace_path.parent
348
366
  while p != Path("."):
349
367
  # write pkgutil init file
@@ -355,11 +373,11 @@ class JinjaSerializer:
355
373
  # Write the service client
356
374
  if self.code_model.rest.request_builders:
357
375
  self._autorestapi.write_file(
358
- namespace_path / Path(f"_{self.code_model.module_name}.py"),
376
+ namespace_path / Path(f"{self.code_model.service_client.filename}.py"),
359
377
  general_serializer.serialize_service_client_file()
360
378
  )
361
379
 
362
- if self.code_model.need_vendored_code:
380
+ if self.code_model.need_vendored_code(async_mode=False):
363
381
  self._autorestapi.write_file(
364
382
  namespace_path / Path("_vendor.py"),
365
383
  general_serializer.serialize_vendor_file()
@@ -391,15 +409,21 @@ class JinjaSerializer:
391
409
  self._autorestapi.write_file(aio_path / Path("__init__.py"), aio_general_serializer.serialize_init_file())
392
410
 
393
411
  # Write the service client
394
- self._autorestapi.write_file(
395
- aio_path / Path(f"_{self.code_model.module_name}.py"),
396
- aio_general_serializer.serialize_service_client_file(),
397
- )
412
+ if self.code_model.rest.request_builders:
413
+ self._autorestapi.write_file(
414
+ aio_path / Path(f"{self.code_model.service_client.filename}.py"),
415
+ aio_general_serializer.serialize_service_client_file(),
416
+ )
398
417
 
399
418
  # Write the config file
400
419
  self._autorestapi.write_file(
401
420
  aio_path / Path("_configuration.py"), aio_general_serializer.serialize_config_file()
402
421
  )
422
+ if self.code_model.need_vendored_code(async_mode=True):
423
+ self._autorestapi.write_file(
424
+ aio_path / Path("_vendor.py"),
425
+ aio_general_serializer.serialize_vendor_file()
426
+ )
403
427
 
404
428
 
405
429
  def _serialize_and_write_metadata(self, env: Environment, namespace_path: Path) -> None: