journapi
标准、可扩展的学术制品元数据检索 SDK + CLI —— 首个数据源为期刊(通过公开的 ISSN Portal),提供 Provider 抽象层,为后续更多数据源(文献、DOI 等)预留扩展能力。
项目状态:stable。ISSN Portal 公开网页接口已实现并经独立复审验证;官方订阅 API(api.issn.org, REST + JWT)提供完整 Provider 骨架(需订阅凭据端到端验证)。
功能特性
- 期刊检索 — 按刊名、ISSN、eISSN、ISSN-L 搜索,返回 ISSN、ISSN-L、ISSN-H、标题、介质、国家等
- 单条记录 — 按 ISSN 精确查询,含 ISSN-L / ISSN-H、正式题名、出版频率、语言、年份等
- ISSN-L 集群 — 展开同一刊物全部介质版本(Print/Online),含频率、语言、创刊年份
- ISSN-H 家族信息 — 展示历史沿革家族标识与成员数(家族明细需订阅)
- Web UI — 内置浏览器界面,搜索 / 精确查询双模式,可视化浏览
- MCP 服务器 —
journapi mcp一行接入 Claude Code / Cursor 等智能体(可选依赖) - 中文支持 — 中国 ISSN 中心源(issn.nlc.cn):为国内中文刊查询困难特意新增,中文刊名检索优先使用(Portal 索引为拼音转写,中文直查命中率低),原生子串匹配含出版单位/主办单位等本地化元数据;查得的 ISSN 可回 Portal 交叉验证补全国际化元数据;另保留 Portal 拼音转写链路(可选依赖)
- 礼貌抓取 — 限速(robots.txt Crawl-delay 1s)、重试退避、可选磁盘缓存(RFC 9111,认证请求绝不落盘)
- Provider 抽象 — 注册式多数据源,官方订阅 API 自动降级到公开源
- CLI + JSON — 表格或 JSON 输出,方便脚本与 Agent 集成
架构概览
+------------------------------------+
| Public API 层 |
| ArtifactSearchClient (门面) |
+----------------+-------------------+
|
+-----------------+-----------------+
| | |
v v v
+------------+ +------------+ +------------+
| issn_portal| |issn_portal_| | 第三方 |
| (公开网页)| | api(订阅) | | Provider |
+------+-----+ +------+-----+ +------+-----+
| | |
+-----------------+-----------------+
|
v
+------------------------------------+
| Provider 抽象层 |
| ArtifactProvider (ABC) |
+----------------+-------------------+
|
v
+------------------------------------+
| 基础设施层 |
| HTTP 客户端 | 限速 | 重试 | 缓存 |
+------------------------------------+
|
v
+------------------------------------+
| 应用层 |
| CLI (search/get/cluster/web/mcp) |
| Web UI (内置浏览器界面) |
| MCP Server (智能体接入, [mcp]) |
| Agent Skill (AI 助手集成) |
+------------------------------------+
项目结构
journapi/
├── src/journapi/ SDK 核心
│ ├── api.py ArtifactSearchClient 门面 + Provider 注册表
│ ├── models.py 统一数据模型(JournalRecord / SearchOptions 等)
│ ├── provider.py ArtifactProvider 抽象基类
│ ├── http.py HTTP 客户端(限速 / 重试 / 缓存)
│ ├── validation.py ISSN 校验唯一来源(格式 + mod-11 校验位)
│ ├── mcp_server.py MCP 服务器适配层([mcp] extra,智能体接入)
│ ├── sources/ 数据源
│ │ ├── issn_portal/ ISSN Portal 期刊源
│ │ │ ├── provider.py 公开网页源(search / get / cluster)
│ │ │ └── api_client.py 官方订阅 API(REST + JWT)
│ │ └── nlc_issn/ 中国 ISSN 中心源(中文刊名友好,issue #34)
│ ├── cli/ CLI 入口(search / get / cluster / web / mcp)
│ └── web/ 内置 Web UI
│ ├── server.py 服务逻辑(模板加载 + 路由 + JSON API)
│ └── templates/ 前端模板(base / search / record / cluster)
├── skills/ AI Agent 技能
│ └── journapi-skill/ 期刊检索技能(SKILL.md)
├── examples/ 可运行示例
├── docs/ 详细文档
└── tests/ 单元测试
安装
包已发布到 PyPI(包名 journapi)。三种使用方式:
1. uvx 免安装直接运行(推荐)
uvx journapi --help
uvx journapi search "Hearing research"
2. pip 安装(长期使用 / 脚本内调用)
pip install journapi # 仅 CLI
pip install "journapi[chinese]" # 含中文刊名分词支持
3. uv tool 全局安装
uv tool install journapi
journapi search "Hearing research"
开发环境
git clone https://cnb.cool/xqitw/journapi.git
cd journapi
uv sync --extra chinese --extra dev
快速开始
Python API
import asyncio
from journapi import ArtifactSearchClient, SearchOptions
async def main():
async with ArtifactSearchClient() as client:
# 1) 按刊名 / ISSN / eISSN / ISSN-L 搜索
results = await client.search("Hearing research")
for rec in results.items:
print(rec.issn, rec.issn_l, rec.issn_h, rec.title)
# 2) 按 ISSN 精确查询(含 ISSN-L / ISSN-H)
rec = await client.get("0964-1998")
print(rec.issn_l, rec.issn_h) # 0964-1998 / 9063-7704
# 3) 展开 ISSN-L 集群
members = await client.cluster_issnl("0378-5955")
for m in members:
print(m.issn, m.medium, m.title)
asyncio.run(main())
完整示例见 examples/ 目录。
CLI
# 搜索期刊(刊名 / ISSN / eISSN / ISSN-L)
# 中文刊名直查(中国 ISSN 中心源,无需转拼音)
uv run journapi search 自动化学报 --provider nlc_issn --json
# nlc 记录回查 Portal 补全国际化元数据(ISSN-L 集群 / 语种 / 频率)
uv run journapi get 0254-4156 --provider nlc_issn --enrich-portal
journapi search "Hearing research"
journapi search 0378-5955 --json
journapi search "hearing" --media online --country USA --page-size 50
# 单条记录
journapi get 0964-1998
# ISSN-L 集群
journapi cluster 0378-5955
# Web UI(浏览器界面)
journapi web --host 127.0.0.1 --port 8787
# 然后浏览器打开 http://127.0.0.1:8787
Web UI
journapi web 启动内置浏览器界面,支持:
- 🔍 搜索 — 按刊名 / 关键词模糊搜索,返回结果列表
- 🎯 精确查询 — 输入 ISSN / eISSN / ISSN-L 直接获取单条记录
- ISSN-L 集群 — 查看刊物全部介质版本
- ISSN-H 家族 — 展示历史沿革标识与成员数
MCP 服务器(AI Agents)
journapi mcp 以 Model Context Protocol 把检索能力暴露给智能体
(Claude Code、Cursor、Cline 等),无需经手 shell。需要 [mcp] extra:
uv tool install "journapi[mcp]" # 或 pip install "journapi[mcp]"
Claude Code 一行接入:
claude mcp add journapi -- uvx --from "journapi[mcp]" journapi mcp
Cursor / Cline 配置片段(stdio):
{
"mcpServers": {
"journapi": {
"command": "uvx",
"args": ["--from", "journapi[mcp]", "journapi", "mcp"]
}
}
}
暴露 3 个工具:
| 工具 | 说明 |
|---|---|
search_journals |
按刊名 / ISSN 检索(source: 中文刊名必用 nlc_issn,默认 Portal;page_size 仅接受 20/30/50/100;country / media 过滤仅 Portal 有效) |
get_journal |
按 ISSN 精确取号(mod-11 校验位本地把关;enrich=true 时 nlc 记录自动回 Portal 交叉验证补全国际化元数据) |
cluster_issnl |
展开 ISSN-L 集群全部介质版本 |
说明:默认
stdiotransport 即标准智能体接入方式;另提供streamable-http(journapi mcp --transport streamable-http)仅供本机调试——HTTP transport 无内置鉴权能力,请勿直接暴露到公网。
模块说明
| 模块 | 说明 |
|---|---|
src/journapi/api.py |
门面 + Provider 注册表(register_provider / list_providers) |
src/journapi/models.py |
统一数据模型:JournalRecord / SearchResult / SearchOptions |
src/journapi/http.py |
HTTP 客户端:限速、重试退避、可选磁盘缓存(hishel / RFC 9111) |
src/journapi/sources/issn_portal/ |
ISSN Portal 期刊数据源(公开网页 + 官方订阅 API) |
src/journapi/cli/ |
CLI:search / get / cluster / web / mcp |
src/journapi/web/ |
内置 Web UI(模板 + 路由 + JSON API) |
src/journapi/mcp_server.py |
MCP 服务器适配层(FastMCP 三工具 + stderr 日志 + 诊断文本契约) |
skills/ |
AI Agent 技能(npx skills 可安装) |
环境变量
| 变量 | 使用方 | 用途 | 何时需要 |
|---|---|---|---|
ISSN_PORTAL_USERNAME |
issn_portal_api |
官方订阅 API 用户名 | 使用官方订阅 API 时(也可通过构造参数传入) |
ISSN_PORTAL_PASSWORD |
issn_portal_api |
官方订阅 API 密码 | 使用官方订阅 API 时(也可通过构造参数传入) |
Skills
通用智能体技能,通过 npx skills 安装。
npx skills add https://cnb.cool/xqitw/journapi.git
关键设计
- Provider 抽象层 — 所有数据源实现
ArtifactProvider接口,上层 API / CLI / Web 与具体源解耦 - 统一数据模型 —
JournalRecord跨数据源一致,字段可空性按数据层级区分(搜索卡片 / 详情页 / 集群页) - 礼貌抓取 — 内置限速(robots.txt Crawl-delay 1s)、重试退避、可选磁盘缓存(RFC 9111 + 并发防击穿)
- 自动降级 — 官方订阅 API 不可用时自动回退到公开网页源
- enrich 合并 —
get()自动从 ISSN-L 集群页合并频率/语言/年份,从搜索卡片反查 ISSN-H 家族成员数 - 前端模板化 — Web UI 前端为独立模板文件,Python 仅做
{{TOKEN}}替换,无内嵌 HTML
合规说明
公开门户面向人工浏览。journapi 遵循其 robots.txt:/resource/ISSN/ 允许抓取,/resource/ISSN-L/ 与 /resource/ISSN-H/ 禁止抓取,并强制 1s 爬取延迟。生产 / 批量场景请订阅官方搜索 API 并使用订阅 Provider。
文档
贡献指南
欢迎参与贡献!详细的贡献规范和开发流程请参考 CONTRIBUTING.md。
许可证
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file journapi-1.0.0.tar.gz.
File metadata
- Download URL: journapi-1.0.0.tar.gz
- Upload date:
- Size: 82.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
uv/0.12.6 {"installer":{"name":"uv","version":"0.12.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
96feeb5cb524e162e1de5e3f32f0bc3776cf69d934aab4044f323ca46c5ce60e
|
|
| MD5 |
3ef34c58a85b23f3b6bc4c67fda928e4
|
|
| BLAKE2b-256 |
7496e556e45d2124eeaaf7062d53ba66c06dac00df1dcd223d3547339bbbbd70
|
File details
Details for the file journapi-1.0.0-py3-none-any.whl.
File metadata
- Download URL: journapi-1.0.0-py3-none-any.whl
- Upload date:
- Size: 58.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
uv/0.12.6 {"installer":{"name":"uv","version":"0.12.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b84848e51b3b65166908012828e28194c873efd4f1f35e6d9cb6d0b585149959
|
|
| MD5 |
6074617584db354a2d3c787b53e8cc01
|
|
| BLAKE2b-256 |
c4e72f0f5d2d771bd72d84224480e438300b601d3fa4685b6e28fb86f69b77b5
|