diff --git a/sdk/storage/azure-storage-blob/azure/storage/blob/__init__.py b/sdk/storage/azure-storage-blob/azure/storage/blob/__init__.py index 9871a54c4cb7..7a8ed8508a59 100644 --- a/sdk/storage/azure-storage-blob/azure/storage/blob/__init__.py +++ b/sdk/storage/azure-storage-blob/azure/storage/blob/__init__.py @@ -126,7 +126,7 @@ def upload_blob_to_url( :rtype: dict(str, Any) """ with BlobClient.from_blob_url(blob_url, credential=credential) as client: - return cast(BlobClient, client).upload_blob(data=data, blob_type=BlobType.BLOCKBLOB, **kwargs) + return client.upload_blob(data=data, blob_type=BlobType.BLOCKBLOB, **kwargs) def _download_to_stream(client: BlobClient, handle: IO[bytes], **kwargs: Any) -> None: diff --git a/sdk/storage/azure-storage-blob/azure/storage/blob/_blob_client.py b/sdk/storage/azure-storage-blob/azure/storage/blob/_blob_client.py index 8ac7c0df6489..7de214f22c4a 100644 --- a/sdk/storage/azure-storage-blob/azure/storage/blob/_blob_client.py +++ b/sdk/storage/azure-storage-blob/azure/storage/blob/_blob_client.py @@ -6,13 +6,13 @@ # pylint: disable=too-many-lines, docstring-keyword-should-match-keyword-only import warnings +from contextlib import AbstractContextManager from datetime import datetime from functools import partial from typing import ( - Any, AnyStr, cast, Dict, IO, Iterable, List, Optional, overload, Tuple, Union, + Any, AnyStr, cast, Dict, IO, Iterable, List, Optional, Tuple, Union, TYPE_CHECKING ) -from typing_extensions import Self from azure.core.exceptions import HttpResponseError, ResourceExistsError, ResourceNotFoundError from azure.core.paging import ItemPaged @@ -89,7 +89,7 @@ ) -class BlobClient(StorageAccountHostsMixin, StorageEncryptionMixin): # pylint: disable=too-many-public-methods +class BlobClient(AbstractContextManager, StorageAccountHostsMixin, StorageEncryptionMixin): # pylint: disable=too-many-public-methods """A client to interact with a specific blob, although that blob may not yet exist. For more optional configuration, please click @@ -190,7 +190,7 @@ def __init__( self._client._config.version = get_api_version(kwargs) # type: ignore [assignment] self._configure_encryption(kwargs) - def __enter__(self) -> Self: + def __enter__(self) -> "BlobClient": self._client.__enter__() return self @@ -221,7 +221,7 @@ def from_blob_url( credential: Optional[Union[str, Dict[str, str], "AzureNamedKeyCredential", "AzureSasCredential", "TokenCredential"]] = None, # pylint: disable=line-too-long snapshot: Optional[Union[str, Dict[str, Any]]] = None, **kwargs: Any - ) -> Self: + ) -> "BlobClient": """Create BlobClient from a blob url. This doesn't support customized blob url with '/' in blob name. :param str blob_url: @@ -269,7 +269,7 @@ def from_connection_string( snapshot: Optional[Union[str, Dict[str, Any]]] = None, credential: Optional[Union[str, Dict[str, str], "AzureNamedKeyCredential", "AzureSasCredential", "TokenCredential"]] = None, # pylint: disable=line-too-long **kwargs: Any - ) -> Self: + ) -> "BlobClient": """Create BlobClient from a Connection String. :param str conn_str: @@ -633,26 +633,6 @@ def upload_blob( return upload_page_blob(**options) return upload_append_blob(**options) - @overload - def download_blob( - self, offset: Optional[int] = None, - length: Optional[int] = None, - *, - encoding: str, - **kwargs: Any - ) -> StorageStreamDownloader[str]: - ... - - @overload - def download_blob( - self, offset: Optional[int] = None, - length: Optional[int] = None, - *, - encoding: None = None, - **kwargs: Any - ) -> StorageStreamDownloader[bytes]: - ... - @distributed_trace def download_blob( self, offset: Optional[int] = None, diff --git a/sdk/storage/azure-storage-blob/azure/storage/blob/_blob_client.pyi b/sdk/storage/azure-storage-blob/azure/storage/blob/_blob_client.pyi new file mode 100644 index 000000000000..d0c3a5a8b78d --- /dev/null +++ b/sdk/storage/azure-storage-blob/azure/storage/blob/_blob_client.pyi @@ -0,0 +1,780 @@ +# ------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# -------------------------------------------------------------------------- +# pylint: skip-file + +from contextlib import AbstractContextManager +from datetime import datetime +from types import TracebackType +from typing import ( + Any, + AnyStr, + Callable, + Dict, + IO, + Iterable, + List, + Literal, + Optional, + overload, + Tuple, + Union, +) + +from azure.core import MatchConditions +from azure.core.credentials import AzureNamedKeyCredential, AzureSasCredential, TokenCredential +from azure.core.paging import ItemPaged +from azure.core.tracing.decorator import distributed_trace +from ._container_client import ContainerClient +from ._download import StorageStreamDownloader +from ._encryption import StorageEncryptionMixin +from ._generated.models import RehydratePriority +from ._lease import BlobLeaseClient +from ._models import ( + ArrowDialect, + BlobBlock, + BlobProperties, + BlobQueryError, + BlobType, + ContentSettings, + CustomerProvidedEncryptionKey, + DelimitedTextDialect, + DelimitedJsonDialect, + ImmutabilityPolicy, + PageRange, + PremiumPageBlobTier, + QuickQueryDialect, + SequenceNumberAction, + StandardBlobTier, +) +from ._quick_query_helper import BlobQueryReader +from ._shared.base_client import StorageAccountHostsMixin + +class BlobClient(AbstractContextManager, StorageAccountHostsMixin, StorageEncryptionMixin): + def __init__( + self, + account_url: str, + container_name: str, + blob_name: str, + snapshot: Optional[Union[str, Dict[str, Any]]] = None, + credential: Optional[ + Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, TokenCredential] + ] = None, + *, + api_version: Optional[str] = None, + secondary_hostname: Optional[str] = None, + version_id: Optional[str] = None, + audience: Optional[str] = None, + max_block_size: int = 4 * 1024 * 1024, + max_page_size: int = 4 * 1024 * 1024, + max_chunk_get_size: int = 4 * 1024 * 1024, + max_single_put_size: int = 64 * 1024 * 1024, + max_single_get_size: int = 32 * 1024 * 1024, + min_large_block_upload_threshold: int = 4 * 1024 * 1024 + 1, + use_byte_buffer: Optional[bool] = None, + **kwargs: Any + ) -> None: ... + def __enter__(self) -> "BlobClient": ... + def __exit__( + self, typ: Optional[type[BaseException]], exc: Optional[BaseException], tb: Optional[TracebackType] + ) -> None: ... + def close(self) -> None: ... + @classmethod + def from_blob_url( + cls, + blob_url: str, + credential: Optional[ + Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, TokenCredential] + ] = None, + snapshot: Optional[Union[str, Dict[str, Any]]] = None, + *, + api_version: Optional[str] = None, + secondary_hostname: Optional[str] = None, + version_id: Optional[str] = None, + audience: Optional[str] = None, + max_block_size: int = 4 * 1024 * 1024, + max_page_size: int = 4 * 1024 * 1024, + max_chunk_get_size: int = 4 * 1024 * 1024, + max_single_put_size: int = 64 * 1024 * 1024, + max_single_get_size: int = 32 * 1024 * 1024, + min_large_block_upload_threshold: int = 4 * 1024 * 1024 + 1, + use_byte_buffer: Optional[bool] = None, + **kwargs: Any + ) -> "BlobClient": ... + @classmethod + def from_connection_string( + cls, + conn_str: str, + container_name: str, + blob_name: str, + snapshot: Optional[Union[str, Dict[str, Any]]] = None, + credential: Optional[ + Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, TokenCredential] + ] = None, + *, + api_version: Optional[str] = None, + secondary_hostname: Optional[str] = None, + version_id: Optional[str] = None, + audience: Optional[str] = None, + max_block_size: int = 4 * 1024 * 1024, + max_page_size: int = 4 * 1024 * 1024, + max_chunk_get_size: int = 4 * 1024 * 1024, + max_single_put_size: int = 64 * 1024 * 1024, + max_single_get_size: int = 32 * 1024 * 1024, + min_large_block_upload_threshold: int = 4 * 1024 * 1024 + 1, + use_byte_buffer: Optional[bool] = None, + **kwargs: Any + ) -> "BlobClient": ... + @distributed_trace + def get_account_information(self, **kwargs: Any) -> Dict[str, str]: ... + @distributed_trace + def upload_blob_from_url( + self, + source_url: str, + *, + metadata: Optional[Dict[str, str]] = None, + overwrite: Optional[bool] = None, + include_source_blob_properties: bool = True, + tags: Optional[Dict[str, str]] = None, + source_content_md5: Optional[bytearray] = None, + source_if_modified_since: Optional[datetime] = None, + source_if_unmodified_since: Optional[datetime] = None, + source_etag: Optional[str] = None, + source_match_condition: Optional[MatchConditions] = None, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + destination_lease: Optional[Union[BlobLeaseClient, str]] = None, + timeout: Optional[int] = None, + content_settings: Optional[ContentSettings] = None, + cpk: Optional[CustomerProvidedEncryptionKey] = None, + encryption_scope: Optional[str] = None, + standard_blob_tier: Optional[StandardBlobTier] = None, + source_authorization: Optional[str] = None, + source_token_intent: Optional[Literal["backup"]] = None, + **kwargs: Any + ) -> Dict[str, Any]: ... + @distributed_trace + def upload_blob( + self, + data: Union[bytes, str, Iterable[AnyStr], IO[bytes]], + blob_type: Union[str, BlobType] = BlobType.BLOCKBLOB, + length: Optional[int] = None, + metadata: Optional[Dict[str, str]] = None, + *, + tags: Optional[Dict[str, str]] = None, + overwrite: bool = False, + content_settings: Optional[ContentSettings] = None, + validate_content: bool = False, + lease: Optional[BlobLeaseClient] = None, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + if_tags_match_condition: Optional[str] = None, + premium_page_blob_tier: Optional[PremiumPageBlobTier] = None, + immutability_policy: Optional[ImmutabilityPolicy] = None, + legal_hold: Optional[bool] = None, + standard_blob_tier: Optional[StandardBlobTier] = None, + maxsize_condition: Optional[int] = None, + max_concurrency: int = 1, + cpk: Optional[CustomerProvidedEncryptionKey] = None, + encryption_scope: Optional[str] = None, + encoding: str = "UTF-8", + progress_hook: Optional[Callable[[int, Optional[int]], None]] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> Dict[str, Any]: ... + @overload + def download_blob( + self, + offset: Optional[int] = None, + length: Optional[int] = None, + *, + version_id: Optional[str] = None, + validate_content: bool = False, + lease: Optional[Union[BlobLeaseClient, str]] = None, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + if_tags_match_condition: Optional[str] = None, + cpk: Optional[CustomerProvidedEncryptionKey] = None, + max_concurrency: int = 1, + encoding: str, + progress_hook: Optional[Callable[[int, int], None]] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> StorageStreamDownloader[str]: ... + @overload + def download_blob( + self, + offset: Optional[int] = None, + length: Optional[int] = None, + *, + version_id: Optional[str] = None, + validate_content: bool = False, + lease: Optional[Union[BlobLeaseClient, str]] = None, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + if_tags_match_condition: Optional[str] = None, + cpk: Optional[CustomerProvidedEncryptionKey] = None, + max_concurrency: int = 1, + encoding: None = None, + progress_hook: Optional[Callable[[int, int], None]] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> StorageStreamDownloader[bytes]: ... + @distributed_trace # type: ignore[misc] + def download_blob( + self, + offset: Optional[int] = None, + length: Optional[int] = None, + *, + version_id: Optional[str] = None, + validate_content: bool = False, + lease: Optional[Union[BlobLeaseClient, str]] = None, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + if_tags_match_condition: Optional[str] = None, + cpk: Optional[CustomerProvidedEncryptionKey] = None, + max_concurrency: int = 1, + encoding: Optional[str] = None, + progress_hook: Optional[Callable[[int, int], None]] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> Union[StorageStreamDownloader[str], StorageStreamDownloader[bytes]]: ... + @distributed_trace + def query_blob( + self, + query_expression: str, + *, + on_error: Optional[Callable[[BlobQueryError], None]] = None, + blob_format: Optional[Union[DelimitedTextDialect, DelimitedJsonDialect, QuickQueryDialect, str]] = None, + output_format: Optional[ + Union[DelimitedTextDialect, DelimitedJsonDialect, QuickQueryDialect, List[ArrowDialect], str] + ] = None, + lease: Optional[Union[BlobLeaseClient, str]] = None, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + if_tags_match_condition: Optional[str] = None, + cpk: Optional[CustomerProvidedEncryptionKey] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> BlobQueryReader: ... + @distributed_trace + def delete_blob( + self, + delete_snapshots: Optional[str] = None, + *, + version_id: Optional[str] = None, + lease: Optional[Union[BlobLeaseClient, str]] = None, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + if_tags_match_condition: Optional[str] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> None: ... + @distributed_trace + def undelete_blob(self, *, timeout: Optional[int] = None, **kwargs: Any) -> None: ... + @distributed_trace + def exists(self, *, version_id: Optional[str] = None, timeout: Optional[int] = None, **kwargs: Any) -> bool: ... + @distributed_trace + def get_blob_properties( + self, + *, + lease: Optional[Union[BlobLeaseClient, str]] = None, + version_id: Optional[str] = None, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + if_tags_match_condition: Optional[str] = None, + cpk: Optional[CustomerProvidedEncryptionKey] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> BlobProperties: ... + @distributed_trace + def set_http_headers( + self, + content_settings: Optional[ContentSettings] = None, + *, + lease: Optional[Union[BlobLeaseClient, str]] = None, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + if_tags_match_condition: Optional[str] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> Dict[str, Any]: ... + @distributed_trace + def set_blob_metadata( + self, + metadata: Optional[Dict[str, str]] = None, + *, + lease: Optional[Union[BlobLeaseClient, str]] = None, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + if_tags_match_condition: Optional[str] = None, + cpk: Optional[CustomerProvidedEncryptionKey] = None, + encryption_scope: Optional[str] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> Dict[str, Union[str, datetime]]: ... + @distributed_trace + def set_immutability_policy( + self, + immutability_policy: ImmutabilityPolicy, + *, + version_id: Optional[str] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> Dict[str, str]: ... + @distributed_trace + def delete_immutability_policy( + self, *, version_id: Optional[str] = None, timeout: Optional[int] = None, **kwargs: Any + ) -> None: ... + @distributed_trace + def set_legal_hold( + self, legal_hold: bool, *, version_id: Optional[str] = None, timeout: Optional[int] = None, **kwargs: Any + ) -> Dict[str, Union[str, datetime, bool]]: ... + @distributed_trace + def create_page_blob( + self, + size: int, + content_settings: Optional[ContentSettings] = None, + metadata: Optional[Dict[str, str]] = None, + premium_page_blob_tier: Optional[Union[str, PremiumPageBlobTier]] = None, + *, + tags: Optional[Dict[str, str]] = None, + sequence_number: Optional[int] = None, + lease: Optional[Union[BlobLeaseClient, str]] = None, + immutability_policy: Optional[ImmutabilityPolicy] = None, + legal_hold: Optional[bool] = None, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + cpk: Optional[CustomerProvidedEncryptionKey] = None, + encryption_scope: Optional[str] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> Dict[str, Union[str, datetime]]: ... + @distributed_trace + def create_append_blob( + self, + content_settings: Optional[ContentSettings] = None, + metadata: Optional[Dict[str, str]] = None, + *, + tags: Optional[Dict[str, str]] = None, + immutability_policy: Optional[ImmutabilityPolicy] = None, + legal_hold: Optional[bool] = None, + lease: Optional[Union[BlobLeaseClient, str]] = None, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + cpk: Optional[CustomerProvidedEncryptionKey] = None, + encryption_scope: Optional[str] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> Dict[str, Union[str, datetime]]: ... + @distributed_trace + def create_snapshot( + self, + metadata: Optional[Dict[str, str]] = None, + *, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + if_tags_match_condition: Optional[str] = None, + lease: Optional[Union[BlobLeaseClient, str]] = None, + cpk: Optional[CustomerProvidedEncryptionKey] = None, + encryption_scope: Optional[str] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> Dict[str, Union[str, datetime]]: ... + @distributed_trace + def start_copy_from_url( + self, + source_url: str, + metadata: Optional[Dict[str, str]] = None, + incremental_copy: bool = False, + *, + tags: Optional[Union[Dict[str, str], Literal["COPY"]]] = None, + immutability_policy: Optional[ImmutabilityPolicy] = None, + legal_hold: Optional[bool] = None, + source_if_modified_since: Optional[datetime] = None, + source_if_unmodified_since: Optional[datetime] = None, + source_etag: Optional[str] = None, + source_match_condition: Optional[MatchConditions] = None, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + if_tags_match_condition: Optional[str] = None, + destination_lease: Optional[Union[BlobLeaseClient, str]] = None, + source_lease: Optional[Union[BlobLeaseClient, str]] = None, + premium_page_blob_tier: Optional[PremiumPageBlobTier] = None, + standard_blob_tier: Optional[StandardBlobTier] = None, + rehydrate_priority: Optional[RehydratePriority] = None, + seal_destination_blob: Optional[bool] = None, + requires_sync: Optional[bool] = None, + source_authorization: Optional[str] = None, + source_token_intent: Optional[Literal["backup"]] = None, + encryption_scope: Optional[str] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> Dict[str, Union[str, datetime]]: ... + @distributed_trace + def abort_copy(self, copy_id: Union[str, Dict[str, Any], BlobProperties], **kwargs: Any) -> None: ... + @distributed_trace + def acquire_lease( + self, + lease_duration: int = -1, + lease_id: Optional[str] = None, + *, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + if_tags_match_condition: Optional[str] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> BlobLeaseClient: ... + @distributed_trace + def set_standard_blob_tier( + self, + standard_blob_tier: Union[str, StandardBlobTier], + *, + rehydrate_priority: Optional[RehydratePriority] = None, + version_id: Optional[str] = None, + if_tags_match_condition: Optional[str] = None, + lease: Optional[Union[BlobLeaseClient, str]] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> None: ... + @distributed_trace + def stage_block( + self, + block_id: str, + data: Union[bytes, str, Iterable[AnyStr], IO[AnyStr]], + length: Optional[int] = None, + *, + validate_content: Optional[bool] = None, + lease: Optional[Union[BlobLeaseClient, str]] = None, + encoding: Optional[str] = None, + cpk: Optional[CustomerProvidedEncryptionKey] = None, + encryption_scope: Optional[str] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> Dict[str, Any]: ... + @distributed_trace + def stage_block_from_url( + self, + block_id: str, + source_url: str, + source_offset: Optional[int] = None, + source_length: Optional[int] = None, + source_content_md5: Optional[Union[bytes, bytearray]] = None, + *, + lease: Optional[Union[BlobLeaseClient, str]] = None, + cpk: Optional[CustomerProvidedEncryptionKey] = None, + encryption_scope: Optional[str] = None, + source_authorization: Optional[str] = None, + source_token_intent: Optional[Literal["backup"]] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> Dict[str, Any]: ... + @distributed_trace + def get_block_list( + self, + block_list_type: str = "committed", + *, + lease: Optional[Union[BlobLeaseClient, str]] = None, + if_tags_match_condition: Optional[str] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> Tuple[List[BlobBlock], List[BlobBlock]]: ... + @distributed_trace + def commit_block_list( + self, + block_list: List[BlobBlock], + content_settings: Optional[ContentSettings] = None, + metadata: Optional[Dict[str, str]] = None, + *, + tags: Optional[Dict[str, str]] = None, + lease: Optional[Union[BlobLeaseClient, str]] = None, + immutability_policy: Optional[ImmutabilityPolicy] = None, + legal_hold: Optional[bool] = None, + validate_content: Optional[bool] = None, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + if_tags_match_condition: Optional[str] = None, + standard_blob_tier: Optional[StandardBlobTier] = None, + cpk: Optional[CustomerProvidedEncryptionKey] = None, + encryption_scope: Optional[str] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> Dict[str, Union[str, datetime]]: ... + @distributed_trace + def set_premium_page_blob_tier( + self, + premium_page_blob_tier: PremiumPageBlobTier, + *, + if_tags_match_condition: Optional[str] = None, + lease: Optional[Union[BlobLeaseClient, str]] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> None: ... + @distributed_trace + def set_blob_tags( + self, + tags: Optional[Dict[str, str]] = None, + *, + version_id: Optional[str] = None, + validate_content: Optional[bool] = None, + if_tags_match_condition: Optional[str] = None, + lease: Optional[Union[BlobLeaseClient, str]] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> Dict[str, Any]: ... + @distributed_trace + def get_blob_tags( + self, + *, + version_id: Optional[str] = None, + if_tags_match_condition: Optional[str] = None, + lease: Optional[Union[BlobLeaseClient, str]] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> Dict[str, str]: ... + @distributed_trace + def get_page_ranges( + self, + offset: Optional[int] = None, + length: Optional[int] = None, + previous_snapshot_diff: Optional[Union[str, Dict[str, Any]]] = None, + *, + lease: Optional[Union[BlobLeaseClient, str]] = None, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + if_tags_match_condition: Optional[str] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> Tuple[List[Dict[str, int]], List[Dict[str, int]]]: ... + @distributed_trace + def list_page_ranges( + self, + *, + offset: Optional[int] = None, + length: Optional[int] = None, + previous_snapshot: Optional[Union[str, Dict[str, Any]]] = None, + lease: Optional[Union[BlobLeaseClient, str]] = None, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + if_tags_match_condition: Optional[str] = None, + results_per_page: Optional[int] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> ItemPaged[PageRange]: ... + @distributed_trace + def get_page_range_diff_for_managed_disk( + self, + previous_snapshot_url: str, + offset: Optional[int] = None, + length: Optional[int] = None, + *, + lease: Optional[Union[BlobLeaseClient, str]] = None, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> Tuple[List[Dict[str, int]], List[Dict[str, int]]]: ... + @distributed_trace + def set_sequence_number( + self, + sequence_number_action: Union[str, SequenceNumberAction], + sequence_number: Optional[str] = None, + *, + lease: Optional[Union[BlobLeaseClient, str]] = None, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + if_tags_match_condition: Optional[str] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> Dict[str, Union[str, datetime]]: ... + @distributed_trace + def resize_blob( + self, + size: int, + *, + lease: Optional[Union[BlobLeaseClient, str]] = None, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + if_tags_match_condition: Optional[str] = None, + premium_page_blob_tier: Optional[PremiumPageBlobTier] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> Dict[str, Union[str, datetime]]: ... + @distributed_trace + def upload_page( + self, + page: bytes, + offset: int, + length: int, + *, + lease: Optional[Union[BlobLeaseClient, str]] = None, + validate_content: Optional[bool] = None, + if_sequence_number_lte: Optional[int] = None, + if_sequence_number_lt: Optional[int] = None, + if_sequence_number_eq: Optional[int] = None, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + if_tags_match_condition: Optional[str] = None, + cpk: Optional[CustomerProvidedEncryptionKey] = None, + encryption_scope: Optional[str] = None, + encoding: Optional[str] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> Dict[str, Union[str, datetime]]: ... + @distributed_trace + def upload_pages_from_url( + self, + source_url: str, + offset: int, + length: int, + source_offset: int, + *, + source_content_md5: Optional[bytes] = None, + source_if_modified_since: Optional[datetime] = None, + source_if_unmodified_since: Optional[datetime] = None, + source_etag: Optional[str] = None, + source_match_condition: Optional[MatchConditions] = None, + lease: Optional[Union[BlobLeaseClient, str]] = None, + if_sequence_number_lte: Optional[int] = None, + if_sequence_number_lt: Optional[int] = None, + if_sequence_number_eq: Optional[int] = None, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + if_tags_match_condition: Optional[str] = None, + cpk: Optional[CustomerProvidedEncryptionKey] = None, + encryption_scope: Optional[str] = None, + source_authorization: Optional[str] = None, + source_token_intent: Optional[Literal["backup"]] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> Dict[str, Any]: ... + @distributed_trace + def clear_page( + self, + offset: int, + length: int, + *, + lease: Optional[Union[BlobLeaseClient, str]] = None, + if_sequence_number_lte: Optional[int] = None, + if_sequence_number_lt: Optional[int] = None, + if_sequence_number_eq: Optional[int] = None, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + if_tags_match_condition: Optional[str] = None, + cpk: Optional[CustomerProvidedEncryptionKey] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> Dict[str, Union[str, datetime]]: ... + @distributed_trace + def append_block( + self, + data: Union[bytes, str, Iterable[AnyStr], IO[AnyStr]], + length: Optional[int] = None, + *, + validate_content: Optional[bool] = None, + maxsize_condition: Optional[int] = None, + appendpos_condition: Optional[int] = None, + lease: Optional[Union[BlobLeaseClient, str]] = None, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + if_tags_match_condition: Optional[str] = None, + encoding: Optional[str] = None, + cpk: Optional[CustomerProvidedEncryptionKey] = None, + encryption_scope: Optional[str] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> Dict[str, Union[str, datetime, int]]: ... + @distributed_trace + def append_block_from_url( + self, + copy_source_url: str, + source_offset: Optional[int] = None, + source_length: Optional[int] = None, + *, + source_content_md5: Optional[bytearray] = None, + maxsize_condition: Optional[int] = None, + appendpos_condition: Optional[int] = None, + lease: Optional[Union[BlobLeaseClient, str]] = None, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + if_tags_match_condition: Optional[str] = None, + source_if_modified_since: Optional[datetime] = None, + source_if_unmodified_since: Optional[datetime] = None, + source_etag: Optional[str] = None, + source_match_condition: Optional[MatchConditions] = None, + cpk: Optional[CustomerProvidedEncryptionKey] = None, + encryption_scope: Optional[str] = None, + source_authorization: Optional[str] = None, + source_token_intent: Optional[Literal["backup"]] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> Dict[str, Union[str, datetime, int]]: ... + @distributed_trace + def seal_append_blob( + self, + *, + appendpos_condition: Optional[int] = None, + lease: Optional[Union[BlobLeaseClient, str]] = None, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> Dict[str, Union[str, datetime, int]]: ... + @distributed_trace + def _get_container_client(self) -> ContainerClient: ... diff --git a/sdk/storage/azure-storage-blob/azure/storage/blob/_blob_service_client.py b/sdk/storage/azure-storage-blob/azure/storage/blob/_blob_service_client.py index 2c9a6d06ece3..a26293dd252f 100644 --- a/sdk/storage/azure-storage-blob/azure/storage/blob/_blob_service_client.py +++ b/sdk/storage/azure-storage-blob/azure/storage/blob/_blob_service_client.py @@ -7,11 +7,11 @@ import functools import warnings +from contextlib import AbstractContextManager from typing import ( Any, Dict, List, Optional, Union, TYPE_CHECKING ) -from typing_extensions import Self from azure.core.exceptions import HttpResponseError from azure.core.paging import ItemPaged @@ -51,7 +51,7 @@ from ._shared.models import UserDelegationKey -class BlobServiceClient(StorageAccountHostsMixin, StorageEncryptionMixin): +class BlobServiceClient(AbstractContextManager, StorageAccountHostsMixin, StorageEncryptionMixin): """A client to interact with the Blob Service at the account level. This client provides operations to retrieve and configure the account properties @@ -131,7 +131,7 @@ def __init__( self._client._config.version = get_api_version(kwargs) # type: ignore [assignment] self._configure_encryption(kwargs) - def __enter__(self) -> Self: + def __enter__(self) -> "BlobServiceClient": self._client.__enter__() return self @@ -147,7 +147,7 @@ def close(self) -> None: """ self._client.close() - def _format_url(self, hostname): + def _format_url(self, hostname: str) -> str: """Format the endpoint URL according to the current location mode hostname. @@ -163,7 +163,7 @@ def from_connection_string( cls, conn_str: str, credential: Optional[Union[str, Dict[str, str], "AzureNamedKeyCredential", "AzureSasCredential", "TokenCredential"]] = None, # pylint: disable=line-too-long **kwargs: Any - ) -> Self: + ) -> "BlobServiceClient": """Create BlobServiceClient from a Connection String. :param str conn_str: @@ -182,6 +182,27 @@ def from_connection_string( ~azure.core.credentials.AzureSasCredential or ~azure.core.credentials.TokenCredential or str or dict[str, str] or None + :keyword str api_version: + The Storage API version to use for requests. Default value is the most recent service version that is + compatible with the current SDK. Setting to an older version may result in reduced feature compatibility. + + .. versionadded:: 12.2.0 + + :keyword str secondary_hostname: + The hostname of the secondary endpoint. + :keyword int max_block_size: The maximum chunk size for uploading a block blob in chunks. + Defaults to 4*1024*1024, or 4MB. + :keyword int max_single_put_size: If the blob size is less than or equal max_single_put_size, then the blob will + be uploaded with only one http PUT request. If the blob size is larger than max_single_put_size, + the blob will be uploaded in chunks. Defaults to 64*1024*1024, or 64MB. + :keyword int min_large_block_upload_threshold: The minimum chunk size required to use the memory efficient + algorithm when uploading a block blob. Defaults to 4*1024*1024+1. + :keyword bool use_byte_buffer: Use a byte buffer for block blob uploads. Defaults to False. + :keyword int max_page_size: The maximum chunk size for uploading a page blob. Defaults to 4*1024*1024, or 4MB. + :keyword int max_single_get_size: The maximum size for a blob to be downloaded in a single call, + the exceeded part will be downloaded in chunks (could be parallel). Defaults to 32*1024*1024, or 32MB. + :keyword int max_chunk_get_size: The maximum chunk size used for downloading a blob. Defaults to 4*1024*1024, + or 4MB. :keyword str audience: The audience to use when requesting tokens for Azure Active Directory authentication. Only has an effect when credential is of type TokenCredential. The value could be https://storage.azure.com/ (default) or https://.blob.core.windows.net. @@ -244,7 +265,7 @@ def get_account_information(self, **kwargs: Any) -> Dict[str, str]: The keys in the returned dictionary include 'sku_name' and 'account_kind'. :return: A dict of account information (SKU and account type). - :rtype: dict(str, str) + :rtype: Dict[str, str] .. admonition:: Example: @@ -538,7 +559,7 @@ def create_container( :param metadata: A dict with name-value pairs to associate with the container as metadata. Example: `{'Category':'test'}` - :type metadata: dict(str, str) + :type metadata: Dict[str, str] :param public_access: Possible values include: 'container', 'blob'. :type public_access: str or ~azure.storage.blob.PublicAccess @@ -766,7 +787,7 @@ def get_blob_client( :param snapshot: The optional blob snapshot on which to operate. This can either be the ID of the snapshot, or a dictionary output returned by :func:`~azure.storage.blob.BlobClient.create_snapshot()`. - :type snapshot: str or dict(str, Any) + :type snapshot: str or Dict[str, Any] :keyword str version_id: The version id parameter is an opaque DateTime value that, when present, specifies the version of the blob to operate on. :return: A BlobClient. diff --git a/sdk/storage/azure-storage-blob/azure/storage/blob/_blob_service_client.pyi b/sdk/storage/azure-storage-blob/azure/storage/blob/_blob_service_client.pyi new file mode 100644 index 000000000000..b62993d9d889 --- /dev/null +++ b/sdk/storage/azure-storage-blob/azure/storage/blob/_blob_service_client.pyi @@ -0,0 +1,183 @@ +# ------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# -------------------------------------------------------------------------- +# pylint: skip-file + +from contextlib import AbstractContextManager +from datetime import datetime +from types import TracebackType +from typing import ( + Any, + Dict, + List, + Optional, + Union, +) +from typing_extensions import Self + +from azure.core import MatchConditions +from azure.core.credentials import AzureNamedKeyCredential, AzureSasCredential, TokenCredential +from azure.core.paging import ItemPaged +from azure.core.tracing.decorator import distributed_trace +from ._blob_client import BlobClient +from ._container_client import ContainerClient +from ._encryption import StorageEncryptionMixin +from ._lease import BlobLeaseClient +from ._models import ( + BlobAnalyticsLogging, + ContainerEncryptionScope, + ContainerProperties, + CorsRule, + FilteredBlob, + Metrics, + PublicAccess, + RetentionPolicy, + StaticWebsite, +) +from ._shared.base_client import StorageAccountHostsMixin +from ._shared.models import UserDelegationKey + +class BlobServiceClient(AbstractContextManager, StorageAccountHostsMixin, StorageEncryptionMixin): + def __init__( + self, + account_url: str, + credential: Optional[ + Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, TokenCredential] + ] = None, + *, + api_version: Optional[str] = None, + secondary_hostname: Optional[str] = None, + max_block_size: int = 4 * 1024 * 1024, + max_single_put_size: int = 64 * 1024 * 1024, + min_large_block_upload_threshold: int = 4 * 1024 * 1024 + 1, + use_byte_buffer: bool = False, + max_page_size: int = 4 * 1024 * 1024, + max_single_get_size: int = 32 * 1024 * 1024, + max_chunk_get_size: int = 4 * 1024 * 1024, + audience: Optional[str] = None, + **kwargs: Any + ) -> None: ... + def __enter__(self) -> "BlobServiceClient": ... + def __exit__( + self, typ: Optional[type[BaseException]], exc: Optional[BaseException], tb: Optional[TracebackType] + ) -> None: ... + def close(self) -> None: ... + @classmethod + def from_connection_string( + cls, + conn_str: str, + credential: Optional[ + Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, TokenCredential] + ] = None, + *, + api_version: Optional[str] = None, + secondary_hostname: Optional[str] = None, + max_block_size: int = 4 * 1024 * 1024, + max_single_put_size: int = 64 * 1024 * 1024, + min_large_block_upload_threshold: int = 4 * 1024 * 1024 + 1, + use_byte_buffer: bool = False, + max_page_size: int = 4 * 1024 * 1024, + max_single_get_size: int = 32 * 1024 * 1024, + max_chunk_get_size: int = 4 * 1024 * 1024, + audience: Optional[str] = None, + **kwargs: Any + ) -> "BlobServiceClient": ... + @distributed_trace + def get_user_delegation_key( + self, key_start_time: datetime, key_expiry_time: datetime, *, timeout: Optional[int] = None, **kwargs: Any + ) -> UserDelegationKey: ... + @distributed_trace + def get_account_information(self, **kwargs: Any) -> Dict[str, str]: ... + @distributed_trace + def get_service_stats(self, *, timeout: Optional[int] = None, **kwargs: Any) -> Dict[str, Any]: ... + @distributed_trace + def get_service_properties(self, *, timeout: Optional[int] = None, **kwargs: Any) -> Dict[str, Any]: ... + @distributed_trace + def set_service_properties( + self, + analytics_logging: Optional[BlobAnalyticsLogging] = None, + hour_metrics: Optional[Metrics] = None, + minute_metrics: Optional[Metrics] = None, + cors: Optional[List[CorsRule]] = None, + target_version: Optional[str] = None, + delete_retention_policy: Optional[RetentionPolicy] = None, + static_website: Optional[StaticWebsite] = None, + *, + timeout: Optional[int] = None, + **kwargs: Any + ) -> None: ... + @distributed_trace + def list_containers( + self, + name_starts_with: Optional[str] = None, + include_metadata: bool = False, + *, + include_deleted: Optional[bool] = None, + include_system: Optional[bool] = None, + results_per_page: Optional[int] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> ItemPaged[ContainerProperties]: ... + @distributed_trace + def find_blobs_by_tags( + self, + filter_expression: str, + *, + results_per_page: Optional[int] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> ItemPaged[FilteredBlob]: ... + @distributed_trace + def create_container( + self, + name: str, + metadata: Optional[Dict[str, str]] = None, + public_access: Optional[Union[PublicAccess, str]] = None, + *, + container_encryption_scope: Optional[Union[dict, ContainerEncryptionScope]] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> ContainerClient: ... + @distributed_trace + def delete_container( + self, + container: Union[ContainerProperties, str], + lease: Optional[Union[BlobLeaseClient, str]] = None, + *, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> None: ... + @distributed_trace + def _rename_container( + self, + name: str, + new_name: str, + *, + lease: Optional[Union[BlobLeaseClient, str]] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> ContainerClient: ... + @distributed_trace + def undelete_container( + self, + deleted_container_name: str, + deleted_container_version: str, + *, + timeout: Optional[int] = None, + **kwargs: Any + ) -> ContainerClient: ... + def get_container_client(self, container: Union[ContainerProperties, str]) -> ContainerClient: ... + def get_blob_client( + self, + container: Union[ContainerProperties, str], + blob: str, + snapshot: Optional[Union[Dict[str, Any], str]] = None, + *, + version_id: Optional[str] = None + ) -> BlobClient: ... diff --git a/sdk/storage/azure-storage-blob/azure/storage/blob/_container_client.py b/sdk/storage/azure-storage-blob/azure/storage/blob/_container_client.py index f524e541055a..08a3cc87eee3 100644 --- a/sdk/storage/azure-storage-blob/azure/storage/blob/_container_client.py +++ b/sdk/storage/azure-storage-blob/azure/storage/blob/_container_client.py @@ -7,13 +7,13 @@ import functools import warnings +from contextlib import AbstractContextManager from datetime import datetime from typing import ( Any, AnyStr, cast, Dict, List, IO, Iterable, Iterator, Optional, overload, Union, TYPE_CHECKING ) from urllib.parse import unquote, urlparse -from typing_extensions import Self from azure.core.exceptions import HttpResponseError, ResourceNotFoundError from azure.core.paging import ItemPaged @@ -66,7 +66,7 @@ ) -class ContainerClient(StorageAccountHostsMixin, StorageEncryptionMixin): # pylint: disable=too-many-public-methods +class ContainerClient(AbstractContextManager, StorageAccountHostsMixin, StorageEncryptionMixin): # pylint: disable=too-many-public-methods """A client to interact with a specific container, although that container may not yet exist. @@ -150,7 +150,7 @@ def __init__( self._client = self._build_generated_client() self._configure_encryption(kwargs) - def __enter__(self) -> Self: + def __enter__(self) -> "ContainerClient": self._client.__enter__() return self @@ -184,7 +184,7 @@ def from_container_url( cls, container_url: str, credential: Optional[Union[str, Dict[str, str], "AzureNamedKeyCredential", "AzureSasCredential", "TokenCredential"]] = None, # pylint: disable=line-too-long **kwargs: Any - ) -> Self: + ) -> "ContainerClient": """Create ContainerClient from a container url. :param str container_url: @@ -237,7 +237,7 @@ def from_connection_string( container_name: str, credential: Optional[Union[str, Dict[str, str], "AzureNamedKeyCredential", "AzureSasCredential", "TokenCredential"]] = None, # pylint: disable=line-too-long **kwargs: Any - ) -> Self: + ) -> "ContainerClient": """Create ContainerClient from a Connection String. :param str conn_str: diff --git a/sdk/storage/azure-storage-blob/azure/storage/blob/_container_client.pyi b/sdk/storage/azure-storage-blob/azure/storage/blob/_container_client.pyi new file mode 100644 index 000000000000..dc06cdca4e9d --- /dev/null +++ b/sdk/storage/azure-storage-blob/azure/storage/blob/_container_client.pyi @@ -0,0 +1,380 @@ +# ------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# -------------------------------------------------------------------------- +# pylint: skip-file + +from contextlib import AbstractContextManager +from datetime import datetime +from types import TracebackType +from typing import ( + Any, + AnyStr, + Callable, + Dict, + List, + IO, + Iterable, + Iterator, + Optional, + overload, + Union, +) + +from azure.core import MatchConditions +from azure.core.credentials import AzureNamedKeyCredential, AzureSasCredential, TokenCredential +from azure.core.paging import ItemPaged +from azure.core.pipeline.transport import HttpResponse +from azure.core.tracing.decorator import distributed_trace +from ._blob_client import BlobClient +from ._blob_service_client import BlobServiceClient +from ._download import StorageStreamDownloader +from ._encryption import StorageEncryptionMixin +from ._generated.models import RehydratePriority +from ._lease import BlobLeaseClient +from ._list_blobs_helper import BlobPrefix +from ._models import ( + AccessPolicy, + BlobProperties, + BlobType, + ContainerEncryptionScope, + ContainerProperties, + ContentSettings, + CustomerProvidedEncryptionKey, + FilteredBlob, + PremiumPageBlobTier, + PublicAccess, + StandardBlobTier, +) +from ._shared.base_client import StorageAccountHostsMixin + +class ContainerClient(StorageAccountHostsMixin, StorageEncryptionMixin): + account_name: str + container_name: str + def __init__( + self, + account_url: str, + container_name: str, + credential: Optional[ + Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, TokenCredential] + ] = None, + *, + api_version: Optional[str] = None, + secondary_hostname: Optional[str] = None, + audience: Optional[str] = None, + max_block_size: int = 4 * 1024 * 1024, + max_page_size: int = 4 * 1024 * 1024, + max_chunk_get_size: int = 4 * 1024 * 1024, + max_single_put_size: int = 64 * 1024 * 1024, + max_single_get_size: int = 32 * 1024 * 1024, + min_large_block_upload_threshold: int = 4 * 1024 * 1024 + 1, + use_byte_buffer: Optional[bool] = None, + **kwargs: Any, + ) -> None: ... + def __enter__(self) -> "ContainerClient": ... + def __exit__( + self, typ: Optional[type[BaseException]], exc: Optional[BaseException], tb: Optional[TracebackType] + ) -> None: ... + def close(self) -> None: ... + @classmethod + def from_container_url( + cls, + container_url: str, + credential: Optional[ + Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, TokenCredential] + ] = None, + *, + api_version: Optional[str] = None, + secondary_hostname: Optional[str] = None, + audience: Optional[str] = None, + max_block_size: int = 4 * 1024 * 1024, + max_page_size: int = 4 * 1024 * 1024, + max_chunk_get_size: int = 4 * 1024 * 1024, + max_single_put_size: int = 64 * 1024 * 1024, + max_single_get_size: int = 32 * 1024 * 1024, + min_large_block_upload_threshold: int = 4 * 1024 * 1024 + 1, + use_byte_buffer: Optional[bool] = None, + **kwargs: Any, + ) -> "ContainerClient": ... + @classmethod + def from_connection_string( + cls, + conn_str: str, + container_name: str, + credential: Optional[ + Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, TokenCredential] + ] = None, + *, + api_version: Optional[str] = None, + secondary_hostname: Optional[str] = None, + audience: Optional[str] = None, + max_block_size: int = 4 * 1024 * 1024, + max_page_size: int = 4 * 1024 * 1024, + max_chunk_get_size: int = 4 * 1024 * 1024, + max_single_put_size: int = 64 * 1024 * 1024, + max_single_get_size: int = 32 * 1024 * 1024, + min_large_block_upload_threshold: int = 4 * 1024 * 1024 + 1, + use_byte_buffer: Optional[bool] = None, + **kwargs: Any, + ) -> "ContainerClient": ... + @distributed_trace + def create_container( + self, + metadata: Optional[Dict[str, str]] = None, + public_access: Optional[Union[PublicAccess, str]] = None, + *, + container_encryption_scope: Optional[Union[Dict[str, Any], ContainerEncryptionScope]] = None, + timeout: Optional[int] = None, + **kwargs: Any, + ) -> Dict[str, Union[str, datetime]]: ... + @distributed_trace + def _rename_container( + self, + new_name: str, + *, + lease: Optional[Union[BlobLeaseClient, str]] = None, + timeout: Optional[int] = None, + **kwargs: Any, + ) -> "ContainerClient": ... + @distributed_trace + def delete_container( + self, + *, + lease: Optional[Union[BlobLeaseClient, str]] = None, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + timeout: Optional[int] = None, + **kwargs: Any, + ) -> None: ... + @distributed_trace + def acquire_lease( + self, + lease_duration: int = -1, + lease_id: Optional[str] = None, + *, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + timeout: Optional[int] = None, + **kwargs: Any, + ) -> BlobLeaseClient: ... + @distributed_trace + def get_account_information(self, **kwargs: Any) -> Dict[str, str]: ... + @distributed_trace + def get_container_properties( + self, *, lease: Optional[Union[BlobLeaseClient, str]] = None, timeout: Optional[int] = None, **kwargs: Any + ) -> ContainerProperties: ... + @distributed_trace + def exists(self, *, timeout: Optional[int] = None, **kwargs: Any) -> bool: ... + @distributed_trace + def set_container_metadata( + self, + metadata: Optional[Dict[str, str]] = None, + *, + lease: Optional[Union[BlobLeaseClient, str]] = None, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + timeout: Optional[int] = None, + **kwargs: Any, + ) -> Dict[str, Union[str, datetime]]: ... + @distributed_trace + def _get_blob_service_client(self) -> BlobServiceClient: ... + @distributed_trace + def get_container_access_policy( + self, *, lease: Optional[Union[BlobLeaseClient, str]] = None, timeout: Optional[int] = None, **kwargs: Any + ) -> Dict[str, Any]: ... + @distributed_trace + def set_container_access_policy( + self, + signed_identifiers: Dict[str, AccessPolicy], + public_access: Optional[Union[str, PublicAccess]] = None, + *, + lease: Optional[Union[BlobLeaseClient, str]] = None, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + timeout: Optional[int] = None, + **kwargs: Any, + ) -> Dict[str, Union[str, datetime]]: ... + @distributed_trace + def list_blobs( + self, + name_starts_with: Optional[str] = None, + include: Optional[Union[str, List[str]]] = None, + *, + timeout: Optional[int] = None, + **kwargs: Any, + ) -> ItemPaged[BlobProperties]: ... + @distributed_trace + def list_blob_names( + self, *, name_starts_with: Optional[str] = None, timeout: Optional[int] = None, **kwargs: Any + ) -> ItemPaged[str]: ... + @distributed_trace + def walk_blobs( + self, + name_starts_with: Optional[str] = None, + include: Optional[Union[List[str], str]] = None, + delimiter: str = "/", + *, + timeout: Optional[int] = None, + **kwargs: Any, + ) -> ItemPaged[Union[BlobProperties, BlobPrefix]]: ... + @distributed_trace + def find_blobs_by_tags( + self, + filter_expression: str, + *, + results_per_page: Optional[int] = None, + timeout: Optional[int] = None, + **kwargs: Any, + ) -> ItemPaged[FilteredBlob]: ... + @distributed_trace + def upload_blob( + self, + name: str, + data: Union[bytes, str, Iterable[AnyStr], IO[AnyStr]], + blob_type: Union[str, BlobType] = BlobType.BLOCKBLOB, + length: Optional[int] = None, + metadata: Optional[Dict[str, str]] = None, + *, + overwrite: Optional[bool] = None, + content_settings: Optional[ContentSettings] = None, + validate_content: Optional[bool] = None, + lease: Optional[Union[BlobLeaseClient, str]] = None, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + if_tags_match_condition: Optional[str] = None, + timeout: Optional[int] = None, + premium_page_blob_tier: Optional[PremiumPageBlobTier] = None, + standard_blob_tier: Optional[StandardBlobTier] = None, + maxsize_condition: Optional[int] = None, + max_concurrency: Optional[int] = None, + cpk: Optional[CustomerProvidedEncryptionKey] = None, + encryption_scope: Optional[str] = None, + encoding: Optional[str] = None, + progress_hook: Optional[Callable[[int, Optional[int]], None]] = None, + **kwargs: Any, + ) -> BlobClient: ... + @distributed_trace + def delete_blob( + self, + blob: str, + delete_snapshots: Optional[str] = None, + *, + version_id: Optional[str] = None, + lease: Optional[Union[BlobLeaseClient, str]] = None, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + if_tags_match_condition: Optional[str] = None, + timeout: Optional[int] = None, + **kwargs: Any, + ) -> None: ... + @overload + def download_blob( + self, + blob: str, + offset: Optional[int] = None, + length: Optional[int] = None, + *, + version_id: Optional[str] = None, + validate_content: Optional[bool] = None, + lease: Optional[Union[BlobLeaseClient, str]] = None, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + if_tags_match_condition: Optional[str] = None, + cpk: Optional[CustomerProvidedEncryptionKey] = None, + max_concurrency: Optional[int] = None, + encoding: str, + progress_hook: Optional[Callable[[int, int], None]] = None, + timeout: Optional[int] = None, + ) -> StorageStreamDownloader[str]: ... + @overload + def download_blob( + self, + blob: str, + offset: Optional[int] = None, + length: Optional[int] = None, + *, + version_id: Optional[str] = None, + validate_content: Optional[bool] = None, + lease: Optional[Union[BlobLeaseClient, str]] = None, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + if_tags_match_condition: Optional[str] = None, + cpk: Optional[CustomerProvidedEncryptionKey] = None, + max_concurrency: Optional[int] = None, + encoding: None = None, + progress_hook: Optional[Callable[[int, int], None]] = None, + timeout: Optional[int] = None, + **kwargs: Any, + ) -> StorageStreamDownloader[bytes]: ... + @distributed_trace # type: ignore[misc] + def download_blob( + self, + blob: str, + offset: Optional[int] = None, + length: Optional[int] = None, + *, + version_id: Optional[str] = None, + validate_content: Optional[bool] = None, + lease: Optional[Union[BlobLeaseClient, str]] = None, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + if_tags_match_condition: Optional[str] = None, + cpk: Optional[CustomerProvidedEncryptionKey] = None, + max_concurrency: Optional[int] = None, + encoding: Optional[str] = None, + progress_hook: Optional[Callable[[int, int], None]] = None, + timeout: Optional[int] = None, + **kwargs: Any, + ) -> Union[StorageStreamDownloader[str], StorageStreamDownloader[bytes]]: ... + @distributed_trace + def delete_blobs( + self, + *blobs: Union[str, Dict[str, Any], BlobProperties], + delete_snapshots: Optional[str] = None, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + if_tags_match_condition: Optional[str] = None, + raise_on_any_failure: bool = True, + timeout: Optional[int] = None, + **kwargs: Any, + ) -> Iterator[HttpResponse]: ... + @distributed_trace + def set_standard_blob_tier_blobs( + self, + standard_blob_tier: Optional[Union[str, StandardBlobTier]], + *blobs: Union[str, Dict[str, Any], BlobProperties], + rehydrate_priority: Optional[RehydratePriority] = None, + if_tags_match_condition: Optional[str] = None, + raise_on_any_failure: bool = True, + timeout: Optional[int] = None, + **kwargs: Any, + ) -> Iterator[HttpResponse]: ... + @distributed_trace + def set_premium_page_blob_tier_blobs( + self, + premium_page_blob_tier: Optional[Union[str, PremiumPageBlobTier]], + *blobs: Union[str, Dict[str, Any], BlobProperties], + raise_on_any_failure: bool = True, + timeout: Optional[int] = None, + **kwargs: Any, + ) -> Iterator[HttpResponse]: ... + def get_blob_client( + self, blob: str, snapshot: Optional[str] = None, *, version_id: Optional[str] = None + ) -> BlobClient: ... diff --git a/sdk/storage/azure-storage-blob/azure/storage/blob/_lease.py b/sdk/storage/azure-storage-blob/azure/storage/blob/_lease.py index 19bd7179c09a..bd9d4508681b 100644 --- a/sdk/storage/azure-storage-blob/azure/storage/blob/_lease.py +++ b/sdk/storage/azure-storage-blob/azure/storage/blob/_lease.py @@ -20,7 +20,7 @@ from datetime import datetime -class BlobLeaseClient(): # pylint: disable=client-accepts-api-version-keyword +class BlobLeaseClient: # pylint: disable=client-accepts-api-version-keyword """Creates a new BlobLeaseClient. This client provides lease operations on a BlobClient or ContainerClient. @@ -41,7 +41,7 @@ class BlobLeaseClient(): # pylint: disable=client-accepts-api-version-keyword """The last modified timestamp of the lease currently being maintained. This will be `None` if no lease has yet been acquired or modified.""" - def __init__( # pylint: disable=missing-client-constructor-parameter-credential, missing-client-constructor-parameter-kwargs + def __init__( # pylint: disable=missing-client-constructor-parameter-credential, missing-client-constructor-parameter-kwargs self, client: Union["BlobClient", "ContainerClient"], lease_id: Optional[str] = None ) -> None: diff --git a/sdk/storage/azure-storage-blob/azure/storage/blob/_lease.pyi b/sdk/storage/azure-storage-blob/azure/storage/blob/_lease.pyi new file mode 100644 index 000000000000..24771b003b4e --- /dev/null +++ b/sdk/storage/azure-storage-blob/azure/storage/blob/_lease.pyi @@ -0,0 +1,78 @@ +# ------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# -------------------------------------------------------------------------- +# pylint: skip-file + +from datetime import datetime +from typing import Any, Optional, Union + +from azure.core import MatchConditions +from azure.core.tracing.decorator import distributed_trace +from ._blob_client import BlobClient +from ._container_client import ContainerClient + +class BlobLeaseClient: + def __init__(self, client: Union[BlobClient, ContainerClient], lease_id: Optional[str] = None) -> None: ... + @distributed_trace + def acquire( + self, + lease_duration: int = -1, + *, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + if_tags_match_condition: Optional[str] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> None: ... + @distributed_trace + def renew( + self, + *, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + if_tags_match_condition: Optional[str] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> None: ... + @distributed_trace + def release( + self, + *, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + if_tags_match_condition: Optional[str] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> None: ... + @distributed_trace + def change( + self, + proposed_lease_id: str, + *, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + if_tags_match_condition: Optional[str] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> None: ... + @distributed_trace + def break_lease( + self, + lease_break_period: Optional[int] = None, + *, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + if_tags_match_condition: Optional[str] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> int: ... diff --git a/sdk/storage/azure-storage-blob/azure/storage/blob/aio/__init__.py b/sdk/storage/azure-storage-blob/azure/storage/blob/aio/__init__.py index 09f8adb73a9a..5c12ee1fbb1c 100644 --- a/sdk/storage/azure-storage-blob/azure/storage/blob/aio/__init__.py +++ b/sdk/storage/azure-storage-blob/azure/storage/blob/aio/__init__.py @@ -7,7 +7,7 @@ import os -from typing import Any, AnyStr, Dict, cast, IO, Iterable, Optional, Union, TYPE_CHECKING +from typing import Any, AnyStr, Dict, IO, Iterable, Optional, Union, TYPE_CHECKING from ._list_blobs_helper import BlobPrefix from .._models import BlobType from .._shared.policies_async import ExponentialRetry, LinearRetry @@ -77,10 +77,7 @@ async def upload_blob_to_url( :rtype: dict[str, Any] """ async with BlobClient.from_blob_url(blob_url, credential=credential) as client: - return await cast(BlobClient, client).upload_blob( - data=data, - blob_type=BlobType.BLOCKBLOB, - **kwargs) + return await client.upload_blob(data=data, blob_type=BlobType.BLOCKBLOB, **kwargs) # Download data to specified open file-handle. @@ -92,7 +89,7 @@ async def _download_to_stream(client, handle, **kwargs): async def download_blob_from_url( blob_url: str, output: str, - credential: Optional[Union[str, Dict[str, str], "AzureNamedKeyCredential", "AzureSasCredential", "AsyncTokenCredential"]] = None, # pylint: disable=line-too-long + credential: Optional[Union[str, Dict[str, str], "AzureNamedKeyCredential", "AzureSasCredential", "AsyncTokenCredential"]] = None, # pylint: disable=line-too-long **kwargs: Any ) -> None: """Download the contents of a blob to a local file or stream. diff --git a/sdk/storage/azure-storage-blob/azure/storage/blob/aio/_blob_client_async.py b/sdk/storage/azure-storage-blob/azure/storage/blob/aio/_blob_client_async.py index 9338084a84db..439a55cdba64 100644 --- a/sdk/storage/azure-storage-blob/azure/storage/blob/aio/_blob_client_async.py +++ b/sdk/storage/azure-storage-blob/azure/storage/blob/aio/_blob_client_async.py @@ -6,14 +6,14 @@ # pylint: disable=too-many-lines, docstring-keyword-should-match-keyword-only import warnings +from contextlib import AbstractAsyncContextManager from datetime import datetime from functools import partial from typing import ( Any, AnyStr, AsyncIterable, Callable, cast, Dict, IO, - Iterable, List, Optional, overload, Tuple, Union, + Iterable, List, Optional, Tuple, Union, TYPE_CHECKING ) -from typing_extensions import Self from azure.core.async_paging import AsyncItemPaged from azure.core.exceptions import ResourceNotFoundError, HttpResponseError, ResourceExistsError @@ -30,7 +30,6 @@ upload_block_blob, upload_page_blob ) -from .._blob_client import StorageAccountHostsMixin from .._blob_client_helpers import ( _abort_copy_options, _append_block_from_url_options, @@ -74,6 +73,7 @@ from .._generated.models import CpkInfo from .._models import BlobType, BlobBlock, BlobProperties, BlobQueryError, PageRange from .._serialize import get_access_conditions, get_api_version, get_modify_conditions, get_version_id +from .._shared.base_client import StorageAccountHostsMixin from .._shared.base_client_async import AsyncStorageAccountHostsMixin, AsyncTransportWrapper, parse_connection_str from .._shared.policies_async import ExponentialRetry from .._shared.response_handlers import process_storage_error, return_response_headers @@ -98,7 +98,12 @@ ) -class BlobClient(AsyncStorageAccountHostsMixin, StorageAccountHostsMixin, StorageEncryptionMixin): # type: ignore [misc] # pylint: disable=too-many-public-methods +class BlobClient( # type: ignore [misc] # pylint: disable=too-many-public-methods + AbstractAsyncContextManager, + AsyncStorageAccountHostsMixin, + StorageAccountHostsMixin, + StorageEncryptionMixin +): """A client to interact with a specific blob, although that blob may not yet exist. :param str account_url: @@ -165,12 +170,12 @@ class BlobClient(AsyncStorageAccountHostsMixin, StorageAccountHostsMixin, Storag :caption: Creating the BlobClient from a SAS URL to a blob. """ def __init__( - self, account_url: str, - container_name: str, - blob_name: str, - snapshot: Optional[Union[str, Dict[str, Any]]] = None, - credential: Optional[Union[str, Dict[str, str], "AzureNamedKeyCredential", "AzureSasCredential", "AsyncTokenCredential"]] = None, # pylint: disable=line-too-long - **kwargs: Any + self, account_url: str, + container_name: str, + blob_name: str, + snapshot: Optional[Union[str, Dict[str, Any]]] = None, + credential: Optional[Union[str, Dict[str, str], "AzureNamedKeyCredential", "AzureSasCredential", "AsyncTokenCredential"]] = None, # pylint: disable=line-too-long + **kwargs: Any ) -> None: kwargs['retry_policy'] = kwargs.get('retry_policy') or ExponentialRetry(**kwargs) parsed_url, sas_token, path_snapshot = _parse_url( @@ -196,7 +201,7 @@ def __init__( self._client._config.version = get_api_version(kwargs) # type: ignore [assignment] self._configure_encryption(kwargs) - async def __aenter__(self) -> Self: + async def __aenter__(self) -> "BlobClient": await self._client.__aenter__() return self @@ -227,7 +232,7 @@ def from_blob_url( credential: Optional[Union[str, Dict[str, str], "AzureNamedKeyCredential", "AzureSasCredential", "AsyncTokenCredential"]] = None, # pylint: disable=line-too-long snapshot: Optional[Union[str, Dict[str, Any]]] = None, **kwargs: Any - ) -> Self: + ) -> "BlobClient": """Create BlobClient from a blob url. This doesn't support customized blob url with '/' in blob name. :param str blob_url: @@ -275,7 +280,7 @@ def from_connection_string( snapshot: Optional[Union[str, Dict[str, Any]]] = None, credential: Optional[Union[str, Dict[str, str], "AzureNamedKeyCredential", "AzureSasCredential", "AsyncTokenCredential"]] = None, # pylint: disable=line-too-long **kwargs: Any - ) -> Self: + ) -> "BlobClient": """Create BlobClient from a Connection String. :param str conn_str: @@ -642,26 +647,6 @@ async def upload_blob( return cast(Dict[str, Any], await upload_page_blob(**options)) return cast(Dict[str, Any], await upload_append_blob(**options)) - @overload - async def download_blob( - self, offset: Optional[int] = None, - length: Optional[int] = None, - *, - encoding: str, - **kwargs: Any - ) -> StorageStreamDownloader[str]: - ... - - @overload - async def download_blob( - self, offset: Optional[int] = None, - length: Optional[int] = None, - *, - encoding: None = None, - **kwargs: Any - ) -> StorageStreamDownloader[bytes]: - ... - @distributed_trace_async async def download_blob( self, offset: Optional[int] = None, diff --git a/sdk/storage/azure-storage-blob/azure/storage/blob/aio/_blob_client_async.pyi b/sdk/storage/azure-storage-blob/azure/storage/blob/aio/_blob_client_async.pyi new file mode 100644 index 000000000000..6ebbdcd07a68 --- /dev/null +++ b/sdk/storage/azure-storage-blob/azure/storage/blob/aio/_blob_client_async.pyi @@ -0,0 +1,764 @@ +# ------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# -------------------------------------------------------------------------- +# pylint: skip-file + +from contextlib import AbstractAsyncContextManager +from datetime import datetime +from types import TracebackType +from typing import ( + Any, + AnyStr, + AsyncIterable, + Awaitable, + Callable, + Dict, + IO, + Iterable, + List, + Literal, + Optional, + overload, + Tuple, + Union, +) + +from azure.core import MatchConditions +from azure.core.credentials import AzureNamedKeyCredential, AzureSasCredential +from azure.core.credentials_async import AsyncTokenCredential +from azure.core.async_paging import AsyncItemPaged +from azure.core.tracing.decorator import distributed_trace +from azure.core.tracing.decorator_async import distributed_trace_async +from ._container_client_async import ContainerClient +from ._download_async import StorageStreamDownloader +from ._lease_async import BlobLeaseClient +from .._encryption import StorageEncryptionMixin +from .._generated.models import RehydratePriority +from .._models import ( + BlobType, + BlobBlock, + BlobProperties, + ContentSettings, + CustomerProvidedEncryptionKey, + ImmutabilityPolicy, + PageRange, + PremiumPageBlobTier, + SequenceNumberAction, + StandardBlobTier, +) +from .._shared.base_client import StorageAccountHostsMixin +from .._shared.base_client_async import AsyncStorageAccountHostsMixin + +class BlobClient( # type: ignore[misc] + AbstractAsyncContextManager, + AsyncStorageAccountHostsMixin, + StorageAccountHostsMixin, + StorageEncryptionMixin, +): + def __init__( + self, + account_url: str, + container_name: str, + blob_name: str, + snapshot: Optional[Union[str, Dict[str, Any]]] = None, + credential: Optional[ + Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, AsyncTokenCredential] + ] = None, + *, + api_version: Optional[str] = None, + secondary_hostname: Optional[str] = None, + version_id: Optional[str] = None, + audience: Optional[str] = None, + max_block_size: int = 4 * 1024 * 1024, + max_page_size: int = 4 * 1024 * 1024, + max_chunk_get_size: int = 4 * 1024 * 1024, + max_single_put_size: int = 64 * 1024 * 1024, + max_single_get_size: int = 32 * 1024 * 1024, + min_large_block_upload_threshold: int = 4 * 1024 * 1024 + 1, + use_byte_buffer: Optional[bool] = None, + **kwargs: Any + ) -> None: ... + async def __aenter__(self) -> "BlobClient": ... + async def __aexit__( + self, typ: Optional[type[BaseException]], exc: Optional[BaseException], tb: Optional[TracebackType] + ) -> None: ... + async def close(self) -> None: ... + @classmethod + def from_blob_url( + cls, + blob_url: str, + credential: Optional[ + Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, AsyncTokenCredential] + ] = None, + snapshot: Optional[Union[str, Dict[str, Any]]] = None, + *, + api_version: Optional[str] = None, + secondary_hostname: Optional[str] = None, + version_id: Optional[str] = None, + audience: Optional[str] = None, + max_block_size: int = 4 * 1024 * 1024, + max_page_size: int = 4 * 1024 * 1024, + max_chunk_get_size: int = 4 * 1024 * 1024, + max_single_put_size: int = 64 * 1024 * 1024, + max_single_get_size: int = 32 * 1024 * 1024, + min_large_block_upload_threshold: int = 4 * 1024 * 1024 + 1, + use_byte_buffer: Optional[bool] = None, + **kwargs: Any + ) -> "BlobClient": ... + @classmethod + def from_connection_string( + cls, + conn_str: str, + container_name: str, + blob_name: str, + snapshot: Optional[Union[str, Dict[str, Any]]] = None, + credential: Optional[ + Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, AsyncTokenCredential] + ] = None, + *, + api_version: Optional[str] = None, + secondary_hostname: Optional[str] = None, + version_id: Optional[str] = None, + audience: Optional[str] = None, + max_block_size: int = 4 * 1024 * 1024, + max_page_size: int = 4 * 1024 * 1024, + max_chunk_get_size: int = 4 * 1024 * 1024, + max_single_put_size: int = 64 * 1024 * 1024, + max_single_get_size: int = 32 * 1024 * 1024, + min_large_block_upload_threshold: int = 4 * 1024 * 1024 + 1, + use_byte_buffer: Optional[bool] = None, + **kwargs: Any + ) -> "BlobClient": ... + @distributed_trace_async + async def get_account_information(self, **kwargs: Any) -> Dict[str, str]: ... + @distributed_trace_async + async def upload_blob_from_url( + self, + source_url: str, + *, + metadata: Optional[Dict[str, str]] = None, + overwrite: Optional[bool] = None, + include_source_blob_properties: bool = True, + tags: Optional[Dict[str, str]] = None, + source_content_md5: Optional[bytearray] = None, + source_if_modified_since: Optional[datetime] = None, + source_if_unmodified_since: Optional[datetime] = None, + source_etag: Optional[str] = None, + source_match_condition: Optional[MatchConditions] = None, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + destination_lease: Optional[Union[BlobLeaseClient, str]] = None, + timeout: Optional[int] = None, + content_settings: Optional[ContentSettings] = None, + cpk: Optional[CustomerProvidedEncryptionKey] = None, + encryption_scope: Optional[str] = None, + standard_blob_tier: Optional[StandardBlobTier] = None, + source_authorization: Optional[str] = None, + source_token_intent: Optional[Literal["backup"]] = None, + **kwargs: Any + ) -> Dict[str, Any]: ... + @distributed_trace_async + async def upload_blob( + self, + data: Union[bytes, str, Iterable[AnyStr], AsyncIterable[AnyStr], IO[bytes]], + blob_type: Union[str, BlobType] = BlobType.BLOCKBLOB, + length: Optional[int] = None, + metadata: Optional[Dict[str, str]] = None, + tags: Optional[Dict[str, str]] = None, + overwrite: bool = False, + content_settings: Optional[ContentSettings] = None, + validate_content: bool = False, + lease: Optional[BlobLeaseClient] = None, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_conditions: Optional[MatchConditions] = None, + if_tags_match_condition: Optional[str] = None, + premium_page_blob_tier: Optional[PremiumPageBlobTier] = None, + immutability_policy: Optional[ImmutabilityPolicy] = None, + legal_hold: Optional[bool] = None, + standard_blob_tier: Optional[StandardBlobTier] = None, + maxsize_condition: Optional[int] = None, + max_concurrency: int = 1, + cpk: Optional[CustomerProvidedEncryptionKey] = None, + encryption_scope: Optional[str] = None, + encoding: str = "UTF-8", + progress_hook: Optional[Callable[[int, Optional[int]], Awaitable[None]]] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> Dict[str, Any]: ... + @overload + async def download_blob( + self, + offset: Optional[int] = None, + length: Optional[int] = None, + *, + version_id: Optional[str] = None, + validate_content: bool = False, + lease: Optional[Union[BlobLeaseClient, str]] = None, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + if_tags_match_condition: Optional[str] = None, + cpk: Optional[CustomerProvidedEncryptionKey] = None, + max_concurrency: int = 1, + encoding: str, + progress_hook: Optional[Callable[[int, int], Awaitable[None]]] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> StorageStreamDownloader[str]: ... + @overload + async def download_blob( + self, + offset: Optional[int] = None, + length: Optional[int] = None, + *, + version_id: Optional[str] = None, + validate_content: bool = False, + lease: Optional[Union[BlobLeaseClient, str]] = None, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + if_tags_match_condition: Optional[str] = None, + cpk: Optional[CustomerProvidedEncryptionKey] = None, + max_concurrency: int = 1, + encoding: None = None, + progress_hook: Optional[Callable[[int, int], Awaitable[None]]] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> StorageStreamDownloader[bytes]: ... + @distributed_trace_async # type: ignore[misc] + async def download_blob( + self, + offset: Optional[int] = None, + length: Optional[int] = None, + *, + version_id: Optional[str] = None, + validate_content: bool = False, + lease: Optional[Union[BlobLeaseClient, str]] = None, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + if_tags_match_condition: Optional[str] = None, + cpk: Optional[CustomerProvidedEncryptionKey] = None, + max_concurrency: int = 1, + encoding: Optional[str] = None, + progress_hook: Optional[Callable[[int, int], Awaitable[None]]] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> Union[StorageStreamDownloader[str], StorageStreamDownloader[bytes]]: ... + @distributed_trace_async + async def delete_blob( + self, + delete_snapshots: Optional[str] = None, + *, + version_id: Optional[str] = None, + lease: Optional[Union[BlobLeaseClient, str]] = None, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + if_tags_match_condition: Optional[str] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> None: ... + @distributed_trace_async + async def undelete_blob(self, *, timeout: Optional[int] = None, **kwargs: Any) -> None: ... + @distributed_trace_async + async def exists( + self, *, version_id: Optional[str] = None, timeout: Optional[int] = None, **kwargs: Any + ) -> bool: ... + @distributed_trace_async + async def get_blob_properties( + self, + *, + lease: Optional[Union[BlobLeaseClient, str]] = None, + version_id: Optional[str] = None, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + if_tags_match_condition: Optional[str] = None, + cpk: Optional[CustomerProvidedEncryptionKey] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> BlobProperties: ... + @distributed_trace_async + async def set_http_headers( + self, + content_settings: Optional[ContentSettings] = None, + *, + lease: Optional[Union[BlobLeaseClient, str]] = None, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + if_tags_match_condition: Optional[str] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> Dict[str, Any]: ... + @distributed_trace_async + async def set_blob_metadata( + self, + metadata: Optional[Dict[str, str]] = None, + *, + lease: Optional[Union[BlobLeaseClient, str]] = None, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + if_tags_match_condition: Optional[str] = None, + cpk: Optional[CustomerProvidedEncryptionKey] = None, + encryption_scope: Optional[str] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> Dict[str, Union[str, datetime]]: ... + @distributed_trace_async + async def set_immutability_policy( + self, + immutability_policy: ImmutabilityPolicy, + *, + version_id: Optional[str] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> Dict[str, str]: ... + @distributed_trace_async + async def delete_immutability_policy( + self, *, version_id: Optional[str] = None, timeout: Optional[int] = None, **kwargs: Any + ) -> None: ... + @distributed_trace_async + async def set_legal_hold( + self, legal_hold: bool, *, version_id: Optional[str] = None, timeout: Optional[int] = None, **kwargs: Any + ) -> Dict[str, Union[str, datetime, bool]]: ... + @distributed_trace_async + async def create_page_blob( + self, + size: int, + content_settings: Optional[ContentSettings] = None, + metadata: Optional[Dict[str, str]] = None, + premium_page_blob_tier: Optional[Union[str, PremiumPageBlobTier]] = None, + *, + tags: Optional[Dict[str, str]] = None, + sequence_number: Optional[int] = None, + lease: Optional[Union[BlobLeaseClient, str]] = None, + immutability_policy: Optional[ImmutabilityPolicy] = None, + legal_hold: Optional[bool] = None, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + cpk: Optional[CustomerProvidedEncryptionKey] = None, + encryption_scope: Optional[str] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> Dict[str, Union[str, datetime]]: ... + @distributed_trace_async + async def create_append_blob( + self, + content_settings: Optional[ContentSettings] = None, + metadata: Optional[Dict[str, str]] = None, + *, + tags: Optional[Dict[str, str]] = None, + immutability_policy: Optional[ImmutabilityPolicy] = None, + legal_hold: Optional[bool] = None, + lease: Optional[Union[BlobLeaseClient, str]] = None, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + cpk: Optional[CustomerProvidedEncryptionKey] = None, + encryption_scope: Optional[str] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> Dict[str, Union[str, datetime]]: ... + @distributed_trace_async + async def create_snapshot( + self, + metadata: Optional[Dict[str, str]] = None, + *, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + if_tags_match_condition: Optional[str] = None, + lease: Optional[Union[BlobLeaseClient, str]] = None, + cpk: Optional[CustomerProvidedEncryptionKey] = None, + encryption_scope: Optional[str] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> Dict[str, Union[str, datetime]]: ... + @distributed_trace_async + async def start_copy_from_url( + self, + source_url: str, + metadata: Optional[Dict[str, str]] = None, + incremental_copy: bool = False, + *, + tags: Optional[Union[Dict[str, str], Literal["COPY"]]] = None, + immutability_policy: Optional[ImmutabilityPolicy] = None, + legal_hold: Optional[bool] = None, + source_if_modified_since: Optional[datetime] = None, + source_if_unmodified_since: Optional[datetime] = None, + source_etag: Optional[str] = None, + source_match_condition: Optional[MatchConditions] = None, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + if_tags_match_condition: Optional[str] = None, + destination_lease: Optional[Union[BlobLeaseClient, str]] = None, + source_lease: Optional[Union[BlobLeaseClient, str]] = None, + premium_page_blob_tier: Optional[PremiumPageBlobTier] = None, + standard_blob_tier: Optional[StandardBlobTier] = None, + rehydrate_priority: Optional[RehydratePriority] = None, + seal_destination_blob: Optional[bool] = None, + requires_sync: Optional[bool] = None, + source_authorization: Optional[str] = None, + source_token_intent: Optional[Literal["backup"]] = None, + encryption_scope: Optional[str] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> Dict[str, Union[str, datetime]]: ... + @distributed_trace_async + async def abort_copy(self, copy_id: Union[str, Dict[str, Any], BlobProperties], **kwargs: Any) -> None: ... + @distributed_trace_async + async def acquire_lease( + self, + lease_duration: int = -1, + lease_id: Optional[str] = None, + *, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + if_tags_match_condition: Optional[str] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> BlobLeaseClient: ... + @distributed_trace_async + async def set_standard_blob_tier( + self, + standard_blob_tier: Union[str, StandardBlobTier], + *, + rehydrate_priority: Optional[RehydratePriority] = None, + version_id: Optional[str] = None, + if_tags_match_condition: Optional[str] = None, + lease: Optional[Union[BlobLeaseClient, str]] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> None: ... + @distributed_trace_async + async def stage_block( + self, + block_id: str, + data: Union[bytes, str, Iterable[AnyStr], IO[AnyStr]], + length: Optional[int] = None, + *, + validate_content: Optional[bool] = None, + lease: Optional[Union[BlobLeaseClient, str]] = None, + encoding: Optional[str] = None, + cpk: Optional[CustomerProvidedEncryptionKey] = None, + encryption_scope: Optional[str] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> Dict[str, Any]: ... + @distributed_trace_async + async def stage_block_from_url( + self, + block_id: str, + source_url: str, + source_offset: Optional[int] = None, + source_length: Optional[int] = None, + source_content_md5: Optional[Union[bytes, bytearray]] = None, + *, + lease: Optional[Union[BlobLeaseClient, str]] = None, + cpk: Optional[CustomerProvidedEncryptionKey] = None, + encryption_scope: Optional[str] = None, + source_authorization: Optional[str] = None, + source_token_intent: Optional[Literal["backup"]] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> Dict[str, Any]: ... + @distributed_trace_async + async def get_block_list( + self, + block_list_type: str = "committed", + *, + lease: Optional[Union[BlobLeaseClient, str]] = None, + if_tags_match_condition: Optional[str] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> Tuple[List[BlobBlock], List[BlobBlock]]: ... + @distributed_trace_async + async def commit_block_list( + self, + block_list: List[BlobBlock], + content_settings: Optional[ContentSettings] = None, + metadata: Optional[Dict[str, str]] = None, + *, + tags: Optional[Dict[str, str]] = None, + lease: Optional[Union[BlobLeaseClient, str]] = None, + immutability_policy: Optional[ImmutabilityPolicy] = None, + legal_hold: Optional[bool] = None, + validate_content: Optional[bool] = None, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + if_tags_match_condition: Optional[str] = None, + standard_blob_tier: Optional[StandardBlobTier] = None, + cpk: Optional[CustomerProvidedEncryptionKey] = None, + encryption_scope: Optional[str] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> Dict[str, Union[str, datetime]]: ... + @distributed_trace_async + async def set_premium_page_blob_tier( + self, + premium_page_blob_tier: PremiumPageBlobTier, + *, + if_tags_match_condition: Optional[str] = None, + lease: Optional[Union[BlobLeaseClient, str]] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> None: ... + @distributed_trace_async + async def set_blob_tags( + self, + tags: Optional[Dict[str, str]] = None, + *, + version_id: Optional[str] = None, + validate_content: Optional[bool] = None, + if_tags_match_condition: Optional[str] = None, + lease: Optional[Union[BlobLeaseClient, str]] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> Dict[str, Any]: ... + @distributed_trace_async + async def get_blob_tags( + self, + *, + version_id: Optional[str] = None, + if_tags_match_condition: Optional[str] = None, + lease: Optional[Union[BlobLeaseClient, str]] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> Dict[str, str]: ... + @distributed_trace_async + async def get_page_ranges( + self, + offset: Optional[int] = None, + length: Optional[int] = None, + previous_snapshot_diff: Optional[Union[str, Dict[str, Any]]] = None, + *, + lease: Optional[Union[BlobLeaseClient, str]] = None, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + if_tags_match_condition: Optional[str] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> Tuple[List[Dict[str, int]], List[Dict[str, int]]]: ... + @distributed_trace + def list_page_ranges( + self, + *, + offset: Optional[int] = None, + length: Optional[int] = None, + previous_snapshot: Optional[Union[str, Dict[str, Any]]] = None, + lease: Optional[Union[BlobLeaseClient, str]] = None, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + if_tags_match_condition: Optional[str] = None, + results_per_page: Optional[int] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> AsyncItemPaged[PageRange]: ... + @distributed_trace_async + async def get_page_range_diff_for_managed_disk( + self, + previous_snapshot_url: str, + offset: Optional[int] = None, + length: Optional[int] = None, + *, + lease: Optional[Union[BlobLeaseClient, str]] = None, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> Tuple[List[Dict[str, int]], List[Dict[str, int]]]: ... + @distributed_trace_async + async def set_sequence_number( + self, + sequence_number_action: Union[str, SequenceNumberAction], + sequence_number: Optional[str] = None, + *, + lease: Optional[Union[BlobLeaseClient, str]] = None, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + if_tags_match_condition: Optional[str] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> Dict[str, Union[str, datetime]]: ... + @distributed_trace_async + async def resize_blob( + self, + size: int, + *, + lease: Optional[Union[BlobLeaseClient, str]] = None, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + if_tags_match_condition: Optional[str] = None, + premium_page_blob_tier: Optional[PremiumPageBlobTier] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> Dict[str, Union[str, datetime]]: ... + @distributed_trace_async + async def upload_page( + self, + page: bytes, + offset: int, + length: int, + *, + lease: Optional[Union[BlobLeaseClient, str]] = None, + validate_content: Optional[bool] = None, + if_sequence_number_lte: Optional[int] = None, + if_sequence_number_lt: Optional[int] = None, + if_sequence_number_eq: Optional[int] = None, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + if_tags_match_condition: Optional[str] = None, + cpk: Optional[CustomerProvidedEncryptionKey] = None, + encryption_scope: Optional[str] = None, + encoding: Optional[str] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> Dict[str, Union[str, datetime]]: ... + @distributed_trace_async + async def upload_pages_from_url( + self, + source_url: str, + offset: int, + length: int, + source_offset: int, + *, + source_content_md5: Optional[bytes] = None, + source_if_modified_since: Optional[datetime] = None, + source_if_unmodified_since: Optional[datetime] = None, + source_etag: Optional[str] = None, + source_match_condition: Optional[MatchConditions] = None, + lease: Optional[Union[BlobLeaseClient, str]] = None, + if_sequence_number_lte: Optional[int] = None, + if_sequence_number_lt: Optional[int] = None, + if_sequence_number_eq: Optional[int] = None, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + if_tags_match_condition: Optional[str] = None, + cpk: Optional[CustomerProvidedEncryptionKey] = None, + encryption_scope: Optional[str] = None, + source_authorization: Optional[str] = None, + source_token_intent: Optional[Literal["backup"]] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> Dict[str, Any]: ... + @distributed_trace_async + async def clear_page( + self, + offset: int, + length: int, + *, + lease: Optional[Union[BlobLeaseClient, str]] = None, + if_sequence_number_lte: Optional[int] = None, + if_sequence_number_lt: Optional[int] = None, + if_sequence_number_eq: Optional[int] = None, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + if_tags_match_condition: Optional[str] = None, + cpk: Optional[CustomerProvidedEncryptionKey] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> Dict[str, Union[str, datetime]]: ... + @distributed_trace_async + async def append_block( + self, + data: Union[bytes, str, Iterable[AnyStr], IO[AnyStr]], + length: Optional[int] = None, + *, + validate_content: Optional[bool] = None, + maxsize_condition: Optional[int] = None, + appendpos_condition: Optional[int] = None, + lease: Optional[Union[BlobLeaseClient, str]] = None, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + if_tags_match_condition: Optional[str] = None, + encoding: Optional[str] = None, + cpk: Optional[CustomerProvidedEncryptionKey] = None, + encryption_scope: Optional[str] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> Dict[str, Union[str, datetime, int]]: ... + @distributed_trace_async + async def append_block_from_url( + self, + copy_source_url: str, + source_offset: Optional[int] = None, + source_length: Optional[int] = None, + *, + source_content_md5: Optional[bytearray] = None, + maxsize_condition: Optional[int] = None, + appendpos_condition: Optional[int] = None, + lease: Optional[Union[BlobLeaseClient, str]] = None, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + if_tags_match_condition: Optional[str] = None, + source_if_modified_since: Optional[datetime] = None, + source_if_unmodified_since: Optional[datetime] = None, + source_etag: Optional[str] = None, + source_match_condition: Optional[MatchConditions] = None, + cpk: Optional[CustomerProvidedEncryptionKey] = None, + encryption_scope: Optional[str] = None, + source_authorization: Optional[str] = None, + source_token_intent: Optional[Literal["backup"]] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> Dict[str, Union[str, datetime, int]]: ... + @distributed_trace_async + async def seal_append_blob( + self, + *, + appendpos_condition: Optional[int] = None, + lease: Optional[Union[BlobLeaseClient, str]] = None, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> Dict[str, Union[str, datetime, int]]: ... + def _get_container_client(self) -> ContainerClient: ... diff --git a/sdk/storage/azure-storage-blob/azure/storage/blob/aio/_blob_service_client_async.py b/sdk/storage/azure-storage-blob/azure/storage/blob/aio/_blob_service_client_async.py index b28e482bcaf2..8691d89b5d78 100644 --- a/sdk/storage/azure-storage-blob/azure/storage/blob/aio/_blob_service_client_async.py +++ b/sdk/storage/azure-storage-blob/azure/storage/blob/aio/_blob_service_client_async.py @@ -7,11 +7,11 @@ import functools import warnings +from contextlib import AbstractAsyncContextManager from typing import ( Any, cast, Dict, Iterable, List, Optional, Union, TYPE_CHECKING ) -from typing_extensions import Self from azure.core.async_paging import AsyncItemPaged from azure.core.exceptions import HttpResponseError @@ -59,6 +59,7 @@ class BlobServiceClient( # type: ignore [misc] + AbstractAsyncContextManager, AsyncStorageAccountHostsMixin, StorageAccountHostsMixin, StorageEncryptionMixin @@ -139,7 +140,7 @@ def __init__( self._client._config.version = get_api_version(kwargs) # type: ignore [assignment] self._configure_encryption(kwargs) - async def __aenter__(self) -> Self: + async def __aenter__(self) -> "BlobServiceClient": await self._client.__aenter__() return self @@ -155,7 +156,7 @@ async def close(self) -> None: """ await self._client.close() - def _format_url(self, hostname): + def _format_url(self, hostname: str) -> str: """Format the endpoint URL according to the current location mode hostname. @@ -171,7 +172,7 @@ def from_connection_string( cls, conn_str: str, credential: Optional[Union[str, Dict[str, str], "AzureNamedKeyCredential", "AzureSasCredential", "AsyncTokenCredential"]] = None, # pylint: disable=line-too-long **kwargs: Any - ) -> Self: + ) -> "BlobServiceClient": """Create BlobServiceClient from a Connection String. :param str conn_str: @@ -190,6 +191,27 @@ def from_connection_string( ~azure.core.credentials.AzureSasCredential or ~azure.core.credentials_async.AsyncTokenCredential or str or dict[str, str] or None + :keyword str api_version: + The Storage API version to use for requests. Default value is the most recent service version that is + compatible with the current SDK. Setting to an older version may result in reduced feature compatibility. + + .. versionadded:: 12.2.0 + + :keyword str secondary_hostname: + The hostname of the secondary endpoint. + :keyword int max_block_size: The maximum chunk size for uploading a block blob in chunks. + Defaults to 4*1024*1024, or 4MB. + :keyword int max_single_put_size: If the blob size is less than or equal max_single_put_size, then the blob will + be uploaded with only one http PUT request. If the blob size is larger than max_single_put_size, + the blob will be uploaded in chunks. Defaults to 64*1024*1024, or 64MB. + :keyword int min_large_block_upload_threshold: The minimum chunk size required to use the memory efficient + algorithm when uploading a block blob. Defaults to 4*1024*1024+1. + :keyword bool use_byte_buffer: Use a byte buffer for block blob uploads. Defaults to False. + :keyword int max_page_size: The maximum chunk size for uploading a page blob. Defaults to 4*1024*1024, or 4MB. + :keyword int max_single_get_size: The maximum size for a blob to be downloaded in a single call, + the exceeded part will be downloaded in chunks (could be parallel). Defaults to 32*1024*1024, or 32MB. + :keyword int max_chunk_get_size: The maximum chunk size used for downloading a blob. Defaults to 4*1024*1024, + or 4MB. :keyword str audience: The audience to use when requesting tokens for Azure Active Directory authentication. Only has an effect when credential is of type TokenCredential. The value could be https://storage.azure.com/ (default) or https://.blob.core.windows.net. @@ -252,7 +274,7 @@ async def get_account_information(self, **kwargs: Any) -> Dict[str, str]: The keys in the returned dictionary include 'sku_name' and 'account_kind'. :return: A dict of account information (SKU and account type). - :rtype: dict(str, str) + :rtype: Dict[str, str] .. admonition:: Example: @@ -545,7 +567,7 @@ async def create_container( :param metadata: A dict with name-value pairs to associate with the container as metadata. Example: `{'Category':'test'}` - :type metadata: dict(str, str) + :type metadata: Dict[str, str] :param public_access: Possible values include: 'container', 'blob'. :type public_access: str or ~azure.storage.blob.PublicAccess @@ -775,7 +797,7 @@ def get_blob_client( The optional blob snapshot on which to operate. This can either be the ID of the snapshot, or a dictionary output returned by :func:`~azure.storage.blob.aio.BlobClient.create_snapshot()`. - :type snapshot: str or dict(str, Any) + :type snapshot: str or Dict[str, Any] :keyword str version_id: The version id parameter is an opaque DateTime value that, when present, specifies the version of the blob to operate on. :return: A BlobClient. diff --git a/sdk/storage/azure-storage-blob/azure/storage/blob/aio/_blob_service_client_async.pyi b/sdk/storage/azure-storage-blob/azure/storage/blob/aio/_blob_service_client_async.pyi new file mode 100644 index 000000000000..348bde13cc8f --- /dev/null +++ b/sdk/storage/azure-storage-blob/azure/storage/blob/aio/_blob_service_client_async.pyi @@ -0,0 +1,187 @@ +# ------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# -------------------------------------------------------------------------- +# pylint: skip-file + +from contextlib import AbstractAsyncContextManager +from datetime import datetime +from types import TracebackType +from typing import ( + Any, + Dict, + List, + Optional, + Union, +) + +from azure.core import MatchConditions +from azure.core.async_paging import AsyncItemPaged +from azure.core.credentials import AzureNamedKeyCredential, AzureSasCredential +from azure.core.credentials_async import AsyncTokenCredential +from azure.core.tracing.decorator import distributed_trace +from azure.core.tracing.decorator_async import distributed_trace_async + +from ._blob_client_async import BlobClient +from ._container_client_async import ContainerClient +from ._lease_async import BlobLeaseClient +from .._encryption import StorageEncryptionMixin +from .._models import ( + BlobAnalyticsLogging, + ContainerEncryptionScope, + ContainerProperties, + CorsRule, + FilteredBlob, + Metrics, + PublicAccess, + RetentionPolicy, + StaticWebsite, +) +from .._shared.base_client import StorageAccountHostsMixin +from .._shared.base_client_async import AsyncStorageAccountHostsMixin +from .._shared.models import UserDelegationKey + +class BlobServiceClient( # type: ignore [misc] + AbstractAsyncContextManager, AsyncStorageAccountHostsMixin, StorageAccountHostsMixin, StorageEncryptionMixin +): + def __init__( + self, + account_url: str, + credential: Optional[ + Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, AsyncTokenCredential] + ] = None, + *, + api_version: Optional[str] = None, + secondary_hostname: Optional[str] = None, + max_block_size: int = 4 * 1024 * 1024, + max_single_put_size: int = 64 * 1024 * 1024, + min_large_block_upload_threshold: int = 4 * 1024 * 1024 + 1, + use_byte_buffer: bool = False, + max_page_size: int = 4 * 1024 * 1024, + max_single_get_size: int = 32 * 1024 * 1024, + max_chunk_get_size: int = 4 * 1024 * 1024, + audience: Optional[str] = None, + **kwargs: Any + ) -> None: ... + async def __aenter__(self) -> "BlobServiceClient": ... + async def __aexit__( + self, typ: Optional[type[BaseException]], exc: Optional[BaseException], tb: Optional[TracebackType] + ) -> None: ... + async def close(self) -> None: ... + @classmethod + def from_connection_string( + cls, + conn_str: str, + credential: Optional[ + Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, AsyncTokenCredential] + ] = None, + *, + api_version: Optional[str] = None, + secondary_hostname: Optional[str] = None, + max_block_size: int = 4 * 1024 * 1024, + max_single_put_size: int = 64 * 1024 * 1024, + min_large_block_upload_threshold: int = 4 * 1024 * 1024 + 1, + use_byte_buffer: bool = False, + max_page_size: int = 4 * 1024 * 1024, + max_single_get_size: int = 32 * 1024 * 1024, + max_chunk_get_size: int = 4 * 1024 * 1024, + audience: Optional[str] = None, + **kwargs: Any + ) -> "BlobServiceClient": ... + @distributed_trace_async + async def get_user_delegation_key( + self, key_start_time: datetime, key_expiry_time: datetime, *, timeout: Optional[int] = None, **kwargs: Any + ) -> UserDelegationKey: ... + @distributed_trace_async + async def get_account_information(self, **kwargs: Any) -> Dict[str, str]: ... + @distributed_trace_async + async def get_service_stats(self, *, timeout: Optional[int] = None, **kwargs: Any) -> Dict[str, Any]: ... + @distributed_trace_async + async def get_service_properties(self, *, timeout: Optional[int] = None, **kwargs: Any) -> Dict[str, Any]: ... + @distributed_trace_async + async def set_service_properties( + self, + analytics_logging: Optional[BlobAnalyticsLogging] = None, + hour_metrics: Optional[Metrics] = None, + minute_metrics: Optional[Metrics] = None, + cors: Optional[List[CorsRule]] = None, + target_version: Optional[str] = None, + delete_retention_policy: Optional[RetentionPolicy] = None, + static_website: Optional[StaticWebsite] = None, + **kwargs: Any + ) -> None: ... + @distributed_trace + def list_containers( + self, + name_starts_with: Optional[str] = None, + include_metadata: bool = False, + *, + include_deleted: Optional[bool] = None, + include_system: Optional[bool] = None, + results_per_page: Optional[int] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> AsyncItemPaged[ContainerProperties]: ... + @distributed_trace + def find_blobs_by_tags( + self, + filter_expression: str, + *, + results_per_page: Optional[int] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> AsyncItemPaged[FilteredBlob]: ... + @distributed_trace_async + async def create_container( + self, + name: str, + metadata: Optional[Dict[str, str]] = None, + public_access: Optional[Union[PublicAccess, str]] = None, + *, + container_encryption_scope: Optional[Union[dict, ContainerEncryptionScope]] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> ContainerClient: ... + @distributed_trace_async + async def delete_container( + self, + container: Union[ContainerProperties, str], + lease: Optional[Union[BlobLeaseClient, str]] = None, + *, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> None: ... + @distributed_trace_async + async def _rename_container( + self, + name: str, + new_name: str, + *, + lease: Optional[Union[BlobLeaseClient, str]] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> ContainerClient: ... + @distributed_trace_async + async def undelete_container( + self, + deleted_container_name: str, + deleted_container_version: str, + *, + timeout: Optional[int] = None, + **kwargs: Any + ) -> ContainerClient: ... + def get_container_client(self, container: Union[ContainerProperties, str]) -> ContainerClient: ... + def get_blob_client( + self, + container: Union[ContainerProperties, str], + blob: str, + snapshot: Optional[Union[Dict[str, Any], str]] = None, + *, + version_id: Optional[str] = None, + **kwargs: Any + ) -> BlobClient: ... diff --git a/sdk/storage/azure-storage-blob/azure/storage/blob/aio/_container_client_async.py b/sdk/storage/azure-storage-blob/azure/storage/blob/aio/_container_client_async.py index 84f87216e5ce..35c348a26cfe 100644 --- a/sdk/storage/azure-storage-blob/azure/storage/blob/aio/_container_client_async.py +++ b/sdk/storage/azure-storage-blob/azure/storage/blob/aio/_container_client_async.py @@ -7,13 +7,13 @@ import functools import warnings +from contextlib import AbstractAsyncContextManager from datetime import datetime from typing import ( Any, AnyStr, AsyncIterable, AsyncIterator, cast, Dict, List, IO, Iterable, Optional, overload, Union, TYPE_CHECKING ) from urllib.parse import unquote, urlparse -from typing_extensions import Self from azure.core.async_paging import AsyncItemPaged, AsyncList from azure.core.exceptions import HttpResponseError, ResourceNotFoundError @@ -62,7 +62,12 @@ ) -class ContainerClient(AsyncStorageAccountHostsMixin, StorageAccountHostsMixin, StorageEncryptionMixin): # type: ignore [misc] # pylint: disable=too-many-public-methods +class ContainerClient( # type: ignore [misc] # pylint: disable=too-many-public-methods + AbstractAsyncContextManager, + AsyncStorageAccountHostsMixin, + StorageAccountHostsMixin, + StorageEncryptionMixin +): """A client to interact with a specific container, although that container may not yet exist. @@ -143,7 +148,7 @@ def __init__( self._client = self._build_generated_client() self._configure_encryption(kwargs) - async def __aenter__(self) -> Self: + async def __aenter__(self) -> "ContainerClient": await self._client.__aenter__() return self @@ -177,7 +182,7 @@ def from_container_url( cls, container_url: str, credential: Optional[Union[str, Dict[str, str], "AzureNamedKeyCredential", "AzureSasCredential", "AsyncTokenCredential"]] = None, # pylint: disable=line-too-long **kwargs: Any - ) -> Self: + ) -> "ContainerClient": """Create ContainerClient from a container url. :param str container_url: @@ -230,7 +235,7 @@ def from_connection_string( container_name: str, credential: Optional[Union[str, Dict[str, str], "AzureNamedKeyCredential", "AzureSasCredential", "AsyncTokenCredential"]] = None, # pylint: disable=line-too-long **kwargs: Any - ) -> Self: + ) -> "ContainerClient": """Create ContainerClient from a Connection String. :param str conn_str: diff --git a/sdk/storage/azure-storage-blob/azure/storage/blob/aio/_container_client_async.pyi b/sdk/storage/azure-storage-blob/azure/storage/blob/aio/_container_client_async.pyi new file mode 100644 index 000000000000..b8e9783e4589 --- /dev/null +++ b/sdk/storage/azure-storage-blob/azure/storage/blob/aio/_container_client_async.pyi @@ -0,0 +1,385 @@ +# ------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# -------------------------------------------------------------------------- +# pylint: skip-file + +from contextlib import AbstractAsyncContextManager +from datetime import datetime +from types import TracebackType +from typing import ( + Any, + AnyStr, + AsyncIterable, + AsyncIterator, + Awaitable, + Callable, + Dict, + List, + IO, + Iterable, + Optional, + overload, + Union, +) +from typing_extensions import Self + +from azure.core import MatchConditions +from azure.core.async_paging import AsyncItemPaged +from azure.core.credentials import AzureNamedKeyCredential, AzureSasCredential +from azure.core.credentials_async import AsyncTokenCredential +from azure.core.pipeline.transport import AsyncHttpResponse +from azure.core.tracing.decorator import distributed_trace +from azure.core.tracing.decorator_async import distributed_trace_async + +from ._blob_client_async import BlobClient +from ._blob_service_client_async import BlobServiceClient +from ._download_async import StorageStreamDownloader +from ._lease_async import BlobLeaseClient +from ._list_blobs_helper import BlobPrefix +from .._encryption import StorageEncryptionMixin +from .._generated.models import RehydratePriority +from .._models import ( + AccessPolicy, + BlobType, + BlobProperties, + ContainerEncryptionScope, + ContainerProperties, + ContentSettings, + CustomerProvidedEncryptionKey, + FilteredBlob, + PremiumPageBlobTier, + PublicAccess, + StandardBlobTier, +) +from .._shared.base_client import StorageAccountHostsMixin +from .._shared.base_client_async import AsyncStorageAccountHostsMixin + +class ContainerClient( # type: ignore[misc] + AbstractAsyncContextManager, AsyncStorageAccountHostsMixin, StorageAccountHostsMixin, StorageEncryptionMixin +): + account_name: str + container_name: str + def __init__( + self, + account_url: str, + container_name: str, + credential: Optional[ + Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, AsyncTokenCredential] + ] = None, + *, + api_version: Optional[str] = None, + secondary_hostname: Optional[str] = None, + audience: Optional[str] = None, + max_block_size: int = 4 * 1024 * 1024, + max_page_size: int = 4 * 1024 * 1024, + max_chunk_get_size: int = 4 * 1024 * 1024, + max_single_put_size: int = 64 * 1024 * 1024, + max_single_get_size: int = 32 * 1024 * 1024, + min_large_block_upload_threshold: int = 4 * 1024 * 1024 + 1, + use_byte_buffer: Optional[bool] = None, + **kwargs: Any + ) -> None: ... + async def __aenter__(self) -> "ContainerClient": ... + async def __aexit__( + self, typ: Optional[type[BaseException]], exc: Optional[BaseException], tb: Optional[TracebackType] + ) -> None: ... + async def close(self) -> None: ... + @classmethod + def from_container_url( + cls, + container_url: str, + credential: Optional[ + Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, AsyncTokenCredential] + ] = None, + *, + api_version: Optional[str] = None, + secondary_hostname: Optional[str] = None, + audience: Optional[str] = None, + max_block_size: int = 4 * 1024 * 1024, + max_page_size: int = 4 * 1024 * 1024, + max_chunk_get_size: int = 4 * 1024 * 1024, + max_single_put_size: int = 64 * 1024 * 1024, + max_single_get_size: int = 32 * 1024 * 1024, + min_large_block_upload_threshold: int = 4 * 1024 * 1024 + 1, + use_byte_buffer: Optional[bool] = None, + **kwargs: Any + ) -> "ContainerClient": ... + @classmethod + def from_connection_string( + cls, + conn_str: str, + container_name: str, + credential: Optional[ + Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, AsyncTokenCredential] + ] = None, + *, + api_version: Optional[str] = None, + secondary_hostname: Optional[str] = None, + audience: Optional[str] = None, + max_block_size: int = 4 * 1024 * 1024, + max_page_size: int = 4 * 1024 * 1024, + max_chunk_get_size: int = 4 * 1024 * 1024, + max_single_put_size: int = 64 * 1024 * 1024, + max_single_get_size: int = 32 * 1024 * 1024, + min_large_block_upload_threshold: int = 4 * 1024 * 1024 + 1, + use_byte_buffer: Optional[bool] = None, + **kwargs: Any + ) -> "ContainerClient": ... + @distributed_trace_async + async def create_container( + self, + metadata: Optional[Dict[str, str]] = None, + public_access: Optional[Union[PublicAccess, str]] = None, + *, + container_encryption_scope: Optional[Union[Dict[str, Any], ContainerEncryptionScope]] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> Dict[str, Union[str, datetime]]: ... + @distributed_trace_async + async def _rename_container( + self, + new_name: str, + *, + lease: Optional[Union[BlobLeaseClient, str]] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> "ContainerClient": ... + @distributed_trace_async + async def delete_container( + self, + *, + lease: Optional[Union[BlobLeaseClient, str]] = None, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> None: ... + @distributed_trace_async + async def acquire_lease( + self, + lease_duration: int = -1, + lease_id: Optional[str] = None, + *, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> BlobLeaseClient: ... + @distributed_trace_async + async def get_account_information(self, **kwargs: Any) -> Dict[str, str]: ... + @distributed_trace_async + async def get_container_properties( + self, *, lease: Optional[Union[BlobLeaseClient, str]] = None, timeout: Optional[int] = None, **kwargs: Any + ) -> ContainerProperties: ... + @distributed_trace_async + async def exists(self, *, timeout: Optional[int] = None, **kwargs: Any) -> bool: ... + @distributed_trace_async + async def set_container_metadata( + self, + metadata: Optional[Dict[str, str]] = None, + *, + lease: Optional[Union[BlobLeaseClient, str]] = None, + if_modified_since: Optional[datetime] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> Dict[str, Union[str, datetime]]: ... + @distributed_trace + def _get_blob_service_client(self) -> BlobServiceClient: ... + @distributed_trace_async + async def get_container_access_policy( + self, *, lease: Optional[Union[BlobLeaseClient, str]] = None, timeout: Optional[int] = None, **kwargs: Any + ) -> Dict[str, Any]: ... + @distributed_trace_async + async def set_container_access_policy( + self, + signed_identifiers: Dict[str, AccessPolicy], + public_access: Optional[Union[str, PublicAccess]] = None, + *, + lease: Optional[Union[BlobLeaseClient, str]] = None, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> Dict[str, Union[str, datetime]]: ... + @distributed_trace + def list_blobs( + self, + name_starts_with: Optional[str] = None, + include: Optional[Union[str, List[str]]] = None, + *, + timeout: Optional[int] = None, + **kwargs: Any + ) -> AsyncItemPaged[BlobProperties]: ... + @distributed_trace + def list_blob_names( + self, *, name_starts_with: Optional[str] = None, timeout: Optional[int] = None, **kwargs: Any + ) -> AsyncItemPaged[str]: ... + @distributed_trace + def walk_blobs( + self, + name_starts_with: Optional[str] = None, + include: Optional[Union[List[str], str]] = None, + delimiter: str = "/", + **kwargs: Any + ) -> AsyncItemPaged[Union[BlobProperties, BlobPrefix]]: ... + @distributed_trace + def find_blobs_by_tags( + self, + filter_expression: str, + *, + results_per_page: Optional[int] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> AsyncItemPaged[FilteredBlob]: ... + @distributed_trace_async + async def upload_blob( + self, + name: str, + data: Union[bytes, str, Iterable[AnyStr], AsyncIterable[AnyStr], IO[AnyStr]], + blob_type: Union[str, BlobType] = BlobType.BLOCKBLOB, + length: Optional[int] = None, + metadata: Optional[Dict[str, str]] = None, + *, + overwrite: Optional[bool] = None, + content_settings: Optional[ContentSettings] = None, + validate_content: Optional[bool] = None, + lease: Optional[Union[BlobLeaseClient, str]] = None, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + if_tags_match_condition: Optional[str] = None, + timeout: Optional[int] = None, + premium_page_blob_tier: Optional[PremiumPageBlobTier] = None, + standard_blob_tier: Optional[StandardBlobTier] = None, + maxsize_condition: Optional[int] = None, + max_concurrency: Optional[int] = None, + cpk: Optional[CustomerProvidedEncryptionKey] = None, + encryption_scope: Optional[str] = None, + encoding: Optional[str] = None, + progress_hook: Optional[Callable[[int, Optional[int]], Awaitable[None]]] = None, + **kwargs: Any + ) -> BlobClient: ... + @distributed_trace_async + async def delete_blob( + self, + blob: str, + delete_snapshots: Optional[str] = None, + *, + version_id: Optional[str] = None, + lease: Optional[Union[BlobLeaseClient, str]] = None, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + if_tags_match_condition: Optional[str] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> None: ... + @overload + async def download_blob( + self, + blob: str, + offset: Optional[int] = None, + length: Optional[int] = None, + *, + version_id: Optional[str] = None, + validate_content: Optional[bool] = None, + lease: Optional[Union[BlobLeaseClient, str]] = None, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + if_tags_match_condition: Optional[str] = None, + cpk: Optional[CustomerProvidedEncryptionKey] = None, + max_concurrency: Optional[int] = None, + encoding: str, + progress_hook: Optional[Callable[[int, int], Awaitable[None]]] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> StorageStreamDownloader[str]: ... + @overload + async def download_blob( + self, + blob: str, + offset: Optional[int] = None, + length: Optional[int] = None, + *, + version_id: Optional[str] = None, + validate_content: Optional[bool] = None, + lease: Optional[Union[BlobLeaseClient, str]] = None, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + if_tags_match_condition: Optional[str] = None, + cpk: Optional[CustomerProvidedEncryptionKey] = None, + max_concurrency: Optional[int] = None, + encoding: None = None, + progress_hook: Optional[Callable[[int, int], Awaitable[None]]] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> StorageStreamDownloader[bytes]: ... + @distributed_trace_async # type: ignore[misc] + async def download_blob( + self, + blob: str, + offset: Optional[int] = None, + length: Optional[int] = None, + *, + version_id: Optional[str] = None, + validate_content: Optional[bool] = None, + lease: Optional[Union[BlobLeaseClient, str]] = None, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + if_tags_match_condition: Optional[str] = None, + cpk: Optional[CustomerProvidedEncryptionKey] = None, + max_concurrency: Optional[int] = None, + encoding: Optional[str] = None, + progress_hook: Optional[Callable[[int, int], Awaitable[None]]] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> Union[StorageStreamDownloader[str], StorageStreamDownloader[bytes]]: ... + @distributed_trace_async + async def delete_blobs( + self, + *blobs: Union[str, Dict[str, Any], BlobProperties], + delete_snapshots: Optional[str] = None, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + if_tags_match_condition: Optional[str] = None, + raise_on_any_failure: bool = True, + timeout: Optional[int] = None, + **kwargs: Any + ) -> AsyncIterator[AsyncHttpResponse]: ... + @distributed_trace_async + async def set_standard_blob_tier_blobs( + self, + standard_blob_tier: Union[str, StandardBlobTier], + *blobs: Union[str, Dict[str, Any], BlobProperties], + rehydrate_priority: Optional[RehydratePriority] = None, + if_tags_match_condition: Optional[str] = None, + raise_on_any_failure: bool = True, + timeout: Optional[int] = None, + **kwargs: Any + ) -> AsyncIterator[AsyncHttpResponse]: ... + @distributed_trace_async + async def set_premium_page_blob_tier_blobs( + self, + premium_page_blob_tier: Union[str, PremiumPageBlobTier], + *blobs: Union[str, Dict[str, Any], BlobProperties], + raise_on_any_failure: bool = True, + timeout: Optional[int] = None, + **kwargs: Any + ) -> AsyncIterator[AsyncHttpResponse]: ... + def get_blob_client( + self, blob: str, snapshot: Optional[str] = None, *, version_id: Optional[str] = None + ) -> BlobClient: ... diff --git a/sdk/storage/azure-storage-blob/azure/storage/blob/aio/_lease_async.py b/sdk/storage/azure-storage-blob/azure/storage/blob/aio/_lease_async.py index e09dce54b05d..79cd779109a5 100644 --- a/sdk/storage/azure-storage-blob/azure/storage/blob/aio/_lease_async.py +++ b/sdk/storage/azure-storage-blob/azure/storage/blob/aio/_lease_async.py @@ -19,7 +19,7 @@ from datetime import datetime -class BlobLeaseClient(): # pylint: disable=client-accepts-api-version-keyword +class BlobLeaseClient: # pylint: disable=client-accepts-api-version-keyword """Creates a new BlobLeaseClient. This client provides lease operations on a BlobClient or ContainerClient. @@ -40,16 +40,15 @@ class BlobLeaseClient(): # pylint: disable=client-accepts-api-version-keyword """The last modified timestamp of the lease currently being maintained. This will be `None` if no lease has yet been acquired or modified.""" - def __init__( # pylint: disable=missing-client-constructor-parameter-credential, missing-client-constructor-parameter-kwargs - self, client: Union["BlobClient", "ContainerClient"], - lease_id: Optional[str] = None + def __init__( # pylint: disable=missing-client-constructor-parameter-credential, missing-client-constructor-parameter-kwargs + self, client: Union["BlobClient", "ContainerClient"], lease_id: Optional[str] = None ) -> None: self.id = lease_id or str(uuid.uuid4()) self.last_modified = None self.etag = None - if hasattr(client, 'blob_name'): + if hasattr(client, "blob_name"): self._client = client._client.blob - elif hasattr(client, 'container_name'): + elif hasattr(client, "container_name"): self._client = client._client.container else: raise TypeError("Lease must use either BlobClient or ContainerClient.") @@ -113,17 +112,18 @@ async def acquire(self, lease_duration: int = -1, **kwargs: Any) -> None: mod_conditions = get_modify_conditions(kwargs) try: response: Any = await self._client.acquire_lease( - timeout=kwargs.pop('timeout', None), + timeout=kwargs.pop("timeout", None), duration=lease_duration, proposed_lease_id=self.id, modified_access_conditions=mod_conditions, cls=return_response_headers, - **kwargs) + **kwargs + ) except HttpResponseError as error: process_storage_error(error) - self.id = response.get('lease_id') - self.last_modified = response.get('last_modified') - self.etag = response.get('etag') + self.id = response.get("lease_id") + self.last_modified = response.get("last_modified") + self.etag = response.get("etag") @distributed_trace_async async def renew(self, **kwargs: Any) -> None: @@ -170,15 +170,16 @@ async def renew(self, **kwargs: Any) -> None: try: response: Any = await self._client.renew_lease( lease_id=self.id, - timeout=kwargs.pop('timeout', None), + timeout=kwargs.pop("timeout", None), modified_access_conditions=mod_conditions, cls=return_response_headers, - **kwargs) + **kwargs + ) except HttpResponseError as error: process_storage_error(error) - self.etag = response.get('etag') - self.id = response.get('lease_id') - self.last_modified = response.get('last_modified') + self.etag = response.get("etag") + self.id = response.get("lease_id") + self.last_modified = response.get("last_modified") @distributed_trace_async async def release(self, **kwargs: Any) -> None: @@ -223,15 +224,16 @@ async def release(self, **kwargs: Any) -> None: try: response: Any = await self._client.release_lease( lease_id=self.id, - timeout=kwargs.pop('timeout', None), + timeout=kwargs.pop("timeout", None), modified_access_conditions=mod_conditions, cls=return_response_headers, - **kwargs) + **kwargs + ) except HttpResponseError as error: process_storage_error(error) - self.etag = response.get('etag') - self.id = response.get('lease_id') - self.last_modified = response.get('last_modified') + self.etag = response.get("etag") + self.id = response.get("lease_id") + self.last_modified = response.get("last_modified") @distributed_trace_async async def change(self, proposed_lease_id: str, **kwargs: Any) -> None: @@ -276,15 +278,16 @@ async def change(self, proposed_lease_id: str, **kwargs: Any) -> None: response: Any = await self._client.change_lease( lease_id=self.id, proposed_lease_id=proposed_lease_id, - timeout=kwargs.pop('timeout', None), + timeout=kwargs.pop("timeout", None), modified_access_conditions=mod_conditions, cls=return_response_headers, - **kwargs) + **kwargs + ) except HttpResponseError as error: process_storage_error(error) - self.etag = response.get('etag') - self.id = response.get('lease_id') - self.last_modified = response.get('last_modified') + self.etag = response.get("etag") + self.id = response.get("lease_id") + self.last_modified = response.get("last_modified") @distributed_trace_async async def break_lease(self, lease_break_period: Optional[int] = None, **kwargs: Any) -> int: @@ -337,11 +340,12 @@ async def break_lease(self, lease_break_period: Optional[int] = None, **kwargs: mod_conditions = get_modify_conditions(kwargs) try: response: Any = await self._client.break_lease( - timeout=kwargs.pop('timeout', None), + timeout=kwargs.pop("timeout", None), break_period=lease_break_period, modified_access_conditions=mod_conditions, cls=return_response_headers, - **kwargs) + **kwargs + ) except HttpResponseError as error: process_storage_error(error) - return response.get('lease_time') # type: ignore + return response.get("lease_time") # type: ignore diff --git a/sdk/storage/azure-storage-blob/azure/storage/blob/aio/_lease_async.pyi b/sdk/storage/azure-storage-blob/azure/storage/blob/aio/_lease_async.pyi new file mode 100644 index 000000000000..d0c4a766dca9 --- /dev/null +++ b/sdk/storage/azure-storage-blob/azure/storage/blob/aio/_lease_async.pyi @@ -0,0 +1,78 @@ +# ------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# -------------------------------------------------------------------------- +# pylint: skip-file + +from datetime import datetime +from typing import Any, Optional, Union + +from azure.core import MatchConditions +from azure.core.tracing.decorator_async import distributed_trace_async +from ._blob_client_async import BlobClient +from ._container_client_async import ContainerClient + +class BlobLeaseClient: + def __init__(self, client: Union[BlobClient, ContainerClient], lease_id: Optional[str] = None) -> None: ... + @distributed_trace_async + async def acquire( + self, + lease_duration: int = -1, + *, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + if_tags_match_condition: Optional[str] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> None: ... + @distributed_trace_async + async def renew( + self, + *, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + if_tags_match_condition: Optional[str] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> None: ... + @distributed_trace_async + async def release( + self, + *, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + if_tags_match_condition: Optional[str] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> None: ... + @distributed_trace_async + async def change( + self, + proposed_lease_id: str, + *, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + etag: Optional[str] = None, + match_condition: Optional[MatchConditions] = None, + if_tags_match_condition: Optional[str] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> None: ... + @distributed_trace_async + async def break_lease( + self, + lease_break_period: Optional[int] = None, + *, + if_modified_since: Optional[datetime] = None, + if_unmodified_since: Optional[datetime] = None, + if_tags_match_condition: Optional[str] = None, + timeout: Optional[int] = None, + **kwargs: Any + ) -> int: ...