or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

async-operations.mdbackup-recovery.mdcrypto-operations.mdimport-export.mdindex.mdkey-management.mdrotation-policies.md

async-operations.mddocs/

0

# Asynchronous Operations

1

2

Complete async/await support for all key management and cryptographic operations, enabling efficient non-blocking I/O in async applications. The azure-keyvault-keys package provides full async implementations parallel to synchronous APIs through dedicated async clients and async-compatible return types.

3

4

## Capabilities

5

6

### Async Key Management Client

7

8

Asynchronous version of KeyClient for non-blocking key operations.

9

10

```python { .api }

11

class KeyClient:

12

"""Asynchronous client for Azure Key Vault key operations."""

13

14

async def __aenter__(self) -> "KeyClient":

15

"""Async context manager entry."""

16

17

async def __aexit__(self, *args) -> None:

18

"""Async context manager exit."""

19

20

async def close(self) -> None:

21

"""Close the client and release resources."""

22

```

23

24

#### Usage Examples

25

26

```python

27

from azure.keyvault.keys.aio import KeyClient

28

from azure.identity.aio import DefaultAzureCredential

29

30

async def main():

31

# Create async client

32

credential = DefaultAzureCredential()

33

async with KeyClient("https://vault.vault.azure.net/", credential) as client:

34

# Perform async operations

35

key = await client.create_rsa_key("async-key", size=2048)

36

print(f"Created key: {key.name}")

37

38

# Run with asyncio

39

import asyncio

40

asyncio.run(main())

41

```

42

43

### Async Key Creation

44

45

Asynchronous key creation operations.

46

47

```python { .api }

48

async def create_key(

49

name: str,

50

key_type: KeyType,

51

**kwargs

52

) -> KeyVaultKey:

53

"""Asynchronously create a new key."""

54

55

async def create_rsa_key(

56

name: str,

57

*,

58

size: int = None,

59

hardware_protected: bool = False,

60

**kwargs

61

) -> KeyVaultKey:

62

"""Asynchronously create an RSA key."""

63

64

async def create_ec_key(

65

name: str,

66

*,

67

curve: KeyCurveName = None,

68

hardware_protected: bool = False,

69

**kwargs

70

) -> KeyVaultKey:

71

"""Asynchronously create an Elliptic Curve key."""

72

73

async def create_oct_key(

74

name: str,

75

*,

76

size: int = None,

77

hardware_protected: bool = False,

78

**kwargs

79

) -> KeyVaultKey:

80

"""Asynchronously create a symmetric key."""

81

```

82

83

#### Usage Examples

84

85

```python

86

import asyncio

87

from azure.keyvault.keys.aio import KeyClient

88

from azure.keyvault.keys import KeyType, KeyCurveName

89

from azure.identity.aio import DefaultAzureCredential

90

91

async def create_multiple_keys():

92

"""Create multiple keys concurrently."""

93

credential = DefaultAzureCredential()

94

95

async with KeyClient("https://vault.vault.azure.net/", credential) as client:

96

# Create keys concurrently

97

tasks = [

98

client.create_rsa_key("async-rsa-key", size=2048),

99

client.create_ec_key("async-ec-key", curve=KeyCurveName.p_256),

100

client.create_oct_key("async-oct-key", size=256)

101

]

102

103

keys = await asyncio.gather(*tasks)

104

105

for key in keys:

106

print(f"Created key: {key.name} ({key.key_type})")

107

108

asyncio.run(create_multiple_keys())

109

```

110

111

### Async Key Retrieval and Management

112

113

Asynchronous key retrieval and management operations.

114

115

```python { .api }

116

async def get_key(name: str, version: str = None, **kwargs) -> KeyVaultKey:

117

"""Asynchronously get a key from the vault."""

118

119

async def update_key_properties(

120

name: str,

121

version: str = None,

122

**kwargs

123

) -> KeyVaultKey:

124

"""Asynchronously update a key's properties."""

125

126

async def begin_delete_key(name: str, **kwargs) -> AsyncLROPoller[DeletedKey]:

127

"""Begin asynchronously deleting a key."""

128

129

async def get_deleted_key(name: str, **kwargs) -> DeletedKey:

130

"""Asynchronously get a deleted key."""

131

132

async def begin_recover_deleted_key(name: str, **kwargs) -> AsyncLROPoller[KeyVaultKey]:

133

"""Begin asynchronously recovering a deleted key."""

134

135

async def purge_deleted_key(name: str, **kwargs) -> None:

136

"""Asynchronously purge a deleted key permanently."""

137

```

138

139

#### Usage Examples

140

141

