@typespec/http-client-python 0.13.0-dev.2 → 0.13.0-dev.3

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 (103) hide show
  1. package/eng/scripts/setup/__pycache__/package_manager.cpython-39.pyc +0 -0
  2. package/eng/scripts/setup/__pycache__/venvtools.cpython-39.pyc +0 -0
  3. package/generator/build/lib/pygen/__init__.py +176 -2
  4. package/generator/build/lib/pygen/black.py +1 -1
  5. package/generator/build/lib/pygen/codegen/__init__.py +4 -256
  6. package/generator/build/lib/pygen/codegen/_utils.py +0 -3
  7. package/generator/build/lib/pygen/codegen/models/__init__.py +1 -1
  8. package/generator/build/lib/pygen/codegen/models/base_builder.py +1 -1
  9. package/generator/build/lib/pygen/codegen/models/client.py +12 -12
  10. package/generator/build/lib/pygen/codegen/models/code_model.py +10 -9
  11. package/generator/build/lib/pygen/codegen/models/enum_type.py +4 -4
  12. package/generator/build/lib/pygen/codegen/models/imports.py +1 -1
  13. package/generator/build/lib/pygen/codegen/models/list_type.py +6 -6
  14. package/generator/build/lib/pygen/codegen/models/lro_operation.py +1 -1
  15. package/generator/build/lib/pygen/codegen/models/operation.py +16 -16
  16. package/generator/build/lib/pygen/codegen/models/operation_group.py +4 -4
  17. package/generator/build/lib/pygen/codegen/models/paging_operation.py +4 -4
  18. package/generator/build/lib/pygen/codegen/models/parameter.py +8 -8
  19. package/generator/build/lib/pygen/codegen/models/property.py +1 -1
  20. package/generator/build/lib/pygen/codegen/models/request_builder.py +2 -2
  21. package/generator/build/lib/pygen/codegen/models/request_builder_parameter.py +2 -2
  22. package/generator/build/lib/pygen/codegen/models/response.py +3 -3
  23. package/generator/build/lib/pygen/codegen/serializers/__init__.py +27 -28
  24. package/generator/build/lib/pygen/codegen/serializers/builder_serializer.py +31 -31
  25. package/generator/build/lib/pygen/codegen/serializers/client_serializer.py +4 -4
  26. package/generator/build/lib/pygen/codegen/serializers/general_serializer.py +4 -4
  27. package/generator/build/lib/pygen/codegen/serializers/metadata_serializer.py +1 -1
  28. package/generator/build/lib/pygen/codegen/serializers/model_serializer.py +1 -1
  29. package/generator/build/lib/pygen/codegen/serializers/operations_init_serializer.py +1 -1
  30. package/generator/build/lib/pygen/codegen/serializers/sample_serializer.py +1 -1
  31. package/generator/build/lib/pygen/codegen/serializers/test_serializer.py +5 -5
  32. package/generator/build/lib/pygen/codegen/templates/config.py.jinja2 +1 -1
  33. package/generator/build/lib/pygen/codegen/templates/config_container.py.jinja2 +1 -1
  34. package/generator/build/lib/pygen/codegen/templates/conftest.py.jinja2 +1 -1
  35. package/generator/build/lib/pygen/codegen/templates/init.py.jinja2 +1 -1
  36. package/generator/build/lib/pygen/codegen/templates/metadata.json.jinja2 +2 -2
  37. package/generator/build/lib/pygen/codegen/templates/model_dpg.py.jinja2 +2 -2
  38. package/generator/build/lib/pygen/codegen/templates/operation_group.py.jinja2 +1 -1
  39. package/generator/build/lib/pygen/codegen/templates/operation_groups_container.py.jinja2 +1 -1
  40. package/generator/build/lib/pygen/codegen/templates/operation_tools.jinja2 +1 -1
  41. package/generator/build/lib/pygen/codegen/templates/packaging_templates/MANIFEST.in.jinja2 +1 -1
  42. package/generator/build/lib/pygen/codegen/templates/packaging_templates/README.md.jinja2 +38 -7
  43. package/generator/build/lib/pygen/codegen/templates/packaging_templates/dev_requirements.txt.jinja2 +1 -1
  44. package/generator/build/lib/pygen/codegen/templates/packaging_templates/setup.py.jinja2 +9 -9
  45. package/generator/build/lib/pygen/codegen/templates/request_builder.py.jinja2 +1 -1
  46. package/generator/build/lib/pygen/codegen/templates/sample.py.jinja2 +1 -1
  47. package/generator/build/lib/pygen/codegen/templates/test.py.jinja2 +6 -6
  48. package/generator/build/lib/pygen/codegen/templates/version.py.jinja2 +1 -1
  49. package/generator/build/lib/pygen/preprocess/__init__.py +1 -1
  50. package/generator/build/lib/pygen/utils.py +4 -0
  51. package/generator/dist/pygen-0.1.0-py3-none-any.whl +0 -0
  52. package/generator/pygen/__init__.py +176 -2
  53. package/generator/pygen/black.py +1 -1
  54. package/generator/pygen/codegen/__init__.py +4 -256
  55. package/generator/pygen/codegen/_utils.py +0 -3
  56. package/generator/pygen/codegen/models/__init__.py +1 -1
  57. package/generator/pygen/codegen/models/base_builder.py +1 -1
  58. package/generator/pygen/codegen/models/client.py +12 -12
  59. package/generator/pygen/codegen/models/code_model.py +10 -9
  60. package/generator/pygen/codegen/models/enum_type.py +4 -4
  61. package/generator/pygen/codegen/models/imports.py +1 -1
  62. package/generator/pygen/codegen/models/list_type.py +6 -6
  63. package/generator/pygen/codegen/models/lro_operation.py +1 -1
  64. package/generator/pygen/codegen/models/operation.py +16 -16
  65. package/generator/pygen/codegen/models/operation_group.py +4 -4
  66. package/generator/pygen/codegen/models/paging_operation.py +4 -4
  67. package/generator/pygen/codegen/models/parameter.py +8 -8
  68. package/generator/pygen/codegen/models/property.py +1 -1
  69. package/generator/pygen/codegen/models/request_builder.py +2 -2
  70. package/generator/pygen/codegen/models/request_builder_parameter.py +2 -2
  71. package/generator/pygen/codegen/models/response.py +3 -3
  72. package/generator/pygen/codegen/serializers/__init__.py +27 -28
  73. package/generator/pygen/codegen/serializers/builder_serializer.py +31 -31
  74. package/generator/pygen/codegen/serializers/client_serializer.py +4 -4
  75. package/generator/pygen/codegen/serializers/general_serializer.py +4 -4
  76. package/generator/pygen/codegen/serializers/metadata_serializer.py +1 -1
  77. package/generator/pygen/codegen/serializers/model_serializer.py +1 -1
  78. package/generator/pygen/codegen/serializers/operations_init_serializer.py +1 -1
  79. package/generator/pygen/codegen/serializers/sample_serializer.py +1 -1
  80. package/generator/pygen/codegen/serializers/test_serializer.py +5 -5
  81. package/generator/pygen/codegen/templates/config.py.jinja2 +1 -1
  82. package/generator/pygen/codegen/templates/config_container.py.jinja2 +1 -1
  83. package/generator/pygen/codegen/templates/conftest.py.jinja2 +1 -1
  84. package/generator/pygen/codegen/templates/init.py.jinja2 +1 -1
  85. package/generator/pygen/codegen/templates/metadata.json.jinja2 +2 -2
  86. package/generator/pygen/codegen/templates/model_dpg.py.jinja2 +2 -2
  87. package/generator/pygen/codegen/templates/operation_group.py.jinja2 +1 -1
  88. package/generator/pygen/codegen/templates/operation_groups_container.py.jinja2 +1 -1
  89. package/generator/pygen/codegen/templates/operation_tools.jinja2 +1 -1
  90. package/generator/pygen/codegen/templates/packaging_templates/MANIFEST.in.jinja2 +1 -1
  91. package/generator/pygen/codegen/templates/packaging_templates/README.md.jinja2 +38 -7
  92. package/generator/pygen/codegen/templates/packaging_templates/dev_requirements.txt.jinja2 +1 -1
  93. package/generator/pygen/codegen/templates/packaging_templates/setup.py.jinja2 +9 -9
  94. package/generator/pygen/codegen/templates/request_builder.py.jinja2 +1 -1
  95. package/generator/pygen/codegen/templates/sample.py.jinja2 +1 -1
  96. package/generator/pygen/codegen/templates/test.py.jinja2 +6 -6
  97. package/generator/pygen/codegen/templates/version.py.jinja2 +1 -1
  98. package/generator/pygen/preprocess/__init__.py +1 -1
  99. package/generator/pygen/utils.py +4 -0
  100. package/generator/test/unittests/test_optional_return_type.py +5 -5
  101. package/generator/test/unittests/test_parameter_ordering.py +5 -5
  102. package/generator/test/unittests/test_sort_schema.py +4 -4
  103. package/package.json +1 -1
