docs(api): add api docs

This commit is contained in:
MingxuanGame
2025-08-12 08:40:27 +00:00
parent 50c25ab0c7
commit 2fa6d6dd7e
13 changed files with 570 additions and 214 deletions

View File

@@ -10,16 +10,22 @@ from app.fetcher import Fetcher
from .router import router
from fastapi import Depends, Form, HTTPException, Query, Security
from fastapi import Depends, Form, HTTPException, Path, Query, Security
from fastapi.responses import RedirectResponse
from httpx import HTTPError
from sqlmodel import select
from sqlmodel.ext.asyncio.session import AsyncSession
@router.get("/beatmapsets/lookup", tags=["beatmapset"], response_model=BeatmapsetResp)
@router.get(
"/beatmapsets/lookup",
tags=["谱面集"],
name="查询谱面集 (通过谱面 ID)",
response_model=BeatmapsetResp,
description=("通过谱面 ID 查询所属谱面集。"),
)
async def lookup_beatmapset(
beatmap_id: int = Query(),
beatmap_id: int = Query(description="谱面 ID"),
current_user: User = Security(get_current_user, scopes=["public"]),
db: AsyncSession = Depends(get_db),
fetcher: Fetcher = Depends(get_fetcher),
@@ -31,15 +37,21 @@ async def lookup_beatmapset(
return resp
@router.get("/beatmapsets/{sid}", tags=["beatmapset"], response_model=BeatmapsetResp)
@router.get(
"/beatmapsets/{beatmapset_id}",
tags=["谱面集"],
name="获取谱面集详情",
response_model=BeatmapsetResp,
description="获取单个谱面集详情。",
)
async def get_beatmapset(
sid: int,
beatmapset_id: int = Path(..., description="谱面集 ID"),
current_user: User = Security(get_current_user, scopes=["public"]),
db: AsyncSession = Depends(get_db),
fetcher: Fetcher = Depends(get_fetcher),
):
try:
beatmapset = await Beatmapset.get_or_fetch(db, fetcher, sid)
beatmapset = await Beatmapset.get_or_fetch(db, fetcher, beatmapset_id)
return await BeatmapsetResp.from_db(
beatmapset, session=db, include=["recent_favourites"], user=current_user
)
@@ -47,35 +59,48 @@ async def get_beatmapset(
raise HTTPException(status_code=404, detail="Beatmapset not found")
@router.get("/beatmapsets/{beatmapset}/download", tags=["beatmapset"])
@router.get(
"/beatmapsets/{beatmapset_id}/download",
tags=["谱面集"],
name="下载谱面集",
description="**客户端专属**\n下载谱面集文件。若用户国家为 CN 则跳转国内镜像。",
)
async def download_beatmapset(
beatmapset: int,
no_video: bool = Query(True, alias="noVideo"),
beatmapset_id: int = Path(..., description="谱面集 ID"),
no_video: bool = Query(True, alias="noVideo", description="是否下载无视频版本"),
current_user: User = Security(get_current_user, scopes=["*"]),
):
if current_user.country_code == "CN":
return RedirectResponse(
f"https://txy1.sayobot.cn/beatmaps/download/"
f"{'novideo' if no_video else 'full'}/{beatmapset}?server=auto"
f"{'novideo' if no_video else 'full'}/{beatmapset_id}?server=auto"
)
else:
return RedirectResponse(
f"https://api.nerinyan.moe/d/{beatmapset}?noVideo={no_video}"
f"https://api.nerinyan.moe/d/{beatmapset_id}?noVideo={no_video}"
)
@router.post("/beatmapsets/{beatmapset}/favourites", tags=["beatmapset"])
@router.post(
"/beatmapsets/{beatmapset_id}/favourites",
tags=["谱面集"],
name="收藏或取消收藏谱面集",
description="**客户端专属**\n收藏或取消收藏指定谱面集。",
)
async def favourite_beatmapset(
beatmapset: int,
action: Literal["favourite", "unfavourite"] = Form(),
beatmapset_id: int = Path(..., description="谱面集 ID"),
action: Literal["favourite", "unfavourite"] = Form(
description="操作类型favourite 收藏 / unfavourite 取消收藏"
),
current_user: User = Security(get_current_user, scopes=["*"]),
db: AsyncSession = Depends(get_db),
):
assert current_user.id is not None
existing_favourite = (
await db.exec(
select(FavouriteBeatmapset).where(
FavouriteBeatmapset.user_id == current_user.id,
FavouriteBeatmapset.beatmapset_id == beatmapset,
FavouriteBeatmapset.beatmapset_id == beatmapset_id,
)
)
).first()
@@ -87,7 +112,7 @@ async def favourite_beatmapset(
if action == "favourite":
favourite = FavouriteBeatmapset(
user_id=current_user.id, beatmapset_id=beatmapset
user_id=current_user.id, beatmapset_id=beatmapset_id
)
db.add(favourite)
else: