- 支持 MiniMax/OpenAI/Google Gemini/智谱/Kimi 五个平台 - 插件化 Provider 架构,自动发现注册 - 多维度 QuotaRule 额度追踪(固定间隔/自然周期/API同步/手动) - OpenAI + Anthropic 兼容 API 代理,SSE 流式转发 - Model 路由表 + 额度耗尽自动 fallback - 多媒体任务队列(图片/语音/视频) - Vue3 + Tailwind 单文件 Web 仪表盘 - Docker 一键部署 Made-with: Cursor
166 lines
4.5 KiB
Python
166 lines
4.5 KiB
Python
"""Pydantic 数据模型 -- API 请求/响应 + 数据库行映射"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from datetime import datetime
|
|
from enum import Enum
|
|
from typing import Any
|
|
|
|
from pydantic import BaseModel, Field
|
|
|
|
|
|
# ── 枚举 ──────────────────────────────────────────────
|
|
|
|
class RefreshType(str, Enum):
|
|
FIXED_INTERVAL = "fixed_interval"
|
|
CALENDAR_CYCLE = "calendar_cycle"
|
|
MANUAL = "manual"
|
|
API_SYNC = "api_sync"
|
|
|
|
|
|
class TaskStatus(str, Enum):
|
|
PENDING = "pending"
|
|
RUNNING = "running"
|
|
COMPLETED = "completed"
|
|
FAILED = "failed"
|
|
CANCELLED = "cancelled"
|
|
|
|
|
|
# ── Plan ──────────────────────────────────────────────
|
|
|
|
class PlanBase(BaseModel):
|
|
name: str
|
|
provider_name: str
|
|
api_base: str = ""
|
|
plan_type: str = "coding"
|
|
supported_models: list[str] = Field(default_factory=list)
|
|
extra_headers: dict[str, str] = Field(default_factory=dict)
|
|
extra_config: dict[str, Any] = Field(default_factory=dict)
|
|
enabled: bool = True
|
|
|
|
|
|
class PlanCreate(PlanBase):
|
|
api_key: str = ""
|
|
|
|
|
|
class PlanUpdate(BaseModel):
|
|
name: str | None = None
|
|
api_key: str | None = None
|
|
api_base: str | None = None
|
|
plan_type: str | None = None
|
|
supported_models: list[str] | None = None
|
|
extra_headers: dict[str, str] | None = None
|
|
extra_config: dict[str, Any] | None = None
|
|
enabled: bool | None = None
|
|
|
|
|
|
class PlanOut(PlanBase):
|
|
id: str
|
|
created_at: datetime
|
|
updated_at: datetime
|
|
|
|
|
|
# ── QuotaRule ─────────────────────────────────────────
|
|
|
|
class QuotaRuleBase(BaseModel):
|
|
rule_name: str
|
|
quota_total: int
|
|
quota_unit: str = "requests"
|
|
refresh_type: RefreshType = RefreshType.CALENDAR_CYCLE
|
|
interval_hours: float | None = None
|
|
calendar_unit: str | None = None
|
|
calendar_anchor: dict[str, Any] | None = None
|
|
enabled: bool = True
|
|
|
|
|
|
class QuotaRuleCreate(QuotaRuleBase):
|
|
plan_id: str
|
|
|
|
|
|
class QuotaRuleUpdate(BaseModel):
|
|
rule_name: str | None = None
|
|
quota_total: int | None = None
|
|
quota_unit: str | None = None
|
|
refresh_type: RefreshType | None = None
|
|
interval_hours: float | None = None
|
|
calendar_unit: str | None = None
|
|
calendar_anchor: dict[str, Any] | None = None
|
|
enabled: bool | None = None
|
|
|
|
|
|
class QuotaRuleOut(QuotaRuleBase):
|
|
id: str
|
|
plan_id: str
|
|
quota_used: int = 0
|
|
last_refresh_at: datetime | None = None
|
|
next_refresh_at: datetime | None = None
|
|
|
|
|
|
# ── QuotaSnapshot ─────────────────────────────────────
|
|
|
|
class QuotaSnapshotOut(BaseModel):
|
|
id: str
|
|
rule_id: str
|
|
quota_used: int
|
|
quota_remaining: int
|
|
checked_at: datetime
|
|
|
|
|
|
# ── Model Route ───────────────────────────────────────
|
|
|
|
class ModelRouteBase(BaseModel):
|
|
model_name: str
|
|
plan_id: str
|
|
priority: int = 0
|
|
|
|
|
|
class ModelRouteOut(ModelRouteBase):
|
|
id: str
|
|
|
|
|
|
# ── Task Queue ────────────────────────────────────────
|
|
|
|
class TaskCreate(BaseModel):
|
|
plan_id: str | None = None
|
|
task_type: str
|
|
request_payload: dict[str, Any] = Field(default_factory=dict)
|
|
priority: int = 0
|
|
max_retries: int = 3
|
|
callback_url: str | None = None
|
|
|
|
|
|
class TaskOut(BaseModel):
|
|
id: str
|
|
plan_id: str | None
|
|
task_type: str
|
|
status: TaskStatus
|
|
request_payload: dict[str, Any]
|
|
response_payload: dict[str, Any] | None = None
|
|
result_file_path: str | None = None
|
|
result_mime_type: str | None = None
|
|
priority: int
|
|
retry_count: int
|
|
max_retries: int
|
|
callback_url: str | None = None
|
|
created_at: datetime
|
|
started_at: datetime | None = None
|
|
completed_at: datetime | None = None
|
|
|
|
|
|
# ── 聚合视图 ──────────────────────────────────────────
|
|
|
|
class PlanWithRules(PlanOut):
|
|
"""Plan + 所有 QuotaRule 的聚合返回"""
|
|
quota_rules: list[QuotaRuleOut] = Field(default_factory=list)
|
|
|
|
|
|
class DashboardPlan(BaseModel):
|
|
"""仪表盘用的精简视图"""
|
|
id: str
|
|
name: str
|
|
provider_name: str
|
|
plan_type: str
|
|
enabled: bool
|
|
quota_rules: list[QuotaRuleOut]
|
|
all_available: bool = True # 所有 Rule 均有余量
|