@@ -9,7 +9,7 @@
9
9
  from .{{ client.filename }} import {{ client.name }} # type: ignore
10
10
  {% endfor %}
11
11
  {% endif %}
12
- {% if not async_mode and code_model.options['package_version']%}
12
+ {% if not async_mode and code_model.options.get("package-version") %}
13
13
  from {{ code_model.get_relative_import_path(serialize_namespace, module_name="_version") }} import VERSION
14
14
 
15
15
  __version__ = VERSION
@@ -9,9 +9,9 @@
9
9
  "description": {{ client.description | tojson }},
10
10
  "host_value": {{ (client.parameters.host.client_default_value_declaration if not client.has_parameterized_host else None) | tojson }},
11
11
  "parameterized_host_template": {{ (keywords.escape_str(client.url) if client.has_parameterized_host else None) | tojson }},
12
- "azure_arm": {{ client.code_model.options["azure_arm"] | tojson }},
12
+ "azure_arm": {{ client.code_model.options["azure-arm"] | tojson }},
13
13
  "has_public_lro_operations": {{ client.has_public_lro_operations | tojson }},
14
- "client_side_validation": {{ client.code_model.options["client_side_validation"] | tojson }},
14
+ "client-side-validation": {{ client.code_model.options["client-side-validation"] | tojson }},
15
15
  "sync_imports": {{ sync_client_imports | tojson }},
