snsdk — ShitNovel API Python SDK

一个功能完整的 ShitNovel API Python 客户端 SDK,覆盖小说、章节、评论、用户、作者、书架、阅读历史、作者创作、许可证及 PAT 管理等全部 API 接口。
功能特性
- 全接口覆盖:小说、章节、分卷、评论、用户、书架、阅读历史、作者创作、许可证管理、PAT 管理
- 双轨认证:支持 Personal Access Token (PAT) 和 Session Cookie 两种认证方式
- 类型安全:所有 API 响应均映射为强类型 dataclass 模型,支持 camelCase → snake_case 自动转换
- 分页支持:内置
PaginatedResult 分页封装
- 错误处理:统一
ShitNovelError 异常,包含 HTTP 状态码与业务错误码
- Python 3.9+:支持 Python 3.9 及以上版本
- 零配置:仅依赖
requests 库,无需复杂依赖
安装
pip install snsdk
快速开始
import snsdk
# 创建客户端(使用 PAT 认证)
client = snsdk.ShitNovelClient(
base_url="https://api.shitnovel.com",
token="snp_your_pat_token_here"
)
# 获取小说列表
novels = client.list_novels(channel=snsdk.Channel.MALE, page=0, size=20)
for item in novels.items:
print(f"{item.title} - {item.author_name}")
# 获取小说详情
novel = client.get_novel(1)
print(f"《{novel.title}》共 {novel.chapter_count} 章")
# 搜索小说
results = client.search("斗破苍穹")
# 获取排行榜
rankings = client.get_rank(snsdk.RankType.HOT)
# 获取章节详情
chapter = client.get_chapter(100)
print(chapter.content)
认证
PAT(Personal Access Token)
client = snsdk.ShitNovelClient(
base_url="https://api.shitnovel.com",
token="snp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
)
Session Cookie
client = snsdk.ShitNovelClient(
base_url="https://api.shitnovel.com",
cookie="SHITNOVEL_SESSION=your_session_cookie"
)
API 接口示例
小说模块
# 列表 + 筛选
client.list_novels(
channel=snsdk.Channel.MALE, # 男频/女频
category_id=5, # 分类 ID
status=snsdk.NovelStatus.SERIALIZING, # 连载中
sort="hot", # 排序:update/hot/favorite/word/new
page=0, size=20
)
# 搜索
client.search("关键词", category_id=5, page=0, size=20)
# 排行榜
client.get_rank(snsdk.RankType.HOT) # hot/favorite/new/complete/word
# 分类 & 标签
client.list_categories(channel=snsdk.Channel.MALE)
client.get_hot_tags(limit=30)
章节模块
# 小说目录(分卷结构)
catalog = client.get_novel_catalog(novel_id=1)
for vol in catalog.volumes:
print(f"卷 {vol.sort}: {vol.title} ({vol.chapterCount} 章)")
# 章节列表(分页)
chapters = client.list_chapters(novel_id=1, volume_id=10, page=0, size=50)
# 章节详情
chapter = client.get_chapter(chapter_id=100)
print(chapter.content)
评论模块
# 小说评论
comments = client.list_novel_comments(novel_id=1, page=0, size=10)
# 章节评论
comments = client.list_chapter_comments(chapter_id=100, page=0, size=10)
# 发表评论
comment = client.create_comment(
target_type=snsdk.CommentType.NOVEL,
target_id=1,
content="这部小说写得太好了!"
)
# 点赞/取消点赞
client.like_comment(comment_id=100)
client.unlike_comment(comment_id=100)
# 删除评论
client.delete_comment(comment_id=100)
用户模块
# 当前用户信息
me = client.get_me()
print(f"你好,{me.nickname}!")
# 修改个人资料
client.update_me(nickname="新昵称", bio="新简介")
# 用户统计
stats = client.get_my_stats()
# 书架
shelf = client.list_bookshelf(page=0, size=20)
client.add_to_bookshelf(novel_id=1)
client.remove_from_bookshelf(novel_id=1)
client.batch_remove_bookshelf(novel_ids=[1, 2, 3])
# 阅读历史
history = client.get_history(page=0, size=20)
client.record_read_progress(novel_id=1, chapter_id=100)
公开用户资料
# 获取指定用户公开资料(无需认证)
user = client.get_user(user_id=100)
print(f"{user.nickname} - {user.role}")
print(f"作品数: {user.stats.novel_count}")
# 获取指定用户的公开作品列表
works = client.list_user_works(user_id=100, page=0, size=12)
# 获取指定用户的公开书架
shelf = client.list_user_bookshelf(user_id=100, page=0, size=20)
作者创作
# 我的小说列表
my_novels = client.list_my_novels(page=0, size=20)
# 创建小说
new_novel = client.create_novel(
title="我的新小说",
category_id=5,
channel=snsdk.Channel.MALE,
description="这是一部关于...的小说",
tags=["玄幻", "热血"]
)
# 更新小说
client.update_novel(
novel_id=new_novel.id,
title="修改后的书名",
status=snsdk.NovelStatus.COMPLETED
)
# 删除小说
client.delete_novel(novel_id=new_novel.id)
# 我的章节列表
my_chapters = client.list_my_chapters(novel_id=1, page=0, size=50)
# 创建章节
chapter = client.create_chapter(
novel_id=1,
title="第3章 新的开始",
content="这里是章节正文内容...",
volume_id=10,
sort=3,
status=snsdk.ChapterStatus.DRAFT
)
# 更新章节(含状态变更/许可证绑定)
client.update_chapter(
chapter_id=chapter.id,
title="第3章 修订版",
status=snsdk.ChapterStatus.PUBLISHED,
license_id=1,
license_version=1
)
# 删除章节
client.delete_chapter(chapter_id=chapter.id)
许可证管理
# 获取预定义许可证列表(无需认证)
predefined = client.list_predefined_licenses()
print(predefined[0].name) # 如 "CC BY 4.0"
# 获取许可证详情
license = client.get_license(license_id=1)
# 获取指定版本详情
version = client.get_license_version(license_id=1, version=1)
# 搜索许可证
results = client.search_licenses(
type=snsdk.LicenseType.PREDEFINED,
status=snsdk.LicenseStatus.ACTIVE,
keyword="CC",
page=0, size=20
)
# 按哈希查询版本
version = client.get_license_by_hash("sha3_384_hash_value")
# 获取我的自定义许可证
my_licenses = client.list_my_licenses()
# 创建自定义许可证
new_lic = client.create_license(
name="我的许可证",
content="本作品仅供学习交流,禁止商业用途。",
change_note="初始版本"
)
# 修改许可证元数据
client.update_license(
license_id=new_lic.id,
name="更新后的名称",
status=snsdk.LicenseStatus.ACTIVE
)
# 创建许可证新版本
new_ver = client.create_license_version(
license_id=new_lic.id,
content="更新后的许可证正文...",
change_note="修订内容"
)
# 许可证状态变更
client.update_license_status(
license_id=new_lic.id,
status=snsdk.LicenseStatus.LOCKED
)
# 绑定小说级许可证
client.bind_novel_license(
novel_id=1,
license_id=1,
license_version=1 # 可选
)
# 绑定章节级许可证
client.bind_chapter_license(
chapter_id=100,
license_id=1
)
# 查询章节的许可证引用历史
refs = client.get_chapter_license_refs(chapter_id=100)
# 查询许可证的引用章节
refs = client.get_license_refs_for_license(license_id=1)
# 按哈希查询许可证引用
refs = client.get_license_refs_by_hash("sha3_384_hash_value")
PAT 管理
# 列出 PAT(仅 Session Cookie 认证)
pats = client.list_pats()
# 创建 PAT(仅 Session Cookie 认证)
new_pat = client.create_pat(
name="我的 APP",
scopes=["novels:read", "user:read", "comments:write"]
)
print(f"新 Token: {new_pat.token}") # 仅显示一次!
# 撤销指定 PAT(仅 Session Cookie 认证)
client.revoke_pat(pat_id=1)
# 撤销自身 PAT(PAT 认证,用于客户端注销)
client.revoke_self()
枚举常量
Channel(频道)
NovelStatus(小说状态)
| 值 |
说明 |
SERIALIZING |
连载中 |
COMPLETED |
已完结 |
HIATUS |
暂停连载 |
ChapterStatus(章节状态)
| 值 |
说明 |
DRAFT |
草稿 |
PUBLISHED |
已发布 |
SCHEDULED |
定时发布 |
CommentType(评论类型)
UserRole(用户角色)
| 值 |
说明 |
USER |
普通用户 |
AUTHOR |
作者 |
ADMIN |
管理员 |
RankType(排行榜类型)
| 值 |
说明 |
HOT |
热门榜 |
FAVORITE |
收藏榜 |
NEW |
新书榜 |
COMPLETE |
完结榜 |
WORD |
字数榜 |
LicenseType(许可证类型)
| 值 |
说明 |
PREDEFINED |
预定义许可证(系统内置) |
CUSTOM |
自定义许可证(用户创建) |
LicenseStatus(许可证状态)
| 值 |
说明 |
ACTIVE |
活跃(可使用、可修改) |
INACTIVE |
停用(不可用于新发布) |
LOCKED |
锁定(不可修改,但可用于新发布) |
错误处理
try:
novel = client.get_novel(99999)
except snsdk.ShitNovelError as e:
print(f"错误 [{e.code}]: {e.message} (HTTP {e.status})")
# e.code: 业务错误码
# e.status: HTTP 状态码
常见错误码
| 错误码 |
说明 |
| 10001 |
参数无效 |
| 10002 |
资源不存在 |
| 20001 |
未认证 |
| 20002 |
Token 无效或已撤销 |
| 20004 |
权限不足 |
| 20006 |
不支持的认证方式 |
类型模型
核心 DTO
| DTO |
说明 |
Novel |
小说完整信息(含 licenseId/licenseVersion) |
NovelListItem |
小说列表项(精简版) |
Author |
作者信息 |
Chapter |
章节元数据(不含正文) |
ChapterDetail |
章节详情(含正文) |
Comment |
评论(支持两级) |
UserMe |
当前用户信息 |
BookshelfItem |
书架项(含阅读进度) |
ReadHistoryItem |
阅读历史项 |
Volume |
分卷 |
Category |
分类 |
Tag |
标签 |
公开用户 DTO
| DTO |
说明 |
PublicUser |
公开用户资料(含嵌套 PublicUserStats) |
PublicUserStats |
公开用户统计(novelCount/totalClicks/totalFavorites 等) |
PublicWork |
公开作品(不含敏感字段) |
PublicBookshelfItem |
公开书架项(不含阅读进度) |
许可证 DTO
| DTO |
说明 |
License |
许可证元数据(code/type/status 等) |
LicenseVersion |
许可证版本(hash/contentKey/changeNote) |
ChapterLicenseRef |
章节许可证引用快照(反欺诈追溯) |
响应 DTO
| DTO |
说明 |
PaginatedResult |
分页封装(items/total/page/size) |
NovelCreated |
创建小说响应 |
NovelUpdated |
更新小说响应 |
ChapterCreated |
创建章节响应 |
ChapterUpdated |
更新章节响应 |
CommentCreated |
创建评论响应 |
CommentLiked |
点赞状态响应 |
LicenseCreated |
创建许可证响应 |
LicenseVersionCreated |
创建许可证版本响应 |
LicenseStatusUpdated |
许可证状态变更响应 |
NovelLicenseBound |
小说许可证绑定响应 |
ChapterLicenseBound |
章节许可证绑定响应 |
PatCreated |
创建 PAT 响应(含 token) |
PatRevoked |
撤销 PAT 响应 |
客户端方法速查表
小说相关
| 方法 |
说明 |
需认证 |
list_novels(channel, category_id, status, sort, page, size) |
小说列表 |
否 |
get_novel(id) |
小说详情 |
否 |
search(q, category_id, status, channel, sort, page, size) |
搜索小说 |
否 |
get_rank(rank_type) |
排行榜 |
否 |
list_categories(channel) |
分类列表 |
否 |
get_hot_tags(limit) |
热门标签 |
否 |
get_author(id) |
作者信息 |
否 |
get_author_novels(id, exclude_novel_id, page, size) |
作者的其他作品 |
否 |
章节相关
| 方法 |
说明 |
需认证 |
get_novel_catalog(novel_id) |
小说目录(分卷结构) |
否 |
list_chapters(novel_id, volume_id, page, size) |
章节列表 |
否 |
get_chapter(id) |
章节详情 |
否 |
list_volumes(novel_id) |
分卷列表 |
否 |
评论相关
| 方法 |
说明 |
需认证 |
list_novel_comments(novel_id, root_only, parent_id, sort, page, size) |
小说评论列表 |
否 |
list_chapter_comments(chapter_id, root_only, parent_id, sort, page, size) |
章节评论列表 |
否 |
get_comment(id) |
评论详情 |
否 |
create_comment(target_type, target_id, content, parent_id) |
发表评论 |
是 |
delete_comment(id) |
删除评论 |
是 |
like_comment(id) |
点赞评论 |
是 |
unlike_comment(id) |
取消点赞 |
是 |
用户相关
| 方法 |
说明 |
需认证 |
get_me() |
当前用户信息 |
是 |
update_me(nickname, avatar, bio) |
修改个人资料 |
是 |
get_my_stats() |
用户统计 |
是 |
list_bookshelf(sort, page, size) |
书架列表 |
是 |
add_to_bookshelf(novel_id) |
加入书架 |
是 |
remove_from_bookshelf(novel_id) |
从书架移除 |
是 |
batch_remove_bookshelf(novel_ids) |
批量移除 |
是 |
get_history(page, size) |
阅读历史 |
是 |
record_read_progress(novel_id, chapter_id) |
记录阅读进度 |
是 |
get_user(user_id) |
公开用户资料 |
否 |
list_user_works(user_id, page, size) |
公开用户作品 |
否 |
list_user_bookshelf(user_id, page, size) |
公开用户书架 |
否 |
作者创作
| 方法 |
说明 |
需 Scope |
list_my_novels(status, page, size) |
我的小说列表 |
author:read |
create_novel(title, category_id, channel, description, cover, tags) |
创建小说 |
author:write |
update_novel(novel_id, title, category_id, description, cover, status, tags) |
更新小说 |
author:write |
delete_novel(novel_id) |
删除小说 |
author:write |
list_my_chapters(novel_id, status, page, size) |
我的章节列表 |
author:read |
create_chapter(novel_id, title, content, volume_id, sort, status) |
创建章节 |
author:write |
update_chapter(chapter_id, title, content, volume_id, sort, status, publish_time, license_id, license_version) |
更新章节 |
author:write |
delete_chapter(chapter_id) |
删除章节 |
author:write |
许可证管理
| 方法 |
说明 |
需认证 |
list_predefined_licenses() |
预定义许可证列表 |
否 |
get_license(id) |
许可证详情 |
否 |
get_license_version(license_id, version) |
版本详情 |
否 |
get_license_by_hash(hash) |
按哈希查询版本 |
否 |
search_licenses(type, status, keyword, hash, page, size) |
搜索许可证 |
否 |
list_my_licenses() |
我的自定义许可证 |
author:read |
create_license(name, content, change_note) |
创建自定义许可证 |
author:write |
update_license(license_id, name, status) |
修改许可证元数据 |
author:write |
create_license_version(license_id, content, change_note) |
创建新版本 |
author:write |
update_license_status(license_id, status) |
状态变更 |
author:write |
bind_novel_license(novel_id, license_id, license_version) |
绑定小说许可证 |
author:write |
bind_chapter_license(chapter_id, license_id, license_version) |
绑定章节许可证 |
author:write |
get_chapter_license_refs(chapter_id) |
章节引用历史 |
否 |
get_license_refs_for_license(license_id) |
许可证引用章节 |
否 |
get_license_refs_by_hash(hash) |
按哈希查询引用 |
否 |
PAT 管理
| 方法 |
说明 |
认证方式 |
list_pats() |
列出 PAT |
Session Cookie |
create_pat(name, scopes, expires_at) |
创建 PAT |
Session Cookie |
revoke_pat(id) |
撤销指定 PAT |
Session Cookie |
revoke_self() |
撤销自身 PAT |
PAT |
兼容性导入
为保持向后兼容,仍支持通过 shitnovel 模块导入:
from shitnovel import ShitNovelClient, Novel, Chapter
文档
完整的 API 文档请参见 API文档.md。
许可证
本项目基于 MIT License 开源。