Files
Aether/_deprecated_py_src/services/provider_ops/architectures/cubence.py
fawney19 1d9c77522a refactor: 移除 Python 后端源码,全面迁移至 Rust gateway 架构
- 删除全部 Python 源码 (src/) 及 Alembic 迁移脚本,归档至 _deprecated_py_src/
- 重构 Rust gateway ai_pipeline: 拆分 planner/finalize 模块,新增 contracts/adaptation 层
- 重组 handlers 模块为 admin/public/proxy/internal/shared 子模块结构
- 新增 executor 模块,引入 Rust 原生数据库迁移 (aether-data/migrations)
- 简化 CI/Docker 构建流程,移除 base image 二级构建,统一为单一 app image
- 移除 Python 相关基础设施文件 (entrypoint.sh, gunicorn_conf.py, Dockerfile.base)
2026-04-03 16:26:16 +08:00

229 lines
7.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
Cubence 架构
针对 Cubence 中转站的预设配置。
"""
from typing import Any
import httpx
from src.services.provider_ops.actions import ProviderAction
from src.services.provider_ops.actions.cubence_balance import CubenceBalanceAction
from src.services.provider_ops.architectures.base import (
ProviderArchitecture,
ProviderConnector,
VerifyResult,
)
from src.services.provider_ops.types import ConnectorAuthType, ProviderActionType
from src.services.provider_ops.utils import extract_cookie_value
class CubenceConnector(ProviderConnector):
"""
Cubence 专用连接器
特点:
- 使用 Cookie 认证token JWT
"""
auth_type = ConnectorAuthType.COOKIE
display_name = "Cubence Cookie"
def __init__(self, base_url: str, config: dict[str, Any] | None = None):
super().__init__(base_url, config)
self._token_cookie: str | None = None
async def connect(self, credentials: dict[str, Any]) -> bool:
"""建立连接"""
token_cookie = credentials.get("token_cookie")
if not token_cookie:
self._set_error("Token Cookie 不能为空")
return False
# 提取纯 token 值
self._token_cookie = extract_cookie_value(token_cookie, "token")
self._set_connected()
return True
async def disconnect(self) -> None:
"""断开连接"""
self._token_cookie = None
self._set_disconnected()
async def is_authenticated(self) -> bool:
"""检查是否已认证"""
return self._token_cookie is not None
def _apply_auth(self, request: httpx.Request) -> httpx.Request:
"""为请求应用认证信息"""
if self._token_cookie:
request.headers["Cookie"] = f"token={self._token_cookie}"
return request
@classmethod
def get_credentials_schema(cls) -> dict[str, Any]:
"""获取凭据配置 schema"""
return {
"type": "object",
"properties": {
"base_url": {
"type": "string",
"title": "站点地址",
"description": "API 基础地址",
"x-default-value": "https://cubence.com",
},
"token_cookie": {
"type": "string",
"title": "Token Cookie",
"description": "从浏览器复制的 token Cookie 值JWT 格式)",
"x-sensitive": True,
"x-input-type": "password",
},
},
"required": ["token_cookie"],
"x-field-groups": [
{"fields": ["base_url"]},
{"fields": ["token_cookie"]},
],
"x-auth-type": "cookie",
"x-default-base-url": "https://cubence.com",
"x-validation": [
{
"type": "required",
"fields": ["token_cookie"],
"message": "请填写 Token Cookie",
},
],
"x-quota-divisor": None,
"x-currency": "USD",
"x-balance-extra-format": [
{
"label": "5h",
"type": "window_limit",
"source": "five_hour_limit",
"unit_divisor": 1000000,
},
{
"label": "",
"type": "window_limit",
"source": "weekly_limit",
"unit_divisor": 1000000,
},
],
}
class CubenceArchitecture(ProviderArchitecture):
"""
Cubence 架构预设
针对 Cubence 中转站优化的预设配置。
特点:
- 使用 Cookie 认证token JWT
- 验证端点: /api/v1/dashboard/overview
- 余额单位直接是美元
- 支持窗口限额5小时/每周)
"""
architecture_id = "cubence"
display_name = "Cubence"
description = "Cubence 中转站预设配置,使用 Cookie 认证"
supported_connectors: list[type[ProviderConnector]] = [
CubenceConnector,
]
supported_actions: list[type[ProviderAction]] = [
CubenceBalanceAction,
]
default_action_configs: dict[ProviderActionType, dict[str, Any]] = {
ProviderActionType.QUERY_BALANCE: {
"endpoint": "/api/v1/dashboard/overview",
"method": "GET",
"response_mapping": {
"total_available": "data.balance.total_balance_dollar",
},
},
}
def get_credentials_schema(self) -> dict[str, Any]:
"""Cubence 使用 token_cookie 认证"""
return CubenceConnector.get_credentials_schema()
def get_verify_endpoint(self) -> str:
"""验证端点"""
return "/api/v1/dashboard/overview"
def build_verify_headers(
self,
config: dict[str, Any],
credentials: dict[str, Any],
) -> dict[str, str]:
"""
构建 Cubence 的验证请求 Headers
使用 Cookie 认证,不使用 Authorization。
"""
headers: dict[str, str] = {}
# 添加 token Cookie
cookie_input = credentials.get("token_cookie")
if cookie_input:
token_value = extract_cookie_value(cookie_input, "token")
headers["Cookie"] = f"token={token_value}"
return headers
def _auth_fail_message(self, status_code: int) -> str:
"""Cookie 认证的错误消息"""
if status_code == 401:
return "Cookie 已失效,请重新配置"
return "Cookie 已失效或无权限"
def _build_verify_result(
self, user_data: dict[str, Any], raw_data: dict[str, Any] | None = None
) -> VerifyResult:
"""Cubence 自定义字段提取user/balance/subscription_limits"""
user_info = user_data.get("user", {})
balance_info = user_data.get("balance", {})
subscription_limits = user_data.get("subscription_limits", {})
# 构建 extra 信息,包含窗口限额
extra: dict[str, Any] = {
"role": user_info.get("role"),
"invite_code": user_info.get("invite_code"),
}
# 5小时窗口限额
five_hour = subscription_limits.get("five_hour", {})
if five_hour:
extra["five_hour_limit"] = {
"limit": five_hour.get("limit"),
"used": five_hour.get("used"),
"remaining": five_hour.get("remaining"),
"resets_at": five_hour.get("resets_at"),
}
# 每周窗口限额
weekly = subscription_limits.get("weekly", {})
if weekly:
extra["weekly_limit"] = {
"limit": weekly.get("limit"),
"used": weekly.get("used"),
"remaining": weekly.get("remaining"),
"resets_at": weekly.get("resets_at"),
}
return VerifyResult(
success=True,
username=user_info.get("username"),
display_name=user_info.get("username"),
quota=balance_info.get("total_balance_dollar"),
extra=extra,
)