Download src/aistudio_api/api/app.py from jlshu/vproxy: direct link, hf CLI and curl.
- Browser
- Download file 4.62 kB
-
https://huggingface.co/spaces/jlshu/vproxy/resolve/main/src/aistudio_api/api/app.py
- Command line
-
hf download hf://spaces/jlshu/vproxy/src/aistudio_api/api/app.py
-
curl -L -o app.py https://huggingface.co/spaces/jlshu/vproxy/resolve/main/src/aistudio_api/api/app.py
4.62 kB
| """FastAPI application entrypoint.""" | |
| from __future__ import annotations | |
| import argparse | |
| import logging | |
| from contextlib import asynccontextmanager | |
| from fastapi import Depends, FastAPI | |
| from fastapi.responses import RedirectResponse | |
| from fastapi.staticfiles import StaticFiles | |
| from aistudio_api.infrastructure.gateway.client import AIStudioClient | |
| from .dependencies import require_api_key | |
| from .routes_accounts import router as accounts_router | |
| from .routes_gemini import router as gemini_router | |
| from .routes_models import router as models_router | |
| from .routes_system import protected_router as system_protected_router | |
| from .routes_system import public_router as system_public_router | |
| from .state import runtime_state | |
| logging.basicConfig( | |
| level=logging.INFO, format="%(asctime)s [%(name)s] %(message)s", datefmt="%H:%M:%S" | |
| ) | |
| logger = logging.getLogger("aistudio.server") | |
| async def lifespan(app: FastAPI): | |
| import asyncio | |
| from aistudio_api.application.account_rotator import RotationMode, init_rotator | |
| from aistudio_api.application.account_service import AccountService | |
| from aistudio_api.config import settings | |
| from aistudio_api.infrastructure.account.account_store import AccountStore | |
| client = AIStudioClient( | |
| port=runtime_state.browser_port, | |
| ) | |
| runtime_state.client = client | |
| from aistudio_api.config import settings as app_settings | |
| runtime_state.busy_lock = asyncio.Semaphore(app_settings.max_concurrency) | |
| # 注入 snapshot 缓存引用,切号时需要清除 | |
| from aistudio_api.infrastructure.gateway.client import _snapshot_cache | |
| runtime_state.snapshot_cache = _snapshot_cache | |
| # 初始化账号管理服务 | |
| account_store = AccountStore() | |
| account_service = AccountService(account_store) | |
| runtime_state.account_service = account_service | |
| # 初始化账号轮询器 | |
| rotation_mode = getattr(settings, "account_rotation_mode", "round_robin") | |
| cooldown = getattr(settings, "account_cooldown_seconds", 60) | |
| rotator = init_rotator( | |
| account_store, | |
| mode=RotationMode(rotation_mode), | |
| cooldown_seconds=cooldown, | |
| ) | |
| runtime_state.rotator = rotator | |
| logger.info( | |
| "Client initialized (port=%s, rotation=%s, accounts=%d)", | |
| runtime_state.browser_port, | |
| rotator.mode, | |
| len(account_store.list_accounts()), | |
| ) | |
| # 后台预热浏览器,避免首次请求延迟 | |
| warmup_task = None | |
| async def _warmup(): | |
| try: | |
| await client.warmup() | |
| except Exception as e: | |
| logger.warning("浏览器预热失败: %s", e) | |
| warmup_task = asyncio.create_task(_warmup()) | |
| yield | |
| logger.info("Shutting down") | |
| if warmup_task and not warmup_task.done(): | |
| warmup_task.cancel() | |
| if client: | |
| try: | |
| await client.close() | |
| except Exception as e: | |
| logger.debug("Error closing client: %s", e) | |
| runtime_state.client = None | |
| runtime_state.busy_lock = None | |
| runtime_state.account_service = None | |
| runtime_state.rotator = None | |
| app = FastAPI(title="AI Studio API", lifespan=lifespan) | |
| app.include_router(system_public_router) | |
| app.include_router(system_protected_router, dependencies=[Depends(require_api_key)]) | |
| app.include_router(gemini_router, dependencies=[Depends(require_api_key)]) | |
| app.include_router(models_router, dependencies=[Depends(require_api_key)]) | |
| app.include_router(accounts_router, dependencies=[Depends(require_api_key)]) | |
| # 挂载静态文件 | |
| import os | |
| static_dir = os.path.join(os.path.dirname(__file__), "..", "static") | |
| if os.path.isdir(static_dir): | |
| app.mount("/static", StaticFiles(directory=static_dir), name="static") | |
| async def root(): | |
| return RedirectResponse(url="/static/index.html") | |
| async def login_page(): | |
| return RedirectResponse(url="/static/login.html") | |
| async def auth_check(): | |
| """检查认证状态,用于前端判断是否需要登录。""" | |
| from aistudio_api.config import settings | |
| return {"auth_enabled": settings.auth_enabled} | |
| def main(): | |
| from aistudio_api.config import settings | |
| parser = argparse.ArgumentParser(description="AI Studio API Server") | |
| parser.add_argument("--port", type=int, default=settings.port) | |
| parser.add_argument("--browser-port", type=int, default=settings.browser_port) | |
| args = parser.parse_args() | |
| runtime_state.browser_port = args.browser_port | |
| import uvicorn | |
| logger.info("Starting server on port %s", args.port) | |
| uvicorn.run(app, host="0.0.0.0", port=args.port, log_level="info") | |