init: 从 /root/zikai 根目录迁入
把原本散落在 /root/zikai 的 FastAPI 服务整理到 server/ 子目录, 开启独立 git 与 venv。运行时数据(config.yaml / keys / uploads) 按 .gitignore 留在工作目录但不入仓。
This commit is contained in:
87
app/main.py
Normal file
87
app/main.py
Normal file
@@ -0,0 +1,87 @@
|
||||
"""FastAPI 应用工厂。
|
||||
|
||||
路由概览:
|
||||
GET / -> 仅返回版本号
|
||||
GET /docs -> Swagger UI(Basic 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()
|
||||
Reference in New Issue
Block a user