2025-12-14 23:45:41 +00:00
|
|
|
"""
|
|
|
|
|
Nakama Moderation Backend - Python FastAPI
|
|
|
|
|
"""
|
|
|
|
|
import os
|
|
|
|
|
from contextlib import asynccontextmanager
|
|
|
|
|
from fastapi import FastAPI
|
|
|
|
|
from fastapi.middleware.cors import CORSMiddleware
|
|
|
|
|
from fastapi.middleware.trustedhost import TrustedHostMiddleware
|
|
|
|
|
import uvicorn
|
|
|
|
|
|
|
|
|
|
from config import settings
|
|
|
|
|
from database import connect_db, close_db
|
2025-12-15 00:09:11 +00:00
|
|
|
# Import from middleware.py file (not directory)
|
|
|
|
|
import middleware as app_middleware
|
2025-12-14 23:45:41 +00:00
|
|
|
from routes.mod_app import router as mod_app_router
|
|
|
|
|
from routes.moderation_auth import router as moderation_auth_router
|
|
|
|
|
from websocket_server import get_socketio_app
|
|
|
|
|
from utils.minio_client import init_minio
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@asynccontextmanager
|
|
|
|
|
async def lifespan(app: FastAPI):
|
|
|
|
|
"""Lifecycle management"""
|
|
|
|
|
# Startup
|
|
|
|
|
print("\n" + "=" * 60)
|
|
|
|
|
print("🚀 Запуск сервера модерации (Python)...")
|
|
|
|
|
await connect_db()
|
|
|
|
|
|
|
|
|
|
# Initialize MinIO
|
|
|
|
|
if settings.MINIO_ENABLED:
|
|
|
|
|
init_minio()
|
|
|
|
|
|
|
|
|
|
print("=" * 60 + "\n")
|
|
|
|
|
|
|
|
|
|
yield
|
|
|
|
|
|
|
|
|
|
# Shutdown
|
|
|
|
|
print("\n" + "=" * 60)
|
|
|
|
|
print("🛑 Остановка сервера модерации...")
|
|
|
|
|
await close_db()
|
|
|
|
|
print("=" * 60 + "\n")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
app = FastAPI(
|
|
|
|
|
title="Nakama Moderation API",
|
|
|
|
|
description="API для модерации Nakama",
|
|
|
|
|
version="2.0.0",
|
|
|
|
|
lifespan=lifespan
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
# CORS
|
|
|
|
|
app.add_middleware(
|
|
|
|
|
CORSMiddleware,
|
|
|
|
|
allow_origins=settings.MODERATION_CORS_ORIGIN.split(',') if settings.MODERATION_CORS_ORIGIN != '*' else ['*'],
|
|
|
|
|
allow_credentials=True,
|
|
|
|
|
allow_methods=["GET", "POST", "PUT", "DELETE", "OPTIONS"],
|
|
|
|
|
allow_headers=["Content-Type", "Authorization", "x-telegram-init-data"],
|
|
|
|
|
max_age=86400,
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
# Setup middleware (security, logging, etc.)
|
2025-12-15 00:09:11 +00:00
|
|
|
app_middleware.setup_middleware(app)
|
2025-12-14 23:45:41 +00:00
|
|
|
|
|
|
|
|
# Health check
|
|
|
|
|
@app.get("/health")
|
|
|
|
|
async def health_check():
|
|
|
|
|
return {
|
|
|
|
|
"status": "ok",
|
|
|
|
|
"service": "moderation",
|
|
|
|
|
"version": "2.0.0-python"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Root endpoint
|
|
|
|
|
@app.get("/")
|
|
|
|
|
async def root():
|
|
|
|
|
return {"message": "Nakama Moderation API - Python"}
|
|
|
|
|
|
|
|
|
|
# Include routers
|
|
|
|
|
app.include_router(mod_app_router, prefix="/api/mod-app", tags=["moderation"])
|
|
|
|
|
app.include_router(moderation_auth_router, prefix="/api/moderation-auth", tags=["auth"])
|
|
|
|
|
|
|
|
|
|
# Mount Socket.IO app for WebSocket
|
2025-12-15 00:37:34 +00:00
|
|
|
# Socket.IO ASGI app needs to wrap FastAPI app to handle both HTTP and WebSocket
|
|
|
|
|
try:
|
|
|
|
|
socketio_app = get_socketio_app()
|
|
|
|
|
# Socket.IO will handle /socket.io and /mod-chat paths
|
|
|
|
|
# We need to mount it so it can intercept WebSocket connections
|
|
|
|
|
# But FastAPI routes should still work
|
|
|
|
|
# The Socket.IO ASGI app will handle its own paths and pass others to FastAPI
|
|
|
|
|
app.mount("/socket.io", socketio_app)
|
|
|
|
|
app.mount("/mod-chat", socketio_app) # Also mount at /mod-chat for namespace
|
|
|
|
|
print("✅ WebSocket (Socket.IO) настроен")
|
|
|
|
|
print(" 📡 Namespace /mod-chat доступен для чата модераторов")
|
|
|
|
|
except Exception as e:
|
|
|
|
|
print(f"⚠️ Ошибка настройки WebSocket: {e}")
|
|
|
|
|
import traceback
|
|
|
|
|
traceback.print_exc()
|
|
|
|
|
print(" Чат модераторов будет недоступен")
|
2025-12-14 23:45:41 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
|
print("\n" + "=" * 60)
|
|
|
|
|
print("✅ Сервер модерации запущен (Python)")
|
|
|
|
|
print(f" 🌐 API: http://0.0.0.0:{settings.MODERATION_PORT}/api")
|
|
|
|
|
print(f" 🔌 WebSocket: http://0.0.0.0:{settings.MODERATION_PORT}/socket.io")
|
|
|
|
|
print(f" 📦 MongoDB: {settings.MONGODB_URI.split('@')[-1] if '@' in settings.MONGODB_URI else settings.MONGODB_URI}")
|
|
|
|
|
print("=" * 60 + "\n")
|
|
|
|
|
|
|
|
|
|
uvicorn.run(
|
|
|
|
|
"main:app",
|
|
|
|
|
host="0.0.0.0",
|
|
|
|
|
port=settings.MODERATION_PORT,
|
|
|
|
|
reload=settings.IS_DEVELOPMENT,
|
|
|
|
|
log_level="info"
|
|
|
|
|
)
|
|
|
|
|
|