docs(api): add api docs
This commit is contained in:
@@ -20,7 +20,7 @@ from app.models.user import BeatmapsetType
|
||||
|
||||
from .router import router
|
||||
|
||||
from fastapi import Depends, HTTPException, Query, Security
|
||||
from fastapi import Depends, HTTPException, Path, Query, Security
|
||||
from pydantic import BaseModel
|
||||
from sqlmodel import exists, false, select
|
||||
from sqlmodel.ext.asyncio.session import AsyncSession
|
||||
@@ -31,13 +31,23 @@ class BatchUserResponse(BaseModel):
|
||||
users: list[UserResp]
|
||||
|
||||
|
||||
@router.get("/users", response_model=BatchUserResponse)
|
||||
@router.get("/users/lookup", response_model=BatchUserResponse)
|
||||
@router.get("/users/lookup/", response_model=BatchUserResponse)
|
||||
@router.get(
|
||||
"/users",
|
||||
response_model=BatchUserResponse,
|
||||
name="批量获取用户信息",
|
||||
description="通过用户 ID 列表批量获取用户信息。",
|
||||
tags=["用户"],
|
||||
)
|
||||
@router.get("/users/lookup", response_model=BatchUserResponse, include_in_schema=False)
|
||||
@router.get("/users/lookup/", response_model=BatchUserResponse, include_in_schema=False)
|
||||
async def get_users(
|
||||
user_ids: list[int] = Query(default_factory=list, alias="ids[]"),
|
||||
user_ids: list[int] = Query(
|
||||
default_factory=list, alias="ids[]", description="要查询的用户 ID 列表"
|
||||
),
|
||||
current_user: User = Security(get_current_user, scopes=["public"]),
|
||||
include_variant_statistics: bool = Query(default=False), # TODO: future use
|
||||
include_variant_statistics: bool = Query(
|
||||
default=False, description="是否包含各模式的统计信息"
|
||||
), # TODO: future use
|
||||
session: AsyncSession = Depends(get_db),
|
||||
):
|
||||
if user_ids:
|
||||
@@ -58,21 +68,25 @@ async def get_users(
|
||||
)
|
||||
|
||||
|
||||
@router.get("/users/{user}/{ruleset}", response_model=UserResp)
|
||||
@router.get("/users/{user}/", response_model=UserResp)
|
||||
@router.get("/users/{user}", response_model=UserResp)
|
||||
async def get_user_info(
|
||||
user: str,
|
||||
ruleset: GameMode | None = None,
|
||||
@router.get(
|
||||
"/users/{user_id}/{ruleset}",
|
||||
response_model=UserResp,
|
||||
name="获取用户信息(指定ruleset)",
|
||||
description="通过用户 ID 或用户名获取单个用户的详细信息,并指定特定 ruleset。",
|
||||
tags=["用户"],
|
||||
)
|
||||
async def get_user_info_ruleset(
|
||||
user_id: str = Path(description="用户 ID 或用户名"),
|
||||
ruleset: GameMode | None = Path(description="指定 ruleset"),
|
||||
session: AsyncSession = Depends(get_db),
|
||||
current_user: User = Security(get_current_user, scopes=["public"]),
|
||||
):
|
||||
searched_user = (
|
||||
await session.exec(
|
||||
select(User).where(
|
||||
User.id == int(user)
|
||||
if user.isdigit()
|
||||
else User.username == user.removeprefix("@")
|
||||
User.id == int(user_id)
|
||||
if user_id.isdigit()
|
||||
else User.username == user_id.removeprefix("@")
|
||||
)
|
||||
)
|
||||
).first()
|
||||
@@ -86,17 +100,51 @@ async def get_user_info(
|
||||
)
|
||||
|
||||
|
||||
@router.get("/users/{user_id}/", response_model=UserResp, include_in_schema=False)
|
||||
@router.get(
|
||||
"/users/{user_id}",
|
||||
response_model=UserResp,
|
||||
name="获取用户信息",
|
||||
description="通过用户 ID 或用户名获取单个用户的详细信息。",
|
||||
tags=["用户"],
|
||||
)
|
||||
async def get_user_info(
|
||||
user_id: str = Path(description="用户 ID 或用户名"),
|
||||
session: AsyncSession = Depends(get_db),
|
||||
current_user: User = Security(get_current_user, scopes=["public"]),
|
||||
):
|
||||
searched_user = (
|
||||
await session.exec(
|
||||
select(User).where(
|
||||
User.id == int(user_id)
|
||||
if user_id.isdigit()
|
||||
else User.username == user_id.removeprefix("@")
|
||||
)
|
||||
)
|
||||
).first()
|
||||
if not searched_user:
|
||||
raise HTTPException(404, detail="User not found")
|
||||
return await UserResp.from_db(
|
||||
searched_user,
|
||||
session,
|
||||
include=SEARCH_INCLUDED,
|
||||
)
|
||||
|
||||
|
||||
@router.get(
|
||||
"/users/{user_id}/beatmapsets/{type}",
|
||||
response_model=list[BeatmapsetResp | BeatmapPlaycountsResp],
|
||||
name="获取用户谱面集列表",
|
||||
description="获取指定用户特定类型的谱面集列表,如最常游玩、收藏等。",
|
||||
tags=["用户"],
|
||||
)
|
||||
async def get_user_beatmapsets(
|
||||
user_id: int,
|
||||
type: BeatmapsetType,
|
||||
user_id: int = Path(description="用户 ID"),
|
||||
type: BeatmapsetType = Path(description="谱面集类型"),
|
||||
current_user: User = Security(get_current_user, scopes=["public"]),
|
||||
session: AsyncSession = Depends(get_db),
|
||||
limit: int = Query(100, ge=1, le=1000),
|
||||
offset: int = Query(0, ge=0),
|
||||
limit: int = Query(100, ge=1, le=1000, description="返回条数 (1-1000)"),
|
||||
offset: int = Query(0, ge=0, description="偏移量"),
|
||||
):
|
||||
if type in {
|
||||
BeatmapsetType.GRAVEYARD,
|
||||
@@ -139,19 +187,32 @@ async def get_user_beatmapsets(
|
||||
return resp
|
||||
|
||||
|
||||
@router.get("/users/{user}/scores/{type}", response_model=list[ScoreResp])
|
||||
@router.get(
|
||||
"/users/{user_id}/scores/{type}",
|
||||
response_model=list[ScoreResp],
|
||||
name="获取用户成绩列表",
|
||||
description="获取用户特定类型的成绩列表,如最好成绩、最近成绩等。",
|
||||
tags=["用户"],
|
||||
)
|
||||
async def get_user_scores(
|
||||
user: int,
|
||||
type: Literal["best", "recent", "firsts", "pinned"],
|
||||
legacy_only: bool = Query(False),
|
||||
include_fails: bool = Query(False),
|
||||
mode: GameMode | None = None,
|
||||
limit: int = Query(100, ge=1, le=1000),
|
||||
offset: int = Query(0, ge=0),
|
||||
user_id: int = Path(description="用户 ID"),
|
||||
type: Literal["best", "recent", "firsts", "pinned"] = Path(
|
||||
description=(
|
||||
"成绩类型: best 最好成绩 / recent 最近 24h 游玩成绩"
|
||||
" / firsts 第一名成绩 / pinned 置顶成绩"
|
||||
)
|
||||
),
|
||||
legacy_only: bool = Query(False, description="是否只查询 Stable 成绩"),
|
||||
include_fails: bool = Query(False, description="是否包含失败的成绩"),
|
||||
mode: GameMode | None = Query(
|
||||
None, description="指定 ruleset (可选,默认为用户主模式)"
|
||||
),
|
||||
limit: int = Query(100, ge=1, le=1000, description="返回条数 (1-1000)"),
|
||||
offset: int = Query(0, ge=0, description="偏移量"),
|
||||
session: AsyncSession = Depends(get_db),
|
||||
current_user: User = Security(get_current_user, scopes=["public"]),
|
||||
):
|
||||
db_user = await session.get(User, user)
|
||||
db_user = await session.get(User, user_id)
|
||||
if not db_user:
|
||||
raise HTTPException(404, detail="User not found")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user