```python

142

async def manage_key_lifecycle():

143

"""Demonstrate async key lifecycle management."""

144

credential = DefaultAzureCredential()

145

146

async with KeyClient("https://vault.vault.azure.net/", credential) as client:

147

# Create key

148

key = await client.create_rsa_key("lifecycle-key")

149

print(f"Created: {key.name}")

150

151

# Update properties

152

updated_key = await client.update_key_properties(

153

"lifecycle-key",

154

enabled=False,

155

tags={"status": "disabled"}

156

)

157

print(f"Updated: {updated_key.name}")

158

159

# Delete key (soft delete)

160

delete_poller = await client.begin_delete_key("lifecycle-key")

161

deleted_key = await delete_poller.result()

162

print(f"Deleted: {deleted_key.name}")

163

164

# Recover key

165

recover_poller = await client.begin_recover_deleted_key("lifecycle-key")

166

recovered_key = await recover_poller.result()

167

print(f"Recovered: {recovered_key.name}")

168

169

asyncio.run(manage_key_lifecycle())

170

```

171

172

### Async Paginated Operations

173

174

Handle paginated results asynchronously.

175

176

```python { .api }

177

def list_properties_of_keys(**kwargs) -> AsyncItemPaged[KeyProperties]:

178

"""List key properties asynchronously with pagination."""

179

180

def list_properties_of_key_versions(name: str, **kwargs) -> AsyncItemPaged[KeyProperties]:

181

"""List key version properties asynchronously with pagination."""

182

183

def list_deleted_keys(**kwargs) -> AsyncItemPaged[DeletedKey]:

184

"""List deleted keys asynchronously with pagination."""

185

```

186

187

#### Usage Examples

188

189

```python

190

async def list_all_keys():

191

"""List all keys in the vault asynchronously."""

192

credential = DefaultAzureCredential()

193

194

async with KeyClient("https://vault.vault.azure.net/", credential) as client:

195

print("All keys in vault:")

196

197

# Iterate through all keys

198

async for key_properties in client.list_properties_of_keys():

199

print(f"- {key_properties.name} (enabled: {key_properties.enabled})")

200

201

# Or process by pages

202

pages = client.list_properties_of_keys().by_page()

203

async for page in pages:

204

print(f"Processing page with {len(page)} keys")

205

for key_properties in page:

206

print(f" - {key_properties.name}")

207

208

async def find_keys_by_tag():

209

"""Find keys with specific tags."""

210

credential = DefaultAzureCredential()

211

212

async with KeyClient("https://vault.vault.azure.net/", credential) as client:

213

production_keys = []

214

215

async for key_properties in client.list_properties_of_keys():

216

if key_properties.tags and key_properties.tags.get("environment") == "production":

217

production_keys.append(key_properties.name)

218

219

print(f"Production keys: {production_keys}")

220

221

asyncio.run(list_all_keys())

222

asyncio.run(find_keys_by_tag())

223

```

224

225

### Async Cryptographic Operations

226

227

Asynchronous cryptographic operations using CryptographyClient.

228

229

```python { .api }

230

class CryptographyClient:

231

"""Asynchronous client for cryptographic operations."""

232

233

async def encrypt(

234

algorithm: EncryptionAlgorithm,

235

plaintext: bytes,

236

**kwargs

237

) -> EncryptResult:

238

"""Asynchronously encrypt data."""

239

240

async def decrypt(

241

algorithm: EncryptionAlgorithm,

242

ciphertext: bytes,

243

**kwargs

244

) -> DecryptResult:

245

"""Asynchronously decrypt data."""

246

247

async def sign(algorithm: SignatureAlgorithm, digest: bytes, **kwargs) -> SignResult:

248

"""Asynchronously sign a digest."""

249

250

async def verify(

251

algorithm: SignatureAlgorithm,

252

digest: bytes,

253

signature: bytes,

254

**kwargs

255

) -> VerifyResult:

256

"""Asynchronously verify a signature."""

257

258

async def wrap_key(algorithm: KeyWrapAlgorithm, key: bytes, **kwargs) -> WrapResult:

259

"""Asynchronously wrap a key."""

260

261

async def unwrap_key(algorithm: KeyWrapAlgorithm, encrypted_key: bytes, **kwargs) -> UnwrapResult:

262

"""Asynchronously unwrap a key."""

263

```

264

265

#### Usage Examples

266

267

