import os from contextlib import asynccontextmanager import uvicorn from fastapi import FastAPI from starlette.middleware.cors import CORSMiddleware from starlette.staticfiles import StaticFiles from dotenv import load_dotenv from app.db.init_db import init_db from app.db.provider_dao import seed_default_providers from app.exceptions.exception_handlers import register_exception_handlers # from app.db.model_dao import init_model_table # from app.db.provider_dao import init_provider_table from app.utils.logger import get_logger from app import create_app from app.transcriber.transcriber_provider import get_transcriber from events import register_handler from ffmpeg_helper import ensure_ffmpeg_or_raise logger = get_logger(__name__) load_dotenv() # 读取 .env 中的路径 static_path = os.getenv('STATIC', '/static') out_dir = os.getenv('OUT_DIR', './static/screenshots') # 自动创建本地目录(static 和 static/screenshots) static_dir = "static" uploads_dir = "uploads" if not os.path.exists(static_dir): os.makedirs(static_dir) if not os.path.exists(uploads_dir): os.makedirs(uploads_dir) if not os.path.exists(out_dir): os.makedirs(out_dir) @asynccontextmanager async def lifespan(app: FastAPI): register_handler() ensure_ffmpeg_or_raise() init_db() get_transcriber(transcriber_type=os.getenv("TRANSCRIBER_TYPE", "fast-whisper")) seed_default_providers() yield app = create_app(lifespan=lifespan) app.add_middleware( CORSMiddleware, allow_origins=["tauri://localhost"], # ✅ 加上 Tauri 的 origin allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) register_exception_handlers(app) app.mount(static_path, StaticFiles(directory=static_dir), name="static") app.mount("/uploads", StaticFiles(directory=uploads_dir), name="uploads") if __name__ == "__main__": port = int(os.getenv("BACKEND_PORT", 8483)) host = os.getenv("BACKEND_HOST", "0.0.0.0") logger.info(f"Starting server on {host}:{port}") uvicorn.run(app, host=host, port=port, reload=False)