- Add VkConnection model with is_online/last_checked_at fields - Add /vk OAuth flow (connect/callback/disconnect/page) - Add VK entry to connections dashboard - Extend background health checker to check VK tokens via users.get - Add Alembic migration for vk_connections table - Add VK_CLIENT_ID/SECRET/SCOPES/API_VERSION config settings Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
76 lines
2.2 KiB
Python
76 lines
2.2 KiB
Python
import asyncio
|
|
import logging
|
|
from datetime import datetime
|
|
|
|
import httpx
|
|
|
|
from web.database import SessionLocal
|
|
from web.models import EvotorConnection, VkConnection
|
|
|
|
logger = logging.getLogger("uvicorn.error")
|
|
|
|
EVOTOR_STORES_URL = "https://api.evotor.ru/stores"
|
|
VK_USERS_GET_URL = "https://api.vk.com/method/users.get"
|
|
VK_API_VERSION = "5.131"
|
|
|
|
|
|
async def check_evotor_connection(access_token: str) -> bool:
|
|
try:
|
|
async with httpx.AsyncClient() as client:
|
|
response = await client.get(
|
|
EVOTOR_STORES_URL,
|
|
headers={"Authorization": f"Bearer {access_token}"},
|
|
timeout=15,
|
|
)
|
|
return response.status_code == 200
|
|
except Exception:
|
|
return False
|
|
|
|
|
|
async def check_vk_connection(access_token: str) -> bool:
|
|
try:
|
|
async with httpx.AsyncClient() as client:
|
|
resp = await client.get(
|
|
VK_USERS_GET_URL,
|
|
params={"access_token": access_token, "v": VK_API_VERSION},
|
|
timeout=10,
|
|
)
|
|
if resp.status_code != 200:
|
|
return False
|
|
data = resp.json()
|
|
return "error" not in data
|
|
except Exception:
|
|
return False
|
|
|
|
|
|
async def run_health_checks() -> None:
|
|
db = SessionLocal()
|
|
try:
|
|
evotor_connections = db.query(EvotorConnection).all()
|
|
for conn in evotor_connections:
|
|
conn.is_online = await check_evotor_connection(conn.access_token)
|
|
conn.last_checked_at = datetime.utcnow()
|
|
|
|
vk_connections = db.query(VkConnection).all()
|
|
for conn in vk_connections:
|
|
conn.is_online = await check_vk_connection(conn.access_token)
|
|
conn.last_checked_at = datetime.utcnow()
|
|
|
|
db.commit()
|
|
logger.info(
|
|
"Health checks completed: %d Evotor, %d VK",
|
|
len(evotor_connections),
|
|
len(vk_connections),
|
|
)
|
|
except Exception:
|
|
logger.exception("Error during health checks")
|
|
db.rollback()
|
|
finally:
|
|
db.close()
|
|
|
|
|
|
async def health_check_loop(interval: int) -> None:
|
|
while True:
|
|
await run_health_checks()
|
|
await asyncio.sleep(interval)
|