Spaces:
Sleeping
Sleeping
| import asyncio | |
| import time | |
| from fastapi import APIRouter, Form, HTTPException, Request, Depends | |
| from src.core.config import DEFAULT_CLOUDINARY_URL, DEFAULT_PINECONE_KEY, IDX_FACES, IDX_OBJECTS | |
| from src.core.security import get_verified_keys | |
| from src.services.db_client import ( | |
| cld_delete_all_paginated, cld_remove_folder, cld_root_folders, | |
| delete_and_recreate_indexes, pinecone_pool, | |
| ) | |
| from src.core.logging import log, warn | |
| from src.common.utils import get_ip, is_default_key | |
| router = APIRouter() | |
| async def reset_database( | |
| request: Request, | |
| user_id: str = Form(""), | |
| keys: dict = Depends(get_verified_keys) | |
| ): | |
| ip = get_ip(request) | |
| start = time.perf_counter() | |
| log("WARNING", "danger.reset_database.attempt", user_id=user_id or "anonymous", ip=ip) | |
| if is_default_key(keys["pinecone_key"], DEFAULT_PINECONE_KEY) or is_default_key(keys["cloudinary_url"], DEFAULT_CLOUDINARY_URL): | |
| log("WARNING", "danger.reset_database.blocked", user_id=user_id or "anonymous", ip=ip) | |
| raise HTTPException(403, "Reset is not allowed on the shared demo database.") | |
| try: | |
| deleted = await asyncio.to_thread(cld_delete_all_paginated, keys["cloudinary_creds"]) | |
| log("INFO", "danger.reset_database.cloudinary_wiped", deleted=deleted) | |
| except Exception as e: | |
| warn(f"Cloudinary wipe error: {e}") | |
| try: | |
| folders_res = await asyncio.to_thread(cld_root_folders, keys["cloudinary_creds"]) | |
| folder_tasks = [ | |
| asyncio.to_thread(cld_remove_folder, f["name"], keys["cloudinary_creds"]) | |
| for f in folders_res.get("folders", []) | |
| ] | |
| if folder_tasks: | |
| await asyncio.gather(*folder_tasks, return_exceptions=True) | |
| except Exception as e: | |
| warn(f"Cloudinary folder cleanup error: {e}") | |
| try: | |
| pc = pinecone_pool.get(keys["pinecone_key"]) | |
| await asyncio.to_thread(delete_and_recreate_indexes, pc) | |
| except Exception as e: | |
| log("ERROR", "danger.reset_database.pinecone_error", user_id=user_id or "anonymous", ip=ip, error=str(e)) | |
| raise HTTPException(500, f"Pinecone reset error: {e}") | |
| log("WARNING", "danger.reset_database.complete", user_id=user_id or "anonymous", ip=ip, duration_ms=round((time.perf_counter() - start) * 1000)) | |
| return {"message": "Database reset complete. All data wiped and indexes recreated."} | |
| async def delete_account( | |
| request: Request, | |
| user_id: str = Form(""), | |
| keys: dict = Depends(get_verified_keys) | |
| ): | |
| ip = get_ip(request) | |
| start = time.perf_counter() | |
| log("WARNING", "danger.delete_account.attempt", user_id=user_id or "anonymous", ip=ip) | |
| if is_default_key(keys["pinecone_key"], DEFAULT_PINECONE_KEY) or is_default_key(keys["cloudinary_url"], DEFAULT_CLOUDINARY_URL): | |
| log("WARNING", "danger.delete_account.blocked", user_id=user_id or "anonymous", ip=ip) | |
| raise HTTPException(403, "Account deletion is not allowed on the shared demo database.") | |
| try: | |
| deleted = await asyncio.to_thread(cld_delete_all_paginated, keys["cloudinary_creds"]) | |
| log("INFO", "danger.delete_account.cloudinary_wiped", deleted=deleted) | |
| except Exception as e: | |
| warn(f"Account delete Cloudinary error: {e}") | |
| try: | |
| folders_res = await asyncio.to_thread(cld_root_folders, keys["cloudinary_creds"]) | |
| folder_tasks = [ | |
| asyncio.to_thread(cld_remove_folder, f["name"], keys["cloudinary_creds"]) | |
| for f in folders_res.get("folders", []) | |
| ] | |
| if folder_tasks: | |
| await asyncio.gather(*folder_tasks, return_exceptions=True) | |
| except Exception as e: | |
| warn(f"Account delete folders error: {e}") | |
| try: | |
| pc = pinecone_pool.get(keys["pinecone_key"]) | |
| def _delete_indexes(): | |
| existing = {idx.name for idx in pc.list_indexes()} | |
| for name in [IDX_OBJECTS, IDX_FACES]: | |
| if name in existing: | |
| pc.delete_index(name) | |
| await asyncio.to_thread(_delete_indexes) | |
| except Exception as e: | |
| warn(f"Account delete Pinecone error: {e}") | |
| log("WARNING", "danger.delete_account.complete", user_id=user_id or "anonymous", ip=ip, duration_ms=round((time.perf_counter() - start) * 1000)) | |
| return {"message": "Account data deleted. Sign out initiated."} |