16
16
  "async_imports": {{ async_client_imports | tojson }}
17
17
  },
@@ -29,7 +29,7 @@
29
29
  {% endif %}
30
30
  {% endfor %}
31
31
 
32
- {% if code_model.options["models_mode"] == "dpg" and model.flattened_property %}
32
+ {% if code_model.options["models-mode"] == "dpg" and model.flattened_property %}
33
33
  __flattened_items = ["{{ model.flattened_items|join('\", \"') }}"]
34
34
  {% endif %}
35
35
 
@@ -65,7 +65,7 @@
65
65
  {% for initialize_property in initialize_properties %}
66
66
  {{ initialize_property }}
67
67
  {% endfor %}
68
- {% if code_model.options["models_mode"] == "dpg" and model.flattened_property %}
68
+ {% if code_model.options["models-mode"] == "dpg" and model.flattened_property %}
69
69
  {% set flattened_property_attr = model.flattened_property.client_name %}
70
70
 
71
71
  def __getattr__(self, name: str) -> Any:
@@ -25,7 +25,7 @@ class {{ operation_group.class_name }}: {{ operation_group.pylint_disable() }}
25
25
  :attr:`{{ operation_group.property_name }}` attribute.
26
26
  """
27
27
 
28
- {% if code_model.public_model_types and code_model.options["models_mode"] == "msrest" %}
28
+ {% if code_model.public_model_types and code_model.options["models-mode"] == "msrest" %}
29
29
  models = _models
30
30
 
31
31
  {% endif %}
@@ -6,7 +6,7 @@
6
6
  {% endif %}
7
7
  {{ imports }}
8
8
  {{ unset }}
9
- {% if code_model.options["builders_visibility"] == "embedded" and not async_mode %}
9
+ {% if code_model.options["builders-visibility"] == "embedded" and not async_mode %}
10
10
  {% if need_declare_serializer %}
11
11
  {{ op_tools.declare_serializer(code_model) }}
12
12
  {% endif %}
@@ -61,7 +61,7 @@ Example:
61
61
  {% macro declare_serializer(code_model) %}
62
62
  {% if code_model.has_non_abstract_operations %}
63
63
  _SERIALIZER = Serializer()
64
- {% if not code_model.options["client_side_validation"] %}
64
+ {% if not code_model.options["client-side-validation"] %}
65
65
  _SERIALIZER.client_side_validation = False
66
66
  {% endif %}
67
67
  {% endif %}
@@ -3,7 +3,7 @@ include LICENSE
3
3
  {% if code_model.is_tsp %}
4
4
  include {{ code_model.namespace.replace('.', '/') }}/py.typed
5
5
  {% else %}
6
- include {{ package_name.replace('-', '/') }}/py.typed
6
+ include {{ options.get("package-name", "").replace('-', '/') }}/py.typed
7
7
  {% endif %}
8
8
  recursive-include tests *.py
9
9
  recursive-include samples *.py *.md
@@ -1,8 +1,8 @@
1
1
  {% if code_model.is_azure_flavor %}
2
- {% if package_mode == "mgmtplane" %}
2
+ {% if options["package-mode"] == "mgmtplane" %}
3
3
  # Microsoft Azure SDK for Python
4
4
 
5
- This is the Microsoft {{package_pprint_name}} Client Library.
5
+ This is the Microsoft {{options["package-pprint-name"]}} Client Library.
6
6
  This package has been tested with Python 3.9+.
7
7
  For a more complete view of Azure libraries, see the [azure sdk python release](https://aka.ms/azsdk/python/all).
8
8
 
@@ -11,7 +11,7 @@ For a more complete view of Azure libraries, see the [azure sdk python release](
11
11
  To learn how to use this package, see the [quickstart guide](https://aka.ms/azsdk/python/mgmt)
12
12
 
13
13
  For docs and references, see [Python SDK References](https://docs.microsoft.com/python/api/overview/azure)
14
- Code samples for this package can be found at [{{package_pprint_name}}](https://docs.microsoft.com/samples/browse/?languages=python&term=Getting%20started%20-%20Managing&terms=Getting%20started%20-%20Managing) on docs.microsoft.com.
14
+ Code samples for this package can be found at [{{options["package-pprint-name"]}}](https://docs.microsoft.com/samples/browse/?languages=python&term=Getting%20started%20-%20Managing&terms=Getting%20started%20-%20Managing) on docs.microsoft.com.
15
15
  Additional code samples for different Azure services are available at [Samples Repo](https://aka.ms/azsdk/python/mgmt/samples)
16
16
 
17
17
  # Provide Feedback
@@ -21,9 +21,9 @@ If you encounter any bugs or have suggestions, please file an issue in the
21
21
  section of the project.
22
22
 
23
23
 
24
- ![Impressions](https://azure-sdk-impressions.azurewebsites.net/api/impressions/azure-sdk-for-python%2F{{package_name}}%2FREADME.png)
24
+ ![Impressions](https://azure-sdk-impressions.azurewebsites.net/api/impressions/azure-sdk-for-python%2F{{options["package-name"]}}%2FREADME.png)
25
25
  {% else %}
26
- # {{ package_pprint_name }} client library for Python
26
+ # {{ options["package-pprint-name"] }} client library for Python
27
27
  <!-- write necessary description of service -->
28
28
 
29
29
  ## Getting started
@@ -31,14 +31,14 @@ section of the project.
31
31
  ### Install the package
32
32
 
33
33
  ```bash
34
- python -m pip install {{ package_name }}
34
+ python -m pip install {{ options["package-name"] }}
35
35
  ```
36
36
 
37
37
  #### Prequisites
38
38
 
39
39
  - Python 3.9 or later is required to use this package.
40
40
  - You need an [Azure subscription][azure_sub] to use this package.
41
- - An existing {{ package_pprint_name }} instance.
41
+ - An existing {{ options["package-pprint-name"] }} instance.
42
42
 
43
43
  {% if token_credential and client_name %}
44
44
  #### Create with an Azure Active Directory Credential
@@ -104,4 +104,35 @@ additional questions or comments.
104
104
  [pip]: https://pypi.org/project/pip/
105
105
  [azure_sub]: https://azure.microsoft.com/free/
106
106
  {% endif %}
107
+ {% else %}
108
+ # Overview
109
+
110
+ This package is generated by `@typespec/http-client-python` with Typespec.
111
+
112
+ ## Getting started
113
+
114
+ ### Prequisites
115
+
116
+ - Python 3.9 or later is required to use this package.
117
+
118
+ ### Install the package
119
+
120
+ Step into folder where setup.py is then run:
121
+
122
+ ```bash
123
+ pip install -e .
124
+ ```
125
+
126
+ ### Examples
127
+
128
+ ```python
129
+ >>> from {{ code_model.namespace }} import {{ client_name }}
130
+ >>> from {{ code_model.core_library }}.exceptions import HttpResponseError
131
+
132
+ >>> client = {{ client_name }}(endpoint='<endpoint>')
133
+ >>> try:
134
+ <!-- write code here -->
135
+ except HttpResponseError as e:
136
+ print('service responds error: {}'.format(e.response.json()))
137
+ ```
107
138
  {% endif %}
@@ -3,7 +3,7 @@
3
3
  {% if token_credential %}
4
4
  ../../identity/azure-identity
5
5
  {% endif -%}
6
- {% if azure_arm %}
6
+ {% if options["azure-arm"] %}
7
7
  ../../core/azure-mgmt-core
8
8
  {% endif %}
9
9
  aiohttp
@@ -5,18 +5,18 @@
5
5
  {{ code_model.license_header }}
6
6
  {% endif %}
7
7
 
8
- {% if package_mode %}
8
+ {% if options["package-mode"] %}
9
9
 
10
10
  import os
11
11
  import re
12
12
  {% endif %}
13
13
  from setuptools import setup, find_packages
14
14
 
15
- {% set package_name = package_name or code_model.clients[0].name %}
15
+ {% set package_name = options["package-name"] or code_model.clients[0].name %}
16
16
 
17
17
  PACKAGE_NAME = "{{ package_name|lower }}"
18
- {% if package_mode %}
19
- PACKAGE_PPRINT_NAME = "{{ package_pprint_name }}"
18
+ {% if options["package-mode"] %}
19
+ PACKAGE_PPRINT_NAME = "{{ options["package-pprint-name"] }}"
20
20
  {% if code_model.is_tsp %}
21
21
  PACKAGE_NAMESPACE = "{{ code_model.namespace|lower }}"
22
22
 
@@ -40,7 +40,7 @@ if not version:
40
40
  {% set author_email = "azpysdkhelp@microsoft.com" %}
41
41
  {% set url = "https://github.com/Azure/azure-sdk-for-python/tree/main/sdk" %}
42
42
  {% else %}
43
- version = "{{ package_version }}"
43
+ version = "{{ options.get("package-version", "unknown") }}"
44
44
  {% set description = "\"%s\""|format(package_name) %}
45
45
  {% set long_description = code_model.description %}
46
46
  {% set author_email = "" %}
@@ -52,7 +52,7 @@ setup(
52
52
  name=PACKAGE_NAME,
53
53
  version=version,
54
54
  description={{ description }},
55
- {% if package_mode %}
55
+ {% if options["package-mode"] %}
56
56
  long_description=open("README.md", "r").read(),
57
57
  long_description_content_type="text/markdown",
58
58
  license="MIT License",
@@ -63,7 +63,7 @@ setup(
63
63
  url="{{ url }}",
64
64
  keywords="azure, azure sdk",
65
65
  {% endif %}
66
- {% if package_mode %}
66
+ {% if options["package-mode"] %}
67
67
  classifiers=[
68
68
  "Development Status :: {{ dev_status }}",
69
69
  "Programming Language :: Python",
@@ -100,7 +100,7 @@ setup(
100
100
  {% else %}
101
101
  "isodate>={{ VERSION_MAP["isodate"] }}",
102
102
  {% endif %}
103
- {% if azure_arm %}
103
+ {% if code_model.options["azure-arm"] %}
104
104
  "azure-mgmt-core>={{ VERSION_MAP["azure-mgmt-core"] }}",
105
105
  {% elif code_model.is_azure_flavor %}
106
106
  "azure-core>={{ VERSION_MAP["azure-core"] }}",
@@ -109,7 +109,7 @@ setup(
109
109
  {% endif %}
110
110
  "typing-extensions>={{ VERSION_MAP['typing-extensions'] }}",
111
111
  ],
112
- {% if package_mode %}
112
+ {% if options["package-mode"] %}
113
113
  python_requires=">={{ MIN_PYTHON_VERSION }}",
114
114
  {% else %}
115
115
  long_description="""\
