Diretrizes de design de linguagem do SDK do Azure para Python

As Diretrizes de Design de Linguagem do SDK do Azure são padrões abrangentes que garantem consistência, previsibilidade e facilidade de uso em todos os SDKs do Azure. Essas diretrizes ajudam os desenvolvedores a trabalhar com eficiência com os serviços do Azure fornecendo padrões e comportamentos familiares em diferentes serviços e linguagens de programação.

As diretrizes consistem em duas categorias:

  • Diretrizes gerais: princípios fundamentais que se aplicam a todos os SDKs do Azure, independentemente da linguagem de programação.
  • Language-Specific Diretrizes: detalhes de implementação otimizados para cada idioma com suporte, incluindo Python, .NET, Java, TypeScript e muito mais. Para obter mais informações, consulte o Sumário começando na página Diretrizes Gerais: Introdução .

Essas diretrizes são desenvolvidas abertamente no GitHub, o que permite a revisão e a contribuição da comunidade.

Princípios gerais de design

Todos os SDKs do Azure seguem estes princípios fundamentais:

Princípio Description
Uso idioma Os SDKs seguem convenções e padrões específicos do idioma.
Consistência Os comportamentos são uniformes em diferentes serviços do Azure.
Simplicidade Tarefas comuns exigem código mínimo.
Divulgação progressiva Os recursos avançados estão disponíveis, mas não complicam o uso básico.
Robustez O tratamento é integrado para erros, tentativas de repetição e timeout.

Diretrizes específicas do Python

O restante deste documento se concentra nas diretrizes do Python.

Convenções de nomenclatura

Os SDKs do Azure para Python seguem as convenções de nomenclatura padrão do Python:

  • Métodos: Usar snake_case.

    list_containers()
    get_secret()
    create_database()
    
  • Variáveis: Use snake_case.

    connection_string = "..."
    retry_count = 3
    
  • Classes: Use PascalCase.

    BlobServiceClient
    SecretClient
    CosmosClient
    
  • Constantes: Use UPPER_CASE.

    DEFAULT_CHUNK_SIZE
    MAX_RETRIES
    

Estrutura do pacote

Os pacotes do SDK do Azure seguem uma estrutura consistente:

azure-<service>-<feature>
├── azure/
│   └── <service>/
│       ├── __init__.py
│       ├── _client.py
│       ├── _models.py
│       └── aio/           # Async implementations
│           └── __init__.py

Instanciação do cliente

Os clientes fornecem vários métodos de instanciação:

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

Os SDKs do Azure usam padrões de autenticação consistentes:

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"
)

Gerenciadores de contexto

A maioria dos clientes do SDK do Azure implementa protocolos de gerenciador de contexto para limpeza automática de recursos:

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()

Observação

Embora a maioria dos clientes dê suporte a gerenciadores de contexto, verifique a documentação específica do cliente quanto à disponibilidade.

Operações assíncronas

Os clientes assíncronos são fornecidos em módulos separados .aio :

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())

Operações de execução longa

Operações de execução longa usam o begin_ prefixo e retornam objetos do poller:

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()

Paginação

As operações de lista retornam iteráveis que manipulam a paginação automaticamente:

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)

Tipos de retorno

Os métodos retornam objetos de modelo fortemente tipado em vez de dicionários:

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)

Tratamento de erros

As exceções do SDK do Azure herdam de AzureError e fornecem tipos de exceção específicos.

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}")

Opções de configuração

Os clientes aceitam a configuração por meio de argumentos de palavra-chave:

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
)

Padrões comuns do SDK

Hierarquia do cliente de serviço

Os SDKs do Azure normalmente seguem uma hierarquia de três níveis:

  • Cliente de serviço: ponto de entrada para operações de serviço:

    service_client = BlobServiceClient(...)
    
  • Cliente de recurso: operações em recursos específicos:

    container_client = service_client.get_container_client("container")
    
  • Métodos de operação: ações em recursos:

    blob_client = container_client.get_blob_client("blob.txt")
    blob_client.upload_blob(data)
    

Nomenclatura de método consistente

Os nomes de método seguem padrões previsíveis:

Operation Padrão de método Example
Create create_<resource> create_container()
Leitura get_<resource> get_blob()
Update update_<resource> update_secret()
Delete delete_<resource> delete_container()
List list_<resources> list_blobs()
Exists exists() blob_client.exists()

Trabalhar com SDKs do Azure

O exemplo a seguir demonstra como as diretrizes de design criam consistência em diferentes serviços do Azure:

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}")

Contribuir com os SDKs do Azure

Ao estender ou contribuir para os SDKs do Azure:

  • Siga as convenções do Python: Use padrões e convenções pythonicas.
  • Manter a consistência: Alinhe-se com os padrões existentes do SDK.
  • Escreva testes abrangentes: Inclua testes de unidade e integração.
  • Documente minuciosamente: Forneça docstrings e exemplos.
  • Consulte as diretrizes: Veja o Guia de Contribuição do SDK do Azure.

Aqui está um exemplo de implementação de um método de cliente personalizado que segue as Diretrizes de Design de Idioma:

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)