0
# Async Operations
1
2
Asynchronous versions of all client classes for high-performance, concurrent operations. The async clients provide identical APIs with async/await patterns, enabling scalable applications that can handle many concurrent storage operations efficiently.
3
4
## Capabilities
5
6
### Async Client Classes
7
8
All client classes have async equivalents in the `azure.storage.blob.aio` module with identical method signatures but using async/await patterns.
9
10
```python { .api }
11
# Async imports
12
from azure.storage.blob.aio import BlobServiceClient, ContainerClient, BlobClient, BlobLeaseClient
13
14
# All async classes support the same methods as sync versions
15
class BlobServiceClient:
16
"""Async version of BlobServiceClient."""
17
async def __aenter__(self) -> 'BlobServiceClient': ...
18
async def __aexit__(self, *args) -> None: ...
19
# All sync methods are available as async methods
20
21
class ContainerClient:
22
"""Async version of ContainerClient."""
23
async def __aenter__(self) -> 'ContainerClient': ...
24
async def __aexit__(self, *args) -> None: ...
25
# All sync methods are available as async methods
26
27
class BlobClient:
28
"""Async version of BlobClient."""
29
async def __aenter__(self) -> 'BlobClient': ...
30
async def __aexit__(self, *args) -> None: ...
31
# All sync methods are available as async methods
32
33
class BlobLeaseClient:
34
"""Async version of BlobLeaseClient."""
35
# All sync methods are available as async methods
36
```
37
38
### Async Context Management
39
40
All async clients support context management for automatic resource cleanup.
41
42
```python { .api }
43
# Context manager support
44
async with BlobServiceClient(account_url, credential) as service_client:
45
# Client is automatically closed when exiting context
46
async for container in service_client.list_containers():
47
print(container.name)
48
```
49
50
### Async Service Client Operations
51
52
Account-level operations with async support for high-throughput scenarios.
53
54
```python { .api }
55
class BlobServiceClient:
56
# Client creation and authentication
57
async def __aenter__(self) -> 'BlobServiceClient': ...
58
async def __aexit__(self, *args) -> None: ...
59
60
# Service configuration (async versions of sync methods)
61
async def get_account_information(self, **kwargs) -> dict: ...
62
async def get_service_properties(self, **kwargs) -> dict: ...
63
async def set_service_properties(self, analytics_logging=None, hour_metrics=None, minute_metrics=None, cors=None, target_version=None, delete_retention_policy=None, static_website=None, **kwargs) -> None: ...
64
async def get_service_stats(self, **kwargs) -> dict: ...
65
async def get_user_delegation_key(self, key_start_time, key_expiry_time, **kwargs) -> 'UserDelegationKey': ...
66
67
# Container management
68
def list_containers(self, name_starts_with=None, include_metadata=False, **kwargs) -> AsyncItemPaged[ContainerProperties]: ...
69
async def create_container(self, name: str, metadata=None, public_access=None, **kwargs) -> ContainerClient: ...
70
async def delete_container(self, container: str, **kwargs) -> None: ...
71
async def undelete_container(self, deleted_container_name: str, deleted_container_version: str, **kwargs) -> ContainerClient: ...
72
73
# Cross-container queries
74
def find_blobs_by_tags(self, filter_expression: str, **kwargs) -> AsyncItemPaged['FilteredBlob']: ...
75
76
# Client factory methods
77
def get_container_client(self, container: str) -> 'ContainerClient': ...
78
def get_blob_client(self, container: str, blob: str, snapshot=None) -> 'BlobClient': ...
79
```
80
81
### Async Container Operations
82
83
Container-level operations with async support for concurrent blob management.
84
85
```python { .api }
86
class ContainerClient:
87
# Context management
88
async def __aenter__(self) -> 'ContainerClient': ...
89
async def __aexit__(self, *args) -> None: ...
90
91
# Container lifecycle
92
async def create_container(self, metadata=None, public_access=None, **kwargs) -> dict: ...
93
async def delete_container(self, **kwargs) -> None: ...
94
async def exists(self, **kwargs) -> bool: ...
95
96
# Properties and metadata
97
async def get_container_properties(self, **kwargs) -> ContainerProperties: ...
98
async def set_container_metadata(self, metadata=None, **kwargs) -> dict: ...
99
async def get_container_access_policy(self, **kwargs) -> dict: ...
100
async def set_container_access_policy(self, signed_identifiers=None, public_access=None, **kwargs) -> dict: ...
101
102
# Leasing
103
async def acquire_lease(self, lease_duration=-1, lease_id=None, **kwargs) -> BlobLeaseClient: ...
104
105
# Blob listing (returns async iterators)
106
def list_blobs(self, name_starts_with=None, include=None, **kwargs) -> AsyncItemPaged[BlobProperties]: ...
107
def list_blob_names(self, **kwargs) -> AsyncItemPaged[str]: ...
108
def walk_blobs(self, name_starts_with=None, include=None, delimiter='/', **kwargs) -> AsyncItemPaged[Union[BlobProperties, BlobPrefix]]: ...
109
def find_blobs_by_tags(self, filter_expression: str, **kwargs) -> AsyncItemPaged['FilteredBlob']: ...
110
111
# Blob operations
112
async def upload_blob(self, name: str, data, blob_type='BlockBlob', **kwargs) -> BlobClient: ...
113
async def download_blob(self, blob: str, offset=None, length=None, **kwargs) -> StorageStreamDownloader: ...
114
async def delete_blob(self, blob: str, delete_snapshots=None, **kwargs) -> None: ...
115
116
# Batch operations (return async iterators)
117
def delete_blobs(self, *blobs, **kwargs) -> AsyncIterator[HttpResponse]: ...
118
def set_standard_blob_tier_blobs(self, *blobs, **kwargs) -> AsyncIterator[HttpResponse]: ...
119
def set_premium_page_blob_tier_blobs(self, *blobs, **kwargs) -> AsyncIterator[HttpResponse]: ...
120
121
# Client factory and account info
122
def get_blob_client(self, blob: str, snapshot=None) -> 'BlobClient': ...
123
async def get_account_information(self, **kwargs) -> dict: ...
124
```
125
126
### Async Blob Operations
127
128
Individual blob operations with async support for high-throughput data transfer.
129
130
```python { .api }
131
class BlobClient:
132
# Context management
133
async def __aenter__(self) -> 'BlobClient': ...
134
async def __aexit__(self, *args) -> None: ...
135
136
# Basic operations
137
async def upload_blob(self, data, blob_type='BlockBlob', **kwargs) -> dict: ...
138
async def download_blob(self, offset=None, length=None, **kwargs) -> StorageStreamDownloader: ...
139
async def delete_blob(self, delete_snapshots=None, **kwargs) -> None: ...
140
async def exists(self, **kwargs) -> bool: ...
141
async def undelete_blob(self, **kwargs) -> None: ...
142
143
# Properties and metadata
144
async def get_blob_properties(self, **kwargs) -> BlobProperties: ...
145
async def set_blob_metadata(self, metadata=None, **kwargs) -> dict: ...
146
async def set_http_headers(self, content_settings=None, **kwargs) -> dict: ...
147
async def set_blob_tags(self, tags=None, **kwargs) -> dict: ...
148
async def get_blob_tags(self, **kwargs) -> dict: ...
149
150
# Snapshots and versioning
151
async def create_snapshot(self, **kwargs) -> dict: ...
152
153
# Copy operations
154
async def start_copy_from_url(self, source_url: str, **kwargs) -> dict: ...
155
async def abort_copy(self, copy_id: str, **kwargs) -> None: ...
156
157
# Leasing
158
async def acquire_lease(self, lease_duration=-1, lease_id=None, **kwargs) -> BlobLeaseClient: ...
159
160
# Tier management
161
async def set_standard_blob_tier(self, standard_blob_tier, **kwargs) -> None: ...
162
async def set_premium_page_blob_tier(self, premium_page_blob_tier, **kwargs) -> None: ...
163
164
# Block blob operations
165
async def stage_block(self, block_id: str, data, **kwargs) -> None: ...
166
async def stage_block_from_url(self, block_id: str, source_url: str, **kwargs) -> None: ...
167
async def get_block_list(self, **kwargs) -> BlockList: ...
168
async def commit_block_list(self, block_list, **kwargs) -> dict: ...
169
170
# Page blob operations
171
async def create_page_blob(self, size: int, **kwargs) -> dict: ...
172
async def upload_page(self, page, offset: int, **kwargs) -> dict: ...
173
async def upload_pages_from_url(self, source_url: str, offset: int, source_offset: int, **kwargs) -> dict: ...
174
async def clear_page(self, offset: int, length: int, **kwargs) -> dict: ...
175
async def get_page_ranges(self, **kwargs) -> PageRanges: ...
176
async def resize_blob(self, size: int, **kwargs) -> dict: ...
177
async def set_sequence_number(self, sequence_number_action, sequence_number=None, **kwargs) -> dict: ...
178
179
# Append blob operations
180
async def create_append_blob(self, **kwargs) -> dict: ...
181
async def append_block(self, data, **kwargs) -> dict: ...
182
async def append_block_from_url(self, copy_source_url: str, **kwargs) -> dict: ...
183
async def seal_append_blob(self, **kwargs) -> dict: ...
184
185
# Query operations
186
async def query_blob(self, query_expression: str, **kwargs) -> BlobQueryReader: ...
187
188
# Immutability and legal hold
189
async def set_immutability_policy(self, **kwargs) -> dict: ...
190
async def delete_immutability_policy(self, **kwargs) -> dict: ...
191
async def set_legal_hold(self, legal_hold: bool, **kwargs) -> dict: ...
192
193
# Account information
194
async def get_account_information(self, **kwargs) -> dict: ...
195
```
196
197
### Async Lease Operations
198
199
Lease management with async support for concurrent lease operations.
200
201
```python { .api }
202
class BlobLeaseClient:
203
# All lease operations as async methods
204
async def acquire(self, lease_duration=-1, **kwargs) -> None: ...
205
async def renew(self, **kwargs) -> None: ...
206
async def release(self, **kwargs) -> None: ...
207
async def change(self, proposed_lease_id: str, **kwargs) -> None: ...
208
async def break_lease(self, lease_break_period=None, **kwargs) -> int: ...
209
```
210
211
### Async Utility Functions
212
213
Convenient async helper functions for common operations.
214
215
```python { .api }
216
async def upload_blob_to_url(blob_url: str, data, credential=None, **kwargs) -> dict:
217
"""
218
Async upload data to a blob URL.
219
220
Args:
221
blob_url (str): Complete URL to the blob
222
data: Data to upload
223
credential: Optional credential for authentication
224
225
Returns:
226
dict: Upload response with ETag and last modified time
227
"""
228
229
async def download_blob_from_url(blob_url: str, output, credential=None, **kwargs) -> None:
230
"""
231
Async download blob from URL to file or stream.
232
233
Args:
234
blob_url (str): Complete URL to the blob
235
output: File path or stream to write to
236
credential: Optional credential for authentication
237
"""
238
```
239
240
## Async Usage Patterns
241
242
### Basic Async Operations
243
244
```python
245
import asyncio
246
from azure.storage.blob.aio import BlobServiceClient
247
248
async def basic_operations():
249
# Create async service client
250
async with BlobServiceClient.from_connection_string(conn_str) as service_client:
251
# List containers asynchronously
252
async for container in service_client.list_containers():
253
print(f"Container: {container.name}")
254
255
# Create container
256
container_client = await service_client.create_container("my-async-container")
257
258
# Upload blob
259
async with container_client.get_blob_client("test.txt") as blob_client:
260
await blob_client.upload_blob("Hello, async world!")
261
262
# Download blob
263
downloader = await blob_client.download_blob()
264
content = await downloader.readall()
265
print(content.decode())
266
267
asyncio.run(basic_operations())
268
```
269
270
### Concurrent Operations
271
272
```python
273
import asyncio
274
from azure.storage.blob.aio import BlobServiceClient
275
276
async def concurrent_uploads():
277
async with BlobServiceClient.from_connection_string(conn_str) as service_client:
278
container_client = service_client.get_container_client("my-container")
279
280
# Upload multiple blobs concurrently
281
async def upload_blob(name, data):
282
blob_client = container_client.get_blob_client(name)
283
return await blob_client.upload_blob(data, overwrite=True)
284
285
# Create multiple upload tasks
286
tasks = [
287
upload_blob(f"file{i}.txt", f"Content of file {i}")
288
for i in range(10)
289
]
290
291
# Execute all uploads concurrently
292
results = await asyncio.gather(*tasks)
293
print(f"Uploaded {len(results)} blobs concurrently")
294
295
asyncio.run(concurrent_uploads())
296
```
297
298
### Async Iteration
299
300
```python
301
async def process_all_blobs():
302
async with BlobServiceClient.from_connection_string(conn_str) as service_client:
303
# Process all containers
304
async for container in service_client.list_containers():
305
print(f"Processing container: {container.name}")
306
307
container_client = service_client.get_container_client(container.name)
308
309
# Process all blobs in container
310
async for blob in container_client.list_blobs():
311
print(f" Blob: {blob.name}, Size: {blob.size}")
312
313
# Download and process blob content if needed
314
if blob.size < 1024: # Small blobs only
315
blob_client = container_client.get_blob_client(blob.name)
316
downloader = await blob_client.download_blob()
317
content = await downloader.readall()
318
# Process content...
319
320
asyncio.run(process_all_blobs())
321
```
322
323
### Async Batch Operations
324
325
```python
326
async def batch_operations():
327
async with BlobServiceClient.from_connection_string(conn_str) as service_client:
328
container_client = service_client.get_container_client("my-container")
329
330
# Batch delete with async iteration
331
blobs_to_delete = ["file1.txt", "file2.txt", "file3.txt"]
332
async for response in container_client.delete_blobs(*blobs_to_delete):
333
if response.status_code == 202:
334
print("Blob deleted successfully")
335
else:
336
print(f"Delete failed: {response.status_code}")
337
338
# Batch tier change with async iteration
339
tier_changes = [
340
("large-file1.dat", StandardBlobTier.COOL),
341
("large-file2.dat", StandardBlobTier.COOL),
342
("old-backup.zip", StandardBlobTier.ARCHIVE)
343
]
344
async for response in container_client.set_standard_blob_tier_blobs(*tier_changes):
345
print(f"Tier change status: {response.status_code}")
346
347
asyncio.run(batch_operations())
348
```
349
350
### Error Handling in Async Operations
351
352
```python
353
from azure.core.exceptions import ResourceNotFoundError, HttpResponseError
354
355
async def async_error_handling():
356
async with BlobServiceClient.from_connection_string(conn_str) as service_client:
357
try:
358
# Attempt operation that might fail
359
blob_client = service_client.get_blob_client("nonexistent-container", "test.txt")
360
await blob_client.upload_blob("test data")
361
362
except ResourceNotFoundError:
363
print("Container does not exist")
364
# Create container and retry
365
container_client = service_client.get_container_client("nonexistent-container")
366
await container_client.create_container()
367
await blob_client.upload_blob("test data")
368
369
except HttpResponseError as e:
370
print(f"HTTP error occurred: {e.status_code} - {e.message}")
371
372
except Exception as e:
373
print(f"Unexpected error: {e}")
374
375
asyncio.run(async_error_handling())
376
```
377
378
## Performance Considerations
379
380
### Concurrency Control
381
382
```python
383
import asyncio
384
from azure.storage.blob.aio import BlobServiceClient
385
386
# Limit concurrent operations to avoid overwhelming the service
387
async def controlled_concurrency():
388
semaphore = asyncio.Semaphore(10) # Max 10 concurrent operations
389
390
async def upload_with_semaphore(container_client, name, data):
391
async with semaphore:
392
blob_client = container_client.get_blob_client(name)
393
return await blob_client.upload_blob(data, overwrite=True)
394
395
async with BlobServiceClient.from_connection_string(conn_str) as service_client:
396
container_client = service_client.get_container_client("my-container")
397
398
# Create many upload tasks with concurrency control
399
tasks = [
400
upload_with_semaphore(container_client, f"file{i}.txt", f"Content {i}")
401
for i in range(100)
402
]
403
404
results = await asyncio.gather(*tasks)
405
print(f"Completed {len(results)} uploads with controlled concurrency")
406
407
asyncio.run(controlled_concurrency())
408
```
409
410
### Async Context Management Best Practices
411
412
```python
413
# Recommended: Use async context managers for automatic cleanup
414
async def recommended_pattern():
415
async with BlobServiceClient.from_connection_string(conn_str) as service_client:
416
async with service_client.get_container_client("my-container") as container_client:
417
async with container_client.get_blob_client("test.txt") as blob_client:
418
await blob_client.upload_blob("data")
419
# All clients automatically closed when exiting context
420
421
# Also supported: Manual client management
422
async def manual_pattern():
423
service_client = BlobServiceClient.from_connection_string(conn_str)
424
try:
425
container_client = service_client.get_container_client("my-container")
426
blob_client = container_client.get_blob_client("test.txt")
427
await blob_client.upload_blob("data")
428
finally:
429
await service_client.close() # Manual cleanup required
430
431
asyncio.run(recommended_pattern())
432
```