增加 pypi uv 部署
配合 NJUPT Suan API v0.1.1 更新一下文档的基本内容~
This commit is contained in:
BIN
image/njupt-suan-api-schedule-1.png
Normal file
BIN
image/njupt-suan-api-schedule-1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 423 KiB |
@@ -2,12 +2,45 @@
|
|||||||
|
|
||||||
酸 API 同时具备 API 和 MCP 后端的功能。因此,酸 API 不支持 stdio 格式的 MCP 调用。
|
酸 API 同时具备 API 和 MCP 后端的功能。因此,酸 API 不支持 stdio 格式的 MCP 调用。
|
||||||
|
|
||||||
|
## cli 命令
|
||||||
|
|
||||||
|
NJUPT Suan API 现在拥有一个 cli 命令行,可以作为入口以及管理工具。在设计上,这个命令行工具叫做 `suanapi`。
|
||||||
|
|
||||||
|
|命令|简介|
|
||||||
|
|--|--|
|
||||||
|
|init|初始化 NJUPT Suan API,包括创建工作目录、创建配置文件以及下载 playwright chromium|
|
||||||
|
|token|显示以及生成新的管理后端令牌|
|
||||||
|
|run|运行 NJUPT Suan API,支持传入 host port reload 参数|
|
||||||
|
|
||||||
|
cli 拥有完整的帮助文档,你可以使用 `--help` 查看。
|
||||||
|
|
||||||
## 部署 Suan API 示例
|
## 部署 Suan API 示例
|
||||||
|
|
||||||
目前的 Suan API 在设计上即不允许(或者说不适合)公开部署、公共服务,因此你需要自行部署 Suan API 实例。
|
目前的 Suan API 在设计上即不允许(或者说不适合)公开部署、公共服务,因此你需要自行部署 Suan API 实例。
|
||||||
|
|
||||||
### 使用 uv 部署
|
### 使用 uv 部署
|
||||||
|
|
||||||
|
芒果计划把 NJUPT Suan API 做成一个 uv 工具,但现在看来好像还存在一些问题。
|
||||||
|
|
||||||
|
你现在可以将 NJUPT Suan API 作为一个依赖安装,然后使用命令行启动。NJUPT Suan API 已经发布至 pypi。
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 初始化 uv 项目
|
||||||
|
uv init -p 3.13
|
||||||
|
|
||||||
|
# 安装
|
||||||
|
uv add njupt-suan-api
|
||||||
|
|
||||||
|
# 初始化 NJUPT Suan API
|
||||||
|
# 只需要首次运行前初始化一次即可
|
||||||
|
uv run suanapi init -f
|
||||||
|
|
||||||
|
# 运行
|
||||||
|
uv run suanapi run
|
||||||
|
```
|
||||||
|
|
||||||
|
初始化时需要加上 `-f` 是一个技术性妥协,芒果需要研究一些更优雅的解决方法。不过目前是可以使用的,芒果已经在 Windows 和 Linux 上做过测试了~
|
||||||
|
|
||||||
### 使用 Docker 部署
|
### 使用 Docker 部署
|
||||||
|
|
||||||
### 从源码部署
|
### 从源码部署
|
||||||
|
|||||||
@@ -1,127 +1,17 @@
|
|||||||
# LLM 工具
|
# LLM 工具
|
||||||
|
|
||||||
## 课表工具
|
LLM 工具是 NJUPT Suan API 为 LLM 提供的可调用 MCP 协议工具。
|
||||||
|
|
||||||
### get_course_schedule_json
|
MCP 接口端点为 `/mcp`,支持 streamable HTTP 模式。
|
||||||
|
|
||||||
```python
|
把给 LLM 使用的工具详细介绍给人类看似乎有些不太合适。请放心,Suan API 为工具提供详细的文档和参数注释,LLM 一定看得懂~
|
||||||
@mcp.tool(
|
|
||||||
name="get_course_schedule_json",
|
|
||||||
title="获取课表 JSON",
|
|
||||||
description="以 JSON 格式获取整学期整周全部课表数据,可选择是否压缩",
|
|
||||||
annotations=ToolAnnotations(
|
|
||||||
title="获取课表 JSON",
|
|
||||||
readOnlyHint=True, # 只读取数据,不修改
|
|
||||||
destructiveHint=False, # 非破坏性操作
|
|
||||||
idempotentHint=True, # 幂等:重复调用结果相同
|
|
||||||
openWorldHint=False, # 不依赖外部世界状态
|
|
||||||
),
|
|
||||||
)
|
|
||||||
async def get_course_schedule_json(compressed: bool = False) -> list[dict] | list[tuple]:
|
|
||||||
"""以 JSON 格式获取整学期整周全部课表
|
|
||||||
|
|
||||||
Args:
|
## 图片说明
|
||||||
compressed: 是否压缩为紧凑的元组格式,默认为 False
|
|
||||||
|
|
||||||
Returns:
|
课表工具可能会返回课程表图片的 URL。与 API 调用时一样,该 URL 是临时的,计划在 Suan API 的正式版本中设计为固定时间内有效、超时后删除。当前,图片会在 Suan API 重启后清理。
|
||||||
未压缩时(compressed=False):
|
|
||||||
课程字典列表,每个课程包含:
|
|
||||||
- name: 课程名称
|
|
||||||
- teacher: 授课教师(可能为 None)
|
|
||||||
- classroom: 教室(可能为 None)
|
|
||||||
- weeks: 周数,list[int]
|
|
||||||
- day: 星期几,int
|
|
||||||
- classes: 当日第几节课,list[int]
|
|
||||||
压缩时(compressed=True):
|
|
||||||
元组列表 (name, teacher, classroom, weeks_str, day, classes)
|
|
||||||
其中 weeks_str 为压缩后的周数字符串(如 "1-17")
|
|
||||||
失败时返回空列表
|
|
||||||
"""
|
|
||||||
```
|
|
||||||
|
|
||||||
LLM 在调用时可以选择是否压缩。
|
Suan API 提供一个专门返回图片本身的 LLM 工具,以帮助 LLM 将课程表图片直接包含在对话数据中,避免随着图片超时被删除而丢失。
|
||||||
|
|
||||||
请注意,[NJUPT Suan](/astrbot-plugin/introduction.md) 提供的渲染课表图片的工具需要经过压缩的课程数据,否则调用时很可能会由于参数过长而失败。
|
## 工具文档
|
||||||
|
|
||||||
### get_week_course_schedule_json
|
工具文档也被包含在 WebUI 中。
|
||||||
|
|
||||||
```python
|
|
||||||
@mcp.tool(
|
|
||||||
name="get_week_course_schedule_json",
|
|
||||||
title="获取指定周课表",
|
|
||||||
description="以 JSON 格式获取指定教学周的全部课表数据,可选择是否压缩",
|
|
||||||
annotations=ToolAnnotations(
|
|
||||||
title="获取指定周课表",
|
|
||||||
readOnlyHint=True, # 只读取数据,不修改
|
|
||||||
destructiveHint=False, # 非破坏性操作
|
|
||||||
idempotentHint=True, # 幂等:重复调用结果相同
|
|
||||||
openWorldHint=False, # 不依赖外部世界状态
|
|
||||||
),
|
|
||||||
)
|
|
||||||
async def get_week_course_schedule_json(week: int, compressed: bool = False) -> list[dict] | list[tuple]:
|
|
||||||
"""以 JSON 格式获取指定教学周的全部课表
|
|
||||||
|
|
||||||
Args:
|
|
||||||
week: 教学周数,范围通常为 1-20
|
|
||||||
compressed: 是否压缩为紧凑的元组格式,默认为 False
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
未压缩时(compressed=False):
|
|
||||||
指定周的课程字典列表,每个课程包含:
|
|
||||||
- name: 课程名称
|
|
||||||
- teacher: 授课教师(可能为 None)
|
|
||||||
- classroom: 教室(可能为 None)
|
|
||||||
- weeks: 周数,list[int]
|
|
||||||
- day: 星期几,int (1-7)
|
|
||||||
- classes: 当日第几节课,list[int]
|
|
||||||
压缩时(compressed=True):
|
|
||||||
元组列表 (name, teacher, classroom, weeks_str, day, classes)
|
|
||||||
其中 weeks_str 为压缩后的周数字符串
|
|
||||||
该周无课程或参数错误时返回空列表
|
|
||||||
"""
|
|
||||||
```
|
|
||||||
|
|
||||||
同上。
|
|
||||||
|
|
||||||
### get_week_day_course_schedule_json
|
|
||||||
|
|
||||||
```python
|
|
||||||
@mcp.tool(
|
|
||||||
name="get_week_day_course_schedule_json",
|
|
||||||
title="获取指定周星期课表",
|
|
||||||
description="以 JSON 格式获取指定教学周和星期的课表数据,可选择是否压缩",
|
|
||||||
annotations=ToolAnnotations(
|
|
||||||
title="获取指定周星期课表",
|
|
||||||
readOnlyHint=True, # 只读取数据,不修改
|
|
||||||
destructiveHint=False, # 非破坏性操作
|
|
||||||
idempotentHint=True, # 幂等:重复调用结果相同
|
|
||||||
openWorldHint=False, # 不依赖外部世界状态
|
|
||||||
),
|
|
||||||
)
|
|
||||||
async def get_week_day_course_schedule_json(week: int, day: int, compressed: bool = False) -> list[dict] | list[tuple]:
|
|
||||||
"""以 JSON 格式获取指定教学周和星期的课表
|
|
||||||
|
|
||||||
Args:
|
|
||||||
week: 教学周数,范围通常为 1-20
|
|
||||||
day: 星期几,1=星期一,2=星期二,...,7=星期日
|
|
||||||
compressed: 是否压缩为紧凑的元组格式,默认为 False
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
未压缩时(compressed=False):
|
|
||||||
指定周和星期的课程字典列表,每个课程包含:
|
|
||||||
- name: 课程名称
|
|
||||||
- teacher: 授课教师(可能为 None)
|
|
||||||
- classroom: 教室(可能为 None)
|
|
||||||
- weeks: 周数,list[int]
|
|
||||||
- day: 星期几,int (1-7)
|
|
||||||
- classes: 当日第几节课,list[int]
|
|
||||||
压缩时(compressed=True):
|
|
||||||
元组列表 (name, teacher, classroom, weeks_str, day, classes)
|
|
||||||
其中 weeks_str 为压缩后的周数字符串
|
|
||||||
该时段无课程或参数错误时返回空列表
|
|
||||||
"""
|
|
||||||
```
|
|
||||||
|
|
||||||
同上。
|
|
||||||
|
|
||||||
此三个工具的返回格式是统一的。
|
|
||||||
|
|||||||
@@ -1,9 +1,17 @@
|
|||||||
# Playwright
|
# Playwright
|
||||||
|
|
||||||
Playwright 是一个用于浏览器自动化的工具,Suan API 通过 playwright 来规避教务系统和统一身份认证的反爬虫措施,顺便用它来截图。
|
playwright 是一个用于浏览器自动化的工具,Suan API 通过 playwright 来规避教务系统和统一身份认证的反爬虫措施,顺便用它来截图。
|
||||||
|
|
||||||
## 安装
|
## 安装
|
||||||
|
|
||||||
Playwright 需要额外的安装步骤,在 [部署](deploy.md) 中已经说明。
|
playwright chromium 的安装会在 `suanapi init` 初始化过程中完成。
|
||||||
|
|
||||||
|
如需从源代码运行,则 playwright 需要额外的安装步骤,在 [部署](deploy.md) 中已经说明。
|
||||||
|
|
||||||
在开发中芒果直接使用的是 chromium,暂未测试其他选项(firefox),不过我估计应该也没什么问题就是了~
|
在开发中芒果直接使用的是 chromium,暂未测试其他选项(firefox),不过我估计应该也没什么问题就是了~
|
||||||
|
|
||||||
|
## 截图
|
||||||
|
|
||||||
|
课程表图片是使用其来渲染的,渲染效果如下。
|
||||||
|
|
||||||
|

|
||||||
|
|||||||
Reference in New Issue
Block a user