Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Azure SDK Language Design Guidelines are comprehensive standards that ensure consistency, predictability, and ease of use across all Azure SDKs. These guidelines help developers work efficiently with Azure services by providing familiar patterns and behaviors across different services and programming languages.
The guidelines consist of two categories:
- General Guidelines: Core principles that apply to all Azure SDKs regardless of programming language.
- Language-Specific Guidelines: Implementation details optimized for each supported language, including Python, .NET, Java, TypeScript, and many more. For more information, see the Table of Contents starting on the General Guidelines: Introduction page.
These guidelines are developed openly on GitHub, which allows for community review and contribution.
General design principles
All Azure SDKs follow these fundamental principles:
| Principle | Description |
|---|---|
| Idiomatic usage | SDKs follow language-specific conventions and patterns. |
| Consistency | Behaviors are uniform across different Azure services. |
| Simplicity | Common tasks require minimal code. |
| Progressive disclosure | Advanced features are available but don't complicate basic usage. |
| Robustness | Handling is built in for errors, retries, and timeouts. |
Python-specific guidelines
The rest of this document focuses on the Python guidelines.
Naming conventions
Azure SDKs for Python follow standard Python naming conventions:
Methods: Use
snake_case.list_containers() get_secret() create_database()Variables: Use
snake_case.connection_string = "..." retry_count = 3Classes: Use
PascalCase.BlobServiceClient SecretClient CosmosClientConstants: Use
UPPER_CASE.DEFAULT_CHUNK_SIZE MAX_RETRIES
Package structure
Azure SDK packages follow a consistent structure:
azure-<service>-<feature>
├── azure/
│ └── <service>/
│ ├── __init__.py
│ ├── _client.py
│ ├── _models.py
│ └── aio/ # Async implementations
│ └── __init__.py
Client instantiation
Clients provide multiple instantiation methods:
from azure.storage.blob import BlobServiceClient
from azure.identity import DefaultAzureCredential
# Note: Do not use connection string if you can possibly avoid it!
# Using account URL and credential
credential = DefaultAzureCredential()
client = BlobServiceClient(account_url="https://account.blob.core.windows.net",
credential=credential)
Authentication
Azure SDKs use consistent authentication patterns:
from azure.identity import DefaultAzureCredential, ClientSecretCredential
# Default credential chain
credential = DefaultAzureCredential()
# Explicit credential
credential = ClientSecretCredential(
tenant_id="tenant-id",
client_id="client-id",
client_secret="secret"
)
Context managers
Most Azure SDK clients implement context manager protocols for automatic resource cleanup:
from azure.storage.blob import BlobServiceClient
# Automatic cleanup with context manager
with BlobServiceClient.from_connection_string(conn_str) as client:
container_client = client.get_container_client("mycontainer")
blob_list = container_client.list_blobs()
Note
Although most clients support context managers, verify specific client documentation for availability.
Asynchronous operations
Async clients are provided in separate .aio modules:
from azure.storage.blob.aio import BlobServiceClient
import asyncio
async def list_blobs_async():
async with BlobServiceClient.from_connection_string(conn_str) as client:
container_client = client.get_container_client("mycontainer")
async for blob in container_client.list_blobs():
print(blob.name)
# Run async function
asyncio.run(list_blobs_async())
Long-running operations
Long-running operations use the begin_ prefix and return poller objects:
from azure.storage.blob import BlobServiceClient
client = BlobServiceClient.from_connection_string(conn_str)
container_client = client.get_container_client("mycontainer")
# Start long-running operation
poller = container_client.begin_copy_blob_from_url(source_url)
# Wait for completion
result = poller.result()
# Or check status
if poller.done():
result = poller.result()
Pagination
List operations return iterables that handle pagination automatically:
from azure.storage.blob import BlobServiceClient
client = BlobServiceClient.from_connection_string(conn_str)
# Automatic pagination
for container in client.list_containers():
print(container.name)
# Manual pagination control
containers = client.list_containers(results_per_page=10).by_page()
for page in containers:
for container in page:
print(container.name)
Return types
Methods return strongly typed model objects rather than dictionaries:
from azure.keyvault.secrets import SecretClient
client = SecretClient(vault_url="...", credential=credential)
# Returns KeyVaultSecret object, not dict
secret = client.get_secret("my-secret")
print(secret.value)
print(secret.properties.created_on)
Error handling
Azure SDK exceptions inherit from AzureError and provide specific exception types:
from azure.core.exceptions import (
AzureError,
ResourceNotFoundError,
ResourceExistsError,
ClientAuthenticationError,
HttpResponseError
)
try:
blob_client.download_blob()
except ResourceNotFoundError:
# Handle missing resource
print("Blob not found")
except ClientAuthenticationError:
# Handle authentication failure
print("Authentication failed")
except HttpResponseError as e:
# Handle HTTP errors
print(f"HTTP {e.status_code}: {e.message}")
except AzureError as e:
# Handle any other Azure SDK error
print(f"Azure SDK error: {e}")
Configuration options
Clients accept configuration through keyword arguments:
from azure.storage.blob import BlobServiceClient
client = BlobServiceClient(
account_url="...",
credential=credential,
# Configuration options
max_single_put_size=64 * 1024 * 1024,
max_block_size=4 * 1024 * 1024,
retry_total=3,
logging_enable=True
)
Common SDK patterns
Service client hierarchy
Azure SDKs typically follow a three-level hierarchy:
Service client: Entry point for service operations:
service_client = BlobServiceClient(...)Resource client: Operations on specific resources:
container_client = service_client.get_container_client("container")Operation methods: Actions on resources:
blob_client = container_client.get_blob_client("blob.txt") blob_client.upload_blob(data)
Consistent method naming
Method names follow predictable patterns:
| Operation | Method pattern | Example |
|---|---|---|
| Create | create_<resource> |
create_container() |
| Read | get_<resource> |
get_blob() |
| Update | update_<resource> |
update_secret() |
| Delete | delete_<resource> |
delete_container() |
| List | list_<resources> |
list_blobs() |
| Exists | exists() |
blob_client.exists() |
Work with Azure SDKs
The following example demonstrates how design guidelines create consistency across different Azure services:
from azure.storage.blob import BlobServiceClient
from azure.keyvault.secrets import SecretClient
from azure.cosmos import CosmosClient
from azure.identity import DefaultAzureCredential
# Consistent authentication
credential = DefaultAzureCredential()
# Consistent client instantiation
blob_service = BlobServiceClient(
account_url="https://account.blob.core.windows.net",
credential=credential
)
secret_client = SecretClient(
vault_url="https://vault.vault.azure.net",
credential=credential
)
cosmos_client = CosmosClient(
url="https://account.documents.azure.com",
credential=credential
)
# Consistent method patterns
containers = blob_service.list_containers()
secrets = secret_client.list_properties_of_secrets()
databases = cosmos_client.list_databases()
# Consistent error handling
from azure.core.exceptions import ResourceNotFoundError
try:
blob_service.get_container_client("container").get_container_properties()
secret_client.get_secret("secret")
cosmos_client.get_database_client("database").read()
except ResourceNotFoundError as e:
print(f"Resource not found: {e}")
Contribute to Azure SDKs
When you extend or contribute to Azure SDKs:
- Follow Python idioms: Use Pythonic patterns and conventions.
- Maintain consistency: Align with existing SDK patterns.
- Write comprehensive tests: Include unit and integration tests.
- Document thoroughly: Provide docstrings and examples.
- Review guidelines: Consult the Azure SDK Contribution Guide.
Here's an example of implementing a custom client method that follows the Language Design Guidelines:
def list_items_with_prefix(self, prefix: str, **kwargs) -> ItemPaged[ItemProperties]:
"""List items that start with the specified prefix.
:param str prefix: The prefix to filter items
:return: An iterable of ItemProperties
:rtype: ~azure.core.paging.ItemPaged[ItemProperties]
:example:
items = client.list_items_with_prefix("test-")
for item in items:
print(item.name)
"""
return self.list_items(name_starts_with=prefix, **kwargs)
Related content
- Review the complete Azure SDK Design Guidelines.
- Read the Azure SDK Releases page.