@typespec/http-client-python 0.23.1 → 0.24.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.
- package/dist/emitter/code-model.d.ts.map +1 -1
- package/dist/emitter/code-model.js +35 -25
- package/dist/emitter/code-model.js.map +1 -1
- package/dist/emitter/http.d.ts +4 -4
- package/dist/emitter/http.d.ts.map +1 -1
- package/dist/emitter/http.js +41 -35
- package/dist/emitter/http.js.map +1 -1
- package/dist/emitter/types.d.ts +1 -1
- package/dist/emitter/types.d.ts.map +1 -1
- package/dist/emitter/types.js +2 -2
- package/dist/emitter/types.js.map +1 -1
- package/dist/emitter/utils.d.ts +2 -2
- package/dist/emitter/utils.d.ts.map +1 -1
- package/dist/emitter/utils.js +7 -6
- package/dist/emitter/utils.js.map +1 -1
- package/emitter/src/code-model.ts +61 -18
- package/emitter/src/http.ts +107 -22
- package/emitter/src/types.ts +2 -1
- package/emitter/src/utils.ts +11 -9
- package/emitter/temp/tsconfig.tsbuildinfo +1 -1
- package/eng/scripts/ci/dev_requirements.txt +3 -3
- package/eng/scripts/ci/pylintrc +1 -1
- package/eng/scripts/ci/regenerate.ts +8 -1
- 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/code_model.py +4 -0
- package/generator/build/lib/pygen/codegen/models/enum_type.py +8 -1
- package/generator/build/lib/pygen/codegen/models/list_type.py +6 -2
- package/generator/build/lib/pygen/codegen/models/model_type.py +2 -2
- package/generator/build/lib/pygen/codegen/models/operation.py +10 -1
- package/generator/build/lib/pygen/codegen/models/operation_group.py +3 -1
- package/generator/build/lib/pygen/codegen/models/request_builder.py +20 -3
- package/generator/build/lib/pygen/codegen/models/response.py +2 -2
- package/generator/build/lib/pygen/codegen/models/utils.py +7 -0
- package/generator/build/lib/pygen/codegen/serializers/builder_serializer.py +20 -11
- package/generator/build/lib/pygen/codegen/serializers/client_serializer.py +1 -2
- package/generator/build/lib/pygen/codegen/serializers/general_serializer.py +1 -1
- package/generator/build/lib/pygen/codegen/serializers/model_serializer.py +3 -0
- package/generator/build/lib/pygen/codegen/templates/enum.py.jinja2 +3 -1
- package/generator/build/lib/pygen/codegen/templates/model_base.py.jinja2 +10 -7
- package/generator/dist/pygen-0.1.0-py3-none-any.whl +0 -0
- package/generator/pygen/codegen/models/code_model.py +4 -0
- package/generator/pygen/codegen/models/enum_type.py +8 -1
- package/generator/pygen/codegen/models/list_type.py +6 -2
- package/generator/pygen/codegen/models/model_type.py +2 -2
- package/generator/pygen/codegen/models/operation.py +10 -1
- package/generator/pygen/codegen/models/operation_group.py +3 -1
- package/generator/pygen/codegen/models/request_builder.py +20 -3
- package/generator/pygen/codegen/models/response.py +2 -2
- package/generator/pygen/codegen/models/utils.py +7 -0
- package/generator/pygen/codegen/serializers/builder_serializer.py +20 -11
- package/generator/pygen/codegen/serializers/client_serializer.py +1 -2
- package/generator/pygen/codegen/serializers/general_serializer.py +1 -1
- package/generator/pygen/codegen/serializers/model_serializer.py +3 -0
- package/generator/pygen/codegen/templates/enum.py.jinja2 +3 -1
- package/generator/pygen/codegen/templates/model_base.py.jinja2 +10 -7
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_client_generator_core_client_default_value_async.py +46 -0
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_client_generator_core_client_location_async.py +48 -21
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_resource_manager_multi_service_async.py +110 -0
- package/generator/test/azure/mock_api_tests/asynctests/test_service_multi_service_async.py +31 -0
- package/generator/test/azure/mock_api_tests/asynctests/test_special_words_async.py +18 -0
- package/generator/test/azure/mock_api_tests/test_azure_arm_operationtemplates.py +16 -0
- package/generator/test/azure/mock_api_tests/test_azure_client_generator_core_client_default_value.py +42 -0
- package/generator/test/azure/mock_api_tests/test_azure_client_generator_core_client_location.py +44 -19
- package/generator/test/azure/mock_api_tests/test_azure_resource_manager_multi_service.py +104 -0
- package/generator/test/azure/mock_api_tests/test_service_multi_service.py +29 -0
- package/generator/test/azure/mock_api_tests/test_special_words.py +17 -0
- package/generator/test/azure/requirements.txt +9 -1
- package/generator/test/generic_mock_api_tests/asynctests/test_parameters_query_async.py +18 -0
- package/generator/test/generic_mock_api_tests/test_parameters_query.py +17 -0
- package/generator/test/generic_mock_api_tests/test_typetest_scalar.py +0 -5
- package/generator/test/generic_mock_api_tests/test_typetest_union_discriminated.py +290 -0
- package/generator/test/unbranded/requirements.txt +2 -0
- package/generator/test/unittests/test_model_base_serialization.py +66 -0
- package/package.json +5 -5
|
@@ -0,0 +1,104 @@
|
|
|
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
|
+
import pytest
|
|
7
|
+
from azure.core.exceptions import HttpResponseError
|
|
8
|
+
from azure.resourcemanager.multiservice.combined import CombinedClient
|
|
9
|
+
from azure.resourcemanager.multiservice.combined.models import VirtualMachine, Disk
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@pytest.fixture
|
|
13
|
+
def client(credential, authentication_policy):
|
|
14
|
+
"""Create a Combined client for testing."""
|
|
15
|
+
return CombinedClient(
|
|
16
|
+
credential=credential, # Will use mock server, no real auth needed
|
|
17
|
+
subscription_id="00000000-0000-0000-0000-000000000000",
|
|
18
|
+
base_url="http://localhost:3000",
|
|
19
|
+
authentication_policy=authentication_policy,
|
|
20
|
+
polling_interval=0.1, # Speed up tests by reducing polling interval
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def test_virtual_machines_get(client):
|
|
25
|
+
resource_group_name = "test-rg"
|
|
26
|
+
vm_name = "vm1"
|
|
27
|
+
|
|
28
|
+
with pytest.raises(HttpResponseError):
|
|
29
|
+
client.virtual_machines.get(
|
|
30
|
+
resource_group_name=resource_group_name,
|
|
31
|
+
vm_name=vm_name,
|
|
32
|
+
api_version="av1", # invalid api version shall raise error
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
result = client.virtual_machines.get(resource_group_name=resource_group_name, vm_name=vm_name)
|
|
36
|
+
|
|
37
|
+
assert result is not None
|
|
38
|
+
assert isinstance(result, VirtualMachine)
|
|
39
|
+
assert result.name == vm_name
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def test_virtual_machines_create_or_update(client):
|
|
43
|
+
resource_group_name = "test-rg"
|
|
44
|
+
vm_name = "vm1"
|
|
45
|
+
|
|
46
|
+
vm_resource = VirtualMachine(location="eastus", properties={})
|
|
47
|
+
|
|
48
|
+
with pytest.raises(HttpResponseError):
|
|
49
|
+
client.virtual_machines.begin_create_or_update(
|
|
50
|
+
resource_group_name=resource_group_name,
|
|
51
|
+
vm_name=vm_name,
|
|
52
|
+
resource=vm_resource,
|
|
53
|
+
api_version="av1", # invalid api version shall raise error
|
|
54
|
+
).result()
|
|
55
|
+
|
|
56
|
+
poller = client.virtual_machines.begin_create_or_update(
|
|
57
|
+
resource_group_name=resource_group_name, vm_name=vm_name, resource=vm_resource
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
result = poller.result()
|
|
61
|
+
assert result is not None
|
|
62
|
+
assert isinstance(result, VirtualMachine)
|
|
63
|
+
assert result.location == "eastus"
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def test_disks_get(client):
|
|
67
|
+
resource_group_name = "test-rg"
|
|
68
|
+
disk_name = "disk1"
|
|
69
|
+
with pytest.raises(HttpResponseError):
|
|
70
|
+
client.disks.get(
|
|
71
|
+
resource_group_name=resource_group_name,
|
|
72
|
+
disk_name=disk_name,
|
|
73
|
+
api_version="av1", # invalid api version shall raise error
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
result = client.disks.get(resource_group_name=resource_group_name, disk_name=disk_name)
|
|
77
|
+
|
|
78
|
+
assert result is not None
|
|
79
|
+
assert isinstance(result, Disk)
|
|
80
|
+
assert result.name == disk_name
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def test_disks_create_or_update(client):
|
|
84
|
+
resource_group_name = "test-rg"
|
|
85
|
+
disk_name = "disk1"
|
|
86
|
+
|
|
87
|
+
disk_resource = Disk(location="eastus", properties={})
|
|
88
|
+
|
|
89
|
+
with pytest.raises(HttpResponseError):
|
|
90
|
+
client.disks.begin_create_or_update(
|
|
91
|
+
resource_group_name=resource_group_name,
|
|
92
|
+
disk_name=disk_name,
|
|
93
|
+
resource=disk_resource,
|
|
94
|
+
api_version="av1", # invalid api version shall raise error
|
|
95
|
+
).result()
|
|
96
|
+
|
|
97
|
+
poller = client.disks.begin_create_or_update(
|
|
98
|
+
resource_group_name=resource_group_name, disk_name=disk_name, resource=disk_resource
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
result = poller.result()
|
|
102
|
+
assert result is not None
|
|
103
|
+
assert isinstance(result, Disk)
|
|
104
|
+
assert result.location == "eastus"
|
|
@@ -0,0 +1,29 @@
|
|
|
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
|
+
import pytest
|
|
7
|
+
from azure.core.exceptions import HttpResponseError
|
|
8
|
+
from service.multiservice import CombinedClient
|
|
9
|
+
from service.multiservice.models import VersionsA, VersionsB
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@pytest.fixture
|
|
13
|
+
def client():
|
|
14
|
+
"""Fixture that creates a CombinedClient for testing."""
|
|
15
|
+
return CombinedClient(endpoint="http://localhost:3000")
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def test_service_multi_service_foo(client):
|
|
19
|
+
with pytest.raises(HttpResponseError):
|
|
20
|
+
client.foo.test(api_version=VersionsA.AV1)
|
|
21
|
+
|
|
22
|
+
client.foo.test()
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def test_service_multi_service_bar(client):
|
|
26
|
+
with pytest.raises(HttpResponseError):
|
|
27
|
+
client.bar.test(api_version=VersionsB.BV1)
|
|
28
|
+
|
|
29
|
+
client.bar.test()
|
|
@@ -35,3 +35,20 @@ def test_model(client: SpecialWordsClient, special_words):
|
|
|
35
35
|
|
|
36
36
|
def test_model_properties(client: SpecialWordsClient):
|
|
37
37
|
client.model_properties.same_as_model(models.SameAsModel(same_as_model="ok"))
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def test_model_properties_dict_methods(client: SpecialWordsClient):
|
|
41
|
+
client.model_properties.dict_methods(
|
|
42
|
+
body=models.DictMethods(
|
|
43
|
+
keys_property="ok",
|
|
44
|
+
items_property="ok",
|
|
45
|
+
values_property="ok",
|
|
46
|
+
popitem_property="ok",
|
|
47
|
+
clear_property="ok",
|
|
48
|
+
update_property="ok",
|
|
49
|
+
setdefault_property="ok",
|
|
50
|
+
pop_property="ok",
|
|
51
|
+
get_property="ok",
|
|
52
|
+
copy_property="ok",
|
|
53
|
+
)
|
|
54
|
+
)
|
|
@@ -13,7 +13,11 @@ azure-mgmt-core==1.6.0
|
|
|
13
13
|
-e ./generated/azure-client-generator-core-hierarchy-building
|
|
14
14
|
-e ./generated/azure-client-generator-core-usage
|
|
15
15
|
-e ./generated/azure-client-generator-core-override
|
|
16
|
-
-e ./generated/azure-client-generator-core-client-location
|
|
16
|
+
-e ./generated/azure-client-generator-core-client-location-move-method-parameter-to-client
|
|
17
|
+
-e ./generated/azure-client-generator-core-client-location-move-to-existing-sub-client
|
|
18
|
+
-e ./generated/azure-client-generator-core-client-location-move-to-new-sub-client
|
|
19
|
+
-e ./generated/azure-client-generator-core-client-location-move-to-root-client
|
|
20
|
+
-e ./generated/azure-client-generator-core-client-default-value
|
|
17
21
|
-e ./generated/azure-client-generator-core-alternate-type
|
|
18
22
|
-e ./generated/azure-client-generator-core-next-link-verb
|
|
19
23
|
-e ./generated/azure-core-basic
|
|
@@ -32,6 +36,7 @@ azure-mgmt-core==1.6.0
|
|
|
32
36
|
-e ./generated/azure-resource-manager-operation-templates
|
|
33
37
|
-e ./generated/azure-resource-manager-resources
|
|
34
38
|
-e ./generated/azure-resource-manager-method-subscription-id
|
|
39
|
+
-e ./generated/azure-resource-manager-multi-service
|
|
35
40
|
-e ./generated/azure-versioning-previewversion
|
|
36
41
|
-e ./generated/client-namespace
|
|
37
42
|
-e ./generated/azure-payload-pageable
|
|
@@ -45,6 +50,7 @@ azure-mgmt-core==1.6.0
|
|
|
45
50
|
-e ./generated/client-structure-twooperationgroup
|
|
46
51
|
-e ./generated/resiliency-srv-driven1
|
|
47
52
|
-e ./generated/resiliency-srv-driven2
|
|
53
|
+
-e ./generated/service-multi-service
|
|
48
54
|
|
|
49
55
|
# common test case
|
|
50
56
|
-e ./generated/authentication-api-key
|
|
@@ -59,6 +65,7 @@ azure-mgmt-core==1.6.0
|
|
|
59
65
|
-e ./generated/parameters-basic
|
|
60
66
|
-e ./generated/parameters-collection-format
|
|
61
67
|
-e ./generated/parameters-path
|
|
68
|
+
-e ./generated/parameters-query
|
|
62
69
|
-e ./generated/parameters-spread
|
|
63
70
|
-e ./generated/serialization-encoded-name-json
|
|
64
71
|
-e ./generated/server-endpoint-not-defined
|
|
@@ -85,6 +92,7 @@ azure-mgmt-core==1.6.0
|
|
|
85
92
|
-e ./generated/typetest-property-additionalproperties
|
|
86
93
|
-e ./generated/typetest-scalar
|
|
87
94
|
-e ./generated/typetest-union
|
|
95
|
+
-e ./generated/typetest-discriminatedunion
|
|
88
96
|
-e ./generated/typetest-model-empty
|
|
89
97
|
-e ./generated/headasbooleantrue
|
|
90
98
|
-e ./generated/headasbooleanfalse
|
|
@@ -0,0 +1,18 @@
|
|
|
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
|
+
import pytest
|
|
7
|
+
from parameters.query.aio import QueryClient
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@pytest.fixture
|
|
11
|
+
async def client():
|
|
12
|
+
async with QueryClient() as client:
|
|
13
|
+
yield client
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@pytest.mark.asyncio
|
|
17
|
+
async def test_constant(client: QueryClient):
|
|
18
|
+
await client.constant.post()
|
|
@@ -0,0 +1,17 @@
|
|
|
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
|
+
import pytest
|
|
7
|
+
from parameters.query import QueryClient
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@pytest.fixture
|
|
11
|
+
def client():
|
|
12
|
+
with QueryClient() as client:
|
|
13
|
+
yield client
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def test_constant(client: QueryClient):
|
|
17
|
+
client.constant.post()
|
|
@@ -51,8 +51,3 @@ def test_decimal128_verify(client: ScalarClient):
|
|
|
51
51
|
def test_decimal_verify(client: ScalarClient):
|
|
52
52
|
prepare = client.decimal_verify.prepare_verify()
|
|
53
53
|
client.decimal_verify.verify(reduce(lambda x, y: x + y, prepare))
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
# open this test case after adopt new version of http-specs for https://github.com/microsoft/typespec/pull/8807
|
|
57
|
-
# def test_constant_query(client: ScalarClient):
|
|
58
|
-
# client.constant_query.post()
|
|
@@ -0,0 +1,290 @@
|
|
|
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
|
+
import pytest
|
|
7
|
+
from typetest.discriminatedunion import DiscriminatedClient
|
|
8
|
+
from typetest.discriminatedunion import models
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@pytest.fixture
|
|
12
|
+
def client():
|
|
13
|
+
with DiscriminatedClient() as client:
|
|
14
|
+
yield client
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@pytest.fixture
|
|
18
|
+
def cat_body():
|
|
19
|
+
"""Cat model for testing."""
|
|
20
|
+
return models.Cat(name="Whiskers", meow=True)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@pytest.fixture
|
|
24
|
+
def dog_body():
|
|
25
|
+
"""Dog model for testing."""
|
|
26
|
+
return models.Dog(name="Rex", bark=False)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
# Tests for No Envelope / Default (inline discriminator with "kind")
|
|
30
|
+
@pytest.mark.skip(reason="After completely support discriminated unions, enable these tests")
|
|
31
|
+
class TestNoEnvelopeDefault:
|
|
32
|
+
"""Test discriminated union with inline discriminator (no envelope)."""
|
|
33
|
+
|
|
34
|
+
def test_get_default_cat(self, client: DiscriminatedClient, cat_body: models.Cat):
|
|
35
|
+
"""Test getting cat with default (no query param or kind=cat).
|
|
36
|
+
|
|
37
|
+
Expected response:
|
|
38
|
+
{
|
|
39
|
+
"kind": "cat",
|
|
40
|
+
"name": "Whiskers",
|
|
41
|
+
"meow": true
|
|
42
|
+
}
|
|
43
|
+
"""
|
|
44
|
+
result = client.no_envelope.default.get()
|
|
45
|
+
assert result == cat_body
|
|
46
|
+
assert isinstance(result, models.Cat)
|
|
47
|
+
|
|
48
|
+
def test_get_with_kind_cat(self, client: DiscriminatedClient, cat_body: models.Cat):
|
|
49
|
+
"""Test getting cat with kind=cat query parameter.
|
|
50
|
+
|
|
51
|
+
Expected response:
|
|
52
|
+
{
|
|
53
|
+
"kind": "cat",
|
|
54
|
+
"name": "Whiskers",
|
|
55
|
+
"meow": true
|
|
56
|
+
}
|
|
57
|
+
"""
|
|
58
|
+
result = client.no_envelope.default.get(kind="cat")
|
|
59
|
+
assert result == cat_body
|
|
60
|
+
assert isinstance(result, models.Cat)
|
|
61
|
+
|
|
62
|
+
def test_get_with_kind_dog(self, client: DiscriminatedClient, dog_body: models.Dog):
|
|
63
|
+
"""Test getting dog with kind=dog query parameter.
|
|
64
|
+
|
|
65
|
+
Expected response:
|
|
66
|
+
{
|
|
67
|
+
"kind": "dog",
|
|
68
|
+
"name": "Rex",
|
|
69
|
+
"bark": false
|
|
70
|
+
}
|
|
71
|
+
"""
|
|
72
|
+
result = client.no_envelope.default.get(kind="dog")
|
|
73
|
+
assert result == dog_body
|
|
74
|
+
assert isinstance(result, models.Dog)
|
|
75
|
+
|
|
76
|
+
def test_put_cat(self, client: DiscriminatedClient, cat_body: models.Cat):
|
|
77
|
+
"""Test sending cat with inline discriminator.
|
|
78
|
+
|
|
79
|
+
Expected request:
|
|
80
|
+
{
|
|
81
|
+
"kind": "cat",
|
|
82
|
+
"name": "Whiskers",
|
|
83
|
+
"meow": true
|
|
84
|
+
}
|
|
85
|
+
"""
|
|
86
|
+
result = client.no_envelope.default.put(cat_body)
|
|
87
|
+
assert result == cat_body
|
|
88
|
+
assert isinstance(result, models.Cat)
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
# Tests for No Envelope / Custom Discriminator (inline with custom "type" property)
|
|
92
|
+
@pytest.mark.skip(reason="After completely support discriminated unions, enable these tests")
|
|
93
|
+
class TestNoEnvelopeCustomDiscriminator:
|
|
94
|
+
"""Test discriminated union with inline discriminator and custom discriminator property name."""
|
|
95
|
+
|
|
96
|
+
def test_get_default_cat(self, client: DiscriminatedClient, cat_body: models.Cat):
|
|
97
|
+
"""Test getting cat with default (no query param or type=cat).
|
|
98
|
+
|
|
99
|
+
Expected response:
|
|
100
|
+
{
|
|
101
|
+
"type": "cat",
|
|
102
|
+
"name": "Whiskers",
|
|
103
|
+
"meow": true
|
|
104
|
+
}
|
|
105
|
+
"""
|
|
106
|
+
result = client.no_envelope.custom_discriminator.get()
|
|
107
|
+
assert result == cat_body
|
|
108
|
+
assert isinstance(result, models.Cat)
|
|
109
|
+
|
|
110
|
+
def test_get_with_type_cat(self, client: DiscriminatedClient, cat_body: models.Cat):
|
|
111
|
+
"""Test getting cat with type=cat query parameter.
|
|
112
|
+
|
|
113
|
+
Expected response:
|
|
114
|
+
{
|
|
115
|
+
"type": "cat",
|
|
116
|
+
"name": "Whiskers",
|
|
117
|
+
"meow": true
|
|
118
|
+
}
|
|
119
|
+
"""
|
|
120
|
+
result = client.no_envelope.custom_discriminator.get(type="cat")
|
|
121
|
+
assert result == cat_body
|
|
122
|
+
assert isinstance(result, models.Cat)
|
|
123
|
+
|
|
124
|
+
def test_get_with_type_dog(self, client: DiscriminatedClient, dog_body: models.Dog):
|
|
125
|
+
"""Test getting dog with type=dog query parameter.
|
|
126
|
+
|
|
127
|
+
Expected response:
|
|
128
|
+
{
|
|
129
|
+
"type": "dog",
|
|
130
|
+
"name": "Rex",
|
|
131
|
+
"bark": false
|
|
132
|
+
}
|
|
133
|
+
"""
|
|
134
|
+
result = client.no_envelope.custom_discriminator.get(type="dog")
|
|
135
|
+
assert result == dog_body
|
|
136
|
+
assert isinstance(result, models.Dog)
|
|
137
|
+
|
|
138
|
+
def test_put_cat(self, client: DiscriminatedClient, cat_body: models.Cat):
|
|
139
|
+
"""Test sending cat with inline custom discriminator.
|
|
140
|
+
|
|
141
|
+
Expected request:
|
|
142
|
+
{
|
|
143
|
+
"type": "cat",
|
|
144
|
+
"name": "Whiskers",
|
|
145
|
+
"meow": true
|
|
146
|
+
}
|
|
147
|
+
"""
|
|
148
|
+
result = client.no_envelope.custom_discriminator.put(cat_body)
|
|
149
|
+
assert result == cat_body
|
|
150
|
+
assert isinstance(result, models.Cat)
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
# Tests for Envelope / Object / Default (envelope with "kind" and "value")
|
|
154
|
+
@pytest.mark.skip(reason="After completely support discriminated unions, enable these tests")
|
|
155
|
+
class TestEnvelopeObjectDefault:
|
|
156
|
+
"""Test discriminated union with default envelope serialization."""
|
|
157
|
+
|
|
158
|
+
def test_get_default_cat(self, client: DiscriminatedClient, cat_body: models.Cat):
|
|
159
|
+
"""Test getting cat with default (no query param or kind=cat).
|
|
160
|
+
|
|
161
|
+
Expected response:
|
|
162
|
+
{
|
|
163
|
+
"kind": "cat",
|
|
164
|
+
"value": {
|
|
165
|
+
"name": "Whiskers",
|
|
166
|
+
"meow": true
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
"""
|
|
170
|
+
result = client.envelope.object.default.get()
|
|
171
|
+
assert result == cat_body
|
|
172
|
+
assert isinstance(result, models.Cat)
|
|
173
|
+
|
|
174
|
+
def test_get_with_kind_cat(self, client: DiscriminatedClient, cat_body: models.Cat):
|
|
175
|
+
"""Test getting cat with kind=cat query parameter.
|
|
176
|
+
|
|
177
|
+
Expected response:
|
|
178
|
+
{
|
|
179
|
+
"kind": "cat",
|
|
180
|
+
"value": {
|
|
181
|
+
"name": "Whiskers",
|
|
182
|
+
"meow": true
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
"""
|
|
186
|
+
result = client.envelope.object.default.get(kind="cat")
|
|
187
|
+
assert result == cat_body
|
|
188
|
+
assert isinstance(result, models.Cat)
|
|
189
|
+
|
|
190
|
+
def test_get_with_kind_dog(self, client: DiscriminatedClient, dog_body: models.Dog):
|
|
191
|
+
"""Test getting dog with kind=dog query parameter.
|
|
192
|
+
|
|
193
|
+
Expected response:
|
|
194
|
+
{
|
|
195
|
+
"kind": "dog",
|
|
196
|
+
"value": {
|
|
197
|
+
"name": "Rex",
|
|
198
|
+
"bark": false
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
"""
|
|
202
|
+
result = client.envelope.object.default.get(kind="dog")
|
|
203
|
+
assert result == dog_body
|
|
204
|
+
assert isinstance(result, models.Dog)
|
|
205
|
+
|
|
206
|
+
def test_put_cat(self, client: DiscriminatedClient, cat_body: models.Cat):
|
|
207
|
+
"""Test sending cat with envelope serialization.
|
|
208
|
+
|
|
209
|
+
Expected request:
|
|
210
|
+
{
|
|
211
|
+
"kind": "cat",
|
|
212
|
+
"value": {
|
|
213
|
+
"name": "Whiskers",
|
|
214
|
+
"meow": true
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
"""
|
|
218
|
+
result = client.envelope.object.default.put(cat_body)
|
|
219
|
+
assert result == cat_body
|
|
220
|
+
assert isinstance(result, models.Cat)
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
# Tests for Envelope / Object / Custom Properties (envelope with custom "petType" and "petData")
|
|
224
|
+
@pytest.mark.skip(reason="After completely support discriminated unions, enable these tests")
|
|
225
|
+
class TestEnvelopeObjectCustomProperties:
|
|
226
|
+
"""Test discriminated union with custom property names in envelope."""
|
|
227
|
+
|
|
228
|
+
def test_get_default_cat(self, client: DiscriminatedClient, cat_body: models.Cat):
|
|
229
|
+
"""Test getting cat with default (no query param or petType=cat).
|
|
230
|
+
|
|
231
|
+
Expected response:
|
|
232
|
+
{
|
|
233
|
+
"petType": "cat",
|
|
234
|
+
"petData": {
|
|
235
|
+
"name": "Whiskers",
|
|
236
|
+
"meow": true
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
"""
|
|
240
|
+
result = client.envelope.object.custom_properties.get()
|
|
241
|
+
assert result == cat_body
|
|
242
|
+
assert isinstance(result, models.Cat)
|
|
243
|
+
|
|
244
|
+
def test_get_with_pet_type_cat(self, client: DiscriminatedClient, cat_body: models.Cat):
|
|
245
|
+
"""Test getting cat with petType=cat query parameter.
|
|
246
|
+
|
|
247
|
+
Expected response:
|
|
248
|
+
{
|
|
249
|
+
"petType": "cat",
|
|
250
|
+
"petData": {
|
|
251
|
+
"name": "Whiskers",
|
|
252
|
+
"meow": true
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
"""
|
|
256
|
+
result = client.envelope.object.custom_properties.get(pet_type="cat")
|
|
257
|
+
assert result == cat_body
|
|
258
|
+
assert isinstance(result, models.Cat)
|
|
259
|
+
|
|
260
|
+
def test_get_with_pet_type_dog(self, client: DiscriminatedClient, dog_body: models.Dog):
|
|
261
|
+
"""Test getting dog with petType=dog query parameter.
|
|
262
|
+
|
|
263
|
+
Expected response:
|
|
264
|
+
{
|
|
265
|
+
"petType": "dog",
|
|
266
|
+
"petData": {
|
|
267
|
+
"name": "Rex",
|
|
268
|
+
"bark": false
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
"""
|
|
272
|
+
result = client.envelope.object.custom_properties.get(pet_type="dog")
|
|
273
|
+
assert result == dog_body
|
|
274
|
+
assert isinstance(result, models.Dog)
|
|
275
|
+
|
|
276
|
+
def test_put_cat(self, client: DiscriminatedClient, cat_body: models.Cat):
|
|
277
|
+
"""Test sending cat with custom property names in envelope.
|
|
278
|
+
|
|
279
|
+
Expected request:
|
|
280
|
+
{
|
|
281
|
+
"petType": "cat",
|
|
282
|
+
"petData": {
|
|
283
|
+
"name": "Whiskers",
|
|
284
|
+
"meow": true
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
"""
|
|
288
|
+
result = client.envelope.object.custom_properties.put(cat_body)
|
|
289
|
+
assert result == cat_body
|
|
290
|
+
assert isinstance(result, models.Cat)
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
-e ./generated/parameters-basic
|
|
15
15
|
-e ./generated/parameters-collection-format
|
|
16
16
|
-e ./generated/parameters-path
|
|
17
|
+
-e ./generated/parameters-query
|
|
17
18
|
-e ./generated/parameters-spread
|
|
18
19
|
-e ./generated/serialization-encoded-name-json
|
|
19
20
|
-e ./generated/server-endpoint-not-defined
|
|
@@ -40,6 +41,7 @@
|
|
|
40
41
|
-e ./generated/typetest-property-additionalproperties
|
|
41
42
|
-e ./generated/typetest-scalar
|
|
42
43
|
-e ./generated/typetest-union
|
|
44
|
+
-e ./generated/typetest-discriminatedunion
|
|
43
45
|
-e ./generated/typetest-model-empty
|
|
44
46
|
-e ./generated/headasbooleantrue
|
|
45
47
|
-e ./generated/headasbooleanfalse
|
|
@@ -332,6 +332,72 @@ def test_property_is_a_type():
|
|
|
332
332
|
assert fishery.fish.species == fishery.fish["species"] == fishery["fish"]["species"] == "Salmon"
|
|
333
333
|
|
|
334
334
|
|
|
335
|
+
def test_model_initialization():
|
|
336
|
+
class DatetimeModel(Model):
|
|
337
|
+
datetime_value: datetime.datetime = rest_field(name="datetimeValue")
|
|
338
|
+
|
|
339
|
+
@overload
|
|
340
|
+
def __init__(self, *, datetime_value: datetime.datetime): ...
|
|
341
|
+
|
|
342
|
+
@overload
|
|
343
|
+
def __init__(self, mapping: Mapping[str, Any], /): ...
|
|
344
|
+
|
|
345
|
+
def __init__(self, *args, **kwargs):
|
|
346
|
+
super().__init__(*args, **kwargs)
|
|
347
|
+
|
|
348
|
+
val_str = "9999-12-31T23:59:59.999000Z"
|
|
349
|
+
val = isodate.parse_datetime(val_str)
|
|
350
|
+
|
|
351
|
+
# when initialize model with dict, the dict value is shall be serialized value
|
|
352
|
+
model1 = DatetimeModel({"datetimeValue": val_str})
|
|
353
|
+
assert model1["datetimeValue"] == val_str
|
|
354
|
+
assert model1.datetime_value == val
|
|
355
|
+
|
|
356
|
+
# when initialize model with keyword args, the value is deserialized value
|
|
357
|
+
model2 = DatetimeModel(datetime_value=val)
|
|
358
|
+
assert model2["datetimeValue"] == val_str
|
|
359
|
+
assert model2.datetime_value == val
|
|
360
|
+
|
|
361
|
+
# what if we initialize with dict but the dict has deserialized value? this case show what happens.
|
|
362
|
+
# Since we always serialize the value before initializing the model from dict, we could still get correct result
|
|
363
|
+
model3 = DatetimeModel({"datetimeValue": val})
|
|
364
|
+
assert model3["datetimeValue"] == val_str
|
|
365
|
+
assert model3.datetime_value == val
|
|
366
|
+
|
|
367
|
+
|
|
368
|
+
def test_model_dict_prop_initialization():
|
|
369
|
+
class DatetimeModel(Model):
|
|
370
|
+
dict_prop: dict[str, datetime.datetime] = rest_field(name="dictProp")
|
|
371
|
+
|
|
372
|
+
@overload
|
|
373
|
+
def __init__(self, *, dict_prop: dict[str, datetime.datetime]): ...
|
|
374
|
+
|
|
375
|
+
@overload
|
|
376
|
+
def __init__(self, mapping: Mapping[str, Any], /): ...
|
|
377
|
+
|
|
378
|
+
def __init__(self, *args, **kwargs):
|
|
379
|
+
super().__init__(*args, **kwargs)
|
|
380
|
+
|
|
381
|
+
val_str = "9999-12-31T23:59:59.999000Z"
|
|
382
|
+
val = isodate.parse_datetime(val_str)
|
|
383
|
+
|
|
384
|
+
# when initialize model with dict, the dict value is shall be serialized value
|
|
385
|
+
model1 = DatetimeModel({"dictProp": {"key1": val_str}})
|
|
386
|
+
assert model1["dictProp"] == {"key1": val_str}
|
|
387
|
+
assert model1.dict_prop == {"key1": val}
|
|
388
|
+
|
|
389
|
+
# when initialize model with keyword args, the value is deserialized value
|
|
390
|
+
model2 = DatetimeModel(dict_prop={"key1": val})
|
|
391
|
+
assert model2["dictProp"] == {"key1": val_str}
|
|
392
|
+
assert model2.dict_prop == {"key1": val}
|
|
393
|
+
|
|
394
|
+
# what if we initialize with dict but the dict has deserialized value? this case show what happens.
|
|
395
|
+
# Since we always serialize the value before initializing the model from dict, we could still get correct result
|
|
396
|
+
model3 = DatetimeModel({"dictProp": {"key1": val}})
|
|
397
|
+
assert model3["dictProp"] == {"key1": val_str}
|
|
398
|
+
assert model3.dict_prop == {"key1": val}
|
|
399
|
+
|
|
400
|
+
|
|
335
401
|
def test_datetime_deserialization():
|
|
336
402
|
class DatetimeModel(Model):
|
|
337
403
|
datetime_value: datetime.datetime = rest_field(name="datetimeValue")
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@typespec/http-client-python",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.24.0",
|
|
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.63.0 <1.0.0",
|
|
59
59
|
"@azure-tools/typespec-azure-resource-manager": ">=0.63.0 <1.0.0",
|
|
60
60
|
"@azure-tools/typespec-azure-rulesets": ">=0.63.0 <1.0.0",
|
|
61
|
-
"@azure-tools/typespec-client-generator-core": ">=0.63.
|
|
61
|
+
"@azure-tools/typespec-client-generator-core": ">=0.63.4 <1.0.0",
|
|
62
62
|
"@typespec/compiler": "^1.7.0",
|
|
63
63
|
"@typespec/http": "^1.7.0",
|
|
64
64
|
"@typespec/openapi": "^1.7.0",
|
|
@@ -81,8 +81,8 @@
|
|
|
81
81
|
"@azure-tools/typespec-azure-core": "~0.63.0",
|
|
82
82
|
"@azure-tools/typespec-azure-resource-manager": "~0.63.0",
|
|
83
83
|
"@azure-tools/typespec-azure-rulesets": "~0.63.0",
|
|
84
|
-
"@azure-tools/typespec-client-generator-core": "~0.63.
|
|
85
|
-
"@azure-tools/azure-http-specs": "0.1.0-alpha.
|
|
84
|
+
"@azure-tools/typespec-client-generator-core": "~0.63.4",
|
|
85
|
+
"@azure-tools/azure-http-specs": "0.1.0-alpha.35-dev.8",
|
|
86
86
|
"@typespec/compiler": "^1.7.0",
|
|
87
87
|
"@typespec/http": "^1.7.0",
|
|
88
88
|
"@typespec/openapi": "^1.7.0",
|
|
@@ -94,7 +94,7 @@
|
|
|
94
94
|
"@typespec/sse": "~0.77.0",
|
|
95
95
|
"@typespec/streams": "~0.77.0",
|
|
96
96
|
"@typespec/xml": "~0.77.0",
|
|
97
|
-
"@typespec/http-specs": "0.1.0-alpha.
|
|
97
|
+
"@typespec/http-specs": "0.1.0-alpha.30-dev.1",
|
|
98
98
|
"@types/js-yaml": "~4.0.5",
|
|
99
99
|
"@types/node": "~24.1.0",
|
|
100
100
|
"@types/semver": "7.5.8",
|