Skip to content

Commit 5228f10

Browse files
04diiguyiYi Gu
andauthored
Add pagination feature (microsoft#652)
* Add new python client * Add first round of pagincation cod * Add first unit test * Add unit test * fix a bug * update tests * Simplify code * update tests * add test case * remove unused file * add a new record * Add a test * add another test * combine test * Add another test * Add a test * Add a test * Add a test * Add a test * Add a test * Add a test * Add a test * Add a test * Add a test * Add a test * Add a test * Add a test * Add a test * Add a test * Add a test * Add a test * Add a test * Add a test * Add a test * Add a test * Add a test * Add a test * Add a test * Add a test * Add a test * Add a test * Add a test * Add keyword restriction * rename pagesize to top * Add unit tests * update tests * update tests * limit package version * limit package version * update * update tests * update datetime * update recording and readme * update unit tests * update length count * update unit test * update unit test * remove aio folder --------- Co-authored-by: Yi Gu <guyi@microsoft.com>
1 parent 6c99137 commit 5228f10

File tree

189 files changed

+53937
-52084
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

189 files changed

+53937
-52084
lines changed

CONTRIBUTING.md

Lines changed: 79 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -67,18 +67,90 @@ To read more about how to create and update recordings for testing code that int
6767

6868
Before merging your code contribution to `main`, make sure that all new code is covered by unit tests and that the unit tests have up-to-date recordings. If you recorded your tests and then updated or refactored the code afterwards, remember to re-record the tests.
6969

70-
### Update/re-generate the Azure Quantum internal SDK client based on Swagger ###
70+
### Update/re-generate the Azure Quantum internal SDK client ###
7171

7272
The internal Azure Quantum Python SDK client (`azure/quantum/_client`) needs to be re-generated every time there is a change in the [Azure Quantum Service API definition](https://github.com/Azure/azure-rest-api-specs/tree/main/specification/quantum/data-plane) (aka Swagger).
7373

74-
To re-generate the client based on the latest published API definition simply run the following PowerShell script
74+
#### Prerequisites
75+
Python 3.8 or later is required
7576

76-
```powershell
77-
./eng/Generate-DataPlane-Client.ps1
78-
```
79-
> See the Generate-DataPlane-Client.ps1 script for more options
77+
linux
78+
79+
sudo apt install python3
80+
81+
sudo apt install python3-pip
82+
83+
sudo apt install python3.{?}-venv explicitly if needed
84+
85+
Node.js 18.3 LTS or later is required
86+
87+
#### Setup your repo
88+
Fork and clone the azure-sdk-for-python repo (we call it's name SDK repo and it's absolute path)
89+
90+
Create a branch in SDK repo to work in
91+
92+
Make sure your typespec definition is merged into main branch of public rest repo (we call it rest repo) or you already make a PR in rest repo so that you could get the github link of your typespec definition which contains commit id (e.g. https://github.com/Azure/azure-rest-api-specs/blob/46ca83821edd120552403d4d11cf1dd22360c0b5/specification/contosowidgetmanager/Contoso.WidgetManager/tspconfig.yaml)
93+
94+
#### Project service name and package name
95+
Two key pieces of information for your project are the service_name and package_name.
96+
97+
The service_name is the short name for the Azure service. The service_name should match across all the SDK language repos and should be name of the directory in the specification folder of the azure-rest-api-specs repo that contains the REST API definition file. An example is Service Bus, whose API definitions are in the specification/servicebus folder of the azure-rest-api-specs repo, and uses the service_name "servicebus". Not every service follows this convention, but it should be the standard unless there are strong reasons to deviate.
98+
99+
In Python, a project's package name is the name used to publish the package in PyPI. For data plane libraries (management plane uses a different convention), the package_name could be just azure-{service_name}. An example is "azure-servicebus".
100+
101+
Some services may need several different packages. For these cases a third component, the module_name, is added to the package_name, as azure-{service_name}-{module_name}. The module_name usually comes from the name of the REST API file itself or one of the directories toward the end of the file path. An example is the Synapse service, with packages azure-synapse, azure-synapse-accesscontrol, azure-synapse-artifacts, etc.
102+
103+
#### Project folder structure
104+
Before we start, we probably should get to know the project folder for SDK repo.
105+
106+
Normally, the folder structure would be something like:
107+
108+
sdk/{service_name}/{package_name}: the PROJECT_ROOT folder
109+
/azure/{service_name}/{module_name} : folder where generated code is.
110+
/tests: folder of test files
111+
/samples: folder of sample files
112+
azure-{service_name}-{module_name}: package name. Usually, package name is same with part of ${PROJECT_ROOT} folder. After release, you can find it in pypi. For example: you can find azure-messaging-webpubsubservice in pypi.
113+
there are also some other files (like setup.py, README.md, etc.) which are necessary for a complete package.
114+
More details on the structure of Azure SDK repos is available in the Azure SDK common repo.
115+
116+
#### How to generate SDK code with Dataplane Codegen
117+
We are working on to automatically generate everything right now, but currently we still need some manual work to get a releasable package. Here're the steps of how to get the package.
118+
119+
1. Configure python emitter in tspconfig.yaml
120+
In rest repo, there shall be tspconfig.yaml where main.tsp of your service is. Make sure there are configuration for Python SDK like:
121+
122+
parameters:
123+
"service-dir":
124+
default: "YOUR_SERVICE_DIRECTORY"
125+
126+
emit: [
127+
"@azure-tools/typespec-autorest", // this value does not affect python code generation
128+
]
129+
130+
options:
131+
"@azure-tools/typespec-python":
132+
package-dir: "YOUR_PACKAGE_NAME"
133+
package-name: "{package-dir}"
134+
flavor: "azure"
135+
YOUR_PACKAGE_NAME is your package name; YOUR_SERVICE_DIRECTORY is SDK directory name. For example, assume that package name is "azure-ai-anomalydetector" and you want to put it in folder "azure-sdk-for-python/sdk/anomalydetector", then "YOUR_PACKAGE_NAME" is "azure-ai-anomalydetector" and "YOUR_SERVICE_DIRECTORY" is "sdk/anomalydetector"
136+
137+
2. Run cmd to generate the SDK
138+
Install tsp-client CLI tool:
139+
140+
npm install -g @azure-tools/typespec-client-generator-cli
141+
For initial set up, from the root of the SDK repo, call:
142+
143+
D:\dev\azure-sdk-for-python> tsp-client init -c YOUR_REMOTE_TSPCONFIG_URL
144+
An example of YOUR_REMOTE_TSPCONFIG_URL is https://github.com/Azure/azure-rest-api-specs/blob/46ca83821edd120552403d4d11cf1dd22360c0b5/specification/contosowidgetmanager/Contoso.WidgetManager/tspconfig.yaml
145+
146+
To update your TypeSpec generated SDK, go to your SDK folder where your tsp-location.yaml is located, call:
147+
148+
D:\dev\azure-sdk-for-python\sdk\contoso\azure-contoso-widget> tox run -e generate -c ..\..\..\eng\tox\tox.ini --root .
149+
Note: To know more about tox, read our contributing guidelines
150+
151+
The tox run -e generate call will look for a tsp-location.yaml file in your local directory. tsp-location.yaml contains the configuration information that will be used to sync your TypeSpec project and generate your SDK. Please make sure that the commit is targeting the correct TypeSpec project updates you wish to generate your SDK from.
80152

81-
After re-generating the client make sure to:
153+
#### After re-generating the client make sure to:
82154

83155
1. Re-run/Re-record all unit tests against the live-service (you can run `./eng/Record-Tests.ps1`)
84156
1. If necessary, adjust the convenience layer for breaking-changes or to expose new features

azure-quantum/azure/quantum/_client/__init__.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,31 @@
22
# --------------------------------------------------------------------------
33
# Copyright (c) Microsoft Corporation. All rights reserved.
44
# Licensed under the MIT License. See License.txt in the project root for license information.
5-
# Code generated by Microsoft (R) AutoRest Code Generator.
5+
# Code generated by Microsoft (R) Python Code Generator.
66
# Changes may cause incorrect behavior and will be lost if the code is regenerated.
77
# --------------------------------------------------------------------------
8+
# pylint: disable=wrong-import-position
89

9-
from ._client import QuantumClient
10+
from typing import TYPE_CHECKING
11+
12+
if TYPE_CHECKING:
13+
from ._patch import * # pylint: disable=unused-wildcard-import
14+
15+
from ._client import ServicesClient # type: ignore
1016
from ._version import VERSION
1117

1218
__version__ = VERSION
1319

1420
try:
1521
from ._patch import __all__ as _patch_all
16-
from ._patch import * # pylint: disable=unused-wildcard-import
22+
from ._patch import *
1723
except ImportError:
1824
_patch_all = []
1925
from ._patch import patch_sdk as _patch_sdk
2026

2127
__all__ = [
22-
"QuantumClient",
28+
"ServicesClient",
2329
]
24-
__all__.extend([p for p in _patch_all if p not in __all__])
30+
__all__.extend([p for p in _patch_all if p not in __all__]) # pyright: ignore
2531

2632
_patch_sdk()

azure-quantum/azure/quantum/_client/_client.py

Lines changed: 40 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,20 @@
22
# --------------------------------------------------------------------------
33
# Copyright (c) Microsoft Corporation. All rights reserved.
44
# Licensed under the MIT License. See License.txt in the project root for license information.
5-
# Code generated by Microsoft (R) AutoRest Code Generator.
5+
# Code generated by Microsoft (R) Python Code Generator.
66
# Changes may cause incorrect behavior and will be lost if the code is regenerated.
77
# --------------------------------------------------------------------------
88

99
from copy import deepcopy
10-
from typing import Any, TYPE_CHECKING
10+
from typing import Any, TYPE_CHECKING, Union
11+
from typing_extensions import Self
1112

1213
from azure.core import PipelineClient
14+
from azure.core.credentials import AzureKeyCredential
1315
from azure.core.pipeline import policies
1416
from azure.core.rest import HttpRequest, HttpResponse
1517

16-
from . import models as _models
17-
from ._configuration import QuantumClientConfiguration
18+
from ._configuration import ServicesClientConfiguration
1819
from ._serialization import Deserializer, Serializer
1920
from .operations import (
2021
JobsOperations,
@@ -26,59 +27,50 @@
2627
)
2728

2829
if TYPE_CHECKING:
29-
# pylint: disable=unused-import,ungrouped-imports
3030
from azure.core.credentials import TokenCredential
3131

3232

33-
class QuantumClient: # pylint: disable=client-accepts-api-version-keyword
34-
"""Azure Quantum REST API client.
33+
class ServicesClient:
34+
"""Azure Quantum Workspace Services.
3535
3636
:ivar jobs: JobsOperations operations
37-
:vartype jobs: azure.quantum._client.operations.JobsOperations
37+
:vartype jobs: azure.quantum.operations.JobsOperations
38+
:ivar sessions: SessionsOperations operations
39+
:vartype sessions: azure.quantum.operations.SessionsOperations
3840
:ivar providers: ProvidersOperations operations
39-
:vartype providers: azure.quantum._client.operations.ProvidersOperations
41+
:vartype providers: azure.quantum.operations.ProvidersOperations
4042
:ivar storage: StorageOperations operations
41-
:vartype storage: azure.quantum._client.operations.StorageOperations
43+
:vartype storage: azure.quantum.operations.StorageOperations
4244
:ivar quotas: QuotasOperations operations
43-
:vartype quotas: azure.quantum._client.operations.QuotasOperations
44-
:ivar sessions: SessionsOperations operations
45-
:vartype sessions: azure.quantum._client.operations.SessionsOperations
45+
:vartype quotas: azure.quantum.operations.QuotasOperations
4646
:ivar top_level_items: TopLevelItemsOperations operations
47-
:vartype top_level_items: azure.quantum._client.operations.TopLevelItemsOperations
48-
:param azure_region: Supported Azure regions for Azure Quantum Services. For example, "eastus".
49-
Required.
50-
:type azure_region: str
51-
:param subscription_id: The Azure subscription ID. This is a GUID-formatted string (e.g.
52-
00000000-0000-0000-0000-000000000000). Required.
53-
:type subscription_id: str
54-
:param resource_group_name: Name of an Azure resource group. Required.
55-
:type resource_group_name: str
56-
:param workspace_name: Name of the workspace. Required.
57-
:type workspace_name: str
58-
:param credential: Credential needed for the client to connect to Azure. Required.
59-
:type credential: ~azure.core.credentials.TokenCredential
60-
:keyword api_version: Api Version. Default value is "2023-11-13-preview". Note that overriding
61-
this default value may result in unsupported behavior.
47+
:vartype top_level_items: azure.quantum.operations.TopLevelItemsOperations
48+
:param region: The Azure region where the Azure Quantum Workspace is located. Required.
49+
:type region: str
50+
:param credential: Credential used to authenticate requests to the service. Is either a
51+
TokenCredential type or a AzureKeyCredential type. Required.
52+
:type credential: ~azure.core.credentials.TokenCredential or
53+
~azure.core.credentials.AzureKeyCredential
54+
:keyword service_base_url: The Azure Quantum service base url. Default value is
55+
"quantum.azure.com".
56+
:paramtype service_base_url: str
57+
:keyword api_version: The API version to use for this operation. Default value is
58+
"2024-10-01-preview". Note that overriding this default value may result in unsupported
59+
behavior.
6260
:paramtype api_version: str
6361
"""
6462

6563
def __init__(
6664
self,
67-
azure_region: str,
68-
subscription_id: str,
69-
resource_group_name: str,
70-
workspace_name: str,
71-
credential: "TokenCredential",
65+
region: str,
66+
credential: Union["TokenCredential", AzureKeyCredential],
67+
*,
68+
service_base_url: str = "quantum.azure.com",
7269
**kwargs: Any
7370
) -> None:
74-
_endpoint = kwargs.pop("endpoint", f"https://{azure_region}.quantum.azure.com")
75-
self._config = QuantumClientConfiguration(
76-
azure_region=azure_region,
77-
subscription_id=subscription_id,
78-
resource_group_name=resource_group_name,
79-
workspace_name=workspace_name,
80-
credential=credential,
81-
**kwargs
71+
_endpoint = "https://{region}.{serviceBaseUrl}"
72+
self._config = ServicesClientConfiguration(
73+
region=region, credential=credential, service_base_url=service_base_url, **kwargs
8274
)
8375
_policies = kwargs.pop("policies", None)
8476
if _policies is None:
@@ -99,16 +91,14 @@ def __init__(
9991
]
10092
self._client: PipelineClient = PipelineClient(base_url=_endpoint, policies=_policies, **kwargs)
10193

102-
client_models = {k: v for k, v in _models._models.__dict__.items() if isinstance(v, type)}
103-
client_models.update({k: v for k, v in _models.__dict__.items() if isinstance(v, type)})
104-
self._serialize = Serializer(client_models)
105-
self._deserialize = Deserializer(client_models)
94+
self._serialize = Serializer()
95+
self._deserialize = Deserializer()
10696
self._serialize.client_side_validation = False
10797
self.jobs = JobsOperations(self._client, self._config, self._serialize, self._deserialize)
98+
self.sessions = SessionsOperations(self._client, self._config, self._serialize, self._deserialize)
10899
self.providers = ProvidersOperations(self._client, self._config, self._serialize, self._deserialize)
109100
self.storage = StorageOperations(self._client, self._config, self._serialize, self._deserialize)
110101
self.quotas = QuotasOperations(self._client, self._config, self._serialize, self._deserialize)
111-
self.sessions = SessionsOperations(self._client, self._config, self._serialize, self._deserialize)
112102
self.top_level_items = TopLevelItemsOperations(self._client, self._config, self._serialize, self._deserialize)
113103

114104
def send_request(self, request: HttpRequest, *, stream: bool = False, **kwargs: Any) -> HttpResponse:
@@ -131,8 +121,9 @@ def send_request(self, request: HttpRequest, *, stream: bool = False, **kwargs:
131121

132122
request_copy = deepcopy(request)
133123
path_format_arguments = {
134-
"azureRegion": self._serialize.url(
135-
"self._config.azure_region", self._config.azure_region, "str", skip_quote=True
124+
"region": self._serialize.url("self._config.region", self._config.region, "str"),
125+
"serviceBaseUrl": self._serialize.url(
126+
"self._config.service_base_url", self._config.service_base_url, "str"
136127
),
137128
}
138129

@@ -142,7 +133,7 @@ def send_request(self, request: HttpRequest, *, stream: bool = False, **kwargs:
142133
def close(self) -> None:
143134
self._client.close()
144135

145-
def __enter__(self) -> "QuantumClient":
136+
def __enter__(self) -> Self:
146137
self._client.__enter__()
147138
return self
148139

0 commit comments

Comments
 (0)