docs(chat): add API docs
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import inspect
|
||||
from typing import Any
|
||||
|
||||
from fastapi import Request
|
||||
@@ -36,4 +37,15 @@ def BodyOrForm[T: BaseModel](model: type[T]):
|
||||
except ValidationError as e:
|
||||
raise RequestValidationError(e.errors())
|
||||
|
||||
dependency.__signature__ = inspect.signature( # pyright: ignore[reportFunctionMemberAccess]
|
||||
lambda x: None
|
||||
).replace(
|
||||
parameters=[
|
||||
inspect.Parameter(
|
||||
name=model.__name__.lower(),
|
||||
kind=inspect.Parameter.POSITIONAL_OR_KEYWORD,
|
||||
annotation=model,
|
||||
)
|
||||
]
|
||||
)
|
||||
return dependency
|
||||
|
||||
@@ -11,8 +11,15 @@ from fastapi import Query
|
||||
__all__ = ["chat_router"]
|
||||
|
||||
|
||||
@router.get("/notifications")
|
||||
async def get_notifications(max_id: int | None = Query(None)):
|
||||
@router.get(
|
||||
"/notifications",
|
||||
tags=["通知", "聊天"],
|
||||
name="获取通知",
|
||||
description="获取当前用户未读通知。根据 ID 排序。同时返回通知服务器入口。",
|
||||
)
|
||||
async def get_notifications(
|
||||
max_id: int | None = Query(None, description="获取 ID 小于此值的通知"),
|
||||
):
|
||||
if settings.server_url is not None:
|
||||
notification_endpoint = f"{settings.server_url}notification-server".replace(
|
||||
"http://", "ws://"
|
||||
|
||||
@@ -18,7 +18,7 @@ from app.router.v2 import api_v2_router as router
|
||||
|
||||
from .server import server
|
||||
|
||||
from fastapi import Depends, HTTPException, Query, Security
|
||||
from fastapi import Depends, HTTPException, Path, Query, Security
|
||||
from pydantic import BaseModel, Field, model_validator
|
||||
from redis.asyncio import Redis
|
||||
from sqlmodel import col, select
|
||||
@@ -30,13 +30,23 @@ class UpdateResponse(BaseModel):
|
||||
silences: list[Any] = Field(default_factory=list)
|
||||
|
||||
|
||||
@router.get("/chat/updates", response_model=UpdateResponse)
|
||||
@router.get(
|
||||
"/chat/updates",
|
||||
response_model=UpdateResponse,
|
||||
name="获取更新",
|
||||
description="获取当前用户所在频道的最新的禁言情况。",
|
||||
tags=["聊天"],
|
||||
)
|
||||
async def get_update(
|
||||
history_since: int | None = Query(None),
|
||||
since: int | None = Query(None),
|
||||
history_since: int | None = Query(
|
||||
None, description="获取自此禁言 ID 之后的禁言记录"
|
||||
),
|
||||
since: int | None = Query(None, description="获取自此消息 ID 之后的禁言记录"),
|
||||
includes: list[str] = Query(
|
||||
["presence", "silences"], alias="includes[]", description="要包含的更新类型"
|
||||
),
|
||||
current_user: User = Security(get_current_user, scopes=["chat.read"]),
|
||||
session: AsyncSession = Depends(get_db),
|
||||
includes: list[str] = Query(["presence"], alias="includes[]"),
|
||||
redis: Redis = Depends(get_redis),
|
||||
):
|
||||
resp = UpdateResponse()
|
||||
@@ -83,10 +93,16 @@ async def get_update(
|
||||
return resp
|
||||
|
||||
|
||||
@router.put("/chat/channels/{channel}/users/{user}", response_model=ChatChannelResp)
|
||||
@router.put(
|
||||
"/chat/channels/{channel}/users/{user}",
|
||||
response_model=ChatChannelResp,
|
||||
name="加入频道",
|
||||
description="加入指定的公开/房间频道。",
|
||||
tags=["聊天"],
|
||||
)
|
||||
async def join_channel(
|
||||
channel: str,
|
||||
user: str,
|
||||
channel: str = Path(..., description="频道 ID/名称"),
|
||||
user: str = Path(..., description="用户 ID"),
|
||||
current_user: User = Security(get_current_user, scopes=["chat.write_manage"]),
|
||||
session: AsyncSession = Depends(get_db),
|
||||
):
|
||||
@@ -100,10 +116,13 @@ async def join_channel(
|
||||
@router.delete(
|
||||
"/chat/channels/{channel}/users/{user}",
|
||||
status_code=204,
|
||||
name="离开频道",
|
||||
description="将用户移出指定的公开/房间频道。",
|
||||
tags=["聊天"],
|
||||
)
|
||||
async def leave_channel(
|
||||
channel: str,
|
||||
user: str,
|
||||
channel: str = Path(..., description="频道 ID/名称"),
|
||||
user: str = Path(..., description="用户 ID"),
|
||||
current_user: User = Security(get_current_user, scopes=["chat.write_manage"]),
|
||||
session: AsyncSession = Depends(get_db),
|
||||
):
|
||||
@@ -115,7 +134,13 @@ async def leave_channel(
|
||||
return
|
||||
|
||||
|
||||
@router.get("/chat/channels")
|
||||
@router.get(
|
||||
"/chat/channels",
|
||||
response_model=list[ChatChannelResp],
|
||||
name="获取频道列表",
|
||||
description="获取所有公开频道。",
|
||||
tags=["聊天"],
|
||||
)
|
||||
async def get_channel_list(
|
||||
current_user: User = Security(get_current_user, scopes=["chat.read"]),
|
||||
session: AsyncSession = Depends(get_db),
|
||||
@@ -148,9 +173,15 @@ class GetChannelResp(BaseModel):
|
||||
users: list[UserResp] = Field(default_factory=list)
|
||||
|
||||
|
||||
@router.get("/chat/channels/{channel}")
|
||||
@router.get(
|
||||
"/chat/channels/{channel}",
|
||||
response_model=GetChannelResp,
|
||||
name="获取频道信息",
|
||||
description="获取指定频道的信息。",
|
||||
tags=["聊天"],
|
||||
)
|
||||
async def get_channel(
|
||||
channel: str,
|
||||
channel: str = Path(..., description="频道 ID/名称"),
|
||||
current_user: User = Security(get_current_user, scopes=["chat.read"]),
|
||||
session: AsyncSession = Depends(get_db),
|
||||
redis: Redis = Depends(get_redis),
|
||||
@@ -211,7 +242,13 @@ class CreateChannelReq(BaseModel):
|
||||
return self
|
||||
|
||||
|
||||
@router.post("/chat/channels")
|
||||
@router.post(
|
||||
"/chat/channels",
|
||||
response_model=ChatChannelResp,
|
||||
name="创建频道",
|
||||
description="创建一个新的私聊/通知频道。如果存在私聊频道则重新加入。",
|
||||
tags=["聊天"],
|
||||
)
|
||||
async def create_channel(
|
||||
req: CreateChannelReq = Depends(BodyOrForm(CreateChannelReq)),
|
||||
current_user: User = Security(get_current_user, scopes=["chat.write_manage"]),
|
||||
|
||||
@@ -19,7 +19,7 @@ from app.router.v2 import api_v2_router as router
|
||||
from .banchobot import bot
|
||||
from .server import server
|
||||
|
||||
from fastapi import Depends, HTTPException, Query, Security
|
||||
from fastapi import Depends, HTTPException, Path, Query, Security
|
||||
from pydantic import BaseModel, Field
|
||||
from redis.asyncio import Redis
|
||||
from sqlmodel import col, select
|
||||
@@ -30,10 +30,18 @@ class KeepAliveResp(BaseModel):
|
||||
silences: list[UserSilenceResp] = Field(default_factory=list)
|
||||
|
||||
|
||||
@router.post("/chat/ack")
|
||||
@router.post(
|
||||
"/chat/ack",
|
||||
name="保持连接",
|
||||
response_model=KeepAliveResp,
|
||||
description="保持公共频道的连接。同时返回最近的禁言列表。",
|
||||
tags=["聊天"],
|
||||
)
|
||||
async def keep_alive(
|
||||
history_since: int | None = Query(None),
|
||||
since: int | None = Query(None),
|
||||
history_since: int | None = Query(
|
||||
None, description="获取自此禁言 ID 之后的禁言记录"
|
||||
),
|
||||
since: int | None = Query(None, description="获取自此消息 ID 之后的禁言记录"),
|
||||
current_user: User = Security(get_current_user, scopes=["chat.read"]),
|
||||
session: AsyncSession = Depends(get_db),
|
||||
):
|
||||
@@ -68,9 +76,15 @@ class MessageReq(BaseModel):
|
||||
uuid: str | None = None
|
||||
|
||||
|
||||
@router.post("/chat/channels/{channel}/messages", response_model=ChatMessageResp)
|
||||
@router.post(
|
||||
"/chat/channels/{channel}/messages",
|
||||
response_model=ChatMessageResp,
|
||||
name="发送消息",
|
||||
description="发送消息到指定频道。",
|
||||
tags=["聊天"],
|
||||
)
|
||||
async def send_message(
|
||||
channel: str,
|
||||
channel: str = Path(..., description="频道 ID/名称"),
|
||||
req: MessageReq = Depends(BodyOrForm(MessageReq)),
|
||||
current_user: User = Security(get_current_user, scopes=["chat.write"]),
|
||||
session: AsyncSession = Depends(get_db),
|
||||
@@ -103,12 +117,18 @@ async def send_message(
|
||||
return resp
|
||||
|
||||
|
||||
@router.get("/chat/channels/{channel}/messages", response_model=list[ChatMessageResp])
|
||||
@router.get(
|
||||
"/chat/channels/{channel}/messages",
|
||||
response_model=list[ChatMessageResp],
|
||||
name="获取消息",
|
||||
description="获取指定频道的消息列表。",
|
||||
tags=["聊天"],
|
||||
)
|
||||
async def get_message(
|
||||
channel: str,
|
||||
limit: int = Query(50, ge=1, le=50),
|
||||
since: int = Query(default=0, ge=0),
|
||||
until: int | None = Query(None),
|
||||
limit: int = Query(50, ge=1, le=50, description="获取消息的数量"),
|
||||
since: int = Query(default=0, ge=0, description="获取自此消息 ID 之后的消息记录"),
|
||||
until: int | None = Query(None, description="获取自此消息 ID 之前的消息记录"),
|
||||
current_user: User = Security(get_current_user, scopes=["chat.read"]),
|
||||
session: AsyncSession = Depends(get_db),
|
||||
):
|
||||
@@ -130,10 +150,16 @@ async def get_message(
|
||||
return resp
|
||||
|
||||
|
||||
@router.put("/chat/channels/{channel}/mark-as-read/{message}", status_code=204)
|
||||
@router.put(
|
||||
"/chat/channels/{channel}/mark-as-read/{message}",
|
||||
status_code=204,
|
||||
name="标记消息为已读",
|
||||
description="标记指定消息为已读。",
|
||||
tags=["聊天"],
|
||||
)
|
||||
async def mark_as_read(
|
||||
channel: str,
|
||||
message: int,
|
||||
channel: str = Path(..., description="频道 ID/名称"),
|
||||
message: int = Path(..., description="消息 ID"),
|
||||
current_user: User = Security(get_current_user, scopes=["chat.read"]),
|
||||
session: AsyncSession = Depends(get_db),
|
||||
):
|
||||
@@ -157,7 +183,12 @@ class NewPMResp(BaseModel):
|
||||
new_channel_id: int
|
||||
|
||||
|
||||
@router.post("/chat/new")
|
||||
@router.post(
|
||||
"/chat/new",
|
||||
name="创建私聊频道",
|
||||
description="创建一个新的私聊频道。",
|
||||
tags=["聊天"],
|
||||
)
|
||||
async def create_new_pm(
|
||||
req: PMReq = Depends(BodyOrForm(PMReq)),
|
||||
current_user: User = Security(get_current_user, scopes=["chat.write"]),
|
||||
|
||||
Reference in New Issue
Block a user