Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
File to new paging
  • Loading branch information
lmazuel committed Jul 24, 2019
commit 9e1124e57ec1245ec4693eea1c500b5f60f3fc99
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

import six
from azure.core.polling import LROPoller
from azure.core.paging import ItemPaged

from .file_client import FileClient

Expand Down Expand Up @@ -269,21 +270,17 @@ def delete_directory(self, timeout=None, **kwargs):
except StorageErrorException as error:
process_storage_error(error)

def list_directories_and_files(self, name_starts_with=None, marker=None, timeout=None, **kwargs):
# type: (Optional[str], Optional[str], Optional[int], **Any) -> DirectoryProperties
def list_directories_and_files(self, name_starts_with=None, timeout=None, **kwargs):
# type: (Optional[str], Optional[str], Optional[int], **Any) -> ItemPaged
"""Lists all the directories and files under the directory.

:param str name_starts_with:
Filters the results to return only entities whose names
begin with the specified prefix.
:param str marker:
An opaque continuation token. This value can be retrieved from the
next_marker field of a previous generator object. If specified,
this generator will begin returning results from this point.
:param int timeout:
The timeout parameter is expressed in seconds.
:returns: An auto-paging iterable of dict-like DirectoryProperties and FileProperties
:rtype: ~azure.storage.file.models.DirectoryPropertiesPaged
:rtype: ~azure.core.paging.ItemPaged[~azure.storage.file.models.DirectoryProperties]

Example:
.. literalinclude:: ../tests/test_file_samples_directory.py
Expand All @@ -299,23 +296,20 @@ def list_directories_and_files(self, name_starts_with=None, marker=None, timeout
sharesnapshot=self.snapshot,
timeout=timeout,
**kwargs)
return DirectoryPropertiesPaged(
command, prefix=name_starts_with, results_per_page=results_per_page, marker=marker)
return ItemPaged(
command, prefix=name_starts_with, results_per_page=results_per_page,
page_iterator_class=DirectoryPropertiesPaged)

def list_handles(self, marker=None, recursive=False, timeout=None, **kwargs):
def list_handles(self, recursive=False, timeout=None, **kwargs):
"""Lists opened handles on a directory or a file under the directory.

:param str marker:
An opaque continuation token. This value can be retrieved from the
next_marker field of a previous generator object. If specified,
this generator will begin returning results from this point.
:param bool recursive:
Boolean that specifies if operation should apply to the directory specified by the client,
its files, its subdirectories and their files. Default value is False.
:param int timeout:
The timeout parameter is expressed in seconds.
:returns: An auto-paging iterable of HandleItems
:rtype: ~azure.storage.file.models.HandlesPaged
:rtype: ~azure.core.paging.ItemPaged[~azure.storage.file.models.Handles]
"""
results_per_page = kwargs.pop('results_per_page', None)
command = functools.partial(
Expand All @@ -324,8 +318,9 @@ def list_handles(self, marker=None, recursive=False, timeout=None, **kwargs):
timeout=timeout,
recursive=recursive,
**kwargs)
return HandlesPaged(
command, results_per_page=results_per_page, marker=marker)
return ItemPaged(
command, results_per_page=results_per_page,
page_iterator_class=HandlesPaged)

def close_handles(
self, handle=None, # type: Union[str, HandleItem]
Expand Down
10 changes: 4 additions & 6 deletions sdk/storage/azure-storage-file/azure/storage/file/file_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import six
from azure.core.polling import LROPoller
from azure.core.paging import ItemPaged

from .models import HandlesPaged
from ._generated import AzureFileStorage
Expand Down Expand Up @@ -784,10 +785,6 @@ def resize_file(self, size, timeout=None, **kwargs): # type: ignore
def list_handles(self, marker=None, timeout=None, **kwargs):
"""Lists handles for file.

:param str marker:
An opaque continuation token. This value can be retrieved from the
next_marker field of a previous generator object. If specified,
this generator will begin returning results from this point.
:param int timeout:
The timeout parameter is expressed in seconds.
:returns: An auto-paging iterable of HandleItems
Expand All @@ -798,8 +795,9 @@ def list_handles(self, marker=None, timeout=None, **kwargs):
sharesnapshot=self.snapshot,
timeout=timeout,
**kwargs)
return HandlesPaged(
command, results_per_page=results_per_page, marker=marker)
return ItemPaged(
command, results_per_page=results_per_page,
page_iterator_class=HandlesPaged)