```python

268

from azure.keyvault.keys.crypto.aio import CryptographyClient

269

from azure.keyvault.keys.crypto import EncryptionAlgorithm, SignatureAlgorithm

270

import hashlib

271

272

async def perform_crypto_operations():

273

"""Perform multiple cryptographic operations concurrently."""

274

credential = DefaultAzureCredential()

275

key_id = "https://vault.vault.azure.net/keys/my-key/version"

276

277

async with CryptographyClient(key_id, credential) as crypto_client:

278

# Prepare data

279

plaintext1 = b"First message"

280

plaintext2 = b"Second message"

281

digest1 = hashlib.sha256(plaintext1).digest()

282

digest2 = hashlib.sha256(plaintext2).digest()

283

284

# Perform operations concurrently

285

tasks = [

286

crypto_client.encrypt(EncryptionAlgorithm.rsa_oaep_256, plaintext1),

287

crypto_client.encrypt(EncryptionAlgorithm.rsa_oaep_256, plaintext2),

288

crypto_client.sign(SignatureAlgorithm.rs256, digest1),

289

crypto_client.sign(SignatureAlgorithm.rs256, digest2)

290

]

291

292

results = await asyncio.gather(*tasks)

293

encrypt_result1, encrypt_result2, sign_result1, sign_result2 = results

294

295

print(f"Encrypted {len(encrypt_result1.ciphertext)} bytes")

296

print(f"Encrypted {len(encrypt_result2.ciphertext)} bytes")

297

print(f"Signature 1: {sign_result1.signature.hex()[:16]}...")

298

print(f"Signature 2: {sign_result2.signature.hex()[:16]}...")

299

300

asyncio.run(perform_crypto_operations())

301

```

302

303

### Async Backup and Recovery

304

305

Asynchronous backup and recovery operations.

306

307

```python { .api }

308

async def backup_key(name: str, **kwargs) -> bytes:

309

"""Asynchronously backup a key."""

310

311

async def restore_key_backup(backup: bytes, **kwargs) -> KeyVaultKey:

312

"""Asynchronously restore a key from backup."""

313

```

314

315

#### Usage Examples

316

317

```python

318

async def backup_multiple_keys():

319

"""Backup multiple keys concurrently."""

320

credential = DefaultAzureCredential()

321

322

async with KeyClient("https://vault.vault.azure.net/", credential) as client:

323

key_names = ["key1", "key2", "key3"]

324

325

# Backup all keys concurrently

326

backup_tasks = [client.backup_key(name) for name in key_names]

327

backups = await asyncio.gather(*backup_tasks, return_exceptions=True)

328

329

for i, (key_name, backup_result) in enumerate(zip(key_names, backups)):

330

if isinstance(backup_result, Exception):

331

print(f"Failed to backup {key_name}: {backup_result}")

332

else:

333

print(f"Backed up {key_name}: {len(backup_result)} bytes")

334

# Save backup to file

335

with open(f"{key_name}_backup.bin", "wb") as f:

336

f.write(backup_result)

337

338

asyncio.run(backup_multiple_keys())

339

```

340

341

### Async Context Management

342

343

Proper resource management with async context managers.

344

345

```python { .api }

346

async def __aenter__(self) -> "KeyClient":

347

"""Enter async context manager."""

348

349

async def __aexit__(self, exc_type, exc_val, exc_tb) -> None:

350

"""Exit async context manager and clean up resources."""

351

352

async def close(self) -> None:

353

"""Close the client and release resources."""

354

```

355

356

#### Usage Examples

357

358

```python

359

async def proper_resource_management():

360

"""Demonstrate proper async resource management."""

361

credential = DefaultAzureCredential()

362

363

# Method 1: Using async context manager (recommended)

364

async with KeyClient("https://vault.vault.azure.net/", credential) as client:

365

key = await client.get_key("my-key")

366

print(f"Got key: {key.name}")

367

# Client automatically closed

368

369

# Method 2: Manual resource management

370

client = KeyClient("https://vault.vault.azure.net/", credential)

371

try:

372

key = await client.get_key("my-key")

373

print(f"Got key: {key.name}")

374

finally:

375

await client.close()

376

377

async def multiple_clients_example():

378

"""Use multiple clients concurrently."""

379

credential = DefaultAzureCredential()

380

381

# Multiple vaults

382

vault_urls = [

383

"https://vault1.vault.azure.net/",

384

"https://vault2.vault.azure.net/",

385

"https://vault3.vault.azure.net/"

386

]

387

388

async def get_key_from_vault(vault_url: str, key_name: str):

389

async with KeyClient(vault_url, credential) as client:

390

try:

391

return await client.get_key(key_name)

392

except Exception as e:

393

print(f"Error getting key from {vault_url}: {e}")

394

return None

395

396

# Get same key from multiple vaults concurrently

397

tasks = [get_key_from_vault(url, "shared-key") for url in vault_urls]

398

keys = await asyncio.gather(*tasks)

399

400

for i, key in enumerate(keys):

401

if key:

402

print(f"Vault {i+1}: Found key {key.name}")

403

else:

404

print(f"Vault {i+1}: Key not found")

405

406

asyncio.run(proper_resource_management())

407

asyncio.run(multiple_clients_example())

408

```