@@ -1,7 +1,7 @@
1
1
  {% import 'keywords.jinja2' as keywords with context %}
2
2
  {% import 'operation_tools.jinja2' as op_tools with context %}
3
3
  {{ request_builder_serializer.method_signature_and_response_type_annotation(request_builder) }}
4
- {% if code_model.options["builders_visibility"] == "public" %}
4
+ {% if code_model.options["builders-visibility"] == "public" %}
5
5
  {{ op_tools.description(request_builder, request_builder_serializer) | indent }}
6
6
  {% endif %}
7
7
  {% if not request_builder.is_overload %}
@@ -11,7 +11,7 @@
11
11
  {% if "credential" in client_params and aad_token in client_params["credential"] %}
12
12
  pip install azure-identity
13
13
  {% endif %}
14
- pip install {{ (code_model.options["package_name"] or code_model.clients[0].name)|lower }}
14
+ pip install {{ (code_model.options.get("package-name") or code_model.clients[0].name)|lower }}
15
15
  # USAGE
16
16
  python {{ file_name }}
17
17
  {% if "credential" in client_params and aad_token in client_params["credential"] %}
@@ -1,5 +1,5 @@
1
1
  {% set prefix_lower = test.prefix|lower %}
2
- {% set client_var = "self.client" if code_model.options["azure_arm"] else "client" %}
2
+ {% set client_var = "self.client" if code_model.options["azure-arm"] else "client" %}
3
3
  {% set async = "async " if test.async_mode else "" %}
