Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Azure SDK per Python astrae le chiamate al protocollo di comunicazione del servizio di Azure sottostante, indipendentemente dal fatto che il protocollo sia HTTP o AMQP (usato per gli SDK di messaggistica come ServiceBus e EventHubs). Ad esempio, se si usa una delle librerie che usano HTTP, Azure SDK per Python effettua richieste HTTP e riceve risposte HTTP sotto le quinte. L'SDK astrae questa complessità in modo che sia possibile usare oggetti Python intuitivi invece di risposte HTTP non elaborate o payload JSON.
Comprendere i tipi di oggetti ricevuti dalle operazioni dell'SDK è essenziale per la scrittura di applicazioni Azure efficaci. Questo articolo illustra i tipi di risposta comuni riscontrati e il modo in cui sono correlati alla comunicazione HTTP sottostante.
Annotazioni
Questo articolo esamina solo lo scenario HTTP, non lo scenario AMQP.
Oggetti Python deserializzati
Azure SDK per Python assegna priorità alla produttività degli sviluppatori restituendo oggetti Python fortemente tipizzati dalle operazioni del servizio. Anziché analizzare JSON o gestire direttamente i codici di stato HTTP, è possibile usare modelli di risorse che rappresentano le risorse di Azure come oggetti Python.
Ad esempio, quando si recupera un BLOB da Archiviazione di Azure, si riceve un BlobProperties oggetto con attributi come name, sizee last_modified anziché un dizionario JSON non elaborato:
from azure.storage.blob import BlobServiceClient
# Connect to storage account
blob_service_client = BlobServiceClient.from_connection_string(connection_string)
container_client = blob_service_client.get_container_client("mycontainer")
# Get blob properties - returns a BlobProperties object
blob_client = container_client.get_blob_client("myblob.txt")
properties = blob_client.get_blob_properties()
# Access properties as Python attributes
print(f"Blob name: {properties.name}")
print(f"Blob size: {properties.size} bytes")
print(f"Last modified: {properties.last_modified}")
Da dove provengono i dati
Comprendere il flusso di dati consente di apprezzare le operazioni dell'SDK in background:
-
Il codice chiama un metodo SDK: Si richiama un metodo come
get_blob_properties(). - L'SDK costruisce una richiesta HTTP: L'SDK compila la richiesta HTTP appropriata con intestazioni, autenticazione e parametri di query.
- Il servizio di Azure risponde: Il servizio restituisce una risposta HTTP, in genere con un payload JSON nel corpo della risposta.
-
L'SDK elabora la risposta: The SDK:
- Controlla il codice di stato HTTP.
- Analizza il corpo della risposta (in genere JSON).
- Convalida i dati rispetto agli schemi previsti.
- Esegue il mapping dei dati agli oggetti modello Python.
- Il codice riceve oggetti Python: È possibile usare gli oggetti deserializzati, non i dati HTTP non elaborati.
Questa astrazione consente di concentrarsi sulla logica dell'applicazione anziché sui dettagli del protocollo HTTP.
Tipi di risposta comuni
Azure SDK per Python usa diversi tipi di risposta standard in tutti i servizi. La comprensione di questi tipi consente di lavorare in modo efficace con qualsiasi servizio di Azure.
Modelli di risorse
La maggior parte delle operazioni SDK restituisce modelli di risorse. Questi oggetti Python rappresentano le risorse di Azure. I modelli sono specifici del servizio, ma seguono modelli coerenti:
# Azure Key Vault example
from azure.keyvault.secrets import SecretClient
secret_client = SecretClient(vault_url=vault_url, credential=credential)
secret = secret_client.get_secret("mysecret") # Returns KeyVaultSecret
print(f"Secret name: {secret.name}")
print(f"Secret value: {secret.value}")
print(f"Secret version: {secret.properties.version}")
# Azure Cosmos DB example
from azure.cosmos import CosmosClient
cosmos_client = CosmosClient(url=cosmos_url, credential=credential)
database = cosmos_client.get_database_client("mydatabase")
container = database.get_container_client("mycontainer")
item = container.read_item(item="item-id", partition_key="partition-value") # Returns dict
print(f"Item ID: {item['id']}")
ItemPaged per i risultati della raccolta
Quando l'SDK elenca le risorse, restituisce ItemPaged oggetti che gestiscono la paginazione in modo trasparente:
from azure.storage.blob import BlobServiceClient
from azure.core.paging import ItemPaged
blob_service_client = BlobServiceClient.from_connection_string(connection_string)
container_client = blob_service_client.get_container_client("mycontainer")
# list_blobs returns ItemPaged[BlobProperties]
blobs: ItemPaged[BlobProperties] = container_client.list_blobs()
# Iterate naturally - SDK handles pagination
for blob in blobs:
print(f"Blob: {blob.name}, Size: {blob.size}")
Accedere alla risposta HTTP non elaborata
Anche se le astrazioni di alto livello dell'SDK soddisfano la maggior parte delle esigenze, a volte è necessario accedere alla risposta HTTP sottostante. Gli scenari comuni includono:
- Debug di richieste non riuscite.
- Accesso alle intestazioni di risposta personalizzate.
- Implementazione della logica di ripetizione dei tentativi personalizzata.
- Utilizzo dei formati di risposta non standard.
La maggior parte dei metodi SDK accetta un raw_response_hook parametro:
from azure.keyvault.secrets import SecretClient
secret_client = SecretClient(vault_url=vault_url, credential=credential)
def inspect_response(response):
# Access the raw HTTP response
print(f"Request URL: {response.http_request.url}")
print(f"Status code: {response.http_response.status_code}")
print(f"Response headers: {dict(response.http_response.headers)}")
# Access custom headers
request_id = response.http_response.headers.get('x-ms-request-id')
print(f"Request ID: {request_id}")
# Must return the response
return response
# Hook is called before deserialization
secret = secret_client.get_secret("mysecret", raw_response_hook=inspect_response)
Paging e iteratori
I servizi di Azure spesso restituiscono grandi raccolte di risorse. L'SDK usa ItemPaged per gestire queste raccolte in modo efficiente senza caricare tutto in memoria contemporaneamente.
Paginazione automatica
L'SDK recupera automaticamente nuove pagine durante l'iterazione:
# List all blobs - could be thousands
blobs = container_client.list_blobs()
# SDK fetches pages as needed during iteration
for blob in blobs:
process_blob(blob) # Pages loaded on-demand
Lavorare con le pagine in modo esplicito
È anche possibile usare le pagine direttamente quando necessario:
blobs = container_client.list_blobs()
# Process by page
for page in blobs.by_page():
print(f"Processing page with {len(list(page))} items")
for blob in page:
process_blob(blob)
Controlla la dimensione della pagina
Molte operazioni di elenco accettano un results_per_page parametro:
# Fetch 100 items per page instead of the default
blobs = container_client.list_blobs(results_per_page=100)
Alcuni metodi per alcuni servizi di Azure hanno altri meccanismi per controllare le dimensioni della pagina. Ad esempio, Azure Key Vault e Ricerca di Azure usano il top kwarg per limitare i risultati per ogni chiamata. Per un esempio che usa il metodo Ricerca di search() Azure, vedere il codice sorgente.
Caso speciale: operazioni e poller a esecuzione prolungata
Alcune operazioni di Azure non possono essere completate immediatamente. Gli esempi includono:
- Creazione o eliminazione di macchine virtuali.
- Distribuzione di modelli di Azure Resource Manager.
- Addestrare modelli di apprendimento automatico.
- Copiare BLOB di grandi dimensioni.
Queste operazioni restituiscono oggetti poller che tengono traccia dello stato dell'operazione.
Collaborare con i poller
from azure.mgmt.storage import StorageManagementClient
storage_client = StorageManagementClient(credential, subscription_id)
# Start storage account creation
poller = storage_client.storage_accounts.begin_create(
resource_group_name="myresourcegroup",
account_name="mystorageaccount",
parameters=storage_parameters
)
# Option 1: Wait for completion (blocking)
storage_account = poller.result()
# Option 2: Check status periodically
while not poller.done():
print(f"Status: {poller.status()}")
time.sleep(5)
storage_account = poller.result()
Poller asincroni
Quando si usano modelli asincroni/await, si lavora con AsyncLROPoller:
from azure.storage.blob.aio import BlobServiceClient
async with BlobServiceClient.from_connection_string(connection_string) as client:
container_client = client.get_container_client("mycontainer")
# Start async copy operation
blob_client = container_client.get_blob_client("large-blob.vhd")
poller = await blob_client.begin_copy_from_url(source_url)
# Wait for async completion
copy_properties = await poller.result()
Esempio di polling di oggetti per operazioni a esecuzione prolungata: Macchine virtuali
La distribuzione di macchine virtuali è un esempio di un'operazione che richiede tempo per completare e gestiscla restituendo oggetti poller (LROPoller per il codice sincrono, AsyncLROPoller per il codice asincrono):
from azure.mgmt.compute import ComputeManagementClient
from azure.core.polling import LROPoller
compute_client = ComputeManagementClient(credential, subscription_id)
# Start VM creation - returns immediately with a poller
poller: LROPoller = compute_client.virtual_machines.begin_create_or_update(
resource_group_name="myresourcegroup",
vm_name="myvm",
parameters=vm_parameters
)
# Wait for completion and get the result
vm = poller.result() # Blocks until operation completes
print(f"VM {vm.name} provisioned successfully")
Accedere alla risposta per i risultati di paging
Per i risultati di paging, usare il by_page() metodo con raw_response_hook:
def page_response_hook(response):
continuation_token = response.http_response.headers.get('x-ms-continuation')
print(f"Continuation token: {continuation_token}")
return response
blobs = container_client.list_blobs()
for page in blobs.by_page(raw_response_hook=page_response_hook):
for blob in page:
print(blob.name)
Procedure consigliate
Preferisce astrazioni di alto livello.
Usare i modelli di risorse dell'SDK anziché le risposte non elaborate quando possibile.
Evitare di accedere a qualsiasi metodo preceduto da un carattere di sottolineatura (_). Per convenzione, questi metodi sono privati in Python. Non esistono garanzie relative a problemi come modifiche che rompono la compatibilità rispetto alle API pubbliche.
# Preferred: Work with typed objects secret = secret_client.get_secret("mysecret") if secret.properties.enabled: use_secret(secret.value) # Avoid: Manual JSON parsing (unless necessary) ... # AND avoid accessing any objects or methods that start with `_` response = secret_client._client.get(...) # Don't access internal clients data = json.loads(response.text) if data['attributes']['enabled']: use_secret(data['value'])Gestire correttamente la paginazione. Scorrere i risultati paginati anziché convertirli sempre in un elenco.
# Good: Memory-efficient iteration for blob in container_client.list_blobs(): process_blob(blob) # Avoid: Loading everything into memory all_blobs = list(container_client.list_blobs()) # Could consume excessive memoryUsare poller.result() per le operazioni a esecuzione prolungata. Usare sempre il
result()metodo per assicurarsi che le operazioni vengano completate correttamente:# Correct: Wait for operation completion poller = compute_client.virtual_machines.begin_delete( resource_group_name="myresourcegroup", vm_name="myvm" ) poller.result() # Ensures deletion completes print("VM deleted successfully") # Wrong: Assuming immediate completion poller = compute_client.virtual_machines.begin_delete(...) print("VM deleted successfully") # Deletion might still be in progress!Accedere alle risposte non elaborate solo quando necessario. Usare con moderazione l'accesso alle risposte non elaborate e solo per requisiti specifici:
# Good use case: Debugging or logging def log_request_id(response): request_id = response.http_response.headers.get('x-ms-request-id') logger.info(f"Operation request ID: {request_id}") return response blob_client.upload_blob(data, raw_response_hook=log_request_id) # Good use case: Custom error handling def check_custom_header(response): if response.http_response.headers.get('x-custom-error'): raise CustomApplicationError("Custom error condition detected") return response