aeat.adapters.outbound.storage._google_drive module

Google Drive v3 adapters.outbound.storage.StorageProvider implementation.

Maps the adapters.outbound.storage.StorageProvider Protocol onto the Drive API:

The _service_factory() helper constructs the real Drive v3 resource lazily so importing this module does not require google-api-python-client or settings initialization.

class GoogleDriveProvider(*, credentials, root_folder_id, vault_folder_name=None)[source]

Bases: object

Bytes-in / bytes-out StorageProvider backed by Google Drive v3.

Parameters:
  • credentials (object)

  • root_folder_id (str)

  • vault_folder_name (str | None)

property root_folder_id: str

Drive folder ID used as the parent of the configured vault folder.

put(namespace, object_key_hmac, payload, *, content_hash, label)[source]

Upload payload to Drive and return ProviderObjectMetadata.

If a file for object_key_hmac already exists the existing Drive file is updated in-place (files().update); otherwise a new file is created (files().create) inside the namespace folder. The appProperties field on the Drive entry records the HMAC, content_hash, namespace, and ownership marker so subsequent get and iter_objects calls can resolve the entry without re-downloading the payload.

Parameters:
  • namespace (str) – Logical bucket name; becomes a Drive sub-folder of aeat-vault/.

  • object_key_hmac (str) – Full HMAC string that uniquely identifies the object. Only the first 8 characters are used in the Drive filename; the full value is stored in appProperties.

  • payload (bytes) – Raw bytes to upload. The provider is opaque to the content; encryption lives at a higher layer.

  • content_hash (str) – Vendor-prefixed digest string (e.g. sha256-<hex>). Stored in appProperties and verified on get.

  • label (str) – Human-readable filename component, sanitised to [A-Za-z0-9\\-_.]{1,64}.

Return type:

ProviderObjectMetadata

Returns:

ProviderObjectMetadata populated from the Drive API response.

Raises:
get(namespace, object_key_hmac)[source]

Download the object, verify the stored hash, and return payload metadata.

Uses files().get_media to stream bytes. If the stored content_hash is a sha256-<hex> string, the payload digest is recomputed after download and compared through verify_content_hash(); a mismatch raises adapters.outbound.storage.OutboundStorageIntegrityError before the payload is returned.

Parameters:
  • namespace (str) – Logical bucket name.

  • object_key_hmac (str) – Full HMAC string identifying the object.

Return type:

tuple[bytes, ProviderObjectMetadata]

Returns:

A two-tuple containing payload bytes and ProviderObjectMetadata.

Raises:
delete(namespace, object_key_hmac)[source]

Permanently delete the Drive file for object_key_hmac.

Returns False immediately (without error) when the namespace folder or the object file does not exist; deleting a non-existent object is idempotent at the provider boundary.

Parameters:
  • namespace (str) – Logical bucket name.

  • object_key_hmac (str) – Full HMAC string identifying the object.

Return type:

bool

Returns:

True when the file was found and deleted; False when the namespace or object was already absent.

Raises:
iter_namespaces()[source]

Yield the name of every namespace folder directly under aeat-vault/.

Paginates through Drive’s files().list using nextPageToken. The namespace folder IDs are cached as a side effect so subsequent _resolve_namespace_folder calls for yielded names skip the Drive lookup.

Yields:

Namespace name strings in Drive-returned order.

Raises:
Return type:

Iterator[str]

iter_objects(namespace)[source]

Yield metadata for every object in namespace.

Only files whose names end with .bin and contain -- are yielded; Drive folders and unrelated files inside the namespace folder are silently skipped. The full HMAC is recovered from appProperties.object_key_hmac when present, falling back to the filename prefix.

Parameters:

namespace (str) – Logical bucket name.

Yields:

ProviderObjectMetadata records in Drive-returned order.

Raises:
Return type:

Iterator[ProviderObjectMetadata]

probe(*, read_only=False)[source]

Assess Drive connectivity and write access, returning a ProviderProbeReport.

Checks, in order:

  1. Service construction — verifies google-api-python-client can be imported and credentials can build a Drive resource.

  2. Root folder existence — confirms root_folder_id names a non-trashed Drive folder.

  3. Sentinel round-trip (skipped when read_only=True) — calls put then delete against a _probe namespace to confirm write access end-to-end.

The method never raises; every failure mode is encoded in the returned ProviderProbeReport.

Parameters:

read_only (bool) – When True, skip the sentinel write round-trip and report writable=False regardless of actual permissions.

Return type:

ProviderProbeReport

Returns:

A ProviderProbeReport with reachable, writable, root_folder_present, and a human-readable detail string.