Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
148a648
Fix SubStream to respect IOBase protocol (#7843)
lmazuel Oct 11, 2019
d81e141
removes NoRetry policy (#7845)
kristapratico Oct 12, 2019
802f6ba
[storage] Makes signed_identifiers a required param (#7844)
kristapratico Oct 14, 2019
921e888
[storage] Changes `file_permission_key` param to `permission_key` (#7…
kristapratico Oct 14, 2019
91cb950
Change the param directive to keyword in docstrings (#7855)
Oct 14, 2019
ab45b98
[storage] Adds from_string to models (#7870)
kristapratico Oct 14, 2019
bf921ad
[storage-file] await async poller (#7872)
kristapratico Oct 14, 2019
10879d0
[File and Queue] Client constructors (#7853)
Oct 15, 2019
854550f
[storage-queue] rename queue messages (#7895)
kristapratico Oct 15, 2019
72a064c
[Storage-Queue][Storage-File] Kwargify positional params (#7877)
Oct 15, 2019
a5e3210
[storage-file, queue] moves param protocol to kwargs in gen_shared_ac…
kristapratico Oct 15, 2019
d77951d
[storage] Unexposes models from aio (#7881)
kristapratico Oct 16, 2019
8333d1b
[Storage-queue] Allow None message encode policy (#7898)
annatisch Oct 16, 2019
1e2ac43
Rename enqueue_message to send_messgae (#7928)
Oct 16, 2019
620394e
[storage-blob, queue] Renames Logging to <ServiceName>AnalyticsLoggin…
kristapratico Oct 16, 2019
1c88847
[Blob][File][Encryption]Fix Download Encrypted Blob/File Bug (#7965)
xiafu-msft Oct 17, 2019
95007d2
Consolidate offset - length behavior in files (#7942)
Oct 17, 2019
ea70800
Stop modifying internal_response body (#7958)
Oct 17, 2019
f1f6351
Merge remote-tracking branch 'origin/master' into feature/storage-pre…
lmazuel Oct 18, 2019
e8a94d2
[Storage] Relocated SAS generation (#7955)
annatisch Oct 19, 2019
9993c23
[Storage] Updated close handles (#7940)
annatisch Oct 19, 2019
88c839e
[Storage] Conditional etag parameters (#8047)
annatisch Oct 19, 2019
6e31ddf
[Storage] Download stream refactor (#7848)
annatisch Oct 19, 2019
7a67989
Design Pipeline ownership (#7981)
rakshith91 Oct 19, 2019
c43a13a
Merge remote-tracking branch 'origin/master' into feature/storage-pre…
lmazuel Oct 21, 2019
177deba
Merge remote-tracking branch 'origin/master' into feature/storage-pre…
lmazuel Oct 21, 2019
32f2199
Merge remote-tracking branch 'origin/master' into feature/storage-pre…
lmazuel Oct 21, 2019
4a2b369
Batching APIs Raise on Any Failure (#7963)
Oct 21, 2019
ddc4d14
Plug HttpLoggingPolicy to Storage (#8081)
lmazuel Oct 21, 2019
e1647e1
[storage] make storage files _internal (#7949)
kristapratico Oct 21, 2019
743048b
fix some tests (#8100)
Oct 21, 2019
3f07302
Fix tests (#8103)
rakshith91 Oct 22, 2019
b424135
[Storage] Bumped version + Pipeline fix (#8089)
annatisch Oct 22, 2019
bbaa3ae
Comment the echo check to workaround batch headers issue (#8118)
lmazuel Oct 22, 2019
dfda5ef
Merge branch 'master' into feature/storage-preview5
lmazuel Oct 22, 2019
0341e86
Fix 8091: expose generated enum to customers (#8117)
lmazuel Oct 22, 2019
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
  •  
  •  
  •  
7 changes: 5 additions & 2 deletions eng/tox/import_all.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,16 @@
# keyvault has dependency issue when loading private module _BearerTokenCredentialPolicyBase from azure.core.pipeline.policies
# azure.core.tracing.opencensus and azure.eventhub.checkpointstoreblob.aio are skipped due to a known issue in loading azure.core.tracing.opencensus
excluded_packages = [
"azure.core.tracing.opencensus",
"azure.core.tracing.opencensus",
"azure.eventhub.checkpointstoreblob.aio",
"azure.identity",
"azure.keyvault.certificates", # Github issue 7879
"azure.keyvault.keys", # Github issue 7879
"azure.keyvault.secrets", # Github issue 7879
"azure.appconfiguration", # Github issue 7879. revisit and close after azure-core POST b4 is released.
"azure.storage.blob", # Github issue 7879.
"azure.storage.file", # Github issue 7879.
"azure.storage.queue", # Github issue 7879.
"azure",
"azure-mgmt"]

Expand Down Expand Up @@ -59,4 +62,4 @@ def should_run_import_all(package_name):
logging.info("Verified module dependency, no issues found")
else:
pass
logging.error("Package {} is excluded from dependency check".format(package_name))
logging.error("Package {} is excluded from dependency check".format(package_name))
33 changes: 33 additions & 0 deletions sdk/storage/azure-storage-blob/HISTORY.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,36 @@
# Change Log azure-storage-blob

## Version 12.0.0b5:

**Breaking changes**

- `set_container_access_policy` has required parameter `signed_identifiers`.
- `NoRetry` policy has been removed. Use keyword argument `retry_total=0` for no retries.
- `StorageStreamDownloader` is no longer iterable. To iterate over the blob data stream, use `StorageStreamDownloader.chunks`.
- The public attributes of `StorageStreamDownloader` have been limited to:
- `name` (str): The name of the blob.
- `container` (str): The container the blob is being downloaded from.
- `properties` (`BlobProperties`): The properties of the blob.
- `size` (int): The size of the download. Either the total blob size, or the length of a subsection if sepcified. Previously called `download_size`.
- `StorageStreamDownloader` now has new functions:
- `readall()`: Reads the complete download stream, returning bytes. This replaces the functions `content_as_bytes` and `content_as_text` which have been deprecated.
- `readinto(stream)`: Download the complete stream into the supplied writable stream, returning the number of bytes written. This replaces the function `download_to_stream` which has been deprecated.
- Module level functions `upload_blob_to_url` and `download_blob_from_url` functions options are now keyword only:
- `overwrite`
- `max_concurrency`
- `encoding`
- Removed types that were accidentally exposed from two modules. Only `BlobServiceClient`, `ContainerClient`,
`BlobClient` and `LeaseClient` should be imported from azure.storage.blob.aio
- `Logging` has been renamed to `BlobAnalyticsLogging`.
- Client and model files have been made internal. Users should import from the top level modules `azure.storage.blob` and `azure.storage.blob.aio` only.
- All operations that take Etag conditional parameters (`if_match` and `if_none_match`) now take explicit `etag` and `match_condition` parameters, where `etag` is the Etag value, and `match_condition` is an instance of `azure.core.MatchConditions`.
- The `generate_shared_access_signature` methods on each of `BlobServiceClient`, `ContainerClient` and `BlobClient` have been replaced by module level functions `generate_account_sas`, `generate_container_sas` and `generate_blob_sas`.
- The batch APIs now have an additional keyword only argument `raise_on_any_failure` which defaults to True. This will raise an error even if there's a partial batch failure.

**New features**

- Added async module-level `upload_blob_to_url` and `download_blob_from_url` functions.
- `ResourceTypes`, and `Services` now have method `from_string` which takes parameters as a string.

## Version 12.0.0b4:

Expand Down Expand Up @@ -37,6 +68,8 @@ changed include:
- Add support for set_premium_page_blob_tier_blobs to ContainerClient (Python 3 only)
- Added support to set rehydrate blob priority for Block Blob, including Set Standard Blob Tier/Copy Blob APIs
- Added blob tier support for Block Blob, including Upload Blob/Commit Block List/Copy Blob APIs.
- `AccountSasPermissions`, `BlobSasPermissions`, `ContainerSasPermissions` now have method `from_string`
which takes parameters as a string.
Comment thread
annatisch marked this conversation as resolved.

**Fixes and improvements**
- Downloading page blobs now take advantage of their sparseness.
Expand Down
4 changes: 2 additions & 2 deletions sdk/storage/azure-storage-blob/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ blob = BlobClient.from_connection_string("my_connection_string", container="myco

with open("./BlockDestination.txt", "wb") as my_blob:
blob_data = blob.download_blob()
my_blob.writelines(blob_data.content_as_bytes())
my_blob.writelines(blob_data.readall())
```

Download a blob asynchronously.
Expand All @@ -165,7 +165,7 @@ blob = BlobClient.from_connection_string("my_connection_string", container="myco

with open("./BlockDestination.txt", "wb") as my_blob:
stream = await blob.download_blob()
data = await stream.content_as_bytes()
data = await stream.readall()
my_blob.write(data)
```

Expand Down
189 changes: 109 additions & 80 deletions sdk/storage/azure-storage-blob/azure/storage/blob/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,16 @@

import os

from typing import Union, Iterable, AnyStr, IO, Any # pylint: disable=unused-import
from .version import VERSION
from .blob_client import BlobClient
from .container_client import ContainerClient
from .blob_service_client import BlobServiceClient
from .lease import LeaseClient
from .download import StorageStreamDownloader
from ._shared.policies import ExponentialRetry, LinearRetry, NoRetry
from typing import Union, Iterable, AnyStr, IO, Any, Dict # pylint: disable=unused-import
from ._version import VERSION
from ._blob_client import BlobClient
from ._container_client import ContainerClient
from ._blob_service_client import BlobServiceClient
from ._lease import LeaseClient
from ._download import StorageStreamDownloader
from ._shared_access_signature import generate_account_sas, generate_container_sas, generate_blob_sas
from ._shared.policies import ExponentialRetry, LinearRetry
from ._shared.response_handlers import PartialBatchErrorException
from ._shared.models import(
LocationMode,
ResourceTypes,
Expand All @@ -24,23 +26,20 @@
from ._generated.models import (
RehydratePriority
)
from .models import (
from ._models import (
BlobType,
BlockState,
StandardBlobTier,
PremiumPageBlobTier,
SequenceNumberAction,
PublicAccess,
Logging,
BlobAnalyticsLogging,
Metrics,
RetentionPolicy,
StaticWebsite,
CorsRule,
ContainerProperties,
ContainerPropertiesPaged,
BlobProperties,
BlobPropertiesPaged,
BlobPrefix,
LeaseProperties,
ContentSettings,
CopyProperties,
Expand All @@ -55,57 +54,12 @@
__version__ = VERSION


__all__ = [
'BlobServiceClient',
'ContainerClient',
'BlobClient',
'BlobType',
'LeaseClient',
'StorageErrorCode',
'UserDelegationKey',
'ExponentialRetry',
'LinearRetry',
'NoRetry',
'LocationMode',
'BlockState',
'StandardBlobTier',
'PremiumPageBlobTier',
'SequenceNumberAction',
'PublicAccess',
'Logging',
'Metrics',
'RetentionPolicy',
'StaticWebsite',
'CorsRule',
'ContainerProperties',
'ContainerPropertiesPaged',
'BlobProperties',
'BlobPropertiesPaged',
'BlobPrefix',
'LeaseProperties',
'ContentSettings',
'CopyProperties',
'BlobBlock',
'PageRange',
'AccessPolicy',
'ContainerSasPermissions',
'BlobSasPermissions',
'ResourceTypes',
'AccountSasPermissions',
'StorageStreamDownloader',
'CustomerProvidedEncryptionKey',
'RehydratePriority'
]


def upload_blob_to_url(
blob_url, # type: str
data, # type: Union[Iterable[AnyStr], IO[AnyStr]]
max_concurrency=1, # type: int
encoding='UTF-8', # type: str
credential=None, # type: Any
**kwargs):
# type: (...) -> dict[str, Any]
# type: (...) -> Dict[str, Any]
"""Upload data to a given URL

The data will be uploaded as a block blob.
Expand All @@ -115,38 +69,50 @@ def upload_blob_to_url(
:param data:
The data to upload. This can be bytes, text, an iterable or a file-like object.
:type data: bytes or str or Iterable
:param bool overwrite:
Whether the blob to be uploaded should overwrite the current data.
If True, upload_blob_to_url will overwrite any existing data. If set to False, the
operation will fail with a ResourceExistsError.
:param credential:
The credentials with which to authenticate. This is optional if the
blob URL already has a SAS token. The value can be a SAS token string, an account
shared access key, or an instance of a TokenCredentials class from azure.identity.
If the URL already has a SAS token, specifying an explicit credential will take priority.
:keyword bool overwrite:
Whether the blob to be uploaded should overwrite the current data.
If True, upload_blob_to_url will overwrite any existing data. If set to False, the
operation will fail with a ResourceExistsError.
:keyword int max_concurrency:
The number of parallel connections with which to download.
:keyword int length:
Number of bytes to read from the stream. This is optional, but
should be supplied for optimal performance.
:keyword metadata:
Name-value pairs associated with the blob as metadata.
:type metadata: dict(str, str)
:keyword bool validate_content:
If true, calculates an MD5 hash for each chunk of the blob. The storage
service checks the hash of the content that has arrived with the hash
that was sent. This is primarily valuable for detecting bitflips on
the wire if using http instead of https as https (the default) will
already validate. Note that this MD5 hash is not stored with the
blob. Also note that if enabled, the memory-efficient upload algorithm
will not be used, because computing the MD5 hash requires buffering
entire blocks, and doing so defeats the purpose of the memory-efficient algorithm.
:keyword str encoding:
Encoding to use if text is supplied as input. Defaults to UTF-8.
:returns: Blob-updated property dict (Etag and last modified)
:rtype: dict(str, Any)
"""
with BlobClient.from_blob_url(blob_url, credential=credential) as client:
return client.upload_blob(
data=data,
blob_type=BlobType.BlockBlob,
max_concurrency=max_concurrency,
encoding=encoding,
**kwargs)
return client.upload_blob(data=data, blob_type=BlobType.BlockBlob, **kwargs)


def _download_to_stream(client, handle, max_concurrency, **kwargs):
def _download_to_stream(client, handle, **kwargs):
"""Download data to specified open file-handle."""
stream = client.download_blob(**kwargs)
stream.download_to_stream(handle, max_concurrency=max_concurrency)
stream.readinto(handle)


def download_blob_from_url(
blob_url, # type: str
output, # type: str
overwrite=False, # type: bool
max_concurrency=1, # type: int
credential=None, # type: Any
**kwargs):
# type: (...) -> None
Expand All @@ -158,23 +124,86 @@ def download_blob_from_url(
Where the data should be downloaded to. This could be either a file path to write to,
or an open IO handle to write to.
:type output: str or writable stream.
:param bool overwrite:
Whether the local file should be overwritten if it already exists. The default value is
`False` - in which case a ValueError will be raised if the file already exists. If set to
`True`, an attempt will be made to write to the existing file. If a stream handle is passed
in, this value is ignored.
:param credential:
The credentials with which to authenticate. This is optional if the
blob URL already has a SAS token or the blob is public. The value can be a SAS token string,
an account shared access key, or an instance of a TokenCredentials class from azure.identity.
If the URL already has a SAS token, specifying an explicit credential will take priority.
:keyword bool overwrite:
Whether the local file should be overwritten if it already exists. The default value is
`False` - in which case a ValueError will be raised if the file already exists. If set to
`True`, an attempt will be made to write to the existing file. If a stream handle is passed
in, this value is ignored.
:keyword int max_concurrency:
The number of parallel connections with which to download.
:keyword int offset:
Start of byte range to use for downloading a section of the blob.
Must be set if length is provided.
:keyword int length:
Number of bytes to read from the stream. This is optional, but
should be supplied for optimal performance.
:keyword bool validate_content:
If true, calculates an MD5 hash for each chunk of the blob. The storage
service checks the hash of the content that has arrived with the hash
that was sent. This is primarily valuable for detecting bitflips on
the wire if using http instead of https as https (the default) will
already validate. Note that this MD5 hash is not stored with the
blob. Also note that if enabled, the memory-efficient upload algorithm
will not be used, because computing the MD5 hash requires buffering
entire blocks, and doing so defeats the purpose of the memory-efficient algorithm.
:rtype: None
"""
overwrite = kwargs.pop('overwrite', False)
with BlobClient.from_blob_url(blob_url, credential=credential) as client:
if hasattr(output, 'write'):
_download_to_stream(client, output, max_concurrency, **kwargs)
_download_to_stream(client, output, **kwargs)
else:
if not overwrite and os.path.isfile(output):
raise ValueError("The file '{}' already exists.".format(output))
with open(output, 'wb') as file_handle:
_download_to_stream(client, file_handle, max_concurrency, **kwargs)
_download_to_stream(client, file_handle, **kwargs)


__all__ = [
'upload_blob_to_url',
'download_blob_from_url',
'BlobServiceClient',
'ContainerClient',
'BlobClient',
'BlobType',
'LeaseClient',
'StorageErrorCode',
'UserDelegationKey',
'ExponentialRetry',
'LinearRetry',
'LocationMode',
'BlockState',
'StandardBlobTier',
'PremiumPageBlobTier',
'SequenceNumberAction',
'PublicAccess',
'BlobAnalyticsLogging',
'Metrics',
'RetentionPolicy',
'StaticWebsite',
'CorsRule',
'ContainerProperties',
'BlobProperties',
'LeaseProperties',
'ContentSettings',
'CopyProperties',
'BlobBlock',
'PageRange',
'AccessPolicy',
'ContainerSasPermissions',
'BlobSasPermissions',
'ResourceTypes',
'AccountSasPermissions',
'StorageStreamDownloader',
'CustomerProvidedEncryptionKey',
'RehydratePriority',
'generate_account_sas',
'generate_container_sas',
'generate_blob_sas',
'PartialBatchErrorException'
]
Loading