298 lines
11 KiB
Python
298 lines
11 KiB
Python
#!/usr/bin/env python3
|
||
"""
|
||
MY Network Server Startup Script
|
||
Скрипт для запуска MY Network с минимальными HTTP эндпоинтами
|
||
"""
|
||
|
||
import asyncio
|
||
import logging
|
||
import signal
|
||
import sys
|
||
from pathlib import Path
|
||
from typing import Optional
|
||
|
||
# Добавить корневую директорию в путь
|
||
sys.path.append(str(Path(__file__).parent))
|
||
|
||
import uvicorn
|
||
from fastapi import FastAPI, HTTPException
|
||
from fastapi.middleware.cors import CORSMiddleware
|
||
from fastapi.staticfiles import StaticFiles
|
||
from fastapi.responses import HTMLResponse
|
||
|
||
# Настройка логирования
|
||
logging.basicConfig(
|
||
level=logging.INFO,
|
||
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
||
handlers=[
|
||
logging.StreamHandler(sys.stdout),
|
||
logging.FileHandler('my_network.log')
|
||
]
|
||
)
|
||
|
||
logger = logging.getLogger(__name__)
|
||
|
||
# Глобальные переменные
|
||
app: Optional[FastAPI] = None
|
||
node_service = None
|
||
|
||
|
||
def create_app() -> FastAPI:
|
||
"""Создать FastAPI приложение для MY Network."""
|
||
|
||
app = FastAPI(
|
||
title="MY Network",
|
||
description="Distributed Content Protocol v2.0",
|
||
version="2.0.0",
|
||
docs_url="/api/docs",
|
||
redoc_url="/api/redoc"
|
||
)
|
||
|
||
# Настройка CORS
|
||
app.add_middleware(
|
||
CORSMiddleware,
|
||
allow_origins=["*"],
|
||
allow_credentials=True,
|
||
allow_methods=["*"],
|
||
allow_headers=["*"],
|
||
)
|
||
|
||
return app
|
||
|
||
|
||
async def init_my_network_service():
|
||
"""Инициализировать MY Network сервис."""
|
||
global node_service
|
||
|
||
try:
|
||
logger.info("Initializing MY Network service...")
|
||
|
||
# Импортировать и инициализировать сервис ноды
|
||
from app.core.my_network.node_service import NodeService
|
||
|
||
# Создать сервис ноды
|
||
node_service = NodeService()
|
||
|
||
# Запустить сервис
|
||
await node_service.start()
|
||
|
||
logger.info("MY Network service initialized successfully")
|
||
|
||
except Exception as e:
|
||
logger.error(f"Failed to initialize MY Network service: {e}")
|
||
raise
|
||
|
||
|
||
def setup_routes(app: FastAPI):
|
||
"""Настроить маршруты приложения."""
|
||
|
||
try:
|
||
# Импортировать маршруты MY Network
|
||
from app.api.routes.my_network_routes import router as my_network_router
|
||
from app.api.routes.my_monitoring import router as monitoring_router
|
||
|
||
# Добавить маршруты
|
||
app.include_router(my_network_router)
|
||
app.include_router(monitoring_router)
|
||
|
||
logger.info("MY Network routes configured")
|
||
|
||
except ImportError as e:
|
||
logger.error(f"Failed to import MY Network routes: {e}")
|
||
|
||
# Создать минимальные маршруты если основные не работают
|
||
setup_minimal_routes(app)
|
||
|
||
|
||
def setup_minimal_routes(app: FastAPI):
|
||
"""Настроить минимальные маршруты."""
|
||
|
||
@app.get("/")
|
||
async def root():
|
||
return {"message": "MY Network v2.0 - Distributed Content Protocol"}
|
||
|
||
@app.get("/health")
|
||
async def health_check():
|
||
return {
|
||
"status": "healthy" if node_service else "initializing",
|
||
"service": "MY Network",
|
||
"version": "2.0.0"
|
||
}
|
||
|
||
@app.get("/api/my/node/info")
|
||
async def node_info():
|
||
if not node_service:
|
||
raise HTTPException(status_code=503, detail="MY Network service not available")
|
||
|
||
try:
|
||
info = await node_service.get_node_info()
|
||
return {"success": True, "data": info}
|
||
except Exception as e:
|
||
logger.error(f"Error getting node info: {e}")
|
||
raise HTTPException(status_code=500, detail=str(e))
|
||
|
||
@app.get("/api/my/monitor/", response_class=HTMLResponse)
|
||
async def monitoring_dashboard():
|
||
"""Простой HTML мониторинг если шаблоны не работают."""
|
||
|
||
html_content = """
|
||
<!DOCTYPE html>
|
||
<html>
|
||
<head>
|
||
<title>MY Network Monitor</title>
|
||
<style>
|
||
body { background: #000; color: #0f0; font-family: monospace; padding: 20px; }
|
||
.container { max-width: 800px; margin: 0 auto; }
|
||
.status { border: 1px solid #0f0; padding: 10px; margin: 10px 0; }
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div class="container">
|
||
<h1>MY Network Monitor</h1>
|
||
<div class="status">
|
||
<h3>Status: ONLINE</h3>
|
||
<p>MY Network service is running</p>
|
||
</div>
|
||
<div class="status">
|
||
<h3>Endpoints:</h3>
|
||
<ul>
|
||
<li><a href="/api/my/node/info" style="color: #0f0;">/api/my/node/info</a> - Node information</li>
|
||
<li><a href="/health" style="color: #0f0;">/health</a> - Health check</li>
|
||
<li><a href="/api/docs" style="color: #0f0;">/api/docs</a> - API Documentation</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
</body>
|
||
</html>
|
||
"""
|
||
|
||
return HTMLResponse(content=html_content)
|
||
|
||
logger.info("Minimal routes configured")
|
||
|
||
|
||
async def startup_event():
|
||
"""Событие запуска приложения."""
|
||
logger.info("Starting MY Network server...")
|
||
|
||
try:
|
||
# Инициализировать MY Network сервис
|
||
await init_my_network_service()
|
||
|
||
logger.info("MY Network server started successfully")
|
||
|
||
except Exception as e:
|
||
logger.error(f"Failed to start MY Network server: {e}")
|
||
# Не останавливать сервер, работать в ограниченном режиме
|
||
logger.info("Running in limited mode without full MY Network features")
|
||
|
||
|
||
async def shutdown_event():
|
||
"""Событие остановки приложения."""
|
||
logger.info("Shutting down MY Network server...")
|
||
|
||
try:
|
||
if node_service:
|
||
await node_service.stop()
|
||
|
||
logger.info("MY Network server stopped successfully")
|
||
|
||
except Exception as e:
|
||
logger.error(f"Error during shutdown: {e}")
|
||
|
||
|
||
def setup_signal_handlers():
|
||
"""Настроить обработчики сигналов."""
|
||
|
||
def signal_handler(signum, frame):
|
||
logger.info(f"Received signal {signum}, shutting down...")
|
||
|
||
# Запустить graceful shutdown
|
||
if node_service:
|
||
try:
|
||
asyncio.create_task(node_service.stop())
|
||
except Exception as e:
|
||
logger.error(f"Error during signal shutdown: {e}")
|
||
|
||
sys.exit(0)
|
||
|
||
signal.signal(signal.SIGINT, signal_handler)
|
||
signal.signal(signal.SIGTERM, signal_handler)
|
||
|
||
|
||
def main():
|
||
"""Главная функция запуска."""
|
||
|
||
print("""
|
||
╔══════════════════════════════════════════════════════════════════════════════╗
|
||
║ MY NETWORK v2.0 ║
|
||
║ Distributed Content Protocol ║
|
||
║ ║
|
||
║ Starting minimal HTTP server with MY Network capabilities... ║
|
||
╚══════════════════════════════════════════════════════════════════════════════╝
|
||
""")
|
||
|
||
try:
|
||
# Настроить обработчики сигналов
|
||
setup_signal_handlers()
|
||
|
||
# Создать приложение
|
||
global app
|
||
app = create_app()
|
||
|
||
# Настроить маршруты
|
||
setup_routes(app)
|
||
|
||
# Добавить события запуска/остановки
|
||
app.add_event_handler("startup", startup_event)
|
||
app.add_event_handler("shutdown", shutdown_event)
|
||
|
||
# Определить порт (15100 для MY Network)
|
||
port = 15100
|
||
|
||
# Попробовать найти свободный порт (приоритет 15100)
|
||
import socket
|
||
for test_port in [15100, 8000, 8001, 8080]:
|
||
try:
|
||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||
sock.bind(('', test_port))
|
||
sock.close()
|
||
port = test_port
|
||
break
|
||
except OSError:
|
||
continue
|
||
|
||
logger.info(f"Starting server on port {port}")
|
||
|
||
print(f"""
|
||
╔══════════════════════════════════════════════════════════════════════════════╗
|
||
║ MY Network Server starting on http://localhost:{port} ║
|
||
║ ║
|
||
║ Available endpoints: ║
|
||
║ • http://localhost:{port}/ - Main page ║
|
||
║ • http://localhost:{port}/health - Health check ║
|
||
║ • http://localhost:{port}/api/my/monitor/ - Monitoring dashboard ║
|
||
║ • http://localhost:{port}/api/docs - API Documentation ║
|
||
║ ║
|
||
║ Press Ctrl+C to stop the server ║
|
||
╚══════════════════════════════════════════════════════════════════════════════╝
|
||
""")
|
||
|
||
# Запустить сервер
|
||
uvicorn.run(
|
||
app,
|
||
host="0.0.0.0",
|
||
port=port,
|
||
log_level="info",
|
||
access_log=True
|
||
)
|
||
|
||
except KeyboardInterrupt:
|
||
logger.info("Received keyboard interrupt, shutting down...")
|
||
except Exception as e:
|
||
logger.error(f"Fatal error: {e}")
|
||
sys.exit(1)
|
||
|
||
|
||
if __name__ == "__main__":
|
||
main() |