Files
ewoooc/services/gemini_guard.py
2026-05-21 14:45:32 +08:00

71 lines
2.4 KiB
Python

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""Central guard for Gemini API egress.
Gemini is emergency fallback only in this project. A plain API key must never be
enough to spend money: traffic is blocked by default with a hard kill switch, and
operators must explicitly unlock emergency fallback before any code path may
initialize the SDK or call the REST API.
"""
from __future__ import annotations
import os
_TRUE_VALUES = {"1", "true", "yes", "on"}
_FALSE_VALUES = {"0", "false", "no", "off"}
def _env_flag(name: str, default: str) -> bool:
value = os.getenv(name, default).strip().lower()
if value in _TRUE_VALUES:
return True
if value in _FALSE_VALUES:
return False
return default.strip().lower() in _TRUE_VALUES
def is_gemini_hard_disabled() -> bool:
"""Master kill switch. Default true means zero Gemini API egress."""
return _env_flag("GEMINI_API_HARD_DISABLED", "true")
def _context_allowed(context: str | None) -> bool:
"""Optional allowlist for emergency fallback contexts."""
raw = os.getenv("GEMINI_ALLOWED_CONTEXTS", "").strip()
if not raw:
return True
if not context:
return False
allowed = {item.strip() for item in raw.split(",") if item.strip()}
return context in allowed
def is_gemini_fallback_enabled(context: str | None = None) -> bool:
"""Return whether Gemini fallback traffic is allowed for this process."""
if is_gemini_hard_disabled():
return False
if not _env_flag("GEMINI_FALLBACK_ENABLED", "false"):
return False
return _context_allowed(context)
def get_gemini_api_key(context: str | None = None) -> str:
"""Return the Gemini API key only when fallback traffic is enabled."""
if not is_gemini_fallback_enabled(context):
return ""
return os.getenv("GEMINI_API_KEY", "")
def gemini_disabled_message(context: str | None = None) -> str:
"""Human-readable reason for telemetry and error paths."""
suffix = f" ({context})" if context else ""
if is_gemini_hard_disabled():
return f"Gemini API hard-disabled by GEMINI_API_HARD_DISABLED=true{suffix}"
if not _env_flag("GEMINI_FALLBACK_ENABLED", "false"):
return f"Gemini fallback disabled by GEMINI_FALLBACK_ENABLED=false{suffix}"
if not _context_allowed(context):
return f"Gemini fallback context not allowed by GEMINI_ALLOWED_CONTEXTS{suffix}"
return f"Gemini fallback disabled{suffix}"