diff --git a/.chronus/changes/auto-microsoft-copilot-fix-8453-2025-8-15-14-14-16.md b/.chronus/changes/auto-microsoft-copilot-fix-8453-2025-8-15-14-14-16.md new file mode 100644 index 00000000000..812a648c6f2 --- /dev/null +++ b/.chronus/changes/auto-microsoft-copilot-fix-8453-2025-8-15-14-14-16.md @@ -0,0 +1,8 @@ +--- +changeKind: feature +packages: + - "@autorest/python" + - "@azure-tools/typespec-python" +--- + +Support nested nextLink for paging operation \ No newline at end of file diff --git a/packages/autorest.python/package.json b/packages/autorest.python/package.json index 890e66b4628..1575d86466d 100644 --- a/packages/autorest.python/package.json +++ b/packages/autorest.python/package.json @@ -29,7 +29,7 @@ }, "homepage": "https://github.com/Azure/autorest.python/blob/main/README.md", "dependencies": { - "@typespec/http-client-python": "~0.17.0", + "@typespec/http-client-python": "https://artprodcus3.artifacts.visualstudio.com/A0fb41ef4-5012-48a9-bf39-4ee3de03ee35/29ec6040-b234-4e31-b139-33dc4287b756/_apis/artifact/cGlwZWxpbmVhcnRpZmFjdDovL2F6dXJlLXNkay9wcm9qZWN0SWQvMjllYzYwNDAtYjIzNC00ZTMxLWIxMzktMzNkYzQyODdiNzU2L2J1aWxkSWQvNTMzNzIyOC9hcnRpZmFjdE5hbWUvYnVpbGRfYXJ0aWZhY3RzX3B5dGhvbg2/content?format=file&subPath=%2Fpackages%2Ftypespec-http-client-python-0.17.0.tgz", "@autorest/system-requirements": "~1.0.2", "fs-extra": "~11.2.0", "tsx": "~4.19.1" @@ -47,4 +47,4 @@ "requirements.txt", "generator/" ] -} +} \ No newline at end of file diff --git a/packages/typespec-python/package.json b/packages/typespec-python/package.json index 8ac7e93b5d6..232993ed157 100644 --- a/packages/typespec-python/package.json +++ b/packages/typespec-python/package.json @@ -67,7 +67,7 @@ "js-yaml": "~4.1.0", "semver": "~7.6.2", "tsx": "~4.19.1", - "@typespec/http-client-python": "~0.17.0", + "@typespec/http-client-python": "https://artprodcus3.artifacts.visualstudio.com/A0fb41ef4-5012-48a9-bf39-4ee3de03ee35/29ec6040-b234-4e31-b139-33dc4287b756/_apis/artifact/cGlwZWxpbmVhcnRpZmFjdDovL2F6dXJlLXNkay9wcm9qZWN0SWQvMjllYzYwNDAtYjIzNC00ZTMxLWIxMzktMzNkYzQyODdiNzU2L2J1aWxkSWQvNTMzNzIyOC9hcnRpZmFjdE5hbWUvYnVpbGRfYXJ0aWZhY3RzX3B5dGhvbg2/content?format=file&subPath=%2Fpackages%2Ftypespec-http-client-python-0.17.0.tgz", "fs-extra": "~11.2.0" }, "devDependencies": { @@ -103,4 +103,4 @@ "chalk": "5.3.0", "@types/fs-extra": "11.0.4" } -} +} \ No newline at end of file diff --git a/packages/typespec-python/test/azure/generated/payload-pageable/payload/pageable/serverdrivenpagination/aio/operations/_operations.py b/packages/typespec-python/test/azure/generated/payload-pageable/payload/pageable/serverdrivenpagination/aio/operations/_operations.py index 33bee994caa..96edd57ebb9 100644 --- a/packages/typespec-python/test/azure/generated/payload-pageable/payload/pageable/serverdrivenpagination/aio/operations/_operations.py +++ b/packages/typespec-python/test/azure/generated/payload-pageable/payload/pageable/serverdrivenpagination/aio/operations/_operations.py @@ -249,7 +249,7 @@ async def extract_data(pipeline_response): list_of_elem = _deserialize(list[_models3.Pet], deserialized.get("nestedItems", {}).get("pets", [])) if cls: list_of_elem = cls(list_of_elem) # type: ignore - return deserialized.get("nestedNext.next") or None, AsyncList(list_of_elem) + return deserialized.get("nestedNext", {}).get("next") or None, AsyncList(list_of_elem) async def get_next(next_link=None): _request = prepare_request(next_link) diff --git a/packages/typespec-python/test/azure/generated/payload-pageable/payload/pageable/serverdrivenpagination/operations/_operations.py b/packages/typespec-python/test/azure/generated/payload-pageable/payload/pageable/serverdrivenpagination/operations/_operations.py index 1e04871be59..c8f5c6c4884 100644 --- a/packages/typespec-python/test/azure/generated/payload-pageable/payload/pageable/serverdrivenpagination/operations/_operations.py +++ b/packages/typespec-python/test/azure/generated/payload-pageable/payload/pageable/serverdrivenpagination/operations/_operations.py @@ -290,7 +290,7 @@ def extract_data(pipeline_response): list_of_elem = _deserialize(list[_models2.Pet], deserialized.get("nestedItems", {}).get("pets", [])) if cls: list_of_elem = cls(list_of_elem) # type: ignore - return deserialized.get("nestedNext.next") or None, iter(list_of_elem) + return deserialized.get("nestedNext", {}).get("next") or None, iter(list_of_elem) def get_next(next_link=None): _request = prepare_request(next_link) diff --git a/packages/typespec-python/test/generic_mock_api_tests/asynctests/test_payload_pageable_async.py b/packages/typespec-python/test/generic_mock_api_tests/asynctests/test_payload_pageable_async.py index 8af75000c29..f2055067737 100644 --- a/packages/typespec-python/test/generic_mock_api_tests/asynctests/test_payload_pageable_async.py +++ b/packages/typespec-python/test/generic_mock_api_tests/asynctests/test_payload_pageable_async.py @@ -31,6 +31,12 @@ async def test_link(client: PageableClient): assert_result(result) +@pytest.mark.asyncio +async def test_link_string(client: PageableClient): + result = [p async for p in client.server_driven_pagination.link_string()] + assert_result(result) + + @pytest.mark.asyncio async def test_request_query_response_body(client: PageableClient): result = [ @@ -73,3 +79,37 @@ async def test_request_header_response_header(client: PageableClient): ) ] assert_result(result) + + +@pytest.mark.asyncio +async def test_nested_link(client: PageableClient): + result = [p async for p in client.server_driven_pagination.nested_link()] + assert_result(result) + + +@pytest.mark.asyncio +async def test_request_query_nested_response_body(client: PageableClient): + result = [ + p + async for p in client.server_driven_pagination.continuation_token.request_query_nested_response_body( + foo="foo", bar="bar" + ) + ] + assert_result(result) + + +@pytest.mark.asyncio +async def test_request_header_nested_response_body(client: PageableClient): + result = [ + p + async for p in client.server_driven_pagination.continuation_token.request_header_nested_response_body( + foo="foo", bar="bar" + ) + ] + assert_result(result) + + +@pytest.mark.asyncio +async def test_list_without_continuation(client: PageableClient): + result = [p async for p in client.list_without_continuation()] + assert_result(result) diff --git a/packages/typespec-python/test/generic_mock_api_tests/test_payload_pageable.py b/packages/typespec-python/test/generic_mock_api_tests/test_payload_pageable.py index f98f6648751..87fd04caf7a 100644 --- a/packages/typespec-python/test/generic_mock_api_tests/test_payload_pageable.py +++ b/packages/typespec-python/test/generic_mock_api_tests/test_payload_pageable.py @@ -30,6 +30,11 @@ def test_link(client: PageableClient): assert_result(result) +def test_link_string(client: PageableClient): + result = list(client.server_driven_pagination.link_string()) + assert_result(result) + + def test_request_query_response_body(client: PageableClient): result = list(client.server_driven_pagination.continuation_token.request_query_response_body(foo="foo", bar="bar")) assert_result(result) @@ -52,3 +57,27 @@ def test_request_header_response_header(client: PageableClient): client.server_driven_pagination.continuation_token.request_header_response_header(foo="foo", bar="bar") ) assert_result(result) + + +def test_nested_link(client: PageableClient): + result = list(client.server_driven_pagination.nested_link()) + assert_result(result) + + +def test_request_query_nested_response_body(client: PageableClient): + result = list( + client.server_driven_pagination.continuation_token.request_query_nested_response_body(foo="foo", bar="bar") + ) + assert_result(result) + + +def test_request_header_nested_response_body(client: PageableClient): + result = list( + client.server_driven_pagination.continuation_token.request_header_nested_response_body(foo="foo", bar="bar") + ) + assert_result(result) + + +def test_list_without_continuation(client: PageableClient): + result = list(client.list_without_continuation()) + assert_result(result) diff --git a/packages/typespec-python/test/unbranded/generated/payload-pageable/payload/pageable/serverdrivenpagination/aio/operations/_operations.py b/packages/typespec-python/test/unbranded/generated/payload-pageable/payload/pageable/serverdrivenpagination/aio/operations/_operations.py index 8a86cbc6624..9906ca03bff 100644 --- a/packages/typespec-python/test/unbranded/generated/payload-pageable/payload/pageable/serverdrivenpagination/aio/operations/_operations.py +++ b/packages/typespec-python/test/unbranded/generated/payload-pageable/payload/pageable/serverdrivenpagination/aio/operations/_operations.py @@ -235,7 +235,7 @@ async def extract_data(pipeline_response): list_of_elem = _deserialize(list[_models3.Pet], deserialized.get("nestedItems", {}).get("pets", [])) if cls: list_of_elem = cls(list_of_elem) # type: ignore - return deserialized.get("nestedNext.next") or None, AsyncList(list_of_elem) + return deserialized.get("nestedNext", {}).get("next") or None, AsyncList(list_of_elem) async def get_next(next_link=None): _request = prepare_request(next_link) diff --git a/packages/typespec-python/test/unbranded/generated/payload-pageable/payload/pageable/serverdrivenpagination/operations/_operations.py b/packages/typespec-python/test/unbranded/generated/payload-pageable/payload/pageable/serverdrivenpagination/operations/_operations.py index 29984f202f9..1a390507154 100644 --- a/packages/typespec-python/test/unbranded/generated/payload-pageable/payload/pageable/serverdrivenpagination/operations/_operations.py +++ b/packages/typespec-python/test/unbranded/generated/payload-pageable/payload/pageable/serverdrivenpagination/operations/_operations.py @@ -276,7 +276,7 @@ def extract_data(pipeline_response): list_of_elem = _deserialize(list[_models2.Pet], deserialized.get("nestedItems", {}).get("pets", [])) if cls: list_of_elem = cls(list_of_elem) # type: ignore - return deserialized.get("nestedNext.next") or None, iter(list_of_elem) + return deserialized.get("nestedNext", {}).get("next") or None, iter(list_of_elem) def get_next(next_link=None): _request = prepare_request(next_link) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8de033012e3..506de770b5a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -60,8 +60,8 @@ importers: specifier: ~1.0.2 version: 1.0.2 '@typespec/http-client-python': - specifier: ~0.17.0 - version: 0.17.0(4dpduvpv7hdb6q7z6oc6wbsr4a) + specifier: https://artprodcus3.artifacts.visualstudio.com/A0fb41ef4-5012-48a9-bf39-4ee3de03ee35/29ec6040-b234-4e31-b139-33dc4287b756/_apis/artifact/cGlwZWxpbmVhcnRpZmFjdDovL2F6dXJlLXNkay9wcm9qZWN0SWQvMjllYzYwNDAtYjIzNC00ZTMxLWIxMzktMzNkYzQyODdiNzU2L2J1aWxkSWQvNTMzNzIyOC9hcnRpZmFjdE5hbWUvYnVpbGRfYXJ0aWZhY3RzX3B5dGhvbg2/content?format=file&subPath=%2Fpackages%2Ftypespec-http-client-python-0.17.0.tgz + version: https://artprodcus3.artifacts.visualstudio.com/A0fb41ef4-5012-48a9-bf39-4ee3de03ee35/29ec6040-b234-4e31-b139-33dc4287b756/_apis/artifact/cGlwZWxpbmVhcnRpZmFjdDovL2F6dXJlLXNkay9wcm9qZWN0SWQvMjllYzYwNDAtYjIzNC00ZTMxLWIxMzktMzNkYzQyODdiNzU2L2J1aWxkSWQvNTMzNzIyOC9hcnRpZmFjdE5hbWUvYnVpbGRfYXJ0aWZhY3RzX3B5dGhvbg2/content?format=file&subPath=%2Fpackages%2Ftypespec-http-client-python-0.17.0.tgz(4dpduvpv7hdb6q7z6oc6wbsr4a) fs-extra: specifier: ~11.2.0 version: 11.2.0 @@ -82,8 +82,8 @@ importers: packages/typespec-python: dependencies: '@typespec/http-client-python': - specifier: ~0.17.0 - version: 0.17.0(4dpduvpv7hdb6q7z6oc6wbsr4a) + specifier: https://artprodcus3.artifacts.visualstudio.com/A0fb41ef4-5012-48a9-bf39-4ee3de03ee35/29ec6040-b234-4e31-b139-33dc4287b756/_apis/artifact/cGlwZWxpbmVhcnRpZmFjdDovL2F6dXJlLXNkay9wcm9qZWN0SWQvMjllYzYwNDAtYjIzNC00ZTMxLWIxMzktMzNkYzQyODdiNzU2L2J1aWxkSWQvNTMzNzIyOC9hcnRpZmFjdE5hbWUvYnVpbGRfYXJ0aWZhY3RzX3B5dGhvbg2/content?format=file&subPath=%2Fpackages%2Ftypespec-http-client-python-0.17.0.tgz + version: https://artprodcus3.artifacts.visualstudio.com/A0fb41ef4-5012-48a9-bf39-4ee3de03ee35/29ec6040-b234-4e31-b139-33dc4287b756/_apis/artifact/cGlwZWxpbmVhcnRpZmFjdDovL2F6dXJlLXNkay9wcm9qZWN0SWQvMjllYzYwNDAtYjIzNC00ZTMxLWIxMzktMzNkYzQyODdiNzU2L2J1aWxkSWQvNTMzNzIyOC9hcnRpZmFjdE5hbWUvYnVpbGRfYXJ0aWZhY3RzX3B5dGhvbg2/content?format=file&subPath=%2Fpackages%2Ftypespec-http-client-python-0.17.0.tgz(4dpduvpv7hdb6q7z6oc6wbsr4a) fs-extra: specifier: ~11.2.0 version: 11.2.0 @@ -1677,8 +1677,9 @@ packages: peerDependencies: '@typespec/compiler': ^1.4.0 - '@typespec/http-client-python@0.17.0': - resolution: {integrity: sha512-xzpBgbB0AhbTYqpgXnGXqaglhjPpfwJ2ADPm05S9fEtbf6abkBJLZqwewt1IhvKHy9ijCH10OxFA8RJueIF+EA==} + '@typespec/http-client-python@https://artprodcus3.artifacts.visualstudio.com/A0fb41ef4-5012-48a9-bf39-4ee3de03ee35/29ec6040-b234-4e31-b139-33dc4287b756/_apis/artifact/cGlwZWxpbmVhcnRpZmFjdDovL2F6dXJlLXNkay9wcm9qZWN0SWQvMjllYzYwNDAtYjIzNC00ZTMxLWIxMzktMzNkYzQyODdiNzU2L2J1aWxkSWQvNTMzNzIyOC9hcnRpZmFjdE5hbWUvYnVpbGRfYXJ0aWZhY3RzX3B5dGhvbg2/content?format=file&subPath=%2Fpackages%2Ftypespec-http-client-python-0.17.0.tgz': + resolution: {tarball: https://artprodcus3.artifacts.visualstudio.com/A0fb41ef4-5012-48a9-bf39-4ee3de03ee35/29ec6040-b234-4e31-b139-33dc4287b756/_apis/artifact/cGlwZWxpbmVhcnRpZmFjdDovL2F6dXJlLXNkay9wcm9qZWN0SWQvMjllYzYwNDAtYjIzNC00ZTMxLWIxMzktMzNkYzQyODdiNzU2L2J1aWxkSWQvNTMzNzIyOC9hcnRpZmFjdE5hbWUvYnVpbGRfYXJ0aWZhY3RzX3B5dGhvbg2/content?format=file&subPath=%2Fpackages%2Ftypespec-http-client-python-0.17.0.tgz} + version: 0.17.0 engines: {node: '>=20.0.0'} peerDependencies: '@azure-tools/typespec-autorest': '>=0.60.0 <1.0.0' @@ -6459,7 +6460,7 @@ snapshots: dependencies: '@typespec/compiler': 1.4.0(@types/node@24.1.0) - '@typespec/http-client-python@0.17.0(4dpduvpv7hdb6q7z6oc6wbsr4a)': + '@typespec/http-client-python@https://artprodcus3.artifacts.visualstudio.com/A0fb41ef4-5012-48a9-bf39-4ee3de03ee35/29ec6040-b234-4e31-b139-33dc4287b756/_apis/artifact/cGlwZWxpbmVhcnRpZmFjdDovL2F6dXJlLXNkay9wcm9qZWN0SWQvMjllYzYwNDAtYjIzNC00ZTMxLWIxMzktMzNkYzQyODdiNzU2L2J1aWxkSWQvNTMzNzIyOC9hcnRpZmFjdE5hbWUvYnVpbGRfYXJ0aWZhY3RzX3B5dGhvbg2/content?format=file&subPath=%2Fpackages%2Ftypespec-http-client-python-0.17.0.tgz(4dpduvpv7hdb6q7z6oc6wbsr4a)': dependencies: '@azure-tools/typespec-autorest': 0.60.0(ezw5aevbqzniqofcqdfpewwsui) '@azure-tools/typespec-azure-core': 0.60.0(@typespec/compiler@1.4.0(@types/node@24.1.0))(@typespec/http@1.4.0(@typespec/compiler@1.4.0(@types/node@24.1.0))(@typespec/streams@0.74.0(@typespec/compiler@1.4.0(@types/node@24.1.0))))(@typespec/rest@0.74.0(@typespec/compiler@1.4.0(@types/node@24.1.0))(@typespec/http@1.4.0(@typespec/compiler@1.4.0(@types/node@24.1.0))(@typespec/streams@0.74.0(@typespec/compiler@1.4.0(@types/node@24.1.0)))))