Skip to content

Commit 9c4e540

Browse files
author
Yalin Li
authored
[AppConfig] Support monitor page changes by page etag (#34346)
1 parent f0a7ed4 commit 9c4e540

17 files changed

+910
-27
lines changed

.vscode/cspell.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1682,6 +1682,12 @@
16821682
"azconfig"
16831683
]
16841684
},
1685+
{
1686+
"filename": "sdk/appconfiguration/azure-appconfiguration/**",
1687+
"words": [
1688+
"kvset"
1689+
]
1690+
},
16851691
{
16861692
"filename": "sdk/personalizer/test-resources.json",
16871693
"words": [

sdk/appconfiguration/azure-appconfiguration/CHANGELOG.md

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,14 @@
11
# Release History
22

3-
## 1.5.1 (Unreleased)
3+
## 1.6.0b1 (2024-03-14)
44

55
### Features Added
6-
7-
### Breaking Changes
6+
- Exposed `send_request()` method in each client to send custom requests using the client's existing pipeline.
7+
- Supported to get page ETag while iterating `list_configuration_setting()` result by page.
88

99
### Bugs Fixed
1010
- Fixed a bug in consuming "etag" value in sync operation `set_configuration_setting()`.
1111

12-
### Other Changes
13-
1412
## 1.5.0 (2023-11-09)
1513

1614
### Other Changes

sdk/appconfiguration/azure-appconfiguration/assets.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22
"AssetsRepo": "Azure/azure-sdk-assets",
33
"AssetsRepoPrefixPath": "python",
44
"TagPrefix": "python/appconfiguration/azure-appconfiguration",
5-
"Tag": "python/appconfiguration/azure-appconfiguration_6ae662d134"
5+
"Tag": "python/appconfiguration/azure-appconfiguration_8137b21bd0"
66
}

sdk/appconfiguration/azure-appconfiguration/azure/appconfiguration/_azure_appconfiguration_client.py

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
# license information.
55
# -------------------------------------------------------------------------
66
import binascii
7+
import functools
78
from datetime import datetime
89
from typing import Any, Dict, List, Mapping, Optional, Union, cast, overload
910
from typing_extensions import Literal
@@ -19,12 +20,18 @@
1920
ResourceModifiedError,
2021
ResourceNotModifiedError,
2122
)
23+
from azure.core.rest import HttpRequest, HttpResponse
2224
from azure.core.utils import CaseInsensitiveDict
2325
from ._azure_appconfiguration_error import ResourceReadOnlyError
2426
from ._azure_appconfiguration_requests import AppConfigRequestsCredentialsPolicy
2527
from ._generated import AzureAppConfiguration
2628
from ._generated.models import SnapshotUpdateParameters, SnapshotStatus
27-
from ._models import ConfigurationSetting, ConfigurationSettingsFilter, ConfigurationSnapshot
29+
from ._models import (
30+
ConfigurationSetting,
31+
ConfigurationSettingsFilter,
32+
ConfigurationSnapshot,
33+
ConfigurationSettingPropertiesPaged,
34+
)
2835
from ._utils import (
2936
prep_if_match,
3037
prep_if_none_match,
@@ -110,6 +117,23 @@ def from_connection_string(cls, connection_string: str, **kwargs: Any) -> "Azure
110117
**kwargs,
111118
)
112119

