chore: post-deployment cleanup and docs update
- Make AI routing rules DB-driven (read from system_configs, removed from config.py) - Add translation quota tracking to LLM translation (OpenAIProvider) - Add Alibaba MT ECS RAM role support (STS token, no AccessKey needed) - Fix admin sidebar link for AI模型配置 page - Fix Quota.vue API path (quotas → translation-quotas) - Fix login auto-redirect to dashboard - Add provider dropdown selects to AI routing config UI - Clean up stale ai_provider_* system_configs records - Remove OpencodeGo, Spark providers (code + DB) - Update deploy config: nginx port 8000, systemd cwd
This commit is contained in:
@@ -1,11 +1,13 @@
|
||||
from typing import Dict, Any, Optional
|
||||
from aliyunsdkcore.client import AcsClient
|
||||
from aliyunsdkcore.auth.credentials import StsTokenCredential
|
||||
from aliyunsdkalimt.request.v20181012 import TranslateGeneralRequest, TranslateECommerceRequest
|
||||
from app.services.translation_quota import TranslationQuotaService
|
||||
from app.database import AsyncSessionLocal
|
||||
import asyncio
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -16,11 +18,55 @@ ALIBABA_LANG_MAP = {
|
||||
"id": "id", "ms": "ms", "tl": "tl", "hi": "hi",
|
||||
}
|
||||
|
||||
ECS_METADATA_URL = "http://100.100.100.200/latest/meta-data/ram/security-credentials/"
|
||||
|
||||
|
||||
def _fetch_ecs_ram_credentials():
|
||||
try:
|
||||
import urllib.request
|
||||
req = urllib.request.Request(ECS_METADATA_URL, method="GET")
|
||||
with urllib.request.urlopen(req, timeout=2) as resp:
|
||||
role_name = resp.read().decode().strip()
|
||||
if not role_name:
|
||||
logger.warning("ECS metadata returned empty role name")
|
||||
return None
|
||||
url = f"{ECS_METADATA_URL}{role_name}"
|
||||
req = urllib.request.Request(url, method="GET")
|
||||
with urllib.request.urlopen(req, timeout=2) as resp:
|
||||
data = json.loads(resp.read().decode())
|
||||
if data.get("Code") == "Success":
|
||||
logger.info(f"Fetched STS token for role {role_name}, expires {data.get('Expiration')}")
|
||||
return (data["AccessKeyId"], data["AccessKeySecret"], data["SecurityToken"])
|
||||
else:
|
||||
logger.warning(f"ECS metadata returned non-success: {data.get('Code')}")
|
||||
except Exception as e:
|
||||
logger.debug(f"ECS metadata fetch failed: {e}")
|
||||
return None
|
||||
|
||||
|
||||
def _build_acs_client(access_key_id: str = "", access_key_secret: str = "",
|
||||
region_id: str = "cn-hangzhou") -> AcsClient:
|
||||
creds = _fetch_ecs_ram_credentials()
|
||||
if creds:
|
||||
ak, sk, token = creds
|
||||
sts_cred = StsTokenCredential(ak, sk, token)
|
||||
client = AcsClient(credential=sts_cred, region_id=region_id)
|
||||
logger.info("Alibaba MT using ECS RAM role (STS token)")
|
||||
return client
|
||||
|
||||
ak = access_key_id or os.getenv("ALIBABA_ACCESS_KEY_ID", "")
|
||||
sk = access_key_secret or os.getenv("ALIBABA_ACCESS_KEY_SECRET", "")
|
||||
if ak and sk:
|
||||
logger.info("Alibaba MT using AccessKey credentials")
|
||||
return AcsClient(ak, sk, region_id)
|
||||
|
||||
raise ValueError("No Alibaba Cloud credentials found (neither ECS RAM role nor AccessKey)")
|
||||
|
||||
|
||||
class AlibabaMTProvider:
|
||||
def __init__(self, access_key_id: str, access_key_secret: str,
|
||||
def __init__(self, access_key_id: str = "", access_key_secret: str = "",
|
||||
region_id: str = "cn-hangzhou"):
|
||||
self.client = AcsClient(access_key_id, access_key_secret, region_id)
|
||||
self.client = _build_acs_client(access_key_id, access_key_secret, region_id)
|
||||
self._name = "alibaba-mt"
|
||||
|
||||
async def translate(self, text: str, source_lang: Optional[str],
|
||||
|
||||
Reference in New Issue
Block a user