synology_apm_repo.sdk.storage.azure module¶
AzureStore — a real, executable ObjectStore implementation for
Azure Blob Storage, matching the s3 module’s scope, structure, and
contract exactly (same four methods, same EOF/NotFoundError semantics, same
lazy-import pattern) — this one only differs where the Azure SDK’s own
shapes force a difference. list_containers mirrors that module’s
list_buckets().
The one genuine shape difference from S3Store: Azure’s hierarchical
listing (azure.storage.blob.ContainerClient.walk_blobs) already
returns one unified sequence of BlobProperties/BlobPrefix entries,
so there’s no separate paginated “common prefixes” collection to merge in
the way S3’s CommonPrefixes/Contents split requires; the SDK’s own
ItemPaged/AsyncItemPaged iterator handles continuation-token
pagination internally too.
Why ``azure.storage.blob.aio``: this is network I/O, and — like
S3Store — this module sits on aiohttp, where many outstanding
round-trips genuinely overlap on one thread; that’s a real gain over a
thread-pool wrapper around a synchronous client. Its client owns an
aiohttp session that must be closed, hence AzureStore.aclose, which
Session.close() calls.
Every client this module builds goes through _with_default_timeouts,
which trims azure-core’s batch-job-tuned defaults down to values an
interactive caller — the TUI’s connect dialog, in particular — can
actually wait through when an endpoint is unreachable (see the
module-level constants below for the exact values).
- class synology_apm_repo.sdk.storage.azure.AzureStore(container, *, client=None, **client_kwargs)¶
Bases:
objectAn Azure Blob Storage container, addressed by
"/"-separated paths relative to the container root.client, if given, is used as-is (tests inject a mockedBlobServiceClientthis way — the contract this class must get right is status-code-to-ObjectStore-semantics translation, not anything a live Azurite instance would exercise differently); otherwise one is built fromclient_kwargs(most commonlyaccount_url, one ofcredential/connection_string) after_resolve_shared_key_credentialresolves a plain-stringcredentialagainstaccount_url.- async aclose()¶
Close the underlying
aiohttptransport.Only for a client this class built itself — an injected
clientbelongs to whoever created it. Safe to call more than once.
- async read(path, offset=0, length=None)¶
- async size(path)¶
- async exists(path)¶
Truefor either a blob exactly atpath, or a “directory” — a prefix with at least one blob under it:db/@dataare never blobs in their own right on an object-storage layout, only prefixes with real blobs underneath (layout.pyrelies on this).
- async listdir(path)¶
An absent “directory” (a prefix with zero blobs under it) and an empty one are indistinguishable in an object store with no real directory entities — both correctly report
[], the same asS3Store.listdir.
- async synology_apm_repo.sdk.storage.azure.list_containers(**client_kwargs)¶
Every container visible to these credentials — a container-less operation
AzureStorehas no method for, since all four of its methods are scoped to one chosen container. Builds its own transient client the same lazy-import wayAzureStoredoes and closes it before returning; no lifecycle for a caller to manage beyond this one call.client_kwargsis exactly what a caller would otherwise pass toAzureStore. Raises whatever the underlying SDK call raises — most notablyHttpResponseErrorwhen the credential has no account-level “list containers” permission, which a container-scoped SAS token never does — unhandled, the same as every other backend-specific exceptionAzureStore’s own methods let propagate.