infinity serch

This commit is contained in:
jze9
2026-05-19 17:48:35 +05:00
parent 57ac3fc317
commit eb4e71ee77
17 changed files with 694 additions and 150 deletions

115
api/route/admin_system.py Normal file
View File

@@ -0,0 +1,115 @@
import os
import time
import asyncio
from urllib.parse import urlparse
from fastapi import APIRouter, Depends
from sqlalchemy import text
from sqlalchemy.ext.asyncio import AsyncSession
from bd.database import get_db, get_redis, DATABASE_URL, REDIS_URL
from route.deps import require_admin
router = APIRouter()
MINIO_ENDPOINT = os.getenv("MINIO_ENDPOINT", "minio:9000")
MINIO_ACCESS_KEY = os.getenv("MINIO_ACCESS_KEY", "minioadmin")
MINIO_SECRET_KEY = os.getenv("MINIO_SECRET_KEY", "minioadmin")
MINIO_BUCKET = os.getenv("MINIO_BUCKET", "news-media")
MINIO_PUBLIC_URL = os.getenv("MINIO_PUBLIC_URL", "http://localhost:9000")
def _parse_db_url(url: str) -> dict:
"""Вытащить host/port/db/user из DATABASE_URL без пароля."""
try:
# postgresql+asyncpg://user:pass@host:port/db
p = urlparse(url.replace("+asyncpg", ""))
return {
"host": p.hostname or "?",
"port": p.port or 5432,
"database": (p.path or "/").lstrip("/") or "?",
"user": p.username or "?",
}
except Exception:
return {"host": "?", "port": 5432, "database": "?", "user": "?"}
def _parse_redis_url(url: str) -> dict:
"""Вытащить host/port из REDIS_URL без пароля."""
try:
p = urlparse(url)
return {
"host": p.hostname or "?",
"port": p.port or 6379,
"db": (p.path or "/0").lstrip("/") or "0",
}
except Exception:
return {"host": "?", "port": 6379, "db": "0"}
async def _check_postgres(db: AsyncSession) -> dict:
info = _parse_db_url(DATABASE_URL)
t0 = time.monotonic()
try:
result = await db.execute(text("SELECT version()"))
version = result.scalar() or ""
latency_ms = round((time.monotonic() - t0) * 1000, 1)
# Извлекаем короткую версию: "PostgreSQL 15.3 ..."
short_ver = version.split(",")[0] if version else "?"
return {"ok": True, "latency_ms": latency_ms, "version": short_ver, **info}
except Exception as e:
return {"ok": False, "error": str(e), "latency_ms": None, **info}
async def _check_redis() -> dict:
info = _parse_redis_url(REDIS_URL)
t0 = time.monotonic()
try:
redis = await get_redis()
pong = await redis.ping()
latency_ms = round((time.monotonic() - t0) * 1000, 1)
server_info = await redis.info("server")
version = server_info.get("redis_version", "?")
return {"ok": bool(pong), "latency_ms": latency_ms, "version": f"Redis {version}", **info}
except Exception as e:
return {"ok": False, "error": str(e), "latency_ms": None, **info}
async def _check_minio() -> dict:
t0 = time.monotonic()
try:
from minio import Minio
loop = asyncio.get_event_loop()
client = Minio(MINIO_ENDPOINT, access_key=MINIO_ACCESS_KEY, secret_key=MINIO_SECRET_KEY, secure=False)
exists = await loop.run_in_executor(None, client.bucket_exists, MINIO_BUCKET)
latency_ms = round((time.monotonic() - t0) * 1000, 1)
return {
"ok": True,
"latency_ms": latency_ms,
"endpoint": MINIO_ENDPOINT,
"bucket": MINIO_BUCKET,
"public_url": MINIO_PUBLIC_URL,
"bucket_exists": exists,
}
except Exception as e:
return {
"ok": False,
"error": str(e),
"latency_ms": None,
"endpoint": MINIO_ENDPOINT,
"bucket": MINIO_BUCKET,
"public_url": MINIO_PUBLIC_URL,
}
@router.get("/status")
async def system_status(db: AsyncSession = Depends(get_db), _: str = Depends(require_admin)):
pg, redis, minio = await asyncio.gather(
_check_postgres(db),
_check_redis(),
_check_minio(),
)
return {
"postgres": pg,
"redis": redis,
"minio": minio,
}