-
Notifications
You must be signed in to change notification settings - Fork 2.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Container Registry] ACR list_repositories pageable #17714
Changes from 93 commits
5e854e6
eb5eb54
785564d
561128f
beba7fc
9c7acd5
8c03d93
5a16d1c
b628b6f
b70ce96
2bedabe
fa6f78e
514d03b
4063d4d
c280520
4a9cc33
5e2270c
b2ba50f
fb4189f
7108594
4dd3c8c
4533cce
2b3bb91
34b094e
a4d0258
2058b4a
70d8524
9da7eee
eea6749
875b422
648102b
7a6bd87
f82ed35
6ba90be
b0922ba
82c5d3c
103db71
9a26fcf
8ec00fd
7e4333e
5d12869
5bd806b
b56c29e
5151b8d
cb9611b
cf02b85
544c9b7
1f1eb4c
643e937
dfdbe82
d68285b
93ad7c4
c1f5198
166661e
b14a81b
06fb6a5
fc88483
da18b29
f3dc746
aef65bd
6304e37
17a1a07
7465c81
7ed5107
340d128
76b8ca0
ac6352b
ce532bc
6be366a
d8e3a4d
5d97e0b
451a186
23caed4
f4799e5
35df077
f95947d
0941cec
4714e61
94c3488
822d407
db97e0f
52a746f
89ab5d0
a728852
f2a5da9
31fc9ff
db4040f
0be38fe
3e6b8c2
4b11a77
47e395b
0cabe74
c2eaab3
de15691
a30712d
af91b4a
c36ed08
9dda7f8
a8adc8b
0fcb0b8
64c8fc0
23f55d6
0a2c1eb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,15 +5,23 @@ | |
# ------------------------------------ | ||
from typing import TYPE_CHECKING | ||
|
||
from azure.core.exceptions import ( | ||
ClientAuthenticationError, | ||
ResourceNotFoundError, | ||
ResourceExistsError, | ||
HttpResponseError, | ||
map_error, | ||
) | ||
from azure.core.paging import ItemPaged | ||
from azure.core.tracing.decorator import distributed_trace | ||
|
||
from ._base_client import ContainerRegistryBaseClient | ||
from ._helpers import _is_tag | ||
from ._generated.models import AcrErrors | ||
from ._helpers import _is_tag, _parse_next_link | ||
from ._models import RepositoryProperties, TagProperties, RegistryArtifactProperties | ||
|
||
if TYPE_CHECKING: | ||
from typing import Any, Dict | ||
from azure.core.paging import ItemPaged | ||
from azure.core.credentials import TokenCredential | ||
from ._models import ContentPermissions | ||
|
||
|
@@ -130,27 +138,112 @@ def list_registry_artifacts(self, **kwargs): | |
|
||
:keyword last: Query parameter for the last item in the previous query | ||
:type last: str | ||
:keyword page_size: Number of items per page | ||
:type page_size: int | ||
:keyword results_per_page: Number of items per page | ||
:type results_per_page: int | ||
:keyword orderby: Order by query parameter | ||
:type orderby: :class:~azure.containerregistry.RegistryArtifactOrderBy | ||
:returns: ~azure.core.paging.ItemPaged[RegistryArtifactProperties] | ||
:raises: None | ||
""" | ||
# GET /acr/v1/{name}/_manifests | ||
name = self.repository | ||
last = kwargs.pop("last", None) | ||
n = kwargs.pop("page_size", None) | ||
n = kwargs.pop("results_per_page", None) | ||
orderby = kwargs.pop("order_by", None) | ||
return self._client.container_registry_repository.get_manifests( | ||
self.repository, | ||
last=last, | ||
n=n, | ||
orderby=orderby, | ||
cls=lambda objs: [ | ||
RegistryArtifactProperties._from_generated(x) for x in objs # pylint: disable=protected-access | ||
], | ||
cls = kwargs.pop( | ||
"cls", lambda objs: [RegistryArtifactProperties._from_generated(x) for x in objs] # pylint: disable=protected-access | ||
) | ||
|
||
error_map = {401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError} | ||
error_map.update(kwargs.pop("error_map", {})) | ||
accept = "application/json" | ||
|
||
def prepare_request(next_link=None): | ||
# Construct headers | ||
header_parameters = {} # type: Dict[str, Any] | ||
header_parameters["Accept"] = self._client._serialize.header( # pylint: disable=protected-access | ||
"accept", accept, "str" | ||
) | ||
|
||
if not next_link: | ||
# Construct URL | ||
url = "/acr/v1/{name}/_manifests" | ||
path_format_arguments = { | ||
"url": self._client._serialize.url( # pylint: disable=protected-access | ||
"self._client._config.url", | ||
self._client._config.url, # pylint: disable=protected-access | ||
"str", | ||
skip_quote=True, | ||
), | ||
"name": self._client._serialize.url("name", name, "str"), # pylint: disable=protected-access | ||
} | ||
url = self._client._client.format_url(url, **path_format_arguments) # pylint: disable=protected-access | ||
# Construct parameters | ||
query_parameters = {} # type: Dict[str, Any] | ||
if last is not None: | ||
query_parameters["last"] = self._client._serialize.query( # pylint: disable=protected-access | ||
"last", last, "str" | ||
) | ||
if n is not None: | ||
query_parameters["n"] = self._client._serialize.query( # pylint: disable=protected-access | ||
"n", n, "int" | ||
) | ||
if orderby is not None: | ||
query_parameters["orderby"] = self._client._serialize.query( # pylint: disable=protected-access | ||
"orderby", orderby, "str" | ||
) | ||
|
||
request = self._client._client.get( # pylint: disable=protected-access | ||
url, query_parameters, header_parameters | ||
) | ||
else: | ||
url = next_link | ||
query_parameters = {} # type: Dict[str, Any] | ||
path_format_arguments = { | ||
"url": self._client._serialize.url( # pylint: disable=protected-access | ||
"self._client._config.url", | ||
self._client._config.url, # pylint: disable=protected-access | ||
"str", | ||
skip_quote=True, | ||
), | ||
"name": self._client._serialize.url("name", name, "str"), # pylint: disable=protected-access | ||
} | ||
url = self._client._client.format_url(url, **path_format_arguments) # pylint: disable=protected-access | ||
request = self._client._client.get( # pylint: disable=protected-access | ||
url, query_parameters, header_parameters | ||
) | ||
return request | ||
|
||
def extract_data(pipeline_response): | ||
deserialized = self._client._deserialize( # pylint: disable=protected-access | ||
"AcrManifests", pipeline_response | ||
) | ||
list_of_elem = deserialized.manifests | ||
if cls: | ||
list_of_elem = cls(list_of_elem) | ||
link = None | ||
if "Link" in pipeline_response.http_response.headers.keys(): | ||
link = _parse_next_link(pipeline_response.http_response.headers["Link"]) | ||
return link, iter(list_of_elem) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. just to clarify: i remember you said before that the first part of the raw link in the response headers includes what you need to pass as a query param to next calls. It seems you're ignoring that info rn, want to check to see if that's right There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The next URL to use is parsed from the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was just recalling when we talked about this in our video chat, that you said the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I must have misspoke, the Link is pre-formatted with the query parameters so all we need to do is get the link, there's no other info necessary in the headers. |
||
|
||
def get_next(next_link=None): | ||
request = prepare_request(next_link) | ||
|
||
pipeline_response = self._client._client._pipeline.run( # pylint: disable=protected-access | ||
request, stream=False, **kwargs | ||
) | ||
response = pipeline_response.http_response | ||
|
||
if response.status_code not in [200]: | ||
error = self._client._deserialize.failsafe_deserialize( # pylint: disable=protected-access | ||
AcrErrors, response | ||
) | ||
map_error(status_code=response.status_code, response=response, error_map=error_map) | ||
raise HttpResponseError(response=response, model=error) | ||
|
||
return pipeline_response | ||
|
||
return ItemPaged(get_next, extract_data) | ||
|
||
@distributed_trace | ||
def list_tags(self, **kwargs): | ||
# type: (...) -> ItemPaged[TagProperties] | ||
|
@@ -159,20 +252,115 @@ def list_tags(self, **kwargs): | |
:param last: Query parameter for the last item in the previous call. Ensuing | ||
call will return values after last lexically | ||
:type last: str | ||
:param order_by: Query paramter for ordering by time ascending or descending | ||
:keyword order_by: Query paramter for ordering by time ascending or descending | ||
seankane-msft marked this conversation as resolved.
Show resolved
Hide resolved
|
||
:type order_by: :class:~azure.containerregistry.TagOrderBy | ||
:keyword digest: Digest to filter on | ||
:type digest: str | ||
:returns: ~azure.core.paging.ItemPaged[TagProperties] | ||
:raises: None | ||
""" | ||
return self._client.container_registry_repository.get_tags( | ||
self.repository, | ||
last=kwargs.pop("last", None), | ||
n=kwargs.pop("page_size", None), | ||
orderby=kwargs.pop("order_by", None), | ||
digest=kwargs.pop("digest", None), | ||
cls=lambda objs: [TagProperties._from_generated(o) for o in objs], # pylint: disable=protected-access | ||
**kwargs | ||
name = self.repository | ||
last = kwargs.pop("last", None) | ||
n = kwargs.pop("results_per_page", None) | ||
orderby = kwargs.pop("order_by", None) | ||
digest = kwargs.pop("digest", None) | ||
cls = kwargs.pop( | ||
"cls", lambda objs: [TagProperties._from_generated(o) for o in objs] # pylint: disable=protected-access | ||
) | ||
|
||
error_map = {401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError} | ||
error_map.update(kwargs.pop("error_map", {})) | ||
accept = "application/json" | ||
|
||
def prepare_request(next_link=None): | ||
# Construct headers | ||
header_parameters = {} # type: Dict[str, Any] | ||
header_parameters["Accept"] = self._client._serialize.header( # pylint: disable=protected-access | ||
"accept", accept, "str" | ||
) | ||
|
||
if not next_link: | ||
# Construct URL | ||
url = "/acr/v1/{name}/_tags" | ||
path_format_arguments = { | ||
"url": self._client._serialize.url( # pylint: disable=protected-access | ||
"self._config.url", | ||
self._client._config.url, # pylint: disable=protected-access | ||
"str", | ||
skip_quote=True, | ||
), | ||
"name": self._client._serialize.url("name", name, "str"), # pylint: disable=protected-access | ||
} | ||
url = self._client._client.format_url(url, **path_format_arguments) # pylint: disable=protected-access | ||
# Construct parameters | ||
query_parameters = {} # type: Dict[str, Any] | ||
if last is not None: | ||
query_parameters["last"] = self._client._serialize.query( # pylint: disable=protected-access | ||
"last", last, "str" | ||
) | ||
if n is not None: | ||
query_parameters["n"] = self._client._serialize.query( # pylint: disable=protected-access | ||
"n", n, "int" | ||
) | ||
if orderby is not None: | ||
query_parameters["orderby"] = self._client._serialize.query( # pylint: disable=protected-access | ||
"orderby", orderby, "str" | ||
) | ||
if digest is not None: | ||
query_parameters["digest"] = self._client._serialize.query( # pylint: disable=protected-access | ||
"digest", digest, "str" | ||
) | ||
|
||
request = self._client._client.get( # pylint: disable=protected-access | ||
url, query_parameters, header_parameters | ||
) | ||
else: | ||
url = next_link | ||
query_parameters = {} # type: Dict[str, Any] | ||
path_format_arguments = { | ||
"url": self._client._serialize.url( # pylint: disable=protected-access | ||
"self._client._config.url", | ||
self._client._config.url, # pylint: disable=protected-access | ||
"str", | ||
skip_quote=True, | ||
), | ||
"name": self._client._serialize.url("name", name, "str"), # pylint: disable=protected-access | ||
} | ||
url = self._client._client.format_url(url, **path_format_arguments) # pylint: disable=protected-access | ||
request = self._client._client.get( # pylint: disable=protected-access | ||
url, query_parameters, header_parameters | ||
) | ||
return request | ||
|
||
def extract_data(pipeline_response): | ||
deserialized = self._client._deserialize("TagList", pipeline_response) # pylint: disable=protected-access | ||
list_of_elem = deserialized.tags | ||
if cls: | ||
list_of_elem = cls(list_of_elem) | ||
link = None | ||
if "Link" in pipeline_response.http_response.headers.keys(): | ||
link = _parse_next_link(pipeline_response.http_response.headers["Link"]) | ||
return link, iter(list_of_elem) | ||
|
||
def get_next(next_link=None): | ||
request = prepare_request(next_link) | ||
|
||
pipeline_response = self._client._client._pipeline.run( # pylint: disable=protected-access | ||
request, stream=False, **kwargs | ||
) | ||
response = pipeline_response.http_response | ||
|
||
if response.status_code not in [200]: | ||
error = self._client._deserialize.failsafe_deserialize( # pylint: disable=protected-access | ||
AcrErrors, response | ||
) | ||
map_error(status_code=response.status_code, response=response, error_map=error_map) | ||
raise HttpResponseError(response=response, model=error) | ||
|
||
return pipeline_response | ||
|
||
return ItemPaged(get_next, extract_data) | ||
|
||
@distributed_trace | ||
def set_manifest_properties(self, digest, permissions, **kwargs): | ||
# type: (str, ContentPermissions) -> None | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oof, lot of code, sorry you had to copy that. I think the code looks reasonable, my only question is if you want to move this code to the helper section. Not a big deal, just think keeping the main container registry client page as bare as possible is neater
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought about that, but then I need to pass in the client too and this was a bit simpler.