Source code for siege_utilities.databricks.secrets

"""Databricks secret management helpers."""

import logging
from typing import Any, Optional

from .session import get_dbutils

log = logging.getLogger(__name__)

__all__ = [
    "ensure_secret_scope",
    "get_runtime_secret",
    "put_secret",
    "runtime_secret_exists",
]



[docs] def get_runtime_secret(scope: str, key: str, dbutils: Optional[Any] = None) -> str: """Read a secret from Databricks runtime dbutils.""" dbutils = dbutils or get_dbutils() return dbutils.secrets.get(scope=scope, key=key)
[docs] def runtime_secret_exists(scope: str, key: str, dbutils: Optional[Any] = None) -> bool: """Check whether a runtime secret key exists in a scope. Returns True if the key exists in the scope, False if it does not. Lookup errors (scope missing, access denied) propagate as the underlying exception type so the caller can distinguish 'key not present' from 'lookup failed' -- writing-code:7 territory. """ dbutils = dbutils or get_dbutils() keys = dbutils.secrets.list(scope=scope) return any(getattr(item, "key", None) == key for item in keys)
[docs] def ensure_secret_scope(scope: str, workspace_client: Any) -> str: """ Ensure a secret scope exists using Databricks workspace APIs. Returns the scope name on either the existed-already or created-now path. Logs at INFO level naming which path was taken (writing-code:11 floor (b)): an auditor can confirm from log output alone whether a new scope was created or an existing one was reused. """ existing = workspace_client.secrets.list_scopes() if any(getattr(item, "name", None) == scope for item in existing): log.info("Databricks secret scope %r already exists; reusing.", scope) return scope workspace_client.secrets.create_scope(scope=scope) log.info("Databricks secret scope %r created.", scope) return scope
[docs] def put_secret( scope: str, key: str, value: str, workspace_client: Any, ) -> str: """Create or update a secret key using Databricks workspace APIs. Returns the scope-qualified key (``<scope>/<key>``) on success. Logs at INFO level naming the scope and key (without the value). The combination satisfies writing-code:11 floor (a) inspectable return + (b) audit log: callers can both inspect the return value AND grep logs to verify the write happened. """ workspace_client.secrets.put_secret(scope=scope, key=key, string_value=value) qualified = f"{scope}/{key}" log.info("Databricks secret written to %s.", qualified) return qualified