@typespec/http-client-python 0.27.1 → 0.27.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/emitter/code-model.d.ts.map +1 -1
- package/dist/emitter/code-model.js +20 -15
- package/dist/emitter/code-model.js.map +1 -1
- package/dist/emitter/http.js +11 -1
- package/dist/emitter/http.js.map +1 -1
- package/emitter/src/code-model.ts +28 -21
- package/emitter/src/http.ts +10 -1
- package/emitter/temp/tsconfig.tsbuildinfo +1 -1
- package/eng/scripts/ci/regenerate-common.ts +472 -0
- package/eng/scripts/ci/regenerate.ts +41 -437
- package/eng/scripts/setup/__pycache__/package_manager.cpython-311.pyc +0 -0
- package/eng/scripts/setup/__pycache__/venvtools.cpython-311.pyc +0 -0
- package/generator/build/lib/pygen/codegen/models/client.py +5 -5
- package/generator/build/lib/pygen/codegen/models/credential_types.py +1 -1
- package/generator/build/lib/pygen/codegen/models/enum_type.py +1 -1
- package/generator/build/lib/pygen/codegen/models/imports.py +2 -3
- package/generator/build/lib/pygen/codegen/models/lro_operation.py +1 -1
- package/generator/build/lib/pygen/codegen/models/model_type.py +2 -2
- package/generator/build/lib/pygen/codegen/models/operation.py +5 -5
- package/generator/build/lib/pygen/codegen/models/operation_group.py +1 -1
- package/generator/build/lib/pygen/codegen/models/paging_operation.py +2 -2
- package/generator/build/lib/pygen/codegen/models/primitive_types.py +1 -1
- package/generator/build/lib/pygen/codegen/models/request_builder.py +1 -1
- package/generator/build/lib/pygen/codegen/serializers/builder_serializer.py +16 -7
- package/generator/build/lib/pygen/codegen/serializers/import_serializer.py +4 -31
- package/generator/build/lib/pygen/codegen/templates/model_base.py.jinja2 +8 -2
- package/generator/dist/pygen-0.1.0-py3-none-any.whl +0 -0
- package/generator/pygen/codegen/models/client.py +5 -5
- package/generator/pygen/codegen/models/credential_types.py +1 -1
- package/generator/pygen/codegen/models/enum_type.py +1 -1
- package/generator/pygen/codegen/models/imports.py +2 -3
- package/generator/pygen/codegen/models/lro_operation.py +1 -1
- package/generator/pygen/codegen/models/model_type.py +2 -2
- package/generator/pygen/codegen/models/operation.py +5 -5
- package/generator/pygen/codegen/models/operation_group.py +1 -1
- package/generator/pygen/codegen/models/paging_operation.py +2 -2
- package/generator/pygen/codegen/models/primitive_types.py +1 -1
- package/generator/pygen/codegen/models/request_builder.py +1 -1
- package/generator/pygen/codegen/serializers/builder_serializer.py +16 -7
- package/generator/pygen/codegen/serializers/import_serializer.py +4 -31
- package/generator/pygen/codegen/templates/model_base.py.jinja2 +8 -2
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_core_page_async.py +12 -0
- package/generator/test/azure/mock_api_tests/test_azure_core_page.py +11 -0
- package/generator/test/azure/mock_api_tests/test_clear_output_folder.py +9 -0
- package/generator/test/azure/requirements.txt +4 -1
- package/generator/test/generic_mock_api_tests/asynctests/test_encode_bytes_async.py +6 -1
- package/generator/test/generic_mock_api_tests/asynctests/test_payload_xml_async.py +21 -0
- package/generator/test/generic_mock_api_tests/data/image.jpg +0 -0
- package/generator/test/generic_mock_api_tests/data/image.png +0 -0
- package/generator/test/generic_mock_api_tests/test_encode_bytes.py +6 -0
- package/generator/test/generic_mock_api_tests/test_payload_xml.py +19 -0
- package/generator/test/unbranded/mock_api_tests/test_unbranded.py +9 -8
- package/generator/test/unbranded/requirements.txt +2 -1
- package/generator/test/unittests/test_model_base_serialization.py +161 -0
- package/package.json +11 -11
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
# Licensed under the MIT License. See License.txt in the project root for
|
|
4
4
|
# license information.
|
|
5
5
|
# --------------------------------------------------------------------------
|
|
6
|
+
import datetime
|
|
6
7
|
import pytest
|
|
7
8
|
from payload.xml.aio import XmlClient
|
|
8
9
|
from payload.xml.models import (
|
|
@@ -18,6 +19,8 @@ from payload.xml.models import (
|
|
|
18
19
|
ModelWithText,
|
|
19
20
|
ModelWithDictionary,
|
|
20
21
|
ModelWithEncodedNames,
|
|
22
|
+
ModelWithEnum,
|
|
23
|
+
ModelWithDatetime,
|
|
21
24
|
)
|
|
22
25
|
|
|
23
26
|
|
|
@@ -119,6 +122,24 @@ async def test_model_with_encoded_names(client: XmlClient):
|
|
|
119
122
|
await client.model_with_encoded_names_value.put(model)
|
|
120
123
|
|
|
121
124
|
|
|
125
|
+
@pytest.mark.asyncio
|
|
126
|
+
async def test_model_with_enum(client: XmlClient):
|
|
127
|
+
model = ModelWithEnum(status="success")
|
|
128
|
+
assert await client.model_with_enum_value.get() == model
|
|
129
|
+
await client.model_with_enum_value.put(model)
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
@pytest.mark.asyncio
|
|
133
|
+
async def test_model_with_datetime(client: XmlClient):
|
|
134
|
+
model = ModelWithDatetime(
|
|
135
|
+
rfc3339=datetime.datetime(2022, 8, 26, 18, 38, 0, tzinfo=datetime.timezone.utc),
|
|
136
|
+
rfc7231=datetime.datetime(2022, 8, 26, 14, 38, 0, tzinfo=datetime.timezone.utc),
|
|
137
|
+
)
|
|
138
|
+
result = await client.model_with_datetime_value.get()
|
|
139
|
+
assert result.rfc3339 == model.rfc3339
|
|
140
|
+
assert result.rfc7231 == model.rfc7231
|
|
141
|
+
|
|
142
|
+
|
|
122
143
|
@pytest.mark.asyncio
|
|
123
144
|
async def test_xml_error_value(client: XmlClient, core_library):
|
|
124
145
|
with pytest.raises(core_library.exceptions.HttpResponseError) as ex:
|
|
Binary file
|
|
Binary file
|
|
@@ -95,6 +95,12 @@ def test_header(client: BytesClient):
|
|
|
95
95
|
)
|
|
96
96
|
|
|
97
97
|
|
|
98
|
+
@pytest.fixture
|
|
99
|
+
def png_data() -> bytes:
|
|
100
|
+
with open(str(FILE_FOLDER / "data/image.png"), "rb") as file_in:
|
|
101
|
+
return file_in.read()
|
|
102
|
+
|
|
103
|
+
|
|
98
104
|
def test_request_body(client: BytesClient, png_data: bytes):
|
|
99
105
|
client.request_body.default(
|
|
100
106
|
value=png_data,
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
# Licensed under the MIT License. See License.txt in the project root for
|
|
4
4
|
# license information.
|
|
5
5
|
# --------------------------------------------------------------------------
|
|
6
|
+
import datetime
|
|
6
7
|
import pytest
|
|
7
8
|
from payload.xml import XmlClient
|
|
8
9
|
from payload.xml.models import (
|
|
@@ -18,6 +19,8 @@ from payload.xml.models import (
|
|
|
18
19
|
ModelWithText,
|
|
19
20
|
ModelWithDictionary,
|
|
20
21
|
ModelWithEncodedNames,
|
|
22
|
+
ModelWithEnum,
|
|
23
|
+
ModelWithDatetime,
|
|
21
24
|
)
|
|
22
25
|
|
|
23
26
|
|
|
@@ -107,6 +110,22 @@ def test_model_with_encoded_names(client: XmlClient):
|
|
|
107
110
|
client.model_with_encoded_names_value.put(model)
|
|
108
111
|
|
|
109
112
|
|
|
113
|
+
def test_model_with_enum(client: XmlClient):
|
|
114
|
+
model = ModelWithEnum(status="success")
|
|
115
|
+
assert client.model_with_enum_value.get() == model
|
|
116
|
+
client.model_with_enum_value.put(model)
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
def test_model_with_datetime(client: XmlClient):
|
|
120
|
+
model = ModelWithDatetime(
|
|
121
|
+
rfc3339=datetime.datetime(2022, 8, 26, 18, 38, 0, tzinfo=datetime.timezone.utc),
|
|
122
|
+
rfc7231=datetime.datetime(2022, 8, 26, 14, 38, 0, tzinfo=datetime.timezone.utc),
|
|
123
|
+
)
|
|
124
|
+
result = client.model_with_datetime_value.get()
|
|
125
|
+
assert result.rfc3339 == model.rfc3339
|
|
126
|
+
assert result.rfc7231 == model.rfc7231
|
|
127
|
+
|
|
128
|
+
|
|
110
129
|
def test_xml_error_value(client: XmlClient, core_library):
|
|
111
130
|
with pytest.raises(core_library.exceptions.HttpResponseError) as ex:
|
|
112
131
|
client.xml_error_value.get()
|
|
@@ -54,11 +54,12 @@ def test_sensitive_word():
|
|
|
54
54
|
check_folder = (Path(os.path.dirname(__file__)) / "../generated").resolve()
|
|
55
55
|
assert [] == check_sensitive_word(check_folder, "azure")
|
|
56
56
|
# after update spector, it shall also equal to []
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
57
|
+
expected = [
|
|
58
|
+
"authentication-oauth2",
|
|
59
|
+
"authentication-noauth-union",
|
|
60
|
+
"authentication-union",
|
|
61
|
+
"setuppy-authentication-union",
|
|
62
|
+
]
|
|
63
|
+
if (check_folder / "generation-subdir").exists():
|
|
64
|
+
expected.append("generation-subdir")
|
|
65
|
+
assert sorted(expected) == sorted(check_sensitive_word(check_folder, "microsoft"))
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
-r ../dev_requirements.txt
|
|
2
2
|
-e ../../
|
|
3
3
|
|
|
4
|
-
# common test
|
|
4
|
+
# === common test dependencies across repos ===
|
|
5
5
|
-e ./generated/authentication-api-key
|
|
6
6
|
-e ./generated/authentication-http-custom
|
|
7
7
|
-e ./generated/authentication-noauth-union
|
|
@@ -66,3 +66,4 @@
|
|
|
66
66
|
-e ./generated/versioning-renamedfrom
|
|
67
67
|
-e ./generated/versioning-returntypechangedfrom
|
|
68
68
|
-e ./generated/versioning-typechangedfrom
|
|
69
|
+
# === end common test dependencies across repos ===
|
|
@@ -4743,3 +4743,164 @@ def test_dictionary_set_datetime():
|
|
|
4743
4743
|
assert dict_ref1 is dict_ref2
|
|
4744
4744
|
assert isinstance(dict_ref1["start"], datetime)
|
|
4745
4745
|
assert isinstance(dict_ref2["start"], datetime)
|
|
4746
|
+
|
|
4747
|
+
|
|
4748
|
+
def test_eq_same_model_instances():
|
|
4749
|
+
"""Two model instances with the same data should be equal."""
|
|
4750
|
+
model1 = BasicResource(
|
|
4751
|
+
platform_update_domain_count=5,
|
|
4752
|
+
platform_fault_domain_count=3,
|
|
4753
|
+
virtual_machines=[],
|
|
4754
|
+
)
|
|
4755
|
+
model2 = BasicResource(
|
|
4756
|
+
platform_update_domain_count=5,
|
|
4757
|
+
platform_fault_domain_count=3,
|
|
4758
|
+
virtual_machines=[],
|
|
4759
|
+
)
|
|
4760
|
+
assert model1 == model2
|
|
4761
|
+
|
|
4762
|
+
|
|
4763
|
+
def test_eq_different_model_data():
|
|
4764
|
+
"""Two model instances with different data should not be equal."""
|
|
4765
|
+
model1 = BasicResource(
|
|
4766
|
+
platform_update_domain_count=5,
|
|
4767
|
+
platform_fault_domain_count=3,
|
|
4768
|
+
virtual_machines=[],
|
|
4769
|
+
)
|
|
4770
|
+
model2 = BasicResource(
|
|
4771
|
+
platform_update_domain_count=10,
|
|
4772
|
+
platform_fault_domain_count=3,
|
|
4773
|
+
virtual_machines=[],
|
|
4774
|
+
)
|
|
4775
|
+
assert model1 != model2
|
|
4776
|
+
|
|
4777
|
+
|
|
4778
|
+
def test_eq_model_constructed_from_dict():
|
|
4779
|
+
"""A model created via kwargs and a model created from a dict should be equal."""
|
|
4780
|
+
dict_response = {
|
|
4781
|
+
"platformUpdateDomainCount": 5,
|
|
4782
|
+
"platformFaultDomainCount": 3,
|
|
4783
|
+
"virtualMachines": [],
|
|
4784
|
+
}
|
|
4785
|
+
model_from_kwargs = BasicResource(
|
|
4786
|
+
platform_update_domain_count=5,
|
|
4787
|
+
platform_fault_domain_count=3,
|
|
4788
|
+
virtual_machines=[],
|
|
4789
|
+
)
|
|
4790
|
+
model_from_dict = BasicResource(dict_response)
|
|
4791
|
+
assert model_from_kwargs == model_from_dict
|
|
4792
|
+
|
|
4793
|
+
|
|
4794
|
+
def test_eq_model_equal_to_plain_dict():
|
|
4795
|
+
"""A model should be equal to a plain dict with matching data (backward compat)."""
|
|
4796
|
+
dict_response = {
|
|
4797
|
+
"platformUpdateDomainCount": 5,
|
|
4798
|
+
"platformFaultDomainCount": 3,
|
|
4799
|
+
"virtualMachines": [],
|
|
4800
|
+
}
|
|
4801
|
+
model = BasicResource(
|
|
4802
|
+
platform_update_domain_count=5,
|
|
4803
|
+
platform_fault_domain_count=3,
|
|
4804
|
+
virtual_machines=[],
|
|
4805
|
+
)
|
|
4806
|
+
assert model == dict_response
|
|
4807
|
+
|
|
4808
|
+
|
|
4809
|
+
def test_eq_model_not_equal_to_non_model_types():
|
|
4810
|
+
"""A model should not be equal to strings, ints, None, or lists."""
|
|
4811
|
+
model = BasicResource(
|
|
4812
|
+
platform_update_domain_count=5,
|
|
4813
|
+
platform_fault_domain_count=3,
|
|
4814
|
+
virtual_machines=[],
|
|
4815
|
+
)
|
|
4816
|
+
assert model != "some string"
|
|
4817
|
+
assert model != 42
|
|
4818
|
+
assert model != None # noqa: E711
|
|
4819
|
+
assert model != []
|
|
4820
|
+
assert model != True # noqa: E712
|
|
4821
|
+
|
|
4822
|
+
|
|
4823
|
+
def test_eq_different_model_types_same_data():
|
|
4824
|
+
"""Two different model types with the same underlying _data should be equal
|
|
4825
|
+
since isinstance checks against _MyMutableMapping, not the specific subclass."""
|
|
4826
|
+
model1 = Pet(name="test", species="dog")
|
|
4827
|
+
|
|
4828
|
+
class AnotherModel(Model):
|
|
4829
|
+
name: str = rest_field()
|
|
4830
|
+
species: str = rest_field()
|
|
4831
|
+
|
|
4832
|
+
@overload
|
|
4833
|
+
def __init__(self, *, name: str, species: str): ...
|
|
4834
|
+
|
|
4835
|
+
@overload
|
|
4836
|
+
def __init__(self, mapping: Mapping[str, Any], /): ...
|
|
4837
|
+
|
|
4838
|
+
def __init__(self, *args, **kwargs):
|
|
4839
|
+
super().__init__(*args, **kwargs)
|
|
4840
|
+
|
|
4841
|
+
model2 = AnotherModel(name="test", species="dog")
|
|
4842
|
+
assert model1 == model2
|
|
4843
|
+
|
|
4844
|
+
|
|
4845
|
+
def test_ne_is_inverse_of_eq():
|
|
4846
|
+
"""__ne__ should return the inverse of __eq__."""
|
|
4847
|
+
model1 = BasicResource(
|
|
4848
|
+
platform_update_domain_count=5,
|
|
4849
|
+
platform_fault_domain_count=3,
|
|
4850
|
+
virtual_machines=[],
|
|
4851
|
+
)
|
|
4852
|
+
model2 = BasicResource(
|
|
4853
|
+
platform_update_domain_count=5,
|
|
4854
|
+
platform_fault_domain_count=3,
|
|
4855
|
+
virtual_machines=[],
|
|
4856
|
+
)
|
|
4857
|
+
model3 = BasicResource(
|
|
4858
|
+
platform_update_domain_count=10,
|
|
4859
|
+
platform_fault_domain_count=3,
|
|
4860
|
+
virtual_machines=[],
|
|
4861
|
+
)
|
|
4862
|
+
assert not (model1 != model2)
|
|
4863
|
+
assert model1 != model3
|
|
4864
|
+
|
|
4865
|
+
|
|
4866
|
+
def test_eq_nested_models():
|
|
4867
|
+
"""Two models with identical nested model children should be equal."""
|
|
4868
|
+
model1 = OptionalModel(
|
|
4869
|
+
optional_str="hello",
|
|
4870
|
+
optional_time=datetime.time(11, 34, 56),
|
|
4871
|
+
optional_dict={
|
|
4872
|
+
"buddy": Pet(name="Buddy", species="Dog"),
|
|
4873
|
+
},
|
|
4874
|
+
optional_myself=OptionalModel(optional_str="inner"),
|
|
4875
|
+
)
|
|
4876
|
+
model2 = OptionalModel(
|
|
4877
|
+
optional_str="hello",
|
|
4878
|
+
optional_time=datetime.time(11, 34, 56),
|
|
4879
|
+
optional_dict={
|
|
4880
|
+
"buddy": Pet(name="Buddy", species="Dog"),
|
|
4881
|
+
},
|
|
4882
|
+
optional_myself=OptionalModel(optional_str="inner"),
|
|
4883
|
+
)
|
|
4884
|
+
assert model1 == model2
|
|
4885
|
+
|
|
4886
|
+
# Change the nested model's data — they should no longer be equal
|
|
4887
|
+
model2_different_inner = OptionalModel(
|
|
4888
|
+
optional_str="hello",
|
|
4889
|
+
optional_time=datetime.time(11, 34, 56),
|
|
4890
|
+
optional_dict={
|
|
4891
|
+
"buddy": Pet(name="Buddy", species="Dog"),
|
|
4892
|
+
},
|
|
4893
|
+
optional_myself=OptionalModel(optional_str="different"),
|
|
4894
|
+
)
|
|
4895
|
+
assert model1 != model2_different_inner
|
|
4896
|
+
|
|
4897
|
+
# Change the nested Pet — they should no longer be equal
|
|
4898
|
+
model2_different_pet = OptionalModel(
|
|
4899
|
+
optional_str="hello",
|
|
4900
|
+
optional_time=datetime.time(11, 34, 56),
|
|
4901
|
+
optional_dict={
|
|
4902
|
+
"buddy": Pet(name="Max", species="Cat"),
|
|
4903
|
+
},
|
|
4904
|
+
optional_myself=OptionalModel(optional_str="inner"),
|
|
4905
|
+
)
|
|
4906
|
+
assert model1 != model2_different_pet
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@typespec/http-client-python",
|
|
3
|
-
"version": "0.27.
|
|
3
|
+
"version": "0.27.2",
|
|
4
4
|
"author": "Microsoft Corporation",
|
|
5
5
|
"description": "TypeSpec emitter for Python SDKs",
|
|
6
6
|
"homepage": "https://typespec.io",
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
"@azure-tools/typespec-azure-core": ">=0.65.0 <1.0.0",
|
|
59
59
|
"@azure-tools/typespec-azure-resource-manager": ">=0.65.0 <1.0.0",
|
|
60
60
|
"@azure-tools/typespec-azure-rulesets": ">=0.65.0 <1.0.0",
|
|
61
|
-
"@azure-tools/typespec-client-generator-core": ">=0.65.
|
|
61
|
+
"@azure-tools/typespec-client-generator-core": ">=0.65.3 <1.0.0",
|
|
62
62
|
"@typespec/compiler": "^1.9.0",
|
|
63
63
|
"@typespec/http": "^1.9.0",
|
|
64
64
|
"@typespec/openapi": "^1.9.0",
|
|
@@ -74,15 +74,15 @@
|
|
|
74
74
|
"marked": "^15.0.6",
|
|
75
75
|
"pyodide": "0.26.2",
|
|
76
76
|
"semver": "~7.6.2",
|
|
77
|
-
"tsx": "
|
|
77
|
+
"tsx": "^4.21.0"
|
|
78
78
|
},
|
|
79
79
|
"devDependencies": {
|
|
80
80
|
"@azure-tools/typespec-autorest": "~0.65.0",
|
|
81
81
|
"@azure-tools/typespec-azure-core": "~0.65.0",
|
|
82
82
|
"@azure-tools/typespec-azure-resource-manager": "~0.65.0",
|
|
83
83
|
"@azure-tools/typespec-azure-rulesets": "~0.65.0",
|
|
84
|
-
"@azure-tools/typespec-client-generator-core": "~0.65.
|
|
85
|
-
"@azure-tools/azure-http-specs": "0.1.0-alpha.
|
|
84
|
+
"@azure-tools/typespec-client-generator-core": "~0.65.3",
|
|
85
|
+
"@azure-tools/azure-http-specs": "0.1.0-alpha.38-dev.2",
|
|
86
86
|
"@typespec/compiler": "^1.9.0",
|
|
87
87
|
"@typespec/http": "^1.9.0",
|
|
88
88
|
"@typespec/openapi": "^1.9.0",
|
|
@@ -94,15 +94,15 @@
|
|
|
94
94
|
"@typespec/sse": "~0.79.0",
|
|
95
95
|
"@typespec/streams": "~0.79.0",
|
|
96
96
|
"@typespec/xml": "~0.79.0",
|
|
97
|
-
"@typespec/http-specs": "0.1.0-alpha.
|
|
97
|
+
"@typespec/http-specs": "0.1.0-alpha.33-dev.2",
|
|
98
98
|
"@types/js-yaml": "~4.0.5",
|
|
99
|
-
"@types/node": "~
|
|
99
|
+
"@types/node": "~25.0.2",
|
|
100
100
|
"@types/semver": "7.5.8",
|
|
101
101
|
"c8": "^10.1.3",
|
|
102
102
|
"chalk": "5.3.0",
|
|
103
|
-
"rimraf": "~6.
|
|
104
|
-
"typescript": "~5.
|
|
105
|
-
"typescript-eslint": "^8.
|
|
106
|
-
"vitest": "^
|
|
103
|
+
"rimraf": "~6.1.2",
|
|
104
|
+
"typescript": "~5.9.2",
|
|
105
|
+
"typescript-eslint": "^8.49.0",
|
|
106
|
+
"vitest": "^4.0.15"
|
|
107
107
|
}
|
|
108
108
|
}
|