-
Notifications
You must be signed in to change notification settings - Fork 3.3k
Consolidate offset - length behavior in files #7942
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
Changes from all commits
79c3863
14f0c77
17002e8
37aa247
ef65959
5d4db54
2c17e8c
54c9c70
e82f978
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 |
|---|---|---|
|
|
@@ -469,12 +469,14 @@ async def download_file( | |
| raise ValueError("Encryption not supported.") | ||
| if length is not None and offset is None: | ||
| raise ValueError("Offset value must not be None if length is set.") | ||
|
|
||
| range_end = None | ||
| if length is not None: | ||
| range_end = offset + length - 1 # Service actually uses an end-range inclusive index | ||
| downloader = StorageStreamDownloader( | ||
| client=self._client.file, | ||
| config=self._config, | ||
| offset=offset, | ||
| length=length, | ||
| length=range_end, | ||
| validate_content=validate_content, | ||
| encryption_options=None, | ||
| cls=deserialize_file_stream, | ||
|
|
@@ -635,25 +637,21 @@ async def set_file_metadata(self, metadata=None, **kwargs): # type: ignore | |
| async def upload_range( # type: ignore | ||
| self, | ||
| data, # type: bytes | ||
| start_range, # type: int | ||
| end_range, # type: int | ||
| offset, # type: int | ||
| length, # type: int | ||
| **kwargs | ||
| ): | ||
| # type: (...) -> Dict[str, Any] | ||
| """Upload a range of bytes to a file. | ||
|
|
||
| :param bytes data: | ||
| The data to upload. | ||
| :param int start_range: | ||
| :param int offset: | ||
| Start of byte range to use for uploading a section of the file. | ||
| The range can be up to 4 MB in size. | ||
| The start_range and end_range params are inclusive. | ||
| Ex: start_range=0, end_range=511 will upload first 512 bytes of file. | ||
| :param int end_range: | ||
| End of byte range to use for uploading a section of the file. | ||
| :param int length: | ||
| Number of bytes to use for uploading a section of the file. | ||
| The range can be up to 4 MB in size. | ||
| The start_range and end_range params are inclusive. | ||
| Ex: start_range=0, end_range=511 will upload first 512 bytes of file. | ||
| :keyword bool validate_content: | ||
| If true, calculates an MD5 hash of the page content. The storage | ||
| service checks the hash of the content that has arrived | ||
|
|
@@ -675,13 +673,12 @@ async def upload_range( # type: ignore | |
| raise ValueError("Encryption not supported.") | ||
| if isinstance(data, six.text_type): | ||
| data = data.encode(encoding) | ||
|
|
||
| content_range = "bytes={0}-{1}".format(start_range, end_range) | ||
| content_length = end_range - start_range + 1 | ||
| end_range = offset + length - 1 # Reformat to an inclusive range index | ||
| content_range = 'bytes={0}-{1}'.format(offset, end_range) | ||
| try: | ||
| return await self._client.file.upload_range( # type: ignore | ||
| range=content_range, | ||
| content_length=content_length, | ||
| content_length=length, | ||
| optionalbody=data, | ||
| timeout=timeout, | ||
| validate_content=validate_content, | ||
|
|
@@ -693,25 +690,21 @@ async def upload_range( # type: ignore | |
|
|
||
| @distributed_trace_async | ||
| async def upload_range_from_url(self, source_url, # type: str | ||
| range_start, # type: int | ||
| range_end, # type: int | ||
| source_range_start, # type: int | ||
| offset, # type: int | ||
| length, # type: int | ||
| source_offset, # type: int | ||
| **kwargs # type: Any | ||
| ): | ||
| # type: (str, int, int, int, **Any) -> Dict[str, Any] | ||
| ''' | ||
| Writes the bytes from one Azure File endpoint into the specified range of another Azure File endpoint. | ||
|
|
||
| :param int range_start: | ||
| :param int offset: | ||
| Start of byte range to use for updating a section of the file. | ||
| The range can be up to 4 MB in size. | ||
| The start_range and end_range params are inclusive. | ||
| Ex: start_range=0, end_range=511 will download first 512 bytes of file. | ||
| :param int range_end: | ||
| End of byte range to use for updating a section of the file. | ||
| :param int length: | ||
| Number of bytes to use for updating a section of the file. | ||
| The range can be up to 4 MB in size. | ||
| The start_range and end_range params are inclusive. | ||
| Ex: start_range=0, end_range=511 will download first 512 bytes of file. | ||
| :param str source_url: | ||
| A URL of up to 2 KB in length that specifies an Azure file or blob. | ||
| The value should be URL-encoded as it would appear in a request URI. | ||
|
|
@@ -721,20 +714,18 @@ async def upload_range_from_url(self, source_url, # type: str | |
| Examples: | ||
| https://myaccount.file.core.windows.net/myshare/mydir/myfile | ||
| https://otheraccount.file.core.windows.net/myshare/mydir/myfile?sastoken | ||
| :param int source_range_start: | ||
| Start of byte range to use for updating a section of the file. | ||
| The range can be up to 4 MB in size. | ||
| The start_range and end_range params are inclusive. | ||
| Ex: start_range=0, end_range=511 will download first 512 bytes of file. | ||
| :param int source_offset: | ||
| This indicates the start of the range of bytes(inclusive) that has to be taken from the copy source. | ||
| The service will read the same number of bytes as the destination range (length-offset). | ||
| :keyword int timeout: | ||
| The timeout parameter is expressed in seconds. | ||
| ''' | ||
|
|
||
| options = self._upload_range_from_url_options( | ||
| source_url=source_url, | ||
| range_start=range_start, | ||
| range_end=range_end, | ||
| source_range_start=source_range_start, | ||
| offset=offset, | ||
| length=length, | ||
| source_offset=source_offset, | ||
| **kwargs | ||
| ) | ||
| try: | ||
|
|
@@ -745,21 +736,17 @@ async def upload_range_from_url(self, source_url, # type: str | |
| @distributed_trace_async | ||
| async def get_ranges( # type: ignore | ||
| self, | ||
| start_range=None, # type: Optional[int] | ||
| end_range=None, # type: Optional[int] | ||
| offset=None, # type: Optional[int] | ||
| length=None, # type: Optional[int] | ||
| **kwargs | ||
| ): | ||
| # type: (...) -> List[dict[str, int]] | ||
| """Returns the list of valid ranges of a file. | ||
|
|
||
| :param int start_range: | ||
| :param int offset: | ||
| Specifies the start offset of bytes over which to get ranges. | ||
| The start_range and end_range params are inclusive. | ||
| Ex: start_range=0, end_range=511 will download first 512 bytes of file. | ||
| :param int end_range: | ||
| Specifies the end offset of bytes over which to get ranges. | ||
| The start_range and end_range params are inclusive. | ||
| Ex: start_range=0, end_range=511 will download first 512 bytes of file. | ||
| :param int length: | ||
| Number of bytes to use over which to get ranges. | ||
| :keyword int timeout: | ||
| The timeout parameter is expressed in seconds. | ||
| :returns: A list of valid ranges. | ||
|
|
@@ -770,11 +757,12 @@ async def get_ranges( # type: ignore | |
| raise ValueError("Unsupported method for encryption.") | ||
|
|
||
| content_range = None | ||
| if start_range is not None: | ||
| if end_range is not None: | ||
| content_range = "bytes={0}-{1}".format(start_range, end_range) | ||
| if offset is not None: | ||
| if length is not None: | ||
| length = offset + length - 1 # Reformat to an inclusive range index | ||
|
Contributor
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. Is there a reason we reuse length here? can we make it offset_end = offset + length - 1
Contributor
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. This one hasn't been addressed 😀
Member
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. Thanks @xiafu-msft - I'm merging these changes into the Stream PR now - will add this |
||
| content_range = "bytes={0}-{1}".format(offset, length) | ||
| else: | ||
| content_range = "bytes={0}-".format(start_range) | ||
| content_range = "bytes={0}-".format(offset) | ||
| try: | ||
| ranges = await self._client.file.get_range_list( | ||
| sharesnapshot=self.snapshot, timeout=timeout, range=content_range, **kwargs | ||
|
|
@@ -786,24 +774,20 @@ async def get_ranges( # type: ignore | |
| @distributed_trace_async | ||
| async def clear_range( # type: ignore | ||
| self, | ||
| start_range, # type: int | ||
| end_range, # type: int | ||
| offset, # type: int | ||
| length, # type: int | ||
| **kwargs | ||
| ): | ||
| # type: (...) -> Dict[str, Any] | ||
| """Clears the specified range and releases the space used in storage for | ||
| that range. | ||
|
|
||
| :param int start_range: | ||
| :param int offset: | ||
| Start of byte range to use for clearing a section of the file. | ||
| The range can be up to 4 MB in size. | ||
| The start_range and end_range params are inclusive. | ||
| Ex: start_range=0, end_range=511 will download first 512 bytes of file. | ||
| :param int end_range: | ||
| End of byte range to use for clearing a section of the file. | ||
| :param int length: | ||
| Number of bytes to use for clearing a section of the file. | ||
| The range can be up to 4 MB in size. | ||
| The start_range and end_range params are inclusive. | ||
| Ex: start_range=0, end_range=511 will download first 512 bytes of file. | ||
| :keyword int timeout: | ||
| The timeout parameter is expressed in seconds. | ||
| :returns: File-updated property dict (Etag and last modified). | ||
|
|
@@ -813,11 +797,12 @@ async def clear_range( # type: ignore | |
| if self.require_encryption or (self.key_encryption_key is not None): | ||
| raise ValueError("Unsupported method for encryption.") | ||
|
|
||
| if start_range is None or start_range % 512 != 0: | ||
| raise ValueError("start_range must be an integer that aligns with 512 file size") | ||
| if end_range is None or end_range % 512 != 511: | ||
| raise ValueError("end_range must be an integer that aligns with 512 file size") | ||
| content_range = "bytes={0}-{1}".format(start_range, end_range) | ||
| if offset is None or offset % 512 != 0: | ||
| raise ValueError("offset must be an integer that aligns with 512 bytes file size") | ||
| if length is None or length % 512 != 0: | ||
| raise ValueError("length must be an integer that aligns with 512 bytes file size") | ||
| end_range = length + offset - 1 # Reformat to an inclusive range index | ||
| content_range = "bytes={0}-{1}".format(offset, end_range) | ||
| try: | ||
| return await self._client.file.upload_range( # type: ignore | ||
| timeout=timeout, | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.