Compare commits
5 Commits
c32995edd4
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| d8eabcb606 | |||
| 405d7ff3b9 | |||
| e7892a21a5 | |||
| 5500c55b71 | |||
| 2aee776bad |
27
CHANGELOG.md
Normal file
27
CHANGELOG.md
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
# CHANGELOG
|
||||||
|
|
||||||
|
此文件中记录 NJUPT Suan API 的主要的版本变更日志。
|
||||||
|
|
||||||
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
||||||
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
6 种更新类别:Added、Changed、Deprecated、Removed、Fixed、Security。
|
||||||
|
|
||||||
|
## [Unreleased]
|
||||||
|
|
||||||
|
等待中...
|
||||||
|
|
||||||
|
## [0.1.4] - 2026-04-26
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- 修复从命令行运行 `njupt-suan-api init` 时由于 playwright 命令未找到而失败的问题。
|
||||||
|
|
||||||
|
## [0.1.3] - 2026-04-26
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- 更改项目的 cli 入口别名与包名 `njupt-suan-api` 一致,以支持更简单地通过 uv tool / uvx 部署本项目。
|
||||||
|
- 依赖更新:
|
||||||
|
- fastapi -> 0.136.1
|
||||||
|
- typer -> 0.25.0
|
||||||
21
LICENSE.txt
Normal file
21
LICENSE.txt
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2026 MangoFanFanw
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
NJUPT Suan API 是一个 FastAPI 项目,目标在于实现对 NJUPT(南京邮电大学)的信息获取 API 和 MCP 服务。
|
NJUPT Suan API 是一个 FastAPI 项目,目标在于实现对 NJUPT(南京邮电大学)的信息获取 API 和 MCP 服务。
|
||||||
|
|
||||||
|
在 `pyproject.toml` 中,本项目的包名,以及命令行入口名为 `njupt-suan-api`。
|
||||||
|
|
||||||
## 文档
|
## 文档
|
||||||
|
|
||||||
虽然项目还没个两样,但是文档其实也没个两样 ~~(什么东西)~~
|
虽然项目还没个两样,但是文档其实也没个两样 ~~(什么东西)~~
|
||||||
@@ -11,11 +13,11 @@ NJUPT Suan API 是一个 FastAPI 项目,目标在于实现对 NJUPT(南京
|
|||||||
## 功能
|
## 功能
|
||||||
|
|
||||||
| 计划功能(芒果画饼中) | 支持进度 |
|
| 计划功能(芒果画饼中) | 支持进度 |
|
||||||
|---------------|---------------|
|
|---------------|------------------|
|
||||||
| 教务系统 - 课程表获取 | ✅ |
|
| 教务系统 - 课程表获取 | ✅ |
|
||||||
| 教务系统 - 课程获取 | ⌛️ |
|
| 教务系统 - 课程获取 | ⌛️ |
|
||||||
| 教务系统 - 成绩获取 | ⌛️ |
|
| 教务系统 - 成绩获取 | ⌛️ |
|
||||||
| 体育部系统 - 早锻炼获取 | ⌛️(等待体育部系统修复) |
|
| 体育部系统 - 早锻炼获取 | ❌(无从破解微信小程序 QAQ) |
|
||||||
|
|
||||||
## 运行
|
## 运行
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,30 @@
|
|||||||
[project]
|
[project]
|
||||||
name = "njupt-suan-api"
|
name = "njupt-suan-api"
|
||||||
version = "0.1.2"
|
version = "0.1.5"
|
||||||
description = "API and MCP server for NJUPT infomation ~"
|
description = "API and MCP server for NJUPT infomation ~"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
requires-python = ">=3.13"
|
requires-python = ">=3.13"
|
||||||
|
license = "MIT"
|
||||||
|
|
||||||
|
authors = [
|
||||||
|
{ name = "MangoFanFanw", email = "mangofanfanw@icloud.com" }
|
||||||
|
]
|
||||||
|
|
||||||
|
maintainers = [
|
||||||
|
{ name = "MangoFanFanw", email = "mangofanfanw@icloud.com" }
|
||||||
|
]
|
||||||
|
|
||||||
|
classifiers = [
|
||||||
|
"Development Status :: 3 - Alpha",
|
||||||
|
"License :: OSI Approved :: MIT License",
|
||||||
|
"Programming Language :: Python :: 3.13",
|
||||||
|
]
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aiofiles>=25.1.0",
|
"aiofiles>=25.1.0",
|
||||||
"beautifulsoup4>=4.14.3",
|
"beautifulsoup4>=4.14.3",
|
||||||
"ddddocr>=1.6.1",
|
"ddddocr>=1.6.1",
|
||||||
"fastapi>=0.135.3",
|
"fastapi>=0.136.1",
|
||||||
"fastmcp>=3.2.0",
|
"fastmcp>=3.2.0",
|
||||||
"loguru>=0.7.3",
|
"loguru>=0.7.3",
|
||||||
"mcp>=1.27.0",
|
"mcp>=1.27.0",
|
||||||
@@ -17,14 +33,21 @@ dependencies = [
|
|||||||
"rich>=15.0.0",
|
"rich>=15.0.0",
|
||||||
"sqlalchemy>=2.0.49",
|
"sqlalchemy>=2.0.49",
|
||||||
"sqlmodel>=0.0.38",
|
"sqlmodel>=0.0.38",
|
||||||
"typer>=0.24.2",
|
"typer>=0.25.0",
|
||||||
"uvicorn>=0.46.0",
|
"uvicorn>=0.46.0",
|
||||||
"watchfiles>=1.1.1",
|
"watchfiles>=1.1.1",
|
||||||
"websockets>=16.0",
|
"websockets>=16.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[project.urls]
|
||||||
|
Homepage = "https://suan.mangofanfan.cn"
|
||||||
|
Documentation = "https://suan.mangofanfan.cn"
|
||||||
|
Repository = "https://github.com/mangofanfan/NJUPT-Suan-API.git"
|
||||||
|
Changelog = "https://github.com/mangofanfan/NJUPT-Suan-API/blob/master/CHANGELOG.md"
|
||||||
|
Issues = "https://github.com/mangofanfan/NJUPT-Suan-API/issues"
|
||||||
|
|
||||||
[project.scripts]
|
[project.scripts]
|
||||||
suanapi = "njupt_suan_api.manage:app"
|
njupt-suan-api = "njupt_suan_api.manage:app"
|
||||||
|
|
||||||
[build-system]
|
[build-system]
|
||||||
requires = ["hatchling"]
|
requires = ["hatchling"]
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import subprocess
|
import subprocess
|
||||||
|
import sys
|
||||||
from secrets import token_urlsafe
|
from secrets import token_urlsafe
|
||||||
|
|
||||||
import typer
|
import typer
|
||||||
@@ -52,7 +53,10 @@ def main(
|
|||||||
CLI 入口回调,所有子命令执行前都会经过这里。
|
CLI 入口回调,所有子命令执行前都会经过这里。
|
||||||
可以在这里放全局初始化(如日志级别、环境检查)。
|
可以在这里放全局初始化(如日志级别、环境检查)。
|
||||||
"""
|
"""
|
||||||
pass # 没有 --version 时就正常放行,继续执行子命令
|
# 没有 --version 时就正常放行,继续执行子命令
|
||||||
|
console.print(
|
||||||
|
"[bright_black]NJUPT Suan API 仍然处于极早期的阶段。如果遇到任何问题,请告诉芒果帆帆喵![/bright_black]\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@app.command()
|
@app.command()
|
||||||
@@ -89,7 +93,7 @@ def init(force: bool = typer.Option(False, "--force", "-f", help="强制初始
|
|||||||
|
|
||||||
# 3 执行 uv run playwright install chromium
|
# 3 执行 uv run playwright install chromium
|
||||||
console.print("[bright_black]即将安装 playwright 的 chromium,这可能是耗时最长的部分。[/bright_black]")
|
console.print("[bright_black]即将安装 playwright 的 chromium,这可能是耗时最长的部分。[/bright_black]")
|
||||||
cp3 = subprocess.run(["playwright", "install", "chromium"], cwd=WORKSPACE_DIR)
|
cp3 = subprocess.run([sys.executable, "-m", "playwright", "install", "chromium"], cwd=WORKSPACE_DIR)
|
||||||
if cp3.returncode != 0:
|
if cp3.returncode != 0:
|
||||||
console.print("[yellow]运行 playwright install chromuim 失败,双是什么原因呢?[/yellow]")
|
console.print("[yellow]运行 playwright install chromuim 失败,双是什么原因呢?[/yellow]")
|
||||||
raise typer.Exit(code=cp3.returncode)
|
raise typer.Exit(code=cp3.returncode)
|
||||||
|
|||||||
18
uv.lock
generated
18
uv.lock
generated
@@ -333,7 +333,7 @@ wheels = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fastapi"
|
name = "fastapi"
|
||||||
version = "0.136.0"
|
version = "0.136.1"
|
||||||
source = { registry = "https://pypi.org/simple" }
|
source = { registry = "https://pypi.org/simple" }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "annotated-doc" },
|
{ name = "annotated-doc" },
|
||||||
@@ -342,9 +342,9 @@ dependencies = [
|
|||||||
{ name = "typing-extensions" },
|
{ name = "typing-extensions" },
|
||||||
{ name = "typing-inspection" },
|
{ name = "typing-inspection" },
|
||||||
]
|
]
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/4e/d9/e66315807e41e69e7f6a1b42a162dada2f249c5f06ad3f1a95f84ab336ef/fastapi-0.136.0.tar.gz", hash = "sha256:cf08e067cc66e106e102d9ba659463abfac245200752f8a5b7b1e813de4ff73e", size = 396607, upload-time = "2026-04-16T11:47:13.623Z" }
|
sdist = { url = "https://files.pythonhosted.org/packages/5d/45/c130091c2dfa061bbfe3150f2a5091ef1adf149f2a8d2ae769ecaf6e99a2/fastapi-0.136.1.tar.gz", hash = "sha256:7af665ad7acfa0a3baf8983d393b6b471b9da10ede59c60045f49fbc89a0fa7f", size = 397448, upload-time = "2026-04-23T16:49:44.046Z" }
|
||||||
wheels = [
|
wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/26/a3/0bd5f0cdb0bbc92650e8dc457e9250358411ee5d1b65e42b6632387daf81/fastapi-0.136.0-py3-none-any.whl", hash = "sha256:8793d44ec7378e2be07f8a013cf7f7aa47d6327d0dfe9804862688ec4541a6b4", size = 117556, upload-time = "2026-04-16T11:47:11.922Z" },
|
{ url = "https://files.pythonhosted.org/packages/5a/ff/2e4eca3ade2c22fe1dea7043b8ee9dabe47753349eb1b56a202de8af6349/fastapi-0.136.1-py3-none-any.whl", hash = "sha256:a6e9d7eeada96c93a4d69cb03836b44fa34e2854accb7244a1ece36cd4781c3f", size = 117683, upload-time = "2026-04-23T16:49:42.437Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -701,7 +701,7 @@ wheels = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "njupt-suan-api"
|
name = "njupt-suan-api"
|
||||||
version = "0.1.1"
|
version = "0.1.3"
|
||||||
source = { editable = "." }
|
source = { editable = "." }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "aiofiles" },
|
{ name = "aiofiles" },
|
||||||
@@ -727,7 +727,7 @@ requires-dist = [
|
|||||||
{ name = "aiofiles", specifier = ">=25.1.0" },
|
{ name = "aiofiles", specifier = ">=25.1.0" },
|
||||||
{ name = "beautifulsoup4", specifier = ">=4.14.3" },
|
{ name = "beautifulsoup4", specifier = ">=4.14.3" },
|
||||||
{ name = "ddddocr", specifier = ">=1.6.1" },
|
{ name = "ddddocr", specifier = ">=1.6.1" },
|
||||||
{ name = "fastapi", specifier = ">=0.135.3" },
|
{ name = "fastapi", specifier = ">=0.136.1" },
|
||||||
{ name = "fastmcp", specifier = ">=3.2.0" },
|
{ name = "fastmcp", specifier = ">=3.2.0" },
|
||||||
{ name = "loguru", specifier = ">=0.7.3" },
|
{ name = "loguru", specifier = ">=0.7.3" },
|
||||||
{ name = "mcp", specifier = ">=1.27.0" },
|
{ name = "mcp", specifier = ">=1.27.0" },
|
||||||
@@ -736,7 +736,7 @@ requires-dist = [
|
|||||||
{ name = "rich", specifier = ">=15.0.0" },
|
{ name = "rich", specifier = ">=15.0.0" },
|
||||||
{ name = "sqlalchemy", specifier = ">=2.0.49" },
|
{ name = "sqlalchemy", specifier = ">=2.0.49" },
|
||||||
{ name = "sqlmodel", specifier = ">=0.0.38" },
|
{ name = "sqlmodel", specifier = ">=0.0.38" },
|
||||||
{ name = "typer", specifier = ">=0.24.2" },
|
{ name = "typer", specifier = ">=0.25.0" },
|
||||||
{ name = "uvicorn", specifier = ">=0.46.0" },
|
{ name = "uvicorn", specifier = ">=0.46.0" },
|
||||||
{ name = "watchfiles", specifier = ">=1.1.1" },
|
{ name = "watchfiles", specifier = ">=1.1.1" },
|
||||||
{ name = "websockets", specifier = ">=16.0" },
|
{ name = "websockets", specifier = ">=16.0" },
|
||||||
@@ -1464,7 +1464,7 @@ wheels = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "typer"
|
name = "typer"
|
||||||
version = "0.24.2"
|
version = "0.25.0"
|
||||||
source = { registry = "https://pypi.org/simple" }
|
source = { registry = "https://pypi.org/simple" }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "annotated-doc" },
|
{ name = "annotated-doc" },
|
||||||
@@ -1472,9 +1472,9 @@ dependencies = [
|
|||||||
{ name = "rich" },
|
{ name = "rich" },
|
||||||
{ name = "shellingham" },
|
{ name = "shellingham" },
|
||||||
]
|
]
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/83/b8/9ebb531b6c2d377af08ac6746a5df3425b21853a5d2260876919b58a2a4a/typer-0.24.2.tar.gz", hash = "sha256:ec070dcfca1408e85ee203c6365001e818c3b7fffe686fd07ff2d68095ca0480", size = 119849, upload-time = "2026-04-22T17:45:34.413Z" }
|
sdist = { url = "https://files.pythonhosted.org/packages/7b/27/ede8cec7596e0041ba7e7b80b47d132562f56ff454313a16f6084e555c9f/typer-0.25.0.tar.gz", hash = "sha256:123eaf9f19bb40fd268310e12a542c0c6b4fab9c98d9d23342a01ff95e3ce930", size = 120150, upload-time = "2026-04-26T08:46:14.767Z" }
|
||||||
wheels = [
|
wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/39/d1/9484b497e0a0410b901c12b8251c3e746e1e863f7d28419ffe06f7892fda/typer-0.24.2-py3-none-any.whl", hash = "sha256:b618bc3d721f9a8d30f3e05565be26416d06e9bcc29d49bc491dc26aba674fa8", size = 55977, upload-time = "2026-04-22T17:45:33.055Z" },
|
{ url = "https://files.pythonhosted.org/packages/9a/72/193d4e586ec5a4db834a36bbeb47641a62f951f114ffd0fe5b1b46e8d56f/typer-0.25.0-py3-none-any.whl", hash = "sha256:ac01b48823d3db9a83c9e164338057eadbb1c9957a2a6b4eeb486669c560b5dc", size = 55993, upload-time = "2026-04-26T08:46:15.889Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|||||||
Reference in New Issue
Block a user