Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
4 changes: 4 additions & 0 deletions azure-storage-blob/BreakingChanges.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# Breaking Changes azure-storage-blob

> See the [Change Log](ChangeLog.md) for a summary of storage library changes.

## Version 1.0.0:

- Metadata keys are now case-preserving when fetched from the service. Previously they were made lower-case by the library.
5 changes: 3 additions & 2 deletions azure-storage-blob/ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@

> See [BreakingChanges](BreakingChanges.md) for a detailed list of API breaks.

## Version XX.XX.XX:
## Version 1.0.0:

- The package has switched from Apache 2.0 to the MIT license.
- Fixed bug where get_blob_to_* cannot get a single byte when start_range and end_range are both equal to 0.
- Optimized page blob upload for create_blob_from_* methods, by skipping the empty chunks.
- Added convenient method to generate container url (make_container_url).
- The package has switched from Apache 2.0 to the MIT license.
- Metadata keys are now case-preserving when fetched from the service. Previously they were made lower-case by the library.

## Version 0.37.1:

Expand Down
2 changes: 1 addition & 1 deletion azure-storage-blob/azure/storage/blob/_constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
# --------------------------------------------------------------------------

__author__ = 'Microsoft Corp. <ptvshelp@microsoft.com>'
__version__ = '0.37.1'
__version__ = '1.0.0'

