From 859183301d154b73395dcfbc3c8c51ec06b23faa Mon Sep 17 00:00:00 2001 From: Peter Wu <162184229+weirongw23-msft@users.noreply.github.com> Date: Thu, 8 May 2025 12:25:25 -0400 Subject: [PATCH 01/11] [Storage] [Named Keywords] Blob Service Client (#40834) --- .../storage/blob/_blob_service_client.py | 29 ++- .../storage/blob/_blob_service_client.pyi | 207 +++++++++++++++++ .../storage/blob/aio/_blob_client_async.py | 12 +- .../blob/aio/_blob_service_client_async.py | 29 ++- .../blob/aio/_blob_service_client_async.pyi | 214 ++++++++++++++++++ 5 files changed, 477 insertions(+), 14 deletions(-) create mode 100644 sdk/storage/azure-storage-blob/azure/storage/blob/_blob_service_client.pyi create mode 100644 sdk/storage/azure-storage-blob/azure/storage/blob/aio/_blob_service_client_async.pyi 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 f6e17cb756f0..72c5dfcf6c3d 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 @@ -131,7 +131,7 @@ def __init__( self._client._config.version = get_api_version(kwargs) # type: ignore [assignment] self._configure_encryption(kwargs) - def _format_url(self, hostname): + def _format_url(self, hostname: str) -> str: """Format the endpoint URL according to the current location mode hostname. @@ -166,6 +166,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. @@ -228,7 +249,7 @@ def get_account_information(self, **kwargs: Any) -> Dict[str, str]: The keys in the returned dictionary include 'sku_name' and 'account_kind'. :returns: A dict of account information (SKU and account type). - :rtype: dict(str, str) + :rtype: Dict[str, str] .. admonition:: Example: @@ -521,7 +542,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 @@ -747,7 +768,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. :returns: 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..6a7a5a164075 --- /dev/null +++ b/sdk/storage/azure-storage-blob/azure/storage/blob/_blob_service_client.pyi @@ -0,0 +1,207 @@ +# ------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# -------------------------------------------------------------------------- +# pylint: disable=unused-argument + +from datetime import datetime +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(StorageAccountHostsMixin, StorageEncryptionMixin): # pylint: disable=client-accepts-api-version-keyword + def __init__( # pylint: disable=super-init-not-called + 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: + ... + + @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 + ) -> Self: + ... + + @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/aio/_blob_client_async.py b/sdk/storage/azure-storage-blob/azure/storage/blob/aio/_blob_client_async.py index a88fe9980655..2d5bb878575c 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 @@ -165,12 +165,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( 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 8f76aa98c8cf..5186f329aea6 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 @@ -139,7 +139,7 @@ def __init__( self._client._config.version = get_api_version(kwargs) # type: ignore [assignment] self._configure_encryption(kwargs) - def _format_url(self, hostname): + def _format_url(self, hostname: str) -> str: """Format the endpoint URL according to the current location mode hostname. @@ -174,6 +174,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. @@ -236,7 +257,7 @@ async def get_account_information(self, **kwargs: Any) -> Dict[str, str]: The keys in the returned dictionary include 'sku_name' and 'account_kind'. :returns: A dict of account information (SKU and account type). - :rtype: dict(str, str) + :rtype: Dict[str, str] .. admonition:: Example: @@ -528,7 +549,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 @@ -757,7 +778,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. :returns: 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..76ae29e84e3f --- /dev/null +++ b/sdk/storage/azure-storage-blob/azure/storage/blob/aio/_blob_service_client_async.pyi @@ -0,0 +1,214 @@ +# ------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# -------------------------------------------------------------------------- +# pylint: disable=unused-argument + +from datetime import datetime +from typing import ( + Any, + Dict, + List, + Optional, + 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.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] + AsyncStorageAccountHostsMixin, + StorageAccountHostsMixin, + StorageEncryptionMixin +): # pylint: disable=client-accepts-api-version-keyword + def __init__( # pylint: disable=super-init-not-called + 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: + ... + + @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 + ) -> Self: + ... + + @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: + ... From 92354c7730c7628d1685d356a85cd78953d24d80 Mon Sep 17 00:00:00 2001 From: Peter Wu <162184229+weirongw23-msft@users.noreply.github.com> Date: Thu, 19 Jun 2025 16:00:05 -0400 Subject: [PATCH 02/11] [Storage] [Named Keywords] [Blob] `_container_client.pyi` and aio (#41030) --- .../azure/storage/blob/_container_client.pyi | 377 +++++++++++++++++ .../blob/aio/_container_client_async.pyi | 380 ++++++++++++++++++ 2 files changed, 757 insertions(+) create mode 100644 sdk/storage/azure-storage-blob/azure/storage/blob/_container_client.pyi create mode 100644 sdk/storage/azure-storage-blob/azure/storage/blob/aio/_container_client_async.pyi 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..c67c30c77bca --- /dev/null +++ b/sdk/storage/azure-storage-blob/azure/storage/blob/_container_client.pyi @@ -0,0 +1,377 @@ +# ------------------------------------------------------------------------- +# 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, + AnyStr, + Callable, + Dict, + List, + IO, + Iterable, + Iterator, + Optional, + overload, + 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.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: ... + @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, + ) -> Self: ... + @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, + ) -> Self: ... + @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, + ) -> Self: ... + @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/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..9fccfb768e26 --- /dev/null +++ b/sdk/storage/azure-storage-blob/azure/storage/blob/aio/_container_client_async.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 datetime import datetime +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] + 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: ... + @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 + ) -> Self: ... + @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 + ) -> Self: ... + @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 + ) -> Self: ... + @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: ... From c264932d0fb86d5fbe5c387f7ab5e35f79028081 Mon Sep 17 00:00:00 2001 From: Peter Wu <162184229+weirongw23-msft@users.noreply.github.com> Date: Thu, 19 Jun 2025 16:00:24 -0400 Subject: [PATCH 03/11] [Storage] [Named Keywords] [Blob] `_lease.pyi` and aio (#41031) --- .../azure/storage/blob/_lease.py | 4 +- .../azure/storage/blob/_lease.pyi | 82 +++++++++++++++++++ .../azure/storage/blob/aio/_lease_async.py | 62 +++++++------- .../azure/storage/blob/aio/_lease_async.pyi | 82 +++++++++++++++++++ 4 files changed, 199 insertions(+), 31 deletions(-) create mode 100644 sdk/storage/azure-storage-blob/azure/storage/blob/_lease.pyi create mode 100644 sdk/storage/azure-storage-blob/azure/storage/blob/aio/_lease_async.pyi 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..748bf0eb16c5 --- /dev/null +++ b/sdk/storage/azure-storage-blob/azure/storage/blob/_lease.pyi @@ -0,0 +1,82 @@ +# ------------------------------------------------------------------------- +# 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/_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..8e102c235498 --- /dev/null +++ b/sdk/storage/azure-storage-blob/azure/storage/blob/aio/_lease_async.pyi @@ -0,0 +1,82 @@ +# ------------------------------------------------------------------------- +# 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: ... From 953a1c4c8f3d41a5c48888b60f0658e49b305c03 Mon Sep 17 00:00:00 2001 From: Peter Wu <162184229+weirongw23-msft@users.noreply.github.com> Date: Mon, 23 Jun 2025 16:07:57 -0400 Subject: [PATCH 04/11] [Storage] [Named Keywords] [Blob] `_blob_client.pyi` and aio (#41029) --- .../azure/storage/blob/__init__.py | 2 +- .../azure/storage/blob/_blob_client.py | 22 +- .../azure/storage/blob/_blob_client.pyi | 779 ++++++++++++++++++ .../storage/blob/_blob_service_client.pyi | 67 +- .../azure/storage/blob/_container_client.pyi | 11 +- .../azure/storage/blob/_lease.pyi | 6 +- .../azure/storage/blob/aio/__init__.py | 9 +- .../storage/blob/aio/_blob_client_async.py | 24 +- .../storage/blob/aio/_blob_client_async.pyi | 764 +++++++++++++++++ .../blob/aio/_blob_service_client_async.pyi | 71 +- .../blob/aio/_container_client_async.pyi | 12 +- .../azure/storage/blob/aio/_lease_async.pyi | 6 +- 12 files changed, 1610 insertions(+), 163 deletions(-) create mode 100644 sdk/storage/azure-storage-blob/azure/storage/blob/_blob_client.pyi create mode 100644 sdk/storage/azure-storage-blob/azure/storage/blob/aio/_blob_client_async.pyi 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..98428b3cc3ae 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 @@ -9,7 +9,7 @@ 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 @@ -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..bea732d1880c --- /dev/null +++ b/sdk/storage/azure-storage-blob/azure/storage/blob/_blob_client.pyi @@ -0,0 +1,779 @@ +# ------------------------------------------------------------------------- +# 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 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(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.pyi b/sdk/storage/azure-storage-blob/azure/storage/blob/_blob_service_client.pyi index 6a7a5a164075..c3f1a6001bd8 100644 --- 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 @@ -3,9 +3,10 @@ # Licensed under the MIT License. See License.txt in the project root for # license information. # -------------------------------------------------------------------------- -# pylint: disable=unused-argument +# pylint: skip-file from datetime import datetime +from types import TracebackType from typing import ( Any, Dict, @@ -37,9 +38,8 @@ from ._models import ( from ._shared.base_client import StorageAccountHostsMixin from ._shared.models import UserDelegationKey - -class BlobServiceClient(StorageAccountHostsMixin, StorageEncryptionMixin): # pylint: disable=client-accepts-api-version-keyword - def __init__( # pylint: disable=super-init-not-called +class BlobServiceClient(StorageAccountHostsMixin, StorageEncryptionMixin): + def __init__( self, account_url: str, credential: Optional[ @@ -57,9 +57,12 @@ class BlobServiceClient(StorageAccountHostsMixin, StorageEncryptionMixin): # py max_chunk_get_size: int = 4 * 1024 * 1024, audience: Optional[str] = None, **kwargs: Any - ) -> None: - ... - + ) -> None: ... + def __enter__(self) -> Self: ... + def __exit__( + self, typ: Optional[type[BaseException]], exc: Optional[BaseException], tb: Optional[TracebackType] + ) -> None: ... + def close(self) -> None: ... @classmethod def from_connection_string( cls, @@ -79,29 +82,17 @@ class BlobServiceClient(StorageAccountHostsMixin, StorageEncryptionMixin): # py max_chunk_get_size: int = 4 * 1024 * 1024, audience: Optional[str] = None, **kwargs: Any - ) -> Self: - ... - + ) -> Self: ... @distributed_trace def get_user_delegation_key( - self, - key_start_time: datetime, - key_expiry_time: datetime, - *, - timeout: Optional[int] = None, - **kwargs: Any - ) -> UserDelegationKey: - ... - + 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, @@ -115,9 +106,7 @@ class BlobServiceClient(StorageAccountHostsMixin, StorageEncryptionMixin): # py *, timeout: Optional[int] = None, **kwargs: Any - ) -> None: - ... - + ) -> None: ... @distributed_trace def list_containers( self, @@ -129,9 +118,7 @@ class BlobServiceClient(StorageAccountHostsMixin, StorageEncryptionMixin): # py results_per_page: Optional[int] = None, timeout: Optional[int] = None, **kwargs: Any - ) -> ItemPaged[ContainerProperties]: - ... - + ) -> ItemPaged[ContainerProperties]: ... @distributed_trace def find_blobs_by_tags( self, @@ -140,9 +127,7 @@ class BlobServiceClient(StorageAccountHostsMixin, StorageEncryptionMixin): # py results_per_page: Optional[int] = None, timeout: Optional[int] = None, **kwargs: Any - ) -> ItemPaged[FilteredBlob]: - ... - + ) -> ItemPaged[FilteredBlob]: ... @distributed_trace def create_container( self, @@ -153,9 +138,7 @@ class BlobServiceClient(StorageAccountHostsMixin, StorageEncryptionMixin): # py container_encryption_scope: Optional[Union[dict, ContainerEncryptionScope]] = None, timeout: Optional[int] = None, **kwargs: Any - ) -> ContainerClient: - ... - + ) -> ContainerClient: ... @distributed_trace def delete_container( self, @@ -168,9 +151,7 @@ class BlobServiceClient(StorageAccountHostsMixin, StorageEncryptionMixin): # py match_condition: Optional[MatchConditions] = None, timeout: Optional[int] = None, **kwargs: Any - ) -> None: - ... - + ) -> None: ... @distributed_trace def _rename_container( self, @@ -180,9 +161,7 @@ class BlobServiceClient(StorageAccountHostsMixin, StorageEncryptionMixin): # py lease: Optional[Union[BlobLeaseClient, str]] = None, timeout: Optional[int] = None, **kwargs: Any - ) -> ContainerClient: - ... - + ) -> ContainerClient: ... @distributed_trace def undelete_container( self, @@ -191,11 +170,8 @@ class BlobServiceClient(StorageAccountHostsMixin, StorageEncryptionMixin): # py *, timeout: Optional[int] = None, **kwargs: Any - ) -> ContainerClient: - ... - + ) -> ContainerClient: ... def get_container_client(self, container: Union[ContainerProperties, str]) -> ContainerClient: ... - def get_blob_client( self, container: Union[ContainerProperties, str], @@ -203,5 +179,4 @@ class BlobServiceClient(StorageAccountHostsMixin, StorageEncryptionMixin): # py snapshot: Optional[Union[Dict[str, Any], str]] = None, *, version_id: Optional[str] = None - ) -> BlobClient: - ... + ) -> BlobClient: ... 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 index c67c30c77bca..4dd38ee97991 100644 --- a/sdk/storage/azure-storage-blob/azure/storage/blob/_container_client.pyi +++ b/sdk/storage/azure-storage-blob/azure/storage/blob/_container_client.pyi @@ -6,6 +6,7 @@ # pylint: skip-file from datetime import datetime +from types import TracebackType from typing import ( Any, AnyStr, @@ -48,10 +49,7 @@ from ._models import ( ) from ._shared.base_client import StorageAccountHostsMixin -class ContainerClient( - StorageAccountHostsMixin, - StorageEncryptionMixin -): +class ContainerClient(StorageAccountHostsMixin, StorageEncryptionMixin): account_name: str container_name: str def __init__( @@ -74,6 +72,11 @@ class ContainerClient( use_byte_buffer: Optional[bool] = None, **kwargs: Any, ) -> None: ... + def __enter__(self) -> Self: ... + def __exit__( + self, typ: Optional[type[BaseException]], exc: Optional[BaseException], tb: Optional[TracebackType] + ) -> None: ... + def close(self) -> None: ... @classmethod def from_container_url( cls, diff --git a/sdk/storage/azure-storage-blob/azure/storage/blob/_lease.pyi b/sdk/storage/azure-storage-blob/azure/storage/blob/_lease.pyi index 748bf0eb16c5..24771b003b4e 100644 --- a/sdk/storage/azure-storage-blob/azure/storage/blob/_lease.pyi +++ b/sdk/storage/azure-storage-blob/azure/storage/blob/_lease.pyi @@ -14,11 +14,7 @@ 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: ... + def __init__(self, client: Union[BlobClient, ContainerClient], lease_id: Optional[str] = None) -> None: ... @distributed_trace def acquire( self, 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 a20b62e60ffa..3ef8d3122ed0 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 @@ -10,7 +10,7 @@ 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 @@ -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 @@ -642,26 +642,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..7e6837ca7469 --- /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] + AsyncStorageAccountHostsMixin, + StorageAccountHostsMixin, + StorageEncryptionMixin, + AbstractAsyncContextManager +): + 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.pyi b/sdk/storage/azure-storage-blob/azure/storage/blob/aio/_blob_service_client_async.pyi index 76ae29e84e3f..6d12758291e9 100644 --- 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 @@ -3,9 +3,10 @@ # Licensed under the MIT License. See License.txt in the project root for # license information. # -------------------------------------------------------------------------- -# pylint: disable=unused-argument +# pylint: skip-file from datetime import datetime +from types import TracebackType from typing import ( Any, Dict, @@ -41,13 +42,10 @@ from .._shared.base_client import StorageAccountHostsMixin from .._shared.base_client_async import AsyncStorageAccountHostsMixin from .._shared.models import UserDelegationKey - class BlobServiceClient( # type: ignore [misc] - AsyncStorageAccountHostsMixin, - StorageAccountHostsMixin, - StorageEncryptionMixin -): # pylint: disable=client-accepts-api-version-keyword - def __init__( # pylint: disable=super-init-not-called + AsyncStorageAccountHostsMixin, StorageAccountHostsMixin, StorageEncryptionMixin +): + def __init__( self, account_url: str, credential: Optional[ @@ -65,9 +63,12 @@ class BlobServiceClient( # type: ignore [misc] max_chunk_get_size: int = 4 * 1024 * 1024, audience: Optional[str] = None, **kwargs: Any - ) -> None: - ... - + ) -> None: ... + async def __aenter__(self) -> Self: ... + 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, @@ -87,29 +88,17 @@ class BlobServiceClient( # type: ignore [misc] max_chunk_get_size: int = 4 * 1024 * 1024, audience: Optional[str] = None, **kwargs: Any - ) -> Self: - ... - + ) -> Self: ... @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: - ... - + 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, @@ -121,9 +110,7 @@ class BlobServiceClient( # type: ignore [misc] delete_retention_policy: Optional[RetentionPolicy] = None, static_website: Optional[StaticWebsite] = None, **kwargs: Any - ) -> None: - ... - + ) -> None: ... @distributed_trace def list_containers( self, @@ -135,9 +122,7 @@ class BlobServiceClient( # type: ignore [misc] results_per_page: Optional[int] = None, timeout: Optional[int] = None, **kwargs: Any - ) -> AsyncItemPaged[ContainerProperties]: - ... - + ) -> AsyncItemPaged[ContainerProperties]: ... @distributed_trace def find_blobs_by_tags( self, @@ -146,9 +131,7 @@ class BlobServiceClient( # type: ignore [misc] results_per_page: Optional[int] = None, timeout: Optional[int] = None, **kwargs: Any - ) -> AsyncItemPaged[FilteredBlob]: - ... - + ) -> AsyncItemPaged[FilteredBlob]: ... @distributed_trace_async async def create_container( self, @@ -159,9 +142,7 @@ class BlobServiceClient( # type: ignore [misc] container_encryption_scope: Optional[Union[dict, ContainerEncryptionScope]] = None, timeout: Optional[int] = None, **kwargs: Any - ) -> ContainerClient: - ... - + ) -> ContainerClient: ... @distributed_trace_async async def delete_container( self, @@ -174,9 +155,7 @@ class BlobServiceClient( # type: ignore [misc] match_condition: Optional[MatchConditions] = None, timeout: Optional[int] = None, **kwargs: Any - ) -> None: - ... - + ) -> None: ... @distributed_trace_async async def _rename_container( self, @@ -186,9 +165,7 @@ class BlobServiceClient( # type: ignore [misc] lease: Optional[Union[BlobLeaseClient, str]] = None, timeout: Optional[int] = None, **kwargs: Any - ) -> ContainerClient: - ... - + ) -> ContainerClient: ... @distributed_trace_async async def undelete_container( self, @@ -197,11 +174,8 @@ class BlobServiceClient( # type: ignore [misc] *, timeout: Optional[int] = None, **kwargs: Any - ) -> ContainerClient: - ... - + ) -> ContainerClient: ... def get_container_client(self, container: Union[ContainerProperties, str]) -> ContainerClient: ... - def get_blob_client( self, container: Union[ContainerProperties, str], @@ -210,5 +184,4 @@ class BlobServiceClient( # type: ignore [misc] *, version_id: Optional[str] = None, **kwargs: Any - ) -> BlobClient: - ... + ) -> BlobClient: ... 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 index 9fccfb768e26..7b31fd84d517 100644 --- 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 @@ -6,6 +6,7 @@ # pylint: skip-file from datetime import datetime +from types import TracebackType from typing import ( Any, AnyStr, @@ -54,10 +55,8 @@ from .._models import ( from .._shared.base_client import StorageAccountHostsMixin from .._shared.base_client_async import AsyncStorageAccountHostsMixin -class ContainerClient( # type: ignore[misc] - AsyncStorageAccountHostsMixin, - StorageAccountHostsMixin, - StorageEncryptionMixin +class ContainerClient( # type: ignore[misc] + AsyncStorageAccountHostsMixin, StorageAccountHostsMixin, StorageEncryptionMixin ): account_name: str container_name: str @@ -81,6 +80,11 @@ class ContainerClient( # type: ignore[misc] use_byte_buffer: Optional[bool] = None, **kwargs: Any ) -> None: ... + async def __aenter__(self) -> Self: ... + 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, 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 index 8e102c235498..d0c4a766dca9 100644 --- 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 @@ -14,11 +14,7 @@ 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: ... + def __init__(self, client: Union[BlobClient, ContainerClient], lease_id: Optional[str] = None) -> None: ... @distributed_trace_async async def acquire( self, From 0f4a49533a29da30b00914d4e1616814cf99ed7a Mon Sep 17 00:00:00 2001 From: Peter Wu Date: Wed, 25 Jun 2025 17:51:47 -0400 Subject: [PATCH 05/11] Reverted changes --- .../azure/storage/blob/_blob_client.pyi | 7 ++++--- .../azure/storage/blob/aio/_blob_client_async.pyi | 9 ++++----- 2 files changed, 8 insertions(+), 8 deletions(-) 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 index bea732d1880c..fa367cf325ab 100644 --- a/sdk/storage/azure-storage-blob/azure/storage/blob/_blob_client.pyi +++ b/sdk/storage/azure-storage-blob/azure/storage/blob/_blob_client.pyi @@ -21,6 +21,7 @@ from typing import ( Tuple, Union, ) +from typing_extensions import Self from azure.core import MatchConditions from azure.core.credentials import AzureNamedKeyCredential, AzureSasCredential, TokenCredential @@ -75,7 +76,7 @@ class BlobClient(StorageAccountHostsMixin, StorageEncryptionMixin): use_byte_buffer: Optional[bool] = None, **kwargs: Any ) -> None: ... - def __enter__(self) -> "BlobClient": ... + def __enter__(self) -> Self: ... def __exit__( self, typ: Optional[type[BaseException]], exc: Optional[BaseException], tb: Optional[TracebackType] ) -> None: ... @@ -101,7 +102,7 @@ class BlobClient(StorageAccountHostsMixin, StorageEncryptionMixin): min_large_block_upload_threshold: int = 4 * 1024 * 1024 + 1, use_byte_buffer: Optional[bool] = None, **kwargs: Any - ) -> "BlobClient": ... + ) -> Self: ... @classmethod def from_connection_string( cls, @@ -125,7 +126,7 @@ class BlobClient(StorageAccountHostsMixin, StorageEncryptionMixin): min_large_block_upload_threshold: int = 4 * 1024 * 1024 + 1, use_byte_buffer: Optional[bool] = None, **kwargs: Any - ) -> "BlobClient": ... + ) -> Self: ... @distributed_trace def get_account_information(self, **kwargs: Any) -> Dict[str, str]: ... @distributed_trace 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 index 7e6837ca7469..9d188840a6fe 100644 --- 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 @@ -5,7 +5,6 @@ # -------------------------------------------------------------------------- # pylint: skip-file -from contextlib import AbstractAsyncContextManager from datetime import datetime from types import TracebackType from typing import ( @@ -24,6 +23,7 @@ from typing import ( Tuple, Union, ) +from typing_extensions import Self from azure.core import MatchConditions from azure.core.credentials import AzureNamedKeyCredential, AzureSasCredential @@ -55,7 +55,6 @@ class BlobClient( # type: ignore[misc] AsyncStorageAccountHostsMixin, StorageAccountHostsMixin, StorageEncryptionMixin, - AbstractAsyncContextManager ): def __init__( self, @@ -80,7 +79,7 @@ class BlobClient( # type: ignore[misc] use_byte_buffer: Optional[bool] = None, **kwargs: Any ) -> None: ... - async def __aenter__(self) -> "BlobClient": ... + async def __aenter__(self) -> Self: ... async def __aexit__( self, typ: Optional[type[BaseException]], exc: Optional[BaseException], tb: Optional[TracebackType] ) -> None: ... @@ -106,7 +105,7 @@ class BlobClient( # type: ignore[misc] min_large_block_upload_threshold: int = 4 * 1024 * 1024 + 1, use_byte_buffer: Optional[bool] = None, **kwargs: Any - ) -> "BlobClient": ... + ) -> Self: ... @classmethod def from_connection_string( cls, @@ -130,7 +129,7 @@ class BlobClient( # type: ignore[misc] min_large_block_upload_threshold: int = 4 * 1024 * 1024 + 1, use_byte_buffer: Optional[bool] = None, **kwargs: Any - ) -> "BlobClient": ... + ) -> Self: ... @distributed_trace_async async def get_account_information(self, **kwargs: Any) -> Dict[str, str]: ... @distributed_trace_async From d41d0f668281aaed2fcc97c77aee0afdd9a7505d Mon Sep 17 00:00:00 2001 From: Peter Wu Date: Thu, 26 Jun 2025 16:10:20 -0400 Subject: [PATCH 06/11] AbstractAsyncContextManager for async pyi files --- .../azure/storage/blob/aio/_blob_client_async.pyi | 2 ++ .../azure/storage/blob/aio/_blob_service_client_async.pyi | 6 +++++- .../azure/storage/blob/aio/_container_client_async.pyi | 6 +++++- 3 files changed, 12 insertions(+), 2 deletions(-) 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 index 9d188840a6fe..11e4cbbe053f 100644 --- 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 @@ -5,6 +5,7 @@ # -------------------------------------------------------------------------- # pylint: skip-file +from contextlib import AbstractAsyncContextManager from datetime import datetime from types import TracebackType from typing import ( @@ -52,6 +53,7 @@ from .._shared.base_client import StorageAccountHostsMixin from .._shared.base_client_async import AsyncStorageAccountHostsMixin class BlobClient( # type: ignore[misc] + AbstractAsyncContextManager, AsyncStorageAccountHostsMixin, StorageAccountHostsMixin, StorageEncryptionMixin, 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 index 6d12758291e9..d12a082bf5f2 100644 --- 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 @@ -5,6 +5,7 @@ # -------------------------------------------------------------------------- # pylint: skip-file +from contextlib import AbstractAsyncContextManager from datetime import datetime from types import TracebackType from typing import ( @@ -43,7 +44,10 @@ from .._shared.base_client_async import AsyncStorageAccountHostsMixin from .._shared.models import UserDelegationKey class BlobServiceClient( # type: ignore [misc] - AsyncStorageAccountHostsMixin, StorageAccountHostsMixin, StorageEncryptionMixin + AbstractAsyncContextManager, + AsyncStorageAccountHostsMixin, + StorageAccountHostsMixin, + StorageEncryptionMixin ): def __init__( self, 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 index 7b31fd84d517..ea557647dafa 100644 --- 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 @@ -5,6 +5,7 @@ # -------------------------------------------------------------------------- # pylint: skip-file +from contextlib import AbstractAsyncContextManager from datetime import datetime from types import TracebackType from typing import ( @@ -56,7 +57,10 @@ from .._shared.base_client import StorageAccountHostsMixin from .._shared.base_client_async import AsyncStorageAccountHostsMixin class ContainerClient( # type: ignore[misc] - AsyncStorageAccountHostsMixin, StorageAccountHostsMixin, StorageEncryptionMixin + AbstractAsyncContextManager, + AsyncStorageAccountHostsMixin, + StorageAccountHostsMixin, + StorageEncryptionMixin ): account_name: str container_name: str From 9d324e81f893a0736b1896977340cd5bfcacf855 Mon Sep 17 00:00:00 2001 From: Peter Wu Date: Thu, 26 Jun 2025 16:11:50 -0400 Subject: [PATCH 07/11] Black formatter --- .../azure/storage/blob/aio/_blob_service_client_async.pyi | 5 +---- .../azure/storage/blob/aio/_container_client_async.pyi | 5 +---- 2 files changed, 2 insertions(+), 8 deletions(-) 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 index d12a082bf5f2..50e473590887 100644 --- 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 @@ -44,10 +44,7 @@ from .._shared.base_client_async import AsyncStorageAccountHostsMixin from .._shared.models import UserDelegationKey class BlobServiceClient( # type: ignore [misc] - AbstractAsyncContextManager, - AsyncStorageAccountHostsMixin, - StorageAccountHostsMixin, - StorageEncryptionMixin + AbstractAsyncContextManager, AsyncStorageAccountHostsMixin, StorageAccountHostsMixin, StorageEncryptionMixin ): def __init__( self, 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 index ea557647dafa..d8b1602c542f 100644 --- 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 @@ -57,10 +57,7 @@ from .._shared.base_client import StorageAccountHostsMixin from .._shared.base_client_async import AsyncStorageAccountHostsMixin class ContainerClient( # type: ignore[misc] - AbstractAsyncContextManager, - AsyncStorageAccountHostsMixin, - StorageAccountHostsMixin, - StorageEncryptionMixin + AbstractAsyncContextManager, AsyncStorageAccountHostsMixin, StorageAccountHostsMixin, StorageEncryptionMixin ): account_name: str container_name: str From d3c35ccbdf1ecbd29f81a4992e0681326c16b102 Mon Sep 17 00:00:00 2001 From: Peter Wu Date: Sat, 28 Jun 2025 11:44:38 -0400 Subject: [PATCH 08/11] Test --- .../azure/storage/blob/_blob_client.py | 9 +++++---- .../azure/storage/blob/_blob_client.pyi | 9 +++++---- 2 files changed, 10 insertions(+), 8 deletions(-) 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 98428b3cc3ae..f7119d5044b6 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,6 +6,7 @@ # 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 ( @@ -89,7 +90,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 +191,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 +222,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 +270,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: 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 index fa367cf325ab..7a87226248f6 100644 --- a/sdk/storage/azure-storage-blob/azure/storage/blob/_blob_client.pyi +++ b/sdk/storage/azure-storage-blob/azure/storage/blob/_blob_client.pyi @@ -5,6 +5,7 @@ # -------------------------------------------------------------------------- # pylint: skip-file +from contextlib import AbstractContextManager from datetime import datetime from types import TracebackType from typing import ( @@ -52,7 +53,7 @@ from ._models import ( from ._quick_query_helper import BlobQueryReader from ._shared.base_client import StorageAccountHostsMixin -class BlobClient(StorageAccountHostsMixin, StorageEncryptionMixin): +class BlobClient(AbstractContextManager, StorageAccountHostsMixin, StorageEncryptionMixin): def __init__( self, account_url: str, @@ -76,7 +77,7 @@ class BlobClient(StorageAccountHostsMixin, StorageEncryptionMixin): use_byte_buffer: Optional[bool] = None, **kwargs: Any ) -> None: ... - def __enter__(self) -> Self: ... + def __enter__(self) -> "BlobClient": ... def __exit__( self, typ: Optional[type[BaseException]], exc: Optional[BaseException], tb: Optional[TracebackType] ) -> None: ... @@ -102,7 +103,7 @@ class BlobClient(StorageAccountHostsMixin, StorageEncryptionMixin): min_large_block_upload_threshold: int = 4 * 1024 * 1024 + 1, use_byte_buffer: Optional[bool] = None, **kwargs: Any - ) -> Self: ... + ) -> "BlobClient": ... @classmethod def from_connection_string( cls, @@ -126,7 +127,7 @@ class BlobClient(StorageAccountHostsMixin, StorageEncryptionMixin): min_large_block_upload_threshold: int = 4 * 1024 * 1024 + 1, use_byte_buffer: Optional[bool] = None, **kwargs: Any - ) -> Self: ... + ) -> "BlobClient": ... @distributed_trace def get_account_information(self, **kwargs: Any) -> Dict[str, str]: ... @distributed_trace From 46c87e679525fc6557cc5d17acab3a14d0a6e1cf Mon Sep 17 00:00:00 2001 From: Peter Wu Date: Sun, 29 Jun 2025 22:35:52 -0400 Subject: [PATCH 09/11] Made classmethods/__enter__ return 'ClassName' consistent --- .../azure/storage/blob/_blob_client.pyi | 1 - .../azure/storage/blob/_blob_service_client.py | 8 ++++---- .../azure/storage/blob/_blob_service_client.pyi | 7 ++++--- .../azure/storage/blob/_container_client.py | 10 +++++----- .../azure/storage/blob/_container_client.pyi | 8 ++++---- .../azure/storage/blob/aio/_blob_client_async.py | 15 ++++++++++----- .../azure/storage/blob/aio/_blob_client_async.pyi | 7 +++---- .../blob/aio/_blob_service_client_async.py | 7 ++++--- .../blob/aio/_blob_service_client_async.pyi | 5 ++--- .../storage/blob/aio/_container_client_async.py | 15 ++++++++++----- .../storage/blob/aio/_container_client_async.pyi | 6 +++--- 11 files changed, 49 insertions(+), 40 deletions(-) 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 index 7a87226248f6..d0c3a5a8b78d 100644 --- a/sdk/storage/azure-storage-blob/azure/storage/blob/_blob_client.pyi +++ b/sdk/storage/azure-storage-blob/azure/storage/blob/_blob_client.pyi @@ -22,7 +22,6 @@ from typing import ( Tuple, Union, ) -from typing_extensions import Self from azure.core import MatchConditions from azure.core.credentials import AzureNamedKeyCredential, AzureSasCredential, TokenCredential 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 81b5775ea24d..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 @@ -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: 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 index c3f1a6001bd8..b62993d9d889 100644 --- 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 @@ -5,6 +5,7 @@ # -------------------------------------------------------------------------- # pylint: skip-file +from contextlib import AbstractContextManager from datetime import datetime from types import TracebackType from typing import ( @@ -38,7 +39,7 @@ from ._models import ( from ._shared.base_client import StorageAccountHostsMixin from ._shared.models import UserDelegationKey -class BlobServiceClient(StorageAccountHostsMixin, StorageEncryptionMixin): +class BlobServiceClient(AbstractContextManager, StorageAccountHostsMixin, StorageEncryptionMixin): def __init__( self, account_url: str, @@ -58,7 +59,7 @@ class BlobServiceClient(StorageAccountHostsMixin, StorageEncryptionMixin): audience: Optional[str] = None, **kwargs: Any ) -> None: ... - def __enter__(self) -> Self: ... + def __enter__(self) -> "BlobServiceClient": ... def __exit__( self, typ: Optional[type[BaseException]], exc: Optional[BaseException], tb: Optional[TracebackType] ) -> None: ... @@ -82,7 +83,7 @@ class BlobServiceClient(StorageAccountHostsMixin, StorageEncryptionMixin): max_chunk_get_size: int = 4 * 1024 * 1024, audience: Optional[str] = None, **kwargs: Any - ) -> Self: ... + ) -> "BlobServiceClient": ... @distributed_trace def get_user_delegation_key( self, key_start_time: datetime, key_expiry_time: datetime, *, timeout: Optional[int] = None, **kwargs: Any 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 index 4dd38ee97991..a45dfb10c31f 100644 --- a/sdk/storage/azure-storage-blob/azure/storage/blob/_container_client.pyi +++ b/sdk/storage/azure-storage-blob/azure/storage/blob/_container_client.pyi @@ -5,6 +5,7 @@ # -------------------------------------------------------------------------- # pylint: skip-file +from contextlib import AbstractContextManager from datetime import datetime from types import TracebackType from typing import ( @@ -20,7 +21,6 @@ from typing import ( overload, Union, ) -from typing_extensions import Self from azure.core import MatchConditions from azure.core.credentials import AzureNamedKeyCredential, AzureSasCredential, TokenCredential @@ -72,7 +72,7 @@ class ContainerClient(StorageAccountHostsMixin, StorageEncryptionMixin): use_byte_buffer: Optional[bool] = None, **kwargs: Any, ) -> None: ... - def __enter__(self) -> Self: ... + def __enter__(self) -> "ContainerClient": ... def __exit__( self, typ: Optional[type[BaseException]], exc: Optional[BaseException], tb: Optional[TracebackType] ) -> None: ... @@ -96,7 +96,7 @@ class ContainerClient(StorageAccountHostsMixin, StorageEncryptionMixin): min_large_block_upload_threshold: int = 4 * 1024 * 1024 + 1, use_byte_buffer: Optional[bool] = None, **kwargs: Any, - ) -> Self: ... + ) -> "ContainerClient": ... @classmethod def from_connection_string( cls, @@ -117,7 +117,7 @@ class ContainerClient(StorageAccountHostsMixin, StorageEncryptionMixin): min_large_block_upload_threshold: int = 4 * 1024 * 1024 + 1, use_byte_buffer: Optional[bool] = None, **kwargs: Any, - ) -> Self: ... + ) -> "ContainerClient": ... @distributed_trace def create_container( self, 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 3ef8d3122ed0..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,6 +6,7 @@ # 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 ( @@ -13,7 +14,6 @@ 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 @@ -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: @@ -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: 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 index 11e4cbbe053f..6ebbdcd07a68 100644 --- 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 @@ -24,7 +24,6 @@ from typing import ( Tuple, Union, ) -from typing_extensions import Self from azure.core import MatchConditions from azure.core.credentials import AzureNamedKeyCredential, AzureSasCredential @@ -81,7 +80,7 @@ class BlobClient( # type: ignore[misc] use_byte_buffer: Optional[bool] = None, **kwargs: Any ) -> None: ... - async def __aenter__(self) -> Self: ... + async def __aenter__(self) -> "BlobClient": ... async def __aexit__( self, typ: Optional[type[BaseException]], exc: Optional[BaseException], tb: Optional[TracebackType] ) -> None: ... @@ -107,7 +106,7 @@ class BlobClient( # type: ignore[misc] min_large_block_upload_threshold: int = 4 * 1024 * 1024 + 1, use_byte_buffer: Optional[bool] = None, **kwargs: Any - ) -> Self: ... + ) -> "BlobClient": ... @classmethod def from_connection_string( cls, @@ -131,7 +130,7 @@ class BlobClient( # type: ignore[misc] min_large_block_upload_threshold: int = 4 * 1024 * 1024 + 1, use_byte_buffer: Optional[bool] = None, **kwargs: Any - ) -> Self: ... + ) -> "BlobClient": ... @distributed_trace_async async def get_account_information(self, **kwargs: Any) -> Dict[str, str]: ... @distributed_trace_async 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 6d28b4c6d732..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 @@ -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: 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 index 50e473590887..348bde13cc8f 100644 --- 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 @@ -15,7 +15,6 @@ from typing import ( Optional, Union, ) -from typing_extensions import Self from azure.core import MatchConditions from azure.core.async_paging import AsyncItemPaged @@ -65,7 +64,7 @@ class BlobServiceClient( # type: ignore [misc] audience: Optional[str] = None, **kwargs: Any ) -> None: ... - async def __aenter__(self) -> Self: ... + async def __aenter__(self) -> "BlobServiceClient": ... async def __aexit__( self, typ: Optional[type[BaseException]], exc: Optional[BaseException], tb: Optional[TracebackType] ) -> None: ... @@ -89,7 +88,7 @@ class BlobServiceClient( # type: ignore [misc] max_chunk_get_size: int = 4 * 1024 * 1024, audience: Optional[str] = None, **kwargs: Any - ) -> Self: ... + ) -> "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 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 index d8b1602c542f..cd7d3cbc16b5 100644 --- 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 @@ -81,7 +81,7 @@ class ContainerClient( # type: ignore[misc] use_byte_buffer: Optional[bool] = None, **kwargs: Any ) -> None: ... - async def __aenter__(self) -> Self: ... + async def __aenter__(self) -> "ContainerClient": ... async def __aexit__( self, typ: Optional[type[BaseException]], exc: Optional[BaseException], tb: Optional[TracebackType] ) -> None: ... @@ -105,7 +105,7 @@ class ContainerClient( # type: ignore[misc] min_large_block_upload_threshold: int = 4 * 1024 * 1024 + 1, use_byte_buffer: Optional[bool] = None, **kwargs: Any - ) -> Self: ... + ) -> "ContainerClient": ... @classmethod def from_connection_string( cls, @@ -126,7 +126,7 @@ class ContainerClient( # type: ignore[misc] min_large_block_upload_threshold: int = 4 * 1024 * 1024 + 1, use_byte_buffer: Optional[bool] = None, **kwargs: Any - ) -> Self: ... + ) -> "ContainerClient": ... @distributed_trace_async async def create_container( self, From 5d1bcf8c4e2076b10652235704676fd2e77e4525 Mon Sep 17 00:00:00 2001 From: Peter Wu Date: Mon, 30 Jun 2025 10:21:50 -0400 Subject: [PATCH 10/11] Fixed various misc errors --- .../azure-storage-blob/azure/storage/blob/_blob_client.py | 1 - .../azure-storage-blob/azure/storage/blob/_container_client.pyi | 2 +- .../azure/storage/blob/aio/_container_client_async.pyi | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) 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 f7119d5044b6..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 @@ -13,7 +13,6 @@ 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 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 index a45dfb10c31f..dc06cdca4e9d 100644 --- a/sdk/storage/azure-storage-blob/azure/storage/blob/_container_client.pyi +++ b/sdk/storage/azure-storage-blob/azure/storage/blob/_container_client.pyi @@ -136,7 +136,7 @@ class ContainerClient(StorageAccountHostsMixin, StorageEncryptionMixin): lease: Optional[Union[BlobLeaseClient, str]] = None, timeout: Optional[int] = None, **kwargs: Any, - ) -> Self: ... + ) -> "ContainerClient": ... @distributed_trace def delete_container( self, 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 index cd7d3cbc16b5..b8e9783e4589 100644 --- 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 @@ -145,7 +145,7 @@ class ContainerClient( # type: ignore[misc] lease: Optional[Union[BlobLeaseClient, str]] = None, timeout: Optional[int] = None, **kwargs: Any - ) -> Self: ... + ) -> "ContainerClient": ... @distributed_trace_async async def delete_container( self, From 8327bafdd455d7ba2c43869440f7157a79ed7c32 Mon Sep 17 00:00:00 2001 From: Peter Wu Date: Wed, 2 Jul 2025 15:23:45 -0400 Subject: [PATCH 11/11] Reverted changes --- .../azure/storage/blob/_blob_client.py | 1 - .../azure/storage/blob/_blob_client.pyi | 1 - .../azure/storage/blob/_blob_service_client.py | 8 ++++---- .../azure/storage/blob/_blob_service_client.pyi | 7 ++++--- .../azure/storage/blob/_container_client.py | 10 +++++----- .../azure/storage/blob/_container_client.pyi | 10 +++++----- .../azure/storage/blob/aio/_blob_client_async.py | 15 ++++++++++----- .../azure/storage/blob/aio/_blob_client_async.pyi | 7 +++---- .../blob/aio/_blob_service_client_async.py | 7 ++++--- .../blob/aio/_blob_service_client_async.pyi | 5 ++--- .../storage/blob/aio/_container_client_async.py | 15 ++++++++++----- .../storage/blob/aio/_container_client_async.pyi | 8 ++++---- 12 files changed, 51 insertions(+), 43 deletions(-) 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 f7119d5044b6..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 @@ -13,7 +13,6 @@ 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 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 index 7a87226248f6..d0c3a5a8b78d 100644 --- a/sdk/storage/azure-storage-blob/azure/storage/blob/_blob_client.pyi +++ b/sdk/storage/azure-storage-blob/azure/storage/blob/_blob_client.pyi @@ -22,7 +22,6 @@ from typing import ( Tuple, Union, ) -from typing_extensions import Self from azure.core import MatchConditions from azure.core.credentials import AzureNamedKeyCredential, AzureSasCredential, TokenCredential 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 81b5775ea24d..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 @@ -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: 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 index c3f1a6001bd8..b62993d9d889 100644 --- 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 @@ -5,6 +5,7 @@ # -------------------------------------------------------------------------- # pylint: skip-file +from contextlib import AbstractContextManager from datetime import datetime from types import TracebackType from typing import ( @@ -38,7 +39,7 @@ from ._models import ( from ._shared.base_client import StorageAccountHostsMixin from ._shared.models import UserDelegationKey -class BlobServiceClient(StorageAccountHostsMixin, StorageEncryptionMixin): +class BlobServiceClient(AbstractContextManager, StorageAccountHostsMixin, StorageEncryptionMixin): def __init__( self, account_url: str, @@ -58,7 +59,7 @@ class BlobServiceClient(StorageAccountHostsMixin, StorageEncryptionMixin): audience: Optional[str] = None, **kwargs: Any ) -> None: ... - def __enter__(self) -> Self: ... + def __enter__(self) -> "BlobServiceClient": ... def __exit__( self, typ: Optional[type[BaseException]], exc: Optional[BaseException], tb: Optional[TracebackType] ) -> None: ... @@ -82,7 +83,7 @@ class BlobServiceClient(StorageAccountHostsMixin, StorageEncryptionMixin): max_chunk_get_size: int = 4 * 1024 * 1024, audience: Optional[str] = None, **kwargs: Any - ) -> Self: ... + ) -> "BlobServiceClient": ... @distributed_trace def get_user_delegation_key( self, key_start_time: datetime, key_expiry_time: datetime, *, timeout: Optional[int] = None, **kwargs: Any 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 index 4dd38ee97991..dc06cdca4e9d 100644 --- a/sdk/storage/azure-storage-blob/azure/storage/blob/_container_client.pyi +++ b/sdk/storage/azure-storage-blob/azure/storage/blob/_container_client.pyi @@ -5,6 +5,7 @@ # -------------------------------------------------------------------------- # pylint: skip-file +from contextlib import AbstractContextManager from datetime import datetime from types import TracebackType from typing import ( @@ -20,7 +21,6 @@ from typing import ( overload, Union, ) -from typing_extensions import Self from azure.core import MatchConditions from azure.core.credentials import AzureNamedKeyCredential, AzureSasCredential, TokenCredential @@ -72,7 +72,7 @@ class ContainerClient(StorageAccountHostsMixin, StorageEncryptionMixin): use_byte_buffer: Optional[bool] = None, **kwargs: Any, ) -> None: ... - def __enter__(self) -> Self: ... + def __enter__(self) -> "ContainerClient": ... def __exit__( self, typ: Optional[type[BaseException]], exc: Optional[BaseException], tb: Optional[TracebackType] ) -> None: ... @@ -96,7 +96,7 @@ class ContainerClient(StorageAccountHostsMixin, StorageEncryptionMixin): min_large_block_upload_threshold: int = 4 * 1024 * 1024 + 1, use_byte_buffer: Optional[bool] = None, **kwargs: Any, - ) -> Self: ... + ) -> "ContainerClient": ... @classmethod def from_connection_string( cls, @@ -117,7 +117,7 @@ class ContainerClient(StorageAccountHostsMixin, StorageEncryptionMixin): min_large_block_upload_threshold: int = 4 * 1024 * 1024 + 1, use_byte_buffer: Optional[bool] = None, **kwargs: Any, - ) -> Self: ... + ) -> "ContainerClient": ... @distributed_trace def create_container( self, @@ -136,7 +136,7 @@ class ContainerClient(StorageAccountHostsMixin, StorageEncryptionMixin): lease: Optional[Union[BlobLeaseClient, str]] = None, timeout: Optional[int] = None, **kwargs: Any, - ) -> Self: ... + ) -> "ContainerClient": ... @distributed_trace def delete_container( self, 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 3ef8d3122ed0..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,6 +6,7 @@ # 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 ( @@ -13,7 +14,6 @@ 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 @@ -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: @@ -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: 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 index 11e4cbbe053f..6ebbdcd07a68 100644 --- 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 @@ -24,7 +24,6 @@ from typing import ( Tuple, Union, ) -from typing_extensions import Self from azure.core import MatchConditions from azure.core.credentials import AzureNamedKeyCredential, AzureSasCredential @@ -81,7 +80,7 @@ class BlobClient( # type: ignore[misc] use_byte_buffer: Optional[bool] = None, **kwargs: Any ) -> None: ... - async def __aenter__(self) -> Self: ... + async def __aenter__(self) -> "BlobClient": ... async def __aexit__( self, typ: Optional[type[BaseException]], exc: Optional[BaseException], tb: Optional[TracebackType] ) -> None: ... @@ -107,7 +106,7 @@ class BlobClient( # type: ignore[misc] min_large_block_upload_threshold: int = 4 * 1024 * 1024 + 1, use_byte_buffer: Optional[bool] = None, **kwargs: Any - ) -> Self: ... + ) -> "BlobClient": ... @classmethod def from_connection_string( cls, @@ -131,7 +130,7 @@ class BlobClient( # type: ignore[misc] min_large_block_upload_threshold: int = 4 * 1024 * 1024 + 1, use_byte_buffer: Optional[bool] = None, **kwargs: Any - ) -> Self: ... + ) -> "BlobClient": ... @distributed_trace_async async def get_account_information(self, **kwargs: Any) -> Dict[str, str]: ... @distributed_trace_async 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 6d28b4c6d732..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 @@ -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: 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 index 50e473590887..348bde13cc8f 100644 --- 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 @@ -15,7 +15,6 @@ from typing import ( Optional, Union, ) -from typing_extensions import Self from azure.core import MatchConditions from azure.core.async_paging import AsyncItemPaged @@ -65,7 +64,7 @@ class BlobServiceClient( # type: ignore [misc] audience: Optional[str] = None, **kwargs: Any ) -> None: ... - async def __aenter__(self) -> Self: ... + async def __aenter__(self) -> "BlobServiceClient": ... async def __aexit__( self, typ: Optional[type[BaseException]], exc: Optional[BaseException], tb: Optional[TracebackType] ) -> None: ... @@ -89,7 +88,7 @@ class BlobServiceClient( # type: ignore [misc] max_chunk_get_size: int = 4 * 1024 * 1024, audience: Optional[str] = None, **kwargs: Any - ) -> Self: ... + ) -> "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 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 index d8b1602c542f..b8e9783e4589 100644 --- 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 @@ -81,7 +81,7 @@ class ContainerClient( # type: ignore[misc] use_byte_buffer: Optional[bool] = None, **kwargs: Any ) -> None: ... - async def __aenter__(self) -> Self: ... + async def __aenter__(self) -> "ContainerClient": ... async def __aexit__( self, typ: Optional[type[BaseException]], exc: Optional[BaseException], tb: Optional[TracebackType] ) -> None: ... @@ -105,7 +105,7 @@ class ContainerClient( # type: ignore[misc] min_large_block_upload_threshold: int = 4 * 1024 * 1024 + 1, use_byte_buffer: Optional[bool] = None, **kwargs: Any - ) -> Self: ... + ) -> "ContainerClient": ... @classmethod def from_connection_string( cls, @@ -126,7 +126,7 @@ class ContainerClient( # type: ignore[misc] min_large_block_upload_threshold: int = 4 * 1024 * 1024 + 1, use_byte_buffer: Optional[bool] = None, **kwargs: Any - ) -> Self: ... + ) -> "ContainerClient": ... @distributed_trace_async async def create_container( self, @@ -145,7 +145,7 @@ class ContainerClient( # type: ignore[misc] lease: Optional[Union[BlobLeaseClient, str]] = None, timeout: Optional[int] = None, **kwargs: Any - ) -> Self: ... + ) -> "ContainerClient": ... @distributed_trace_async async def delete_container( self,