integrate sub2api as upstream for auth/keys/usage via FastAPI BFF
Preserve local user table for superDream-specific features while syncing user lifecycle, API key CRUD and usage queries through sub2api. Admin token handles reads and user lifecycle; per-user tokens (Fernet-encrypted in DB) handle key writes that admin endpoints do not expose. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,10 +1,12 @@
|
||||
from decimal import Decimal
|
||||
from pydantic import BaseModel, EmailStr
|
||||
from datetime import datetime, date
|
||||
from typing import Optional, List
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import datetime
|
||||
from typing import Any, Dict, List, Optional
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
|
||||
# ── Auth ──
|
||||
# ── Auth ──────────────────────────────────────────────────────────────
|
||||
|
||||
class RegisterRequest(BaseModel):
|
||||
email: str
|
||||
@@ -36,144 +38,59 @@ class ResetPasswordRequest(BaseModel):
|
||||
|
||||
|
||||
class UserResponse(BaseModel):
|
||||
"""Local user view. Balance mirrored from sub2api when available."""
|
||||
|
||||
id: str
|
||||
email: str
|
||||
balance: Decimal
|
||||
status: str
|
||||
created_at: datetime
|
||||
sub2api_user_id: Optional[int] = None
|
||||
balance: float = 0.0
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
# ── API Key ──
|
||||
# ── API Key (shapes match sub2api dto.APIKey 1:1) ─────────────────────
|
||||
|
||||
class CreateKeyRequest(BaseModel):
|
||||
name: str = ""
|
||||
|
||||
|
||||
class ApiKeyResponse(BaseModel):
|
||||
id: str
|
||||
name: str
|
||||
key_prefix: str
|
||||
key_suffix: str
|
||||
status: str
|
||||
created_at: datetime
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
group_id: Optional[int] = None
|
||||
custom_key: Optional[str] = None
|
||||
ip_whitelist: List[str] = []
|
||||
ip_blacklist: List[str] = []
|
||||
quota: Optional[float] = None
|
||||
expires_in_days: Optional[int] = None
|
||||
rate_limit_5h: Optional[float] = None
|
||||
rate_limit_1d: Optional[float] = None
|
||||
rate_limit_7d: Optional[float] = None
|
||||
|
||||
|
||||
class ApiKeyCreatedResponse(BaseModel):
|
||||
id: str
|
||||
name: str
|
||||
key: str
|
||||
key_prefix: str
|
||||
key_suffix: str
|
||||
created_at: datetime
|
||||
class UpdateKeyRequest(BaseModel):
|
||||
name: Optional[str] = None
|
||||
group_id: Optional[int] = None
|
||||
status: Optional[str] = None
|
||||
ip_whitelist: Optional[List[str]] = None
|
||||
ip_blacklist: Optional[List[str]] = None
|
||||
quota: Optional[float] = None
|
||||
expires_at: Optional[str] = None
|
||||
reset_quota: Optional[bool] = None
|
||||
rate_limit_5h: Optional[float] = None
|
||||
rate_limit_1d: Optional[float] = None
|
||||
rate_limit_7d: Optional[float] = None
|
||||
reset_rate_limit_usage: Optional[bool] = None
|
||||
|
||||
|
||||
# ── Wallet ──
|
||||
# ── Usage ─────────────────────────────────────────────────────────────
|
||||
|
||||
class RedeemCodeRequest(BaseModel):
|
||||
code: str
|
||||
class DashboardAPIKeysUsageRequest(BaseModel):
|
||||
api_key_ids: List[int]
|
||||
|
||||
|
||||
class TransactionResponse(BaseModel):
|
||||
id: str
|
||||
type: str
|
||||
amount: Decimal
|
||||
balance_after: Decimal
|
||||
reference_id: str
|
||||
created_at: datetime
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
class BalanceResponse(BaseModel):
|
||||
balance: Decimal
|
||||
|
||||
|
||||
# ── Models ──
|
||||
|
||||
class ModelPricingResponse(BaseModel):
|
||||
id: int
|
||||
model_name: str
|
||||
provider: str
|
||||
input_price_per_1k: Decimal
|
||||
output_price_per_1k: Decimal
|
||||
status: str
|
||||
updated_at: datetime
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
# ── Example (legacy) ──
|
||||
|
||||
class ExampleCreate(BaseModel):
|
||||
name: str
|
||||
description: str = ""
|
||||
|
||||
|
||||
class ExampleResponse(BaseModel):
|
||||
id: str
|
||||
name: str
|
||||
description: str
|
||||
created_at: datetime
|
||||
|
||||
|
||||
# ── Common ──
|
||||
# ── Common ────────────────────────────────────────────────────────────
|
||||
|
||||
class MessageResponse(BaseModel):
|
||||
message: str
|
||||
|
||||
|
||||
# ── Usage ──
|
||||
|
||||
class UsageSummaryResponse(BaseModel):
|
||||
today_tokens: int
|
||||
today_cost: Decimal
|
||||
month_tokens: int
|
||||
month_cost: Decimal
|
||||
total_requests: int
|
||||
|
||||
|
||||
class DailyUsageResponse(BaseModel):
|
||||
date: date
|
||||
total_tokens: int
|
||||
cost: Decimal
|
||||
requests: int
|
||||
|
||||
|
||||
class ModelUsageResponse(BaseModel):
|
||||
model: str
|
||||
total_tokens: int
|
||||
cost: Decimal
|
||||
requests: int
|
||||
|
||||
|
||||
class KeyUsageResponse(BaseModel):
|
||||
key_id: str
|
||||
key_name: str
|
||||
key_prefix: str
|
||||
key_suffix: str
|
||||
total_tokens: int
|
||||
cost: Decimal
|
||||
requests: int
|
||||
|
||||
|
||||
class UsageLogResponse(BaseModel):
|
||||
id: int
|
||||
key_id: str
|
||||
model: str
|
||||
prompt_tokens: int
|
||||
completion_tokens: int
|
||||
total_tokens: int
|
||||
cost: Decimal
|
||||
request_time: datetime
|
||||
status: str
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
JSONDict = Dict[str, Any]
|
||||
Reference in New Issue
Block a user