4
4
  {% set async_suffix = "_async" if test.async_mode else "" %}
5
5
  # coding=utf-8
@@ -9,13 +9,13 @@
9
9
  import pytest
10
10
  {{ imports }}
11
11
 
12
- {% if code_model.options["azure_arm"] %}
12
+ {% if code_model.options["azure-arm"] %}
13
13
  AZURE_LOCATION = "eastus"
14
14
  {% endif %}
15
15
 
16
16
  @pytest.mark.skip("you may need to update the auto-generated test case before run it")
17
17
  class {{ test.test_class_name }}({{ test.base_test_class_name }}):
18
- {% if code_model.options["azure_arm"] %}
18
+ {% if code_model.options["azure-arm"] %}
19
19
  def setup_method(self, method):
20
20
  {% if test.async_mode %}
21
21
  self.client = self.create_mgmt_client({{ test.client_name }}, is_async=True)
@@ -24,13 +24,13 @@ class {{ test.test_class_name }}({{ test.base_test_class_name }}):
24
24
  {% endif %}
25
25
  {% endif %}
26
26
  {% for testcase in test.testcases %}
27
- {% if code_model.options["azure_arm"] %}
27
+ {% if code_model.options["azure-arm"] %}
28
28
  @{{ test.preparer_name }}(location=AZURE_LOCATION)