409

410

### Error Handling in Async Operations

411

412

Handle errors appropriately in async contexts.

413

414

```python

415

from azure.core.exceptions import ResourceNotFoundError, ServiceRequestError

416

import asyncio

417

418

async def robust_async_key_operations():

419

"""Demonstrate robust error handling in async operations."""

420

credential = DefaultAzureCredential()

421

422

async with KeyClient("https://vault.vault.azure.net/", credential) as client:

423

key_names = ["key1", "nonexistent-key", "key3"]

424

425

async def safe_get_key(name: str):

426

try:

427

return await client.get_key(name)

428

except ResourceNotFoundError:

429

print(f"Key '{name}' not found")

430

return None

431

except ServiceRequestError as e:

432

print(f"Service error for key '{name}': {e}")

433

return None

434

except Exception as e:

435

print(f"Unexpected error for key '{name}': {e}")

436

return None

437

438

# Get keys with error handling

439

tasks = [safe_get_key(name) for name in key_names]

440

results = await asyncio.gather(*tasks)

441

442

successful_keys = [key for key in results if key is not None]

443

print(f"Successfully retrieved {len(successful_keys)} keys")

444

445

asyncio.run(robust_async_key_operations())

446

```

447

448

## Types

449

450

```python { .api }

451

class AsyncLROPoller:

452

"""Asynchronous long-running operation poller."""

453

454

async def result(timeout: int = None) -> Any:

455

"""Asynchronously get the final result of the operation."""

456

457

async def wait(timeout: int = None) -> None:

458

"""Asynchronously wait for the operation to complete."""

459

460

def done() -> bool:

461

"""Check if the operation is complete."""

462

463

def status() -> str:

464

"""Get the current status of the operation."""

465

466

class AsyncItemPaged:

467

"""Asynchronous paginated collection of items."""

468

469

def __aiter__(self):

470

"""Async iterator over all items across pages."""

471

472

def by_page(self):

473

"""Iterate page by page asynchronously."""

474

```

475

476

## Best Practices for Async Operations

477

478

### Concurrency and Performance

479

480

```python

481

async def efficient_bulk_operations():

482

"""Demonstrate efficient patterns for bulk operations."""

483

credential = DefaultAzureCredential()

484

485

async with KeyClient("https://vault.vault.azure.net/", credential) as client:

486

# Limit concurrency to avoid overwhelming the service

487

semaphore = asyncio.Semaphore(10) # Max 10 concurrent operations

488

489

async def create_key_with_semaphore(name: str):

490

async with semaphore:

491

return await client.create_rsa_key(name, size=2048)

492

493

# Create many keys with controlled concurrency

494

key_names = [f"bulk-key-{i}" for i in range(50)]

495

tasks = [create_key_with_semaphore(name) for name in key_names]

496

497

keys = await asyncio.gather(*tasks, return_exceptions=True)

498

499

successful = sum(1 for key in keys if not isinstance(key, Exception))

500

print(f"Successfully created {successful}/{len(keys)} keys")

501

502

asyncio.run(efficient_bulk_operations())

503

```

504

505

### Timeout and Retry Patterns

506

507

```python

508

async def resilient_async_operations():

509

"""Implement timeout and retry patterns."""

510

511

async def retry_operation(operation, max_retries=3, delay=1.0):

512

"""Retry an async operation with exponential backoff."""

513

for attempt in range(max_retries):

514

try:

515

return await asyncio.wait_for(operation(), timeout=30.0)

516

except asyncio.TimeoutError:

517

if attempt == max_retries - 1:

518

raise

519

print(f"Timeout on attempt {attempt + 1}, retrying...")

520

await asyncio.sleep(delay * (2 ** attempt))

521

except Exception as e:

522

if attempt == max_retries - 1:

523

raise

524

print(f"Error on attempt {attempt + 1}: {e}, retrying...")

525

await asyncio.sleep(delay)

526

527

credential = DefaultAzureCredential()

528

client = KeyClient("https://vault.vault.azure.net/", credential)

529

530

try:

531

# Retry key creation with timeout

532

key = await retry_operation(

533

lambda: client.create_rsa_key("resilient-key", size=2048)

534

)

535

print(f"Created key: {key.name}")

536

finally:

537

await client.close()

538

539

asyncio.run(resilient_async_operations())

540

```