Files
zTools2/app/main.py
zikai 80b96d236f init: 从 /root/zikai 根目录迁入
把原本散落在 /root/zikai 的 FastAPI 服务整理到 server/ 子目录,
开启独立 git 与 venv。运行时数据(config.yaml / keys / uploads)
按 .gitignore 留在工作目录但不入仓。
2026-06-23 16:17:31 +00:00

88 lines
2.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""FastAPI 应用工厂。
路由概览:
GET / -> 仅返回版本号
GET /docs -> Swagger UIBasic Auth
GET /redoc -> ReDoc Basic Auth
GET /openapi.json -> OpenAPI 文档Basic Auth
GET /health -> 存活探针(公开)
GET /api/... -> 业务接口
"""
from __future__ import annotations
import logging
from contextlib import asynccontextmanager
from fastapi import Depends, FastAPI
from fastapi.openapi.docs import get_redoc_html, get_swagger_ui_html
from fastapi.responses import JSONResponse, PlainTextResponse
from .controllers import file_router, system_router
from .database import init_db_schema
from .security import require_docs_auth
logger = logging.getLogger("zikai")
@asynccontextmanager
async def lifespan(app: FastAPI):
try:
init_db_schema()
logger.info("数据库表已就绪。")
except Exception as exc: # pragma: no cover
logger.error("初始化数据库失败:%s", exc)
yield
def create_app() -> FastAPI:
app = FastAPI(
title="zikai file service",
description=(
"f.zikai.wang 的文件上传与主机监控服务。\n\n"
"- `GET /api/system/status` — CPU / 内存 / 磁盘HTML 或 JSON\n"
"- `POST /api/files/upload` — 大文件流式上传\n"
"- 内置 SFTP 服务(详见 README\n\n"
"/docs 等接口需 Basic Auth凭据见 config.yaml 的 docs 段。"
),
version="1.0.0",
docs_url=None,
redoc_url=None,
openapi_url=None,
lifespan=lifespan,
)
app.include_router(system_router)
app.include_router(file_router)
# 受 Basic Auth 保护的文档接口
@app.get("/openapi.json", include_in_schema=False)
def protected_openapi(_: str = Depends(require_docs_auth)) -> JSONResponse:
return JSONResponse(app.openapi())
@app.get("/docs", include_in_schema=False)
def protected_docs(_: str = Depends(require_docs_auth)):
return get_swagger_ui_html(
openapi_url="/openapi.json", title="zikai docs", swagger_favicon_url=""
)
@app.get("/redoc", include_in_schema=False)
def protected_redoc(_: str = Depends(require_docs_auth)):
return get_redoc_html(
openapi_url="/openapi.json", title="zikai docs", redoc_favicon_url=""
)
# 公开元信息(不暴露接口列表)
@app.get("/", include_in_schema=False, response_class=PlainTextResponse)
def root() -> PlainTextResponse:
return PlainTextResponse(f"zikai {app.version}\n")
@app.get("/health", include_in_schema=False)
def health() -> dict:
return {"status": "ok"}
return app
app = create_app()