feat: add Vision monthly cap, WIF auth, and cloud-primary hybrid engine (refs #127)
- Add VISION_MONTHLY_LIMIT config setting (default 1000) - Update CloudEngine to use WIF credential config via ADC - Rewrite HybridEngine to support cloud-primary with Redis counter - Pass monthly_limit through engine factory Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -15,8 +15,8 @@ from app.engines.base_engine import (
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# Default path for Google Vision service account key (Docker secret mount)
|
||||
_DEFAULT_KEY_PATH = "/run/secrets/google-vision-key.json"
|
||||
# Default path for Google WIF credential config (Docker secret mount)
|
||||
_DEFAULT_KEY_PATH = "/run/secrets/google-wif-config.json"
|
||||
|
||||
|
||||
class CloudEngine(OcrEngine):
|
||||
@@ -42,25 +42,33 @@ class CloudEngine(OcrEngine):
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
def _get_client(self) -> Any:
|
||||
"""Create the Vision client on first use."""
|
||||
"""Create the Vision client on first use.
|
||||
|
||||
Uses Application Default Credentials (ADC) pointed at a WIF
|
||||
credential config file. The WIF config references an executable
|
||||
that fetches an Auth0 M2M JWT.
|
||||
"""
|
||||
if self._client is not None:
|
||||
return self._client
|
||||
|
||||
# Verify credentials file exists
|
||||
# Verify credentials config exists
|
||||
if not os.path.isfile(self._key_path):
|
||||
raise EngineUnavailableError(
|
||||
f"Google Vision key not found at {self._key_path}. "
|
||||
f"Google Vision credential config not found at {self._key_path}. "
|
||||
"Set GOOGLE_VISION_KEY_PATH or mount the secret."
|
||||
)
|
||||
|
||||
try:
|
||||
from google.cloud import vision # type: ignore[import-untyped]
|
||||
|
||||
# Point the SDK at the service account key
|
||||
# Point ADC at the WIF credential config
|
||||
os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = self._key_path
|
||||
# Required for executable-sourced credentials
|
||||
os.environ["GOOGLE_EXTERNAL_ACCOUNT_ALLOW_EXECUTABLES"] = "1"
|
||||
self._client = vision.ImageAnnotatorClient()
|
||||
logger.info(
|
||||
"Google Vision client initialized (key: %s)", self._key_path
|
||||
"Google Vision client initialized via WIF (config: %s)",
|
||||
self._key_path,
|
||||
)
|
||||
return self._client
|
||||
except ImportError as exc:
|
||||
|
||||
Reference in New Issue
Block a user