29
29
  {% else %}
30
30
  @{{ test.preparer_name }}()
31
31
  {% endif %}
32
32
  @recorded_by_proxy{{ async_suffix }}
33
- {% if code_model.options["azure_arm"] %}
33
+ {% if code_model.options["azure-arm"] %}
34
34
  {{ async }}def test_{{ testcase.name }}(self, resource_group):
35
35
  {% else %}
36
36
  {{ async }}def test_{{ testcase.name }}(self, {{ prefix_lower }}_endpoint):
@@ -38,7 +38,7 @@ class {{ test.test_class_name }}({{ test.base_test_class_name }}):
38
38
  {% endif %}
39
39
  {{testcase.response }}{{ client_var }}{{ testcase.operation_group_prefix }}.{{ testcase.operation.name }}(
40
40
  {% for key, value in testcase.params.items() %}
41
- {% if code_model.options["azure_arm"] and key == "resource_group_name" %}
41
+ {% if code_model.options["azure-arm"] and key == "resource_group_name" %}
42
42
  {{ key }}=resource_group.name,
43
43
  {% else %}
44
44
  {{ key }}={{ value|indent(12) }},
@@ -3,4 +3,4 @@
3
3
  {{ code_model.license_header }}
4
4
  {% endif %}
5
5
 
6
- VERSION = "{{ code_model.options['package_version'] }}"
6
+ VERSION = "{{ code_model.options.get("package-version") }}"
@@ -210,7 +210,7 @@ class PreProcessPlugin(YamlUpdatePlugin):
210
210
  if not (self.is_tsp and has_multi_part_content_type(body_parameter)):
211
211
  body_parameter["type"]["types"].append(KNOWN_TYPES["binary"])
212
212
 
213
- if origin_type == "model" and is_dpg_model and self.models_mode == "dpg":
213
+ if origin_type == "model" and is_dpg_model and self.options["models-mode"] == "dpg":
214
214
  body_parameter["type"]["types"].insert(1, KNOWN_TYPES["any-object"])
215
215
  code_model["types"].append(body_parameter["type"])
216
216
 
@@ -7,6 +7,10 @@ from typing import Any, Dict, Tuple, List
7
7
  import re
8
8
  import argparse
9
9
 
10
+ SWAGGER_PACKAGE_MODE = ["mgmtplane", "dataplane"] # for backward compatibility
11
+ TYPESPEC_PACKAGE_MODE = ["azure-mgmt", "azure-dataplane", "generic"]
12
+ VALID_PACKAGE_MODE = SWAGGER_PACKAGE_MODE + TYPESPEC_PACKAGE_MODE
13
+
10
14
 
11
15
  def update_enum_value(name: str, value: Any, description: str, enum_type: Dict[str, Any]) -> Dict[str, Any]:
12
16
  return {
@@ -3,13 +3,15 @@
3
3
  # Licensed under the MIT License. See License.txt in the project root for
4
4
  # license information.
5
5
  # --------------------------------------------------------------------------
6
+ from collections.abc import ItemsView, KeysView, MutableMapping, ValuesView
6
7
  import logging
7
8
  from pathlib import Path
8
9
  import json
9
10
  from abc import ABC, abstractmethod
10
- from typing import Any, Dict, Union, List
11
+ from typing import Any, Dict, Iterator, Optional, Union, List
11
12
 
12
13
  import yaml
14
+ from .utils import TYPESPEC_PACKAGE_MODE, VALID_PACKAGE_MODE
13
15
 
14
16
  from ._version import VERSION
15
17
 
@@ -18,6 +20,177 @@ __version__ = VERSION
18
20
  _LOGGER = logging.getLogger(__name__)
19
21
 
20
22
 
23
+ class OptionsDict(MutableMapping):
24
+ DEFAULTS = {
25
+ "azure-arm": False,
26
+ "basic-setup-py": False,
27
+ "client-side-validation": False,
28
+ "emit-cross-language-definition-file": False,
29
+ "flavor": "azure", # need to default to azure in shared code so we don't break swagger generation
30
+ "from-typespec": False,
31
+ "generate-sample": False,
32
+ "generate-test": False,
33
+ "head-as-boolean": True,
34
+ "keep-version-file": False,
35
+ "low-level-client": False,
36
+ "multiapi": False,
37
+ "no-async": False,
38
+ "no-namespace-folders": False,
39
+ "polymorphic-examples": 5,
40
+ "validate-versioning": True,
41
+ "version-tolerant": True,
42
+ }
43
+
44
+ def __init__(self, options: Optional[Dict[str, Any]] = None) -> None:
45
+ self._data = options.copy() if options else {}
46
+ self._validate_combinations()
47
+
48
+ def __getitem__(self, key: str) -> Any:
49
+ if key == "head-as-boolean" and self.get("azure-arm"):
50
+ # override to always true if azure-arm is set
51
+ return True
52
+ if key in self._data:
53
+ retval = self._data[key]
54
+ if key == "package-files-config":
55
+ try:
56
+ return {k.strip(): v.strip() for k, v in [i.split(":") for i in retval.split("|")]}
57
+ except AttributeError:
58
+ return retval
59
+ return retval
60
+ if key == "package-mode" and self._data.get("packaging-files-dir"):
61
+ # if packaging-files-dir is set, use it as package-mode
62
+ return self._data["packaging-files-dir"]
63
+ return self._get_default(key)
64
+
65
+ def __setitem__(self, key: str, value: Any) -> None:
66
+ validated_value = self._validate_and_transform(key, value)
67
+ self._data[key] = validated_value
68
+
69
+ def __delitem__(self, key: str) -> None:
70
+ if key in self._data:
71
+ del self._data[key]
72
+ else:
73
+ raise KeyError(f"Option '{key}' not found")
74
+
75
+ def __iter__(self) -> Iterator[str]:
76
+ # Return both explicitly set keys and all possible default keys
77
+ return iter(set(self.keys()))
78
+
79
+ def __len__(self) -> int:
80
+ return len(set(self._data.keys()).union(self.DEFAULTS.keys()))
81
+
82
+ def __contains__(self, key: str) -> bool: # type: ignore
83
+ return key in self._data or key in self.DEFAULTS
84
+
85
+ def __repr__(self) -> str:
86
+ """String representation."""
87
+ return f"OptionsDict({dict(self.items())})"
88
+
89
+ def _get_default(self, key: str) -> Any: # pylint: disable=too-many-return-statements
90
+ if key == "show-operations":
91
+ return not self.get("low-level-client")
92
+ if key == "tracing":
93
+ return self.get("show-operations") and self.get("flavor") == "azure"
94
+ if key in ["show-send-request", "only-path-and-body-params-positional", "default-optional-constants-to-none"]:
95
+ return self.get("low-level-client") or self.get("version-tolerant")
96
+ if key == "combine-operation-files":
97
+ return self.get("version-tolerant")
98
+ if key == "package-pprint-name":
99
+ return " ".join([i.capitalize() for i in str(self.get("package-name", "")).split("-")])
100
+ if key == "builders-visibility":
101
+ # Default to public if low-level client is not set, otherwise embedded
102
+ return "embedded" if not self.get("low-level-client") else "public"
103
+ if key == "models-mode":
104
+ models_mode_default = False if self.get("low-level-client") or self.get("version-tolerant") else "msrest"
105
+ if self.get("tsp_file") is not None:
106
+ models_mode_default = "dpg"
107
+ # switch to falsy value for easier code writing
108
+ return models_mode_default
109
+ return self.DEFAULTS[key]
110
+
111
+ def _validate_combinations(self) -> None:
112
+ if not self.get("show-operations") and self.get("builders-visibility") == "embedded":
113
+ raise ValueError(
114
+ "Can not embed builders without operations. "
115
+ "Either set --show-operations to True, or change the value of --builders-visibility "
116
+ "to 'public' or 'hidden'."
117
+ )
118
+
119
+ if self.get("basic-setup-py") and not self.get("package-version"):
120
+ raise ValueError("--basic-setup-py must be used with --package-version")
121
+
122
+ if self.get("package-mode") and not self.get("package-version"):
123
+ raise ValueError("--package-mode must be used with --package-version")
124
+
125
+ if not self.get("show-operations") and self.get("combine-operation-files"):
126
+ raise ValueError(
127
+ "Can not combine operation files if you are not showing operations. "
128
+ "If you want operation files, pass in flag --show-operations"
129
+ )
130
+
131
+ if self.get("multiapi") and self.get("version-tolerant"):
132
+ raise ValueError(
133
+ "Can not currently generate version tolerant multiapi SDKs. "
134
+ "We are working on creating a new multiapi SDK for version tolerant and it is not available yet."
135
+ )
136
+
137
+ if self.get("client-side-validation") and self.get("version-tolerant"):
138
+ raise ValueError("Can not generate version tolerant with --client-side-validation. ")
139
+
140
+ if not (self.get("azure-arm") or self.get("version-tolerant")):
141
+ _LOGGER.warning(
142
+ "You are generating with options that would not allow the SDK to be shipped as an official Azure SDK. "
143
+ "Please read https://aka.ms/azsdk/dpcodegen for more details."
144
+ )
145
+
146
+ if self.get("flavor") != "azure" and self.get("tracing"):
147
+ raise ValueError("Can only have tracing turned on for Azure SDKs.")
148
+
149
+ def _validate_and_transform(self, key: str, value: Any) -> Any:
150
+ if key == "builders-visibility" and value not in ["public", "hidden", "embedded"]:
151
+ raise ValueError("The value of --builders-visibility must be either 'public', 'hidden', or 'embedded'")
152
+
153
+ if key == "models-mode" and value == "none":
154
+ value = False # switch to falsy value for easier code writing
155
+
156
+ if key == "models-mode" and value not in ["msrest", "dpg", False]:
157
+ raise ValueError(
158
+ "--models-mode can only be 'msrest', 'dpg' or 'none'. "
159
+ "Pass in 'msrest' if you want msrest models, or "
160
+ "'none' if you don't want any."
161
+ )
162
+ if key == "package-mode":
163
+ if (
164
+ (value not in TYPESPEC_PACKAGE_MODE and self.get("from-typespec"))
165
+ or (value not in VALID_PACKAGE_MODE and not self.get("from-typespec"))
166
+ ) and not Path(value).exists():
167
+ raise ValueError(
168
+ f"--package-mode can only be {' or '.join(TYPESPEC_PACKAGE_MODE)} or directory which contains template files" # pylint: disable=line-too-long
169
+ )
170
+ return value
171
+
172
+ def setdefault(self, key: str, default: Any, /) -> Any: # type: ignore # pylint: disable=arguments-differ
173
+ """Set a default value for a key if it does not exist."""
174
+ if key not in self._data:
175
+ self[key] = default
176
+ return self[key]
177
+
178
+ def keys(self) -> KeysView[str]:
179
+ """Return all keys, including defaults."""
180
+ all_keys = set(self._data.keys())
181
+ for key in self.DEFAULTS:
182
+ if key not in all_keys:
183
+ all_keys.add(key)
184
+ all_keys.update(self.DEFAULTS.keys())
185
+ return KeysView({key: None for key in all_keys})
186
+
187
+ def values(self) -> ValuesView[Any]:
188
+ return {key: self[key] for key in self.keys()}.values() # pylint: disable=consider-using-dict-items
189
+
190
+ def items(self) -> ItemsView[str, Any]:
191
+ return {key: self[key] for key in self.keys()}.items() # pylint: disable=consider-using-dict-items
192
+
193
+
21
194
  class ReaderAndWriter:
22
195
  def __init__(self, *, output_folder: Union[str, Path], **kwargs: Any) -> None:
23
196
  self.output_folder = Path(output_folder)
@@ -31,7 +204,8 @@ class ReaderAndWriter:
31
204
  python_json = json.load(fd)
32
205
  except Exception: # pylint: disable=broad-except
33
206
  python_json = {}
34
- self.options = kwargs
207
+ kwargs["output-folder"] = str(self.output_folder)
208
+ self.options = OptionsDict(kwargs)
35
209
  if python_json:
36
210
  _LOGGER.warning("Loading python.json file. This behavior will be depreacted")
37
211
  self.options.update(python_json)
@@ -21,7 +21,7 @@ _BLACK_MODE.line_length = 120
21
21
  class BlackScriptPlugin(Plugin):
22
22
  def __init__(self, **kwargs):
23
23
  super().__init__(**kwargs)
24
- output_folder = self.options.get("output_folder", str(self.output_folder))
24
+ output_folder = self.options.get("output-folder", str(self.output_folder))
25
25
  if output_folder.startswith("file:"):
26
26
  output_folder = output_folder[5:]
27
27
  if os.name == "nt" and output_folder.startswith("///"):