Backend: - Fix Content-Length mismatch by not forwarding client headers to Ollama - Proxy /v1/chat/completions directly to Ollama's OpenAI-compatible endpoint (eliminates manual Ollama↔OpenAI format conversion, fixes tool use) - Add streaming support via SSE passthrough - Fix ollama_url /v1 suffix stripped on save - Replace BaseHTTPMiddleware with FastAPI global dependency (fixes double logging) - Add rotating usage log (8 KB, logs key name + model + token estimate + prompt preview) - Add httpx timeout 300s - Add activate and delete endpoints for API keys - Return usage data (tokens/requests) in GET /api/api-keys Frontend: - Admin table: remove ID column, status as icon, icon-only action buttons with CSS tooltips - Add activate + delete buttons; edit available for inactive keys too - Quota columns: fixed equal width, progress bars with k-unit formatting - Create form: structured layout matching edit form style - Edit form: token inputs in k units (÷1000 display, ×1000 on save) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
63 lines
1.6 KiB
Python
63 lines
1.6 KiB
Python
from pydantic import BaseModel
|
|
from datetime import datetime
|
|
from typing import Optional
|
|
|
|
class APIKeyCreate(BaseModel):
|
|
name: str
|
|
expires_at: Optional[datetime] = None
|
|
daily_tokens: Optional[int] = None
|
|
monthly_tokens: Optional[int] = None
|
|
daily_requests: Optional[int] = None
|
|
monthly_requests: Optional[int] = None
|
|
|
|
class APIKey(BaseModel):
|
|
id: int
|
|
name: str
|
|
key: str
|
|
key_prefix: Optional[str] = None
|
|
is_active: bool
|
|
created_at: datetime
|
|
expires_at: Optional[datetime] = None
|
|
daily_tokens: Optional[int] = None
|
|
monthly_tokens: Optional[int] = None
|
|
daily_requests: Optional[int] = None
|
|
monthly_requests: Optional[int] = None
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
class APIKeyCreated(APIKey):
|
|
plaintext_key: Optional[str] = None
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
class QuotaUpdate(BaseModel):
|
|
daily_tokens: Optional[int] = None
|
|
monthly_tokens: Optional[int] = None
|
|
daily_requests: Optional[int] = None
|
|
monthly_requests: Optional[int] = None
|
|
|
|
class Settings(BaseModel):
|
|
ollama_url: str
|
|
default_model: str
|
|
|
|
class UsageStats(BaseModel):
|
|
tokens_used_today: int = 0
|
|
tokens_used_month: int = 0
|
|
requests_today: int = 0
|
|
requests_month: int = 0
|
|
daily_reset_at: Optional[datetime] = None
|
|
monthly_reset_at: Optional[datetime] = None
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
class APIKeyWithUsage(APIKey):
|
|
tokens_used_today: int = 0
|
|
tokens_used_month: int = 0
|
|
requests_today: int = 0
|
|
requests_month: int = 0
|
|
|
|
class Config:
|
|
from_attributes = True |