def close_handles(
self, handle=None, # type: Union[str, HandleItem]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
except ImportError:
from urlparse import urlparse # type: ignore

from azure.core.paging import ItemPaged

from .share_client import ShareClient
from ._shared.shared_access_signature import SharedAccessSignature
from ._shared.models import Services
Expand Down Expand Up @@ -270,11 +272,10 @@ def list_shares(
self, name_starts_with=None, # type: Optional[str]
include_metadata=False, # type: Optional[bool]
include_snapshots=False, # type: Optional[bool]
marker=None,
timeout=None, # type: Optional[int]
**kwargs
):
# type: (...) -> SharePropertiesPaged
# type: (...) -> ItemPaged[ShareProperties]
"""Returns auto-paging iterable of dict-like ShareProperties under the specified account.
The generator will lazily follow the continuation tokens returned by
the service and stop when all shares have been returned.
Expand All @@ -286,14 +287,10 @@ def list_shares(
Specifies that share metadata be returned in the response.
:param bool include_snapshots:
Specifies that share snapshot be returned in the response.
:param str marker:
An opaque continuation token. This value can be retrieved from the
next_marker field of a previous generator object. If specified,
this generator will begin returning results from this point.
:param int timeout:
The timeout parameter is expressed in seconds.
:returns: An iterable (auto-paging) of ShareProperties.
:rtype: ~azure.storage.file.models.SharePropertiesPaged
:rtype: ~azure.core.paging.ItemPaged[~azure.storage.file.models.SharePropertiesPaged]

Example:
.. literalinclude:: ../tests/test_file_samples_service.py
Expand All @@ -314,8 +311,9 @@ def list_shares(
include=include,
timeout=timeout,
**kwargs)
return SharePropertiesPaged(
command, prefix=name_starts_with, results_per_page=results_per_page, marker=marker)
return ItemPaged(
command, prefix=name_starts_with, results_per_page=results_per_page,
page_iterator_class=SharePropertiesPaged)

def create_share(
self, share_name, # type: str
Expand Down
108 changes: 50 additions & 58 deletions sdk/storage/azure-storage-file/azure/storage/file/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
# pylint: disable=too-few-public-methods, too-many-instance-attributes
# pylint: disable=super-init-not-called, too-many-lines

from azure.core.paging import Paged
from azure.core.paging import PageIterator
from ._shared.utils import (
return_context_and_deserialized,
process_storage_error)
Expand Down Expand Up @@ -243,7 +243,7 @@ def _from_generated(cls, generated):
return props


class SharePropertiesPaged(Paged):
class SharePropertiesPaged(PageIterator):
"""An iterable of Share properties.

:ivar str service_endpoint: The service URL.
Expand All @@ -261,43 +261,40 @@ class SharePropertiesPaged(Paged):
begin with the specified prefix.
:param int results_per_page: The maximum number of share names to retrieve per
call.
:param str marker: An opaque continuation token.
:param str continuation_token: An opaque continuation token.
"""
def __init__(self, command, prefix=None, results_per_page=None, marker=None, **kwargs):
super(SharePropertiesPaged, self).__init__(command, None)
def __init__(self, command, prefix=None, results_per_page=None, continuation_token=None):
super(SharePropertiesPaged, self).__init__(
get_next=self._get_next_cb,
extract_data=self._extract_data_cb,
continuation_token=continuation_token or ""
)
self._command = command
self.service_endpoint = None
self.prefix = prefix
self.current_marker = None
self.results_per_page = results_per_page
self.next_marker = marker or ""
self.location_mode = None
self.current_page = []

def _advance_page(self):
"""Force moving the cursor to the next azure call.
This method is for advanced usage, iterator protocol is prefered.
:raises: StopIteration if no further page
:return: The current page list
:rtype: list
"""
if self.next_marker is None:
raise StopIteration("End of paging")
self._current_page_iter_index = 0
def _get_next_cb(self, continuation_token):
try:
self.location_mode, self._response = self._get_next(
marker=self.next_marker or None,
return self._command(
marker=continuation_token or None,
maxresults=self.results_per_page,
cls=return_context_and_deserialized,
use_location=self.location_mode)
except StorageErrorException as error:
process_storage_error(error)

def _extract_data_cb(self, get_next_return):
self.location_mode, self._response = get_next_return
self.service_endpoint = self._response.service_endpoint
self.prefix = self._response.prefix
self.current_marker = self._response.marker
self.results_per_page = self._response.max_results
self.current_page = [ShareProperties._from_generated(i) for i in self._response.share_items] # pylint: disable=protected-access
self.next_marker = self._response.next_marker or None
return self.current_page
return self._response.next_marker or None, self.current_page


class Handle(DictMixin):
Expand Down Expand Up @@ -352,7 +349,7 @@ def _from_generated(cls, generated):
return handle


class HandlesPaged(Paged):
class HandlesPaged(PageIterator):
"""An iterable of Handles.

:ivar str current_marker: The continuation token of the current page of results.
Expand All @@ -366,36 +363,34 @@ class HandlesPaged(Paged):
:param callable command: Function to retrieve the next page of items.
:param int results_per_page: The maximum number of share names to retrieve per
call.
:param str marker: An opaque continuation token.
:param str continuation_token: An opaque continuation token.
"""
def __init__(self, command, results_per_page=None, marker=None, **kwargs):
super(HandlesPaged, self).__init__(command, None)
def __init__(self, command, results_per_page=None, continuation_token=None):
super(HandlesPaged, self).__init__(
get_next=self._get_next_cb,
extract_data=self._extract_data_cb,
continuation_token=continuation_token or ""
)
self._command = command
self.current_marker = None
self.results_per_page = results_per_page
self.next_marker = marker or ""
self.location_mode = None
self.current_page = []

def _advance_page(self):
"""Force moving the cursor to the next azure call.
This method is for advanced usage, iterator protocol is prefered.
:raises: StopIteration if no further page
:return: The current page list
:rtype: list
"""
if self.next_marker is None:
raise StopIteration("End of paging")
self._current_page_iter_index = 0
def _get_next_cb(self, continuation_token):
try:
self.location_mode, self._response = self._get_next(
marker=self.next_marker or None,
return self._command(
marker=continuation_token or None,
maxresults=self.results_per_page,
cls=return_context_and_deserialized,
use_location=self.location_mode)
except StorageErrorException as error:
process_storage_error(error)

def _extract_data_cb(self, get_next_return):
self.location_mode, self._response = get_next_return
self.current_page = [Handle._from_generated(h) for h in self._response.handle_list] # pylint: disable=protected-access
self.next_marker = self._response.next_marker or None
return self.current_page
return self._response.next_marker or None, self.current_page


class DirectoryProperties(DictMixin):
Expand Down Expand Up @@ -432,7 +427,7 @@ def _from_generated(cls, generated):
return props


class DirectoryPropertiesPaged(Paged):
class DirectoryPropertiesPaged(PageIterator):
"""An iterable for the contents of a directory.

This iterable will yield dicts for the contents of the directory. The dicts
Expand All @@ -454,45 +449,42 @@ class DirectoryPropertiesPaged(Paged):
begin with the specified prefix.
:param int results_per_page: The maximum number of share names to retrieve per
call.
:param str marker: An opaque continuation token.
:param str continuation_token: An opaque continuation token.
"""
def __init__(self, command, prefix=None, results_per_page=None, marker=None, **kwargs):
super(DirectoryPropertiesPaged, self).__init__(command, None)
def __init__(self, command, prefix=None, results_per_page=None, continuation_token=None):
super(DirectoryPropertiesPaged, self).__init__(
get_next=self._get_next_cb,
extract_data=self._extract_data_cb,
continuation_token=continuation_token or ""
)
self._command = command
self.service_endpoint = None
self.prefix = prefix
self.current_marker = None
self.results_per_page = results_per_page
self.next_marker = marker or ""
self.location_mode = None
self.current_page = []

def _advance_page(self):
"""Force moving the cursor to the next azure call.
This method is for advanced usage, iterator protocol is prefered.
:raises: StopIteration if no further page
:return: The current page list
:rtype: list
"""
if self.next_marker is None:
raise StopIteration("End of paging")
self._current_page_iter_index = 0
def _get_next_cb(self, continuation_token):
try:
self.location_mode, self._response = self._get_next(
marker=self.next_marker or None,
return self._command(
marker=continuation_token or None,
prefix=self.prefix,
maxresults=self.results_per_page,
cls=return_context_and_deserialized,
use_location=self.location_mode)
except StorageErrorException as error:
process_storage_error(error)

def _extract_data_cb(self, get_next_return):
self.location_mode, self._response = get_next_return
self.service_endpoint = self._response.service_endpoint
self.prefix = self._response.prefix
self.current_marker = self._response.marker
self.results_per_page = self._response.max_results
self.current_page = [_wrap_item(i) for i in self._response.segment.directory_items]
self.current_page.extend([_wrap_item(i) for i in self._response.segment.file_items])
self.next_marker = self._response.next_marker or None
return self.current_page
return self._response.next_marker or None, self.current_page


class FileProperties(DictMixin):
Expand Down
13 changes: 7 additions & 6 deletions sdk/storage/azure-storage-file/tests/test_handle.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,20 +114,21 @@ def test_list_handles_with_marker(self):
root = share.get_directory_client()

# Act
handle_generator = root.list_handles(recursive=True, results_per_page=1)
next(handle_generator)
handle_generator = root.list_handles(recursive=True, results_per_page=1).by_page()
handles = list(next(handle_generator))

# Assert
self.assertIsNotNone(handle_generator.next_marker)
handles = handle_generator.current_page
self.assertIsNotNone(handle_generator.continuation_token)
self._validate_handles(handles)

# Note down a handle that we saw
old_handle = handles[0]

# Continue listing
remaining_handles = list(
root.list_handles(recursive=True, marker=handle_generator.next_marker))
remaining_handles = list(next(
root.list_handles(recursive=True).by_page(
continuation_token=handle_generator.continuation_token)
))
self._validate_handles(handles)

# Make sure the old handle did not appear
Expand Down
Loading