# x-ms-version for storage service.
X_MS_VERSION = '2017-04-17'
Expand Down
3 changes: 3 additions & 0 deletions azure-storage-blob/azure/storage/blob/baseblobservice.py
Original file line number Diff line number Diff line change
Expand Up @@ -1900,6 +1900,9 @@ def get_blob_to_stream(
_validate_not_none('blob_name', blob_name)
_validate_not_none('stream', stream)

if end_range is not None:
_validate_not_none("start_range", start_range)

# If the user explicitly sets max_connections to 1, do a single shot download
if max_connections == 1:
blob = self._get_blob(container_name,
Expand Down
4 changes: 2 additions & 2 deletions azure-storage-blob/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@

setup(
name='azure-storage-blob',
version='0.37.1',
version='1.0.0',
description='Microsoft Azure Storage Blob Client Library for Python',
long_description=open('README.rst', 'r').read(),
license='MIT License',
Expand All @@ -74,7 +74,7 @@
packages=find_packages(),
install_requires=[
'azure-common>=1.1.5',
'azure-storage-common>=0.37.1,<0.38.0'
'azure-storage-common>=1.0.0,<1.1.0'
],
extras_require={
":python_version<'3.0'": ['futures'],
Expand Down
4 changes: 2 additions & 2 deletions azure-storage-common/BreakingChanges.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@

> See the [Change Log](ChangeLog.md) for a summary of storage library changes.

## Version XX.XX.XX:
## Version 1.0.0:

- Renamed the confusing argument name increment_power to increment_base on ExponentialRetry.
- Renamed the confusing argument name increment_power to increment_base on ExponentialRetry.
6 changes: 4 additions & 2 deletions azure-storage-common/ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,16 @@

> See [BreakingChanges](BreakingChanges.md) for a detailed list of API breaks.

## Version XX.XX.XX:
## Version 1.0.0:

- The package has switched from Apache 2.0 to the MIT license.
- Added back the ability to generate account SAS for table service.
- Fixed bug where a question mark prefix on SAS tokens causes failures.
- The package has switched from Apache 2.0 to the MIT license.
- Fixed the handling of path style host for the Storage Emulator, specifically the location lock and retry to secondary location.
- Renamed the confusing argument name increment_power to increment_base on ExponentialRetry.

## Version 0.37.1:

- Fixed the return type of __add__ and __or__ methods on the AccountPermissions class
- Added the captured exception to retry_context, in case the user wants more info in retry_callback or implement their own retry class.
- Added random jitters to retry intervals, in order to avoid multiple retries to happen at the exact same time
Expand Down
2 changes: 1 addition & 1 deletion azure-storage-common/azure/storage/common/_constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import platform

__author__ = 'Microsoft Corp. <ptvshelp@microsoft.com>'
__version__ = '0.37.1'
__version__ = '1.0.0'

# UserAgent string sample: 'Azure-Storage/0.37.0-0.38.0 (Python CPython 3.4.2; Windows 8)'
# First version(0.37.0) is the common package, and the second version(0.38.0) is the service package
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ def _parse_metadata(response):

metadata = _dict()
for key, value in response.headers.items():
if key.startswith('x-ms-meta-'):
if key.lower().startswith('x-ms-meta-'):
metadata[key[10:]] = _to_str(value)

return metadata
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,11 @@ def perform_request(self, request):
status = int(response.status_code)
response_headers = {}
for key, name in response.headers.items():
response_headers[key.lower()] = name
# Preserve the case of metadata
if key.lower().startswith('x-ms-meta-'):
response_headers[key] = name
else:
response_headers[key.lower()] = name

wrap = HTTPResponse(status, response.reason, response_headers, response.content)
response.close()
Expand Down
2 changes: 1 addition & 1 deletion azure-storage-common/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@

setup(
name='azure-storage-common',
version='0.37.1',
version='1.0.0',
description='Microsoft Azure Storage Common Client Library for Python',
long_description=open('README.rst', 'r').read(),
license='MIT License',
Expand Down
4 changes: 4 additions & 0 deletions azure-storage-file/BreakingChanges.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# Breaking Changes azure-storage-file

> See the [Change Log](ChangeLog.md) for a summary of storage library changes.

## Version 1.0.0:

- Metadata keys are now case-preserving when fetched from the service. Previously they were made lower-case by the library.
5 changes: 3 additions & 2 deletions azure-storage-file/ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

> See [BreakingChanges](BreakingChanges.md) for a detailed list of API breaks.

## Version XX.XX.XX:
## Version 1.0.0:

- The package has switched from Apache 2.0 to the MIT license.
- Fixed bug where get_file_to_* cannot get a single byte when start_range and end_range are both equal to 0.
- Fixed bug where get_file_to_* cannot get a single byte when start_range and end_range are both equal to 0.
- Metadata keys are now case-preserving when fetched from the service. Previously they were made lower-case by the library.
2 changes: 1 addition & 1 deletion azure-storage-file/azure/storage/file/_constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
# --------------------------------------------------------------------------

__author__ = 'Microsoft Corp. <ptvshelp@microsoft.com>'
__version__ = '0.37.0'
__version__ = '1.0.0'

# x-ms-version for storage service.
X_MS_VERSION = '2017-04-17'
4 changes: 2 additions & 2 deletions azure-storage-file/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@

setup(
name='azure-storage-file',
version='0.37.0',
version='1.0.0',
description='Microsoft Azure Storage File Client Library for Python',
long_description=open('README.rst', 'r').read(),
license='MIT License',
Expand All @@ -74,7 +74,7 @@
packages=find_packages(),
install_requires=[
'azure-common>=1.1.5',
'azure-storage-common>=0.37.0,<0.38.0'
'azure-storage-common>=1.0.0,<1.1.0'
],
extras_require={
":python_version<'3.0'": ['futures'],
Expand Down
2 changes: 1 addition & 1 deletion azure-storage-nspkg/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@

setup(
name='azure-storage-nspkg',
version='2.0.0',
version='3.0.0',
description='Microsoft Azure Storage Namespace Package [Internal]',
long_description=open('README.rst', 'r').read(),
license='MIT License',
Expand Down
2 changes: 1 addition & 1 deletion azure-storage-queue/ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@

> See [BreakingChanges](BreakingChanges.md) for a detailed list of API breaks.

## Version XX.XX.XX:
## Version 1.0.0:

- The package has switched from Apache 2.0 to the MIT license.
2 changes: 1 addition & 1 deletion azure-storage-queue/azure/storage/queue/_constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
# --------------------------------------------------------------------------

__author__ = 'Microsoft Corp. <ptvshelp@microsoft.com>'
__version__ = '0.37.0'
__version__ = '1.0.0'

# x-ms-version for storage service.
X_MS_VERSION = '2017-04-17'
4 changes: 2 additions & 2 deletions azure-storage-queue/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@

setup(
name='azure-storage-queue',
version='0.37.0',
version='1.0.0',
description='Microsoft Azure Storage Queue Client Library for Python',
long_description=open('README.rst', 'r').read(),
license='MIT License',
Expand All @@ -74,7 +74,7 @@
packages=find_packages(),
install_requires=[
'azure-common>=1.1.5',
'azure-storage-common>=0.37.0,<0.38.0'
'azure-storage-common>=1.0.0,<1.1.0'
],
cmdclass=cmdclass
)
4 changes: 2 additions & 2 deletions doc/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,9 @@
# built documents.
#
# The short X.Y version.
version = '0.37.1'
version = '1.0.0'
# The full version, including alpha/beta/rc tags.
release = '0.37.1'
release = '1.0.0'

# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
Expand Down
3 changes: 2 additions & 1 deletion tests/blob/test_common_blob.py
Original file line number Diff line number Diff line change
Expand Up @@ -528,7 +528,8 @@ def test_set_blob_metadata_with_upper_case(self):
self.assertEqual(3, len(md))
self.assertEqual(md['hello'], 'world')
self.assertEqual(md['number'], '42')
self.assertEqual(md['up'], 'UPval')
self.assertEqual(md['UP'], 'UPval')
self.assertFalse('up' in md)

@record
def test_delete_blob_with_existing_blob(self):
Expand Down
11 changes: 11 additions & 0 deletions tests/blob/test_get_blob.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,17 @@ def test_ranged_get_blob_to_bytes_with_zero_byte(self):
with self.assertRaises(AzureHttpError):
self.bs.get_blob_to_bytes(self.container_name, blob_name, start_range=3, end_range=5)

@record
def test_ranged_get_blob_with_missing_start_range(self):
blob_data = b'foobar'
blob_name = self._get_blob_reference()
self.bs.create_blob_from_bytes(self.container_name, blob_name, blob_data)

# Act
# the get request should fail fast in this case since start_range is missing while end_range is specified
with self.assertRaises(ValueError):
self.bs.get_blob_to_bytes(self.container_name, blob_name, end_range=3)

def test_get_blob_to_bytes_snapshot(self):
# parallel tests introduce random order of requests, can only run live
if TestMode.need_recording_file(self.test_mode):
Expand Down
8 changes: 6 additions & 2 deletions tests/common/test_account.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ def test_generate_account_sas(self):

service = self.account.create_block_blob_service()
data = b'shared access signature with read permission on blob'
container_name = 'container1'
container_name = self.get_resource_name("container")
blob_name = 'blob1.txt'

try:
Expand Down Expand Up @@ -241,12 +241,16 @@ def test_generate_account_sas_with_multiple_permissions(self):
service_with_key = self.account.create_block_blob_service()
service_with_sas = BlockBlobService(account_name=self.account_name, sas_token=token, is_emulated=self.settings.IS_EMULATED)
data = b'shared access signature with read/write permission on blob'
container_name = 'container2'
container_name = self.get_resource_name("container")
blob_name = 'blob1.txt'

try:
# Act Write
service_with_key.create_container(container_name)

# wait a few seconds to allow the container to be created
self.sleep(5)

resp = service_with_sas.create_blob_from_text(container_name, blob_name, data)

# Assert Write
Expand Down
3 changes: 2 additions & 1 deletion tests/file/test_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,8 @@ def test_set_file_metadata_with_upper_case(self):
self.assertEqual(3, len(md))
self.assertEqual(md['hello'], 'world')
self.assertEqual(md['number'], '42')
self.assertEqual(md['up'], 'UPval')
self.assertEqual(md['UP'], 'UPval')
self.assertFalse('up' in md)

@record
def test_delete_file_with_existing_file(self):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,57 +4,57 @@ interactions:
headers:
Connection: [keep-alive]
Content-Length: ['0']
User-Agent: [Azure-Storage/0.37.1-0.37.1 (Python CPython 3.6.1; Darwin 16.7.0)]
User-Agent: [Azure-Storage/1.0.0-1.0.0 (Python CPython 3.6.3; Darwin 17.3.0)]
x-ms-blob-type: [AppendBlob]
x-ms-client-request-id: [0d7c0e26-c0c5-11e7-a45d-b8e8564491f6]
x-ms-date: ['Fri, 03 Nov 2017 18:30:22 GMT']
x-ms-client-request-id: [9b56e7c8-fc9a-11e7-af0d-b8e8564491f6]
x-ms-date: ['Thu, 18 Jan 2018 21:57:41 GMT']
x-ms-version: ['2017-04-17']
method: PUT
uri: https://storagename.blob.core.windows.net/utcontainerb59f1281/blobb59f1281
response:
body: {string: ''}
headers:
Date: ['Fri, 03 Nov 2017 18:30:22 GMT']
ETag: ['"0x8D522E8F1D8BCBE"']
Last-Modified: ['Fri, 03 Nov 2017 18:30:22 GMT']
Date: ['Thu, 18 Jan 2018 21:57:42 GMT']
ETag: ['"0x8D55EBE7F339500"']
Last-Modified: ['Thu, 18 Jan 2018 21:57:41 GMT']
Server: [Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0]
Transfer-Encoding: [chunked]
x-ms-request-id: [a9abb7d0-001e-012c-6ed1-5490bc000000]
x-ms-request-id: [935dcf2d-001e-001a-49a7-907bbb000000]
x-ms-request-server-encrypted: ['true']
x-ms-version: ['2017-04-17']
status: {code: 201, message: Created}
- request:
body: null
headers:
Connection: [keep-alive]
User-Agent: [Azure-Storage/0.37.1-0.37.1 (Python CPython 3.6.1; Darwin 16.7.0)]
x-ms-client-request-id: [0d93e92e-c0c5-11e7-a04b-b8e8564491f6]
x-ms-date: ['Fri, 03 Nov 2017 18:30:22 GMT']
User-Agent: [Azure-Storage/1.0.0-1.0.0 (Python CPython 3.6.3; Darwin 17.3.0)]
x-ms-client-request-id: [9b72a1f4-fc9a-11e7-bb70-b8e8564491f6]
x-ms-date: ['Thu, 18 Jan 2018 21:57:42 GMT']
x-ms-range: [bytes=0-33554431]
x-ms-version: ['2017-04-17']
method: GET
uri: https://storagename.blob.core.windows.net/utcontainerb59f1281/blobb59f1281
response:
body: {string: "\uFEFF<?xml version=\"1.0\" encoding=\"utf-8\"?><Error><Code>InvalidRange</Code><Message>The\
\ range specified is invalid for the current size of the resource.\nRequestId:a9abb7e3-001e-012c-7cd1-5490bc000000\n\
Time:2017-11-03T18:30:22.8372982Z</Message></Error>"}
body: {string: "\uFEFF<?xml version=\"1.0\" encoding=\"utf-8\"?><Error><Code>InvalidRange</Code><Message>The
range specified is invalid for the current size of the resource.\nRequestId:935dcf77-001e-001a-0da7-907bbb000000\nTime:2018-01-18T21:57:42.5269445Z</Message></Error>"}
headers:
Content-Length: ['249']
Content-Range: [bytes */0]
Content-Type: [application/xml]
Date: ['Fri, 03 Nov 2017 18:30:22 GMT']
Date: ['Thu, 18 Jan 2018 21:57:42 GMT']
Server: [Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0]
x-ms-request-id: [a9abb7e3-001e-012c-7cd1-5490bc000000]
Vary: [Origin]
x-ms-request-id: [935dcf77-001e-001a-0da7-907bbb000000]
x-ms-version: ['2017-04-17']
status: {code: 416, message: The range specified is invalid for the current size
of the resource.}
- request:
body: null
headers:
Connection: [keep-alive]
User-Agent: [Azure-Storage/0.37.1-0.37.1 (Python CPython 3.6.1; Darwin 16.7.0)]
x-ms-client-request-id: [0d997628-c0c5-11e7-b68b-b8e8564491f6]
x-ms-date: ['Fri, 03 Nov 2017 18:30:22 GMT']
User-Agent: [Azure-Storage/1.0.0-1.0.0 (Python CPython 3.6.3; Darwin 17.3.0)]
x-ms-client-request-id: [9b786d12-fc9a-11e7-968d-b8e8564491f6]
x-ms-date: ['Thu, 18 Jan 2018 21:57:42 GMT']
x-ms-version: ['2017-04-17']
method: GET
uri: https://storagename.blob.core.windows.net/utcontainerb59f1281/blobb59f1281
Expand All @@ -64,15 +64,16 @@ interactions:
Accept-Ranges: [bytes]
Content-Length: ['0']
Content-Type: [application/octet-stream]
Date: ['Fri, 03 Nov 2017 18:30:22 GMT']
ETag: ['"0x8D522E8F1D8BCBE"']
Last-Modified: ['Fri, 03 Nov 2017 18:30:22 GMT']
Date: ['Thu, 18 Jan 2018 21:57:42 GMT']
ETag: ['"0x8D55EBE7F339500"']
Last-Modified: ['Thu, 18 Jan 2018 21:57:41 GMT']
Server: [Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0]
Vary: [Origin]
x-ms-blob-committed-block-count: ['0']
x-ms-blob-type: [AppendBlob]
x-ms-lease-state: [available]
x-ms-lease-status: [unlocked]
x-ms-request-id: [a9abb7ed-001e-012c-05d1-5490bc000000]
x-ms-request-id: [935dcf90-001e-001a-23a7-907bbb000000]
x-ms-server-encrypted: ['true']
x-ms-version: ['2017-04-17']
status: {code: 200, message: OK}
Expand Down
Loading