| | """Grok2API""" |
| |
|
| | import os |
| | import sys |
| | from contextlib import asynccontextmanager |
| | from pathlib import Path |
| |
|
| | from fastapi import FastAPI |
| | from fastapi.middleware.cors import CORSMiddleware |
| | from fastapi.staticfiles import StaticFiles |
| | from app.core.logger import logger |
| | from app.core.exception import register_exception_handlers |
| | from app.core.storage import storage_manager |
| | from app.core.config import setting |
| | from app.services.grok.token import token_manager |
| | from app.api.v1.chat import router as chat_router |
| | from app.api.v1.models import router as models_router |
| | from app.api.v1.images import router as images_router |
| | from app.api.admin.manage import router as admin_router |
| | from app.services.mcp import mcp |
| |
|
| | |
| | try: |
| | if sys.platform != 'win32': |
| | import uvloop |
| | uvloop.install() |
| | logger.info("[Grok2API] 启用uvloop高性能事件循环") |
| | else: |
| | logger.info("[Grok2API] Windows系统,使用默认asyncio事件循环") |
| | except ImportError: |
| | logger.info("[Grok2API] uvloop未安装,使用默认asyncio事件循环") |
| |
|
| | |
| | mcp_app = mcp.http_app(stateless_http=True, transport="streamable-http") |
| |
|
| | |
| | @asynccontextmanager |
| | async def lifespan(app: FastAPI): |
| | """ |
| | 启动顺序: |
| | 1. 初始化核心服务 (storage, settings, token_manager) |
| | 2. 异步加载 token 数据 |
| | 3. 启动批量保存任务 |
| | 4. 启动MCP服务生命周期 |
| | |
| | 关闭顺序 (LIFO): |
| | 1. 关闭MCP服务生命周期 |
| | 2. 关闭批量保存任务并刷新数据 |
| | 3. 关闭核心服务 |
| | """ |
| | |
| | |
| | await storage_manager.init() |
| |
|
| | |
| | storage = storage_manager.get_storage() |
| | setting.set_storage(storage) |
| | token_manager.set_storage(storage) |
| | |
| | |
| | await setting.reload() |
| | logger.info("[Grok2API] 核心服务初始化完成") |
| | |
| | |
| | from app.core.proxy_pool import proxy_pool |
| | proxy_url = setting.grok_config.get("proxy_url", "") |
| | proxy_pool_url = setting.grok_config.get("proxy_pool_url", "") |
| | proxy_pool_interval = setting.grok_config.get("proxy_pool_interval", 300) |
| | proxy_pool.configure(proxy_url, proxy_pool_url, proxy_pool_interval) |
| | |
| | |
| | await token_manager._load_data() |
| | logger.info("[Grok2API] Token数据加载完成") |
| | |
| | |
| | from app.services.api_keys import api_key_manager |
| | await api_key_manager.init() |
| | logger.info("[Grok2API] API Key数据加载完成") |
| |
|
| | |
| | from app.services.request_stats import request_stats |
| | from app.services.request_logger import request_logger |
| | await request_stats.init() |
| | await request_logger.init() |
| | logger.info("[Grok2API] 统计和日志数据加载完成") |
| | |
| | |
| | await token_manager.start_batch_save() |
| |
|
| | |
| | mcp_lifespan_context = mcp_app.lifespan(app) |
| | await mcp_lifespan_context.__aenter__() |
| | logger.info("[MCP] MCP服务初始化完成") |
| |
|
| | logger.info("[Grok2API] 应用启动成功") |
| | |
| | try: |
| | yield |
| | finally: |
| | |
| | |
| | await mcp_lifespan_context.__aexit__(None, None, None) |
| | logger.info("[MCP] MCP服务已关闭") |
| | |
| | |
| | await token_manager.shutdown() |
| | logger.info("[Token] Token管理器已关闭") |
| | |
| | |
| | await storage_manager.close() |
| | logger.info("[Grok2API] 应用关闭成功") |
| |
|
| |
|
| | |
| | logger.info("[Grok2API] 应用正在启动...") |
| | logger.info("[Grok2API] Fork 版本维护: @Tomiya233") |
| |
|
| | |
| | app = FastAPI( |
| | title="Grok2API", |
| | description="Grok API 转换服务", |
| | version="1.3.1", |
| | lifespan=lifespan |
| | ) |
| |
|
| | |
| | register_exception_handlers(app) |
| |
|
| | |
| | app.include_router(chat_router, prefix="/v1") |
| | app.include_router(models_router, prefix="/v1") |
| | app.include_router(images_router) |
| | app.include_router(admin_router) |
| |
|
| | |
| | app.mount("/static", StaticFiles(directory="app/template"), name="template") |
| |
|
| | @app.get("/") |
| | async def root(): |
| | """根路径""" |
| | from fastapi.responses import RedirectResponse |
| | return RedirectResponse(url="/login") |
| |
|
| |
|
| | @app.get("/health") |
| | async def health_check(): |
| | """健康检查接口""" |
| | return { |
| | "status": "healthy", |
| | "service": "Grok2API", |
| | "version": "1.0.3" |
| | } |
| |
|
| | |
| | app.mount("", mcp_app) |
| |
|
| |
|
| | if __name__ == "__main__": |
| | import uvicorn |
| | import os |
| | |
| | |
| | workers = int(os.getenv("WORKERS", "1")) |
| | |
| | |
| | if workers > 1: |
| | logger.info( |
| | f"[Grok2API] 多进程模式已启用 (workers={workers})。" |
| | f"建议使用 Redis/MySQL 存储以获得最佳性能。" |
| | ) |
| | |
| | |
| | loop_type = "auto" |
| | if workers == 1 and sys.platform != 'win32': |
| | try: |
| | import uvloop |
| | loop_type = "uvloop" |
| | except ImportError: |
| | pass |
| | |
| | uvicorn.run( |
| | "main:app", |
| | host="0.0.0.0", |
| | port=8000, |
| | workers=workers, |
| | loop=loop_type |
| | ) |
| |
|