120+
@distributed_trace
121+
def send_request(self, request: HttpRequest, *, stream: bool = False, **kwargs) -> HttpResponse:
122+
"""Runs a network request using the client's existing pipeline.
123+
124+
The request URL can be relative to the vault URL. The service API version used for the request is the same as
125+
the client's unless otherwise specified. This method does not raise if the response is an error; to raise an
126+
exception, call `raise_for_status()` on the returned response object. For more information about how to send
127+
custom requests with this method, see https://aka.ms/azsdk/dpcodegen/python/send_request.
128+
129+
:param request: The network request you want to make.
130+
:type request: ~azure.core.rest.HttpRequest
131+
:keyword bool stream: Whether the response payload will be streamed. Defaults to False.
132+
:return: The response of your network call. Does not do error handling on your response.
133+
:rtype: ~azure.core.rest.HttpResponse
134+
"""
135+
return self._impl._send_request(request, stream=stream, **kwargs)
136+
113137
@overload
114138
def list_configuration_settings(
115139
self,
@@ -192,14 +216,16 @@ def list_configuration_settings(self, *args, **kwargs) -> ItemPaged[Configuratio
192216
)
193217
key_filter, kwargs = get_key_filter(*args, **kwargs)
194218
label_filter, kwargs = get_label_filter(*args, **kwargs)
195-
return self._impl.get_key_values( # type: ignore
219+
command = functools.partial(self._impl.get_key_values_in_one_page, **kwargs) # type: ignore[attr-defined]
220+
return ItemPaged(
221+
command,
196222
key=key_filter,
197223
label=label_filter,
198224
accept_datetime=accept_datetime,
199225
select=select,
200-
cls=lambda objs: [ConfigurationSetting._from_generated(x) for x in objs],
201-
**kwargs,
226+
page_iterator_class=ConfigurationSettingPropertiesPaged,
202227
)
228+
203229
except binascii.Error as exc:
204230
raise binascii.Error("Connection string secret has incorrect padding") from exc
205231

sdk/appconfiguration/azure-appconfiguration/azure/appconfiguration/_generated/aio/operations/_patch.py

Lines changed: 150 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,157 @@
66
77
Follow our quickstart for examples: https://aka.ms/azsdk/python/dpcodegen/python/customize
88
"""
9-
from typing import List
9+
import urllib.parse
10+
from typing import Any, AsyncIterable, List, Optional, Union
11+
from azure.core.exceptions import (
12+
ClientAuthenticationError,
13+
HttpResponseError,
14+
ResourceExistsError,
15+
ResourceNotFoundError,
16+
ResourceNotModifiedError,
17+
map_error,
18+
)
19+
from azure.core.rest import HttpRequest
20+
from azure.core.tracing.decorator_async import distributed_trace_async
21+
from azure.core.utils import case_insensitive_dict
22+
from ._azure_app_configuration_operations import (
23+
AzureAppConfigurationOperationsMixin as AzureAppConfigOpGenerated,
24+
ClsType,
25+
build_get_key_values_request,
26+
)
27+
from ... import models as _models
28+
from ..._vendor import _convert_request
1029

11-
__all__: List[str] = [] # Add all objects you want publicly available to users at this package level
30+
31+
class AzureAppConfigurationOperationsMixin(AzureAppConfigOpGenerated):
32+
@distributed_trace_async
33+
async def get_key_values_in_one_page(
34+
self,
35+
key: Optional[str] = None,
36+
label: Optional[str] = None,
37+
after: Optional[str] = None,
38+
accept_datetime: Optional[str] = None,
39+
select: Optional[List[Union[str, _models.KeyValueFields]]] = None,
40+
if_match: Optional[str] = None,
41+
if_none_match: Optional[str] = None,
42+
continuation_token: Optional[str] = None,
43+
**kwargs: Any
44+
) -> AsyncIterable["_models.KeyValue"]:
45+
"""Gets a list of key-values in one page.
46+
47+
Gets a list of key-values in one page.
48+
49+
:param key: A filter used to match keys. Default value is None.
50+
:type key: str
51+
:param label: A filter used to match labels. Default value is None.
52+
:type label: str
53+
:param after: Instructs the server to return elements that appear after the element referred to
54+
by the specified token. Default value is None.
55+
:type after: str
56+
:param accept_datetime: Requests the server to respond with the state of the resource at the
57+
specified time. Default value is None.
58+
:type accept_datetime: str
59+
:param select: Used to select what fields are present in the returned resource(s). Default
60+
value is None.
61+
:type select: list[str or ~azure.appconfiguration.models.KeyValueFields]
62+
:param if_match: Used to perform an operation only if the targeted resource's etag matches the
63+
value provided. Default value is None.
64+
:type if_match: str
65+
:param if_none_match: Used to perform an operation only if the targeted resource's etag does
66+
not match the value provided. Default value is None.
67+
:type if_none_match: str
68+
:param str continuation_token: An opaque continuation token.
69+
:keyword callable cls: A custom type or function that will be passed the direct response
70+
:return: An iterator like instance of either KeyValue or the result of cls(response)
71+
:rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.appconfiguration.models.KeyValue]
72+
:raises ~azure.core.exceptions.HttpResponseError:
73+
"""
74+
_headers = kwargs.pop("headers", {}) or {}
75+
_params = case_insensitive_dict(kwargs.pop("params", {}) or {})
76+
77+
api_version: str = kwargs.pop("api_version", _params.pop("api-version", self._config.api_version))
78+
cls: ClsType[_models.KeyValueListResult] = kwargs.pop("cls", None)
79+
80+
error_map = {
81+
401: ClientAuthenticationError,
82+
404: ResourceNotFoundError,
83+
409: ResourceExistsError,
84+
304: ResourceNotModifiedError,
85+
}
86+
error_map.update(kwargs.pop("error_map", {}) or {})
87+
88+
def prepare_request(next_link=None):
89+
if not next_link:
90+
91+
_request = build_get_key_values_request(
92+
key=key,
93+
label=label,
94+
after=after,
95+
accept_datetime=accept_datetime,
96+
select=select,
97+
if_match=if_match,
98+
if_none_match=if_none_match,
99+
sync_token=self._config.sync_token,
100+
api_version=api_version,
101+
headers=_headers,
102+
params=_params,
103+
)
104+
_request = _convert_request(_request)
105+
path_format_arguments = {
106+
"endpoint": self._serialize.url(
107+
"self._config.endpoint", self._config.endpoint, "str", skip_quote=True
108+
),
109+
}
110+
_request.url = self._client.format_url(_request.url, **path_format_arguments)
111+
112+
else:
113+
# make call to next link with the client's api-version
114+
_parsed_next_link = urllib.parse.urlparse(next_link)
115+
_next_request_params = case_insensitive_dict(
116+
{
117+
key: [urllib.parse.quote(v) for v in value]
118+
for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items()
119+
}
120+
)
121+
_next_request_params["api-version"] = self._config.api_version
122+
_request = HttpRequest(
123+
"GET", urllib.parse.urljoin(next_link, _parsed_next_link.path), params=_next_request_params
124+
)
125+
_request = _convert_request(_request)
126+
path_format_arguments = {
127+
"endpoint": self._serialize.url(
128+
"self._config.endpoint", self._config.endpoint, "str", skip_quote=True
129+
),
130+
}
131+
_request.url = self._client.format_url(_request.url, **path_format_arguments)
132+
_request.method = "GET"
133+
return _request
134+
135+
_request = prepare_request(continuation_token)
136+
137+
_stream = False
138+
pipeline_response: PipelineResponse = await self._client._pipeline.run( # type: ignore # pylint: disable=protected-access
139+
_request, stream=_stream, **kwargs
140+
)
141+
response = pipeline_response.http_response
142+
143+
if response.status_code not in [200]:
144+
map_error(status_code=response.status_code, response=response, error_map=error_map)
145+
error = self._deserialize.failsafe_deserialize(_models.Error, pipeline_response)
146+
raise HttpResponseError(response=response, model=error)
147+
148+
response_headers = response.headers
149+
deserialized = self._deserialize("KeyValueListResult", pipeline_response)
150+
151+
if cls:
152+
return cls(pipeline_response, deserialized, response_headers)
153+
154+
return deserialized
155+
156+
157+
__all__: List[str] = [
158+
"AzureAppConfigurationOperationsMixin"
159+
] # Add all objects you want publicly available to users at this package level
12160

13161

14162
def patch_sdk():

0 commit comments

Comments
 (0)