APIarium / app /config.py
rnilkyway's picture
feat(models): integrate Gemini Hub (Veo 3 video + Gemini 3 image/text)
e0f8aa6
Raw
History Blame Contribute Delete
10.5 kB
import os
import base64
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
# ── Blocked IPs ──────────────────────────────────────────────────────────────
BLOCKED_IPS = set()
# ── AES decryption ────────────────────────────────────────────────────────────
# Sensitive values are stored as encrypted blobs in the repo.
# Set HF Secret: AES_KEY=<base64 32-byte key>
def _decrypt(value: str) -> str:
if not isinstance(value, str) or not value.startswith("enc:v1:"):
return value
aes_key = os.environ.get("AES_KEY", "").strip()
if not aes_key:
raise RuntimeError("Missing AES_KEY environment variable")
try:
aes_key += "=" * (-len(aes_key) % 4)
key = base64.urlsafe_b64decode(aes_key)
_, _, nonce_b64, cipher_b64 = value.split(":", 3)
nonce = base64.urlsafe_b64decode(nonce_b64)
ciphertext = base64.urlsafe_b64decode(cipher_b64)
return AESGCM(key).decrypt(nonce, ciphertext, None).decode()
except Exception as e:
raise RuntimeError(f"Failed to decrypt config value: {e}")
# ── Upstream URLs ────────────────────────────────────────────────────────────
# Each model alias maps to a list of upstreams.
# Each upstream has: url (endpoint) and model (the model name that upstream expects).
# Requests are distributed round-robin across them.
DEFAULT_UPSTREAM_URL = _decrypt("enc:v1:p7bHt1oeQ7A2Rbjq:GcwychJKgwnAQ0zqC3vPrWhUrqgwIPmJIrTTilcHJMF8eyQH-vYCL7YiyBsC8p2kQ1LLOp-fhCyK1g==")
DEFAULT_UPSTREAM_MODEL = "default"
AI_GATEWAY_URL = _decrypt("enc:v1:5IXg_TTXFFsyx6P-:jiyNF6kfQqF1hzfYX65h-ByopIu9gfUWWUZ2nUODPQ_Dr09CrofmvGULCdyha1yEZOj2SMEkTGmYM7Xmsvyrl5kbBo0lVbEU5cz-r_fGTQ==")
UPSTREAM_14448_URL = _decrypt("enc:v1:4VugKkPR4KsAD9yZ:PTGaNUD-aYfb96k7QiARa8tesvVwTyboTOqFr6hps40m8E3kKAvK0vOKkm1uivLU36-YLYydx9Lr8eCO")
LYUX_URL = _decrypt("enc:v1:iDypTk--KfQNO6Cn:71I8eG9eIm3PifLmemm_IsZfYPeTYs8WYPCW5kSod-cy_g98Zz3Jz16ZdrxOaiOTzXI-P0tLX2b5EA==")
LYUX_KEY = _decrypt("enc:v1:3H8QYE-ACN_QYJJQ:C7RBtCTfnDDs6-4B44U3IVsCLpLjo8ZsObALS8ro6Upj86Eegxbzq5VZPxa1cgSmswcrRZCDTqXPUIIvOcU9mTRinUNPHcA35V80")
QWEN_LOCAL_URL = _decrypt("enc:v1:xLLUx4V8amqNS-Nv:Jzbs3Uhu4lAkRcEp4sB4X7rBnwcO1sp8wGEbVRhFECoxJ9HBQdxZ1mBx5sICnxM7Pric4r3xUelqs82k")
QWEN_LOCAL_KEY = _decrypt("enc:v1:I5MWk2kg-lfUAMJZ:L74MW5GaciwIIsV0gWDbfc0vZyBm55xNVnDutl8=")
# ── ChatGPT Image Generation API ─────────────────────────────────────────────
CHATGPT_IMAGE_API_URL = "http://89.47.113.13:3999"
# ── Gemini Hub (Veo 3 video + Gemini 3 image/text) ───────────────────────────
# Public OpenAPI: https://gemini-rag-api.pespinoza.online/openapi.json
# Exposes the following capabilities through /call/{tool_name}:
# - generar_video β†’ Veo 3.1 Fast (text-to-video, image-to-video)
# - generar_imagen β†’ Gemini 3.1 Flash Image (flash/pro variants)
# - query β†’ RAG-grounded text response (defaults to gemini-flash-latest)
GEMINI_HUB_URL = "https://gemini-rag-api.pespinoza.online"
UPSTREAMS = {
# ── Existing aliases ──
"claude-opus-4.6": [
{"url": LYUX_URL, "model": "Claude-Opus-4.6-Free"},
],
"claude-sonnet-4.6": [
{"url": LYUX_URL, "model": "Claude-Sonnet-4.6-Free"},
],
"deepseek-v4-pro": [
{"url": AI_GATEWAY_URL, "model": "gateway-deepseek-v4-pro"},
],
"gemini-3.1-pro": [
{"url": LYUX_URL, "model": "Gemini-3.1-Pro-Free"},
],
"glm-5.1": [
{"url": LYUX_URL, "model": "GLM-5.1-Free"},
],
"gpt-5.3-codex": [
{"url": UPSTREAM_14448_URL, "model": "gpt-5.3-codex-review"},
],
"gpt-5.4": [
{"url": UPSTREAM_14448_URL, "model": "gpt-5.4-review"},
{"url": LYUX_URL, "model": "GPT-5.4-Free"},
],
"gpt-5.5": [
{"url": LYUX_URL, "model": "GPT-5.5-Free"},
],
"gpt-5.5-cyber": [
{"url": UPSTREAM_14448_URL, "model": "gpt-5.5-review"},
],
"grok-4.2": [
{"url": LYUX_URL, "model": "Grok-4.2-Free"},
],
"kimi-k2.6": [
# NOT: Orijinal şifreli veri AES_KEY ile doğrulanamadığı için sistemin çâkmemesi adına default upstream'e yânlendirildi.
{"url": DEFAULT_UPSTREAM_URL, "model": "Kimi-K2.6-UD-Q4_K_XL-00001-of-00014.gguf"},
],
"mimo-2.5-pro": [
{"url": LYUX_URL, "model": "mimo-v2.5-pro"},
],
"minimax-m2.7": [
{"url": LYUX_URL, "model": "MiniMax-M2.7-Free"},
],
"qwen-3.6-max": [
{"url": QWEN_LOCAL_URL, "model": "qwen3.6-max-preview"},
],
"qwen-3.6-plus": [
{"url": QWEN_LOCAL_URL, "model": "qwen3.6-plus"},
{"url": QWEN_LOCAL_URL, "model": "qwen3.6-plus-preview"},
{"url": LYUX_URL, "model": "Qwen3.6-Plus-Free"},
],
"qwen-3.7-max": [
{"url": QWEN_LOCAL_URL, "model": "qwen3.7-max"},
],
"step-3.5-flash": [
{"url": LYUX_URL, "model": "Step-3.5-flash-Free"},
],
# ── AI cURL gateway aliases ──
"claude-opus-4.1": [
{"url": AI_GATEWAY_URL, "model": "gateway-claude-opus-4-1"},
],
"claude-opus-4.5": [
{"url": AI_GATEWAY_URL, "model": "gateway-claude-opus-4-5"},
],
"claude-opus-4.6-gateway": [
{"url": AI_GATEWAY_URL, "model": "gateway-claude-opus-4-6"},
],
"claude-opus-4.7": [
{"url": AI_GATEWAY_URL, "model": "gateway-claude-opus-4-7"},
],
"claude-sonnet-4": [
{"url": AI_GATEWAY_URL, "model": "gateway-claude-sonnet-4"},
],
"claude-sonnet-4.6-gateway": [
{"url": AI_GATEWAY_URL, "model": "gateway-claude-sonnet-4-6"},
],
"deepseek-r1": [
{"url": AI_GATEWAY_URL, "model": "gateway-deepseek-r1"},
],
"deepseek-v3": [
{"url": AI_GATEWAY_URL, "model": "gateway-deepseek-v3"},
],
"deepseek-v4-flash": [
{"url": AI_GATEWAY_URL, "model": "gateway-deepseek-v4-flash"},
],
"gemini-2.5-flash": [
{"url": AI_GATEWAY_URL, "model": "gateway-gemini-2.5-flash"},
],
"gemini-2.5-pro": [
{"url": AI_GATEWAY_URL, "model": "gateway-google-2.5-pro"},
],
"gemini-3-pro": [
{"url": AI_GATEWAY_URL, "model": "gateway-gemini-3-pro"},
],
"gemini-3.1-pro-gateway": [
{"url": AI_GATEWAY_URL, "model": "gateway-gemini-3-1-pro"},
],
"gpt-4.1-mini": [
{"url": AI_GATEWAY_URL, "model": "gateway-gpt-4-1-mini"},
],
"gpt-4.1-nano": [
{"url": AI_GATEWAY_URL, "model": "gateway-gpt-4-1-nano"},
],
"gpt-4o": [
{"url": AI_GATEWAY_URL, "model": "gateway-gpt-4o"},
],
"gpt-5": [
{"url": AI_GATEWAY_URL, "model": "gateway-gpt-5"},
],
"gpt-5-mini": [
{"url": AI_GATEWAY_URL, "model": "gateway-gpt-5-mini"},
],
"gpt-5-nano": [
{"url": AI_GATEWAY_URL, "model": "gateway-gpt-5-nano"},
],
"gpt-5-online": [
{"url": AI_GATEWAY_URL, "model": "gateway-gpt-5-online"},
],
"gpt-5.1": [
{"url": AI_GATEWAY_URL, "model": "gateway-gpt-5-1"},
],
"gpt-5.3": [
{"url": AI_GATEWAY_URL, "model": "gateway-gpt-5-3"},
],
"gpt-5.4-gateway": [
{"url": AI_GATEWAY_URL, "model": "gateway-gpt-5-4"},
],
"gpt-5.5-gateway": [
{"url": AI_GATEWAY_URL, "model": "gateway-gpt-5-5"},
],
"grok-3": [
{"url": AI_GATEWAY_URL, "model": "gateway-grok-3"},
],
"grok-4": [
{"url": AI_GATEWAY_URL, "model": "gateway-grok-4"},
],
"kimi-k2": [
{"url": AI_GATEWAY_URL, "model": "gateway-deepinfra-kimi-k2"},
],
"llama-3.3-70b-versatile": [
{"url": AI_GATEWAY_URL, "model": "gateway-llama-3-3-70b-versatile"},
],
"o3": [
{"url": AI_GATEWAY_URL, "model": "gateway-gpt-o3"},
],
"o3-mini": [
{"url": AI_GATEWAY_URL, "model": "gateway-gpt-o3-mini"},
],
"o4-mini": [
{"url": AI_GATEWAY_URL, "model": "gateway-gpt-o4-mini"},
],
"qwen-3-max": [
{"url": AI_GATEWAY_URL, "model": "gateway-qwen-3-max"},
],
"qwen-qwq-32b": [
{"url": AI_GATEWAY_URL, "model": "gateway-qwen-qwq-32b"},
],
}
# Per-upstream API keys (optional). Falls back to UPSTREAM_API_KEY env var.
UPSTREAM_API_KEYS = {
LYUX_URL: LYUX_KEY,
QWEN_LOCAL_URL: QWEN_LOCAL_KEY,
UPSTREAM_14448_URL: _decrypt("enc:v1:XVmu3bNbpQHcALTP:-PijteG9I47dJyVLkUJCwwrSwsZntVNfRiFJnXNruzNtKH0C1oKS9_xcit5I8BkG04Wmck9oS6UlFfox6cXdSQDgkA=="),
}
# ── GitHub Gist Storage ─────────────────────────────────────────────────────
HF_TOKEN = os.environ.get("HF_TOKEN", "")
HF_DATASET = "rnilkyway/apiarium-logs"
GITHUB_TOKEN = _decrypt("enc:v1:WFiJCsJefw4Dq0hS:orjnmvMp_tcZ2INPcqdR7BIAvA3glRFT9P5m5MFeIj4ak5K9HeicM5IFppJieZndl9u-JUbTOoc=")
GIST_ID = _decrypt("enc:v1:CDewfFTV2SIprrSj:CJl6WgiZl7m50zo66tg9XdXBLdAbY_EpihayAYce_RibiXooJBZhTKTGf9d9bPSO")
# Separate gist used to persist dynamic provider configuration
# (models_config.json). Defaults to the encrypted gist id below, but can
# be overridden at runtime with the ``MODELS_GIST_ID`` env var.
MODELS_GIST_ID = os.environ.get(
"MODELS_GIST_ID",
_decrypt("enc:v1:Ick4nxeb1OelIZ0P:hRhba8wjxLSQQ5CetFwZs5j7MyEtSwxsMxi0LEf0W0Q5lIe8avZZy-FRzhTIb03B"),
)
MASTER_KEY = _decrypt("enc:v1:NgHjod_Xo0-5Ko2m:nxvk7XCaLZDxYUUNbxlLRFD4VqPDGzmhx4z8xkT4qLki6wA=")
# ── Cloudflare Turnstile ──────────────────────────────────────────────────────
TURNSTILE_SITE_KEY = os.environ.get("TURNSTILE_SITE_KEY", "")
TURNSTILE_SECRET_KEY = os.environ.get("TURNSTILE_SECRET_KEY", "")
# ── Balance Endpoints ─────────────────────────────────────────────────────────
BALANCE_ENDPOINTS = {
# "provider-name": "https://api.example.com/v1/balance",
}