-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.py
More file actions
154 lines (126 loc) · 4.45 KB
/
main.py
File metadata and controls
154 lines (126 loc) · 4.45 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
"""
FastAPI应用入口文件
"""
from contextlib import asynccontextmanager
import structlog
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from app import __version__, __description__
from app.api import convert_router, status_router, static_router, health_router, auth_router, async_convert_router
from app.config import settings
from app.database import init_database
from app.middleware import (
RequestLoggingMiddleware,
ResponseTimeMiddleware,
RequestSizeMiddleware,
ErrorHandlingMiddleware,
RateLimitMiddleware,
APIKeyAuthMiddleware
)
logger = structlog.get_logger(__name__)
@asynccontextmanager
async def lifespan(app: FastAPI):
"""应用生命周期管理"""
# 启动事件
logger.info("Starting pdf2othersAPI", version=__version__)
try:
# 初始化数据库
await init_database()
logger.info("Database initialized")
# 初始化队列管理器
from app.core.queue_manager import initialize_queue_manager
await initialize_queue_manager()
logger.info("Queue manager initialized")
# 启动后台处理进程
from app.core.process_pool import start_background_processing
start_background_processing()
logger.info("Background processing started")
# 验证外部依赖
from app.core import mineru_client, pandoc_client
# 检查vLLM服务
vllm_healthy = await mineru_client.check_vllm_health()
if vllm_healthy:
logger.info("vLLM service is available")
else:
logger.warning("vLLM service is not available")
# 检查Pandoc
pandoc_available = await pandoc_client.check_pandoc_availability()
if pandoc_available:
pandoc_version = await pandoc_client.get_pandoc_version()
logger.info("Pandoc is available", version=pandoc_version)
else:
logger.warning("Pandoc is not available")
# 确保存储目录存在
settings.storage.pdfs_path.mkdir(parents=True, exist_ok=True)
settings.storage.tmp_trs_dir.mkdir(parents=True, exist_ok=True)
logger.info("Storage directories initialized")
except Exception as e:
logger.error("Failed to initialize application", error=str(e))
raise
yield
# 关闭事件
logger.info("Shutting down pdf2othersAPI")
# 停止后台处理进程
try:
from app.core.process_pool import stop_background_processing
stop_background_processing()
logger.info("Background processing stopped")
except Exception as e:
logger.error("Failed to stop background processing", error=str(e))
# 创建FastAPI应用
app = FastAPI(
title="pdf2othersAPI",
description=__description__,
version=__version__,
lifespan=lifespan,
docs_url="/docs",
redoc_url="/redoc",
openapi_url="/openapi.json"
)
# 添加CORS中间件
app.add_middleware(
CORSMiddleware,
allow_origins=["*"], # 生产环境应该限制源
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# 添加自定义中间件(顺序很重要)
app.add_middleware(ErrorHandlingMiddleware)
app.add_middleware(RateLimitMiddleware, max_requests=100, window_seconds=60)
app.add_middleware(RequestSizeMiddleware)
app.add_middleware(ResponseTimeMiddleware)
app.add_middleware(RequestLoggingMiddleware)
# 添加认证中间件(在其他中间件之后)
if settings.auth_enabled:
app.add_middleware(
APIKeyAuthMiddleware,
public_paths=["/", "/docs", "/redoc", "/openapi.json", "/health", "/favicon.ico", "/auth/permissions"],
api_key_header=settings.api_key_header
)
# 注册路由
app.include_router(health_router)
app.include_router(auth_router) # 认证路由(在其他路由之前)
app.include_router(convert_router)
app.include_router(async_convert_router) # 异步转换路由
app.include_router(status_router)
app.include_router(static_router)
@app.get("/")
async def root():
"""根端点"""
return {
"name": "pdf2othersAPI",
"version": __version__,
"description": __description__,
"docs": "/docs",
"health": "/health"
}
if __name__ == "__main__":
import uvicorn
uvicorn.run(
"main:app",
host=settings.api.host,
port=settings.api.port,
reload=True,
log_level=settings.log_level.lower()
)