You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

37 lines
1.1 KiB

"""Secure API-key storage backed by the operating system keyring."""
from __future__ import annotations
import keyring
SERVICE_NAME = "voice-transcriptor"
ACCOUNT_NAME = "openai-api-key"
class CredentialError(Exception):
"""A credential operation failed without exposing backend details."""
class CredentialService:
"""Read and write the application's API key through a keyring backend."""
def __init__(self, backend=keyring) -> None:
self._backend = backend
def get_api_key(self) -> str | None:
try:
return self._backend.get_password(SERVICE_NAME, ACCOUNT_NAME)
except Exception:
raise CredentialError("Unable to access the saved API key.") from None
def has_api_key(self) -> bool:
return bool(self.get_api_key())
def set_api_key(self, value: str) -> None:
if not isinstance(value, str) or not value.strip():
raise CredentialError("An API key is required.")
try:
self._backend.set_password(SERVICE_NAME, ACCOUNT_NAME, value)
except Exception:
raise CredentialError("Unable to save the API key.") from None