from __future__ import annotations from datetime import datetime from typing import Any, Dict, List, Optional from pydantic import BaseModel # ── Auth ────────────────────────────────────────────────────────────── class RegisterRequest(BaseModel): email: str password: str class LoginRequest(BaseModel): email: str password: str class TokenResponse(BaseModel): access_token: str refresh_token: Optional[str] = None token_type: str = "bearer" class RefreshRequest(BaseModel): refresh_token: str class ForgotPasswordRequest(BaseModel): email: str class ResetPasswordRequest(BaseModel): token: str new_password: str class UserResponse(BaseModel): """Local user view. Balance mirrored from sub2api when available.""" id: str email: str status: str created_at: datetime sub2api_user_id: Optional[int] = None balance: float = 0.0 class Config: from_attributes = True # ── API Key (shapes match sub2api dto.APIKey 1:1) ───────────────────── class CreateKeyRequest(BaseModel): name: str 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 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 # ── Usage ───────────────────────────────────────────────────────────── class DashboardAPIKeysUsageRequest(BaseModel): api_key_ids: List[int] # ── Common ──────────────────────────────────────────────────────────── class MessageResponse(BaseModel): message: str JSONDict = Dict[str, Any]