Spaces:
Paused
Paused
| import uuid | |
| from datetime import datetime, timezone | |
| from fastapi import APIRouter, Depends, HTTPException | |
| from pydantic import BaseModel | |
| from sqlalchemy import select | |
| from sqlalchemy.orm import Session | |
| from auth import generate_api_key, require_auth | |
| from db import get_db | |
| from models import APIKey, User | |
| from schemas import MessageResponse | |
| router = APIRouter(prefix="/api-keys", tags=["api-keys"]) | |
| class CreateKeyRequest(BaseModel): | |
| label: str | |
| class CreateKeyResponse(BaseModel): | |
| id: str | |
| key: str | |
| label: str | |
| key_prefix: str | |
| created_at: datetime | |
| class KeyListItem(BaseModel): | |
| id: str | |
| label: str | |
| key_prefix: str | |
| created_at: datetime | |
| last_used_at: datetime | None | |
| model_config = {"from_attributes": True} | |
| def list_keys(user: User = Depends(require_auth), db: Session = Depends(get_db)): | |
| keys = ( | |
| db.execute( | |
| select(APIKey) | |
| .where(APIKey.created_by == user.id, APIKey.revoked_at.is_(None)) | |
| .order_by(APIKey.created_at.desc()) | |
| ) | |
| .scalars() | |
| .all() | |
| ) | |
| return [ | |
| KeyListItem( | |
| id=str(k.id), | |
| label=k.label, | |
| key_prefix=k.key_prefix, | |
| created_at=k.created_at, | |
| last_used_at=k.last_used_at, | |
| ) | |
| for k in keys | |
| ] | |
| def create_key(body: CreateKeyRequest, user: User = Depends(require_auth), db: Session = Depends(get_db)): | |
| full_key, prefix, key_hash = generate_api_key() | |
| api_key = APIKey(key_prefix=prefix, key_hash=key_hash, label=body.label, created_by=user.id) | |
| db.add(api_key) | |
| db.commit() | |
| db.refresh(api_key) | |
| return CreateKeyResponse( | |
| id=str(api_key.id), | |
| key=full_key, | |
| label=api_key.label, | |
| key_prefix=prefix, | |
| created_at=api_key.created_at, | |
| ) | |
| def revoke_key(key_id: str, user: User = Depends(require_auth), db: Session = Depends(get_db)): | |
| try: | |
| key_uuid = uuid.UUID(key_id) | |
| except (TypeError, ValueError): | |
| raise HTTPException(status_code=404, detail="API key not found.") | |
| api_key = db.get(APIKey, key_uuid) | |
| if api_key is None or api_key.created_by != user.id: | |
| raise HTTPException(status_code=404, detail="API key not found.") | |
| if api_key.revoked_at is not None: | |
| raise HTTPException(status_code=400, detail="API key is already revoked.") | |
| api_key.revoked_at = datetime.now(timezone.utc) | |
| db.commit() | |
| return MessageResponse(message="API key revoked.") |