main.py 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. import random
  2. from fastapi import FastAPI
  3. from contextlib import asynccontextmanager
  4. import uvicorn
  5. from pathlib import Path
  6. from datetime import datetime
  7. from typing import List, Dict, Optional
  8. from pydantic import BaseModel
  9. import yaml
  10. import asyncio
  11. import httpx
  12. from config.settings import settings
  13. from routers.subscriptions import router
  14. from routers.mihomo import mihomo_router,stop_all_mihomo,get_mihomo_running_status
  15. from utils.mihomo_service import download_mihomo
  16. from database.engine import create_db_and_tables
  17. from aiomultiprocess import Pool
  18. from utils.processes_mgr import process_manager
  19. @asynccontextmanager
  20. async def lifespan(app: FastAPI):
  21. """应用生命周期管理"""
  22. # 初始化目录结构
  23. settings.PATH_CONFIG_DIR.mkdir(parents=True, exist_ok=True)
  24. settings.PATH_SUBSCRIPTION_DIR.mkdir(parents=True, exist_ok=True)
  25. create_db_and_tables()
  26. # 检查并下载mihomo
  27. await download_mihomo()
  28. await stop_all_mihomo()
  29. yield
  30. process_manager.stop_all_processes()
  31. app = FastAPI(lifespan=lifespan)
  32. # 注册路由
  33. app.include_router(router, prefix="/subscriptions", tags=["订阅管理"])
  34. app.include_router(mihomo_router, prefix="/mihomo", tags=["mihomo管理"])
  35. # 添加健康检查路由
  36. @app.get("/health")
  37. async def health_check():
  38. """服务健康检查"""
  39. return {"status": "healthy"}
  40. @app.get("/")
  41. async def root():
  42. return {
  43. "message": "代理池管理API",
  44. "endpoints": {
  45. "/docs": "API文档",
  46. "/configs": "配置管理",
  47. "/subscriptions": "订阅管理"
  48. }
  49. }
  50. @app.get("/get")
  51. async def get_random_proxy():
  52. results = await get_mihomo_running_status()
  53. if not results:
  54. return {"message": "No running mihomo instances", 'code': 404}
  55. active_results = []
  56. for result in results:
  57. if result.delay is not None and result.delay < 2000:
  58. active_results.append(result.mixed_port)
  59. return {"port": random.choice(active_results)}
  60. if __name__ == "__main__":
  61. uvicorn.run("main:app", host=settings.HOST, port=settings.PORT, reload=False)