paper-search-cli 1.0.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- paper_search_cli-1.0.2/.env.example +21 -0
- paper_search_cli-1.0.2/.github/workflows/publish.yml +180 -0
- paper_search_cli-1.0.2/.gitignore +175 -0
- paper_search_cli-1.0.2/Dockerfile +26 -0
- paper_search_cli-1.0.2/LICENSE +21 -0
- paper_search_cli-1.0.2/PKG-INFO +191 -0
- paper_search_cli-1.0.2/README.md +161 -0
- paper_search_cli-1.0.2/claude-skill/paper-search.md +46 -0
- paper_search_cli-1.0.2/paper_search/__init__.py +3 -0
- paper_search_cli-1.0.2/paper_search/academic_platforms/__init__.py +0 -0
- paper_search_cli-1.0.2/paper_search/academic_platforms/acm.py +113 -0
- paper_search_cli-1.0.2/paper_search/academic_platforms/arxiv.py +157 -0
- paper_search_cli-1.0.2/paper_search/academic_platforms/base.py +54 -0
- paper_search_cli-1.0.2/paper_search/academic_platforms/base_search.py +253 -0
- paper_search_cli-1.0.2/paper_search/academic_platforms/biorxiv.py +144 -0
- paper_search_cli-1.0.2/paper_search/academic_platforms/chemrxiv.py +183 -0
- paper_search_cli-1.0.2/paper_search/academic_platforms/citeseerx.py +407 -0
- paper_search_cli-1.0.2/paper_search/academic_platforms/core.py +470 -0
- paper_search_cli-1.0.2/paper_search/academic_platforms/crossref.py +354 -0
- paper_search_cli-1.0.2/paper_search/academic_platforms/dblp.py +387 -0
- paper_search_cli-1.0.2/paper_search/academic_platforms/doaj.py +476 -0
- paper_search_cli-1.0.2/paper_search/academic_platforms/europepmc.py +430 -0
- paper_search_cli-1.0.2/paper_search/academic_platforms/google_scholar.py +233 -0
- paper_search_cli-1.0.2/paper_search/academic_platforms/hal.py +259 -0
- paper_search_cli-1.0.2/paper_search/academic_platforms/iacr.py +499 -0
- paper_search_cli-1.0.2/paper_search/academic_platforms/ieee.py +107 -0
- paper_search_cli-1.0.2/paper_search/academic_platforms/medrxiv.py +145 -0
- paper_search_cli-1.0.2/paper_search/academic_platforms/oaipmh.py +467 -0
- paper_search_cli-1.0.2/paper_search/academic_platforms/openaire.py +718 -0
- paper_search_cli-1.0.2/paper_search/academic_platforms/openalex.py +188 -0
- paper_search_cli-1.0.2/paper_search/academic_platforms/pmc.py +413 -0
- paper_search_cli-1.0.2/paper_search/academic_platforms/pubmed.py +162 -0
- paper_search_cli-1.0.2/paper_search/academic_platforms/sci_hub.py +178 -0
- paper_search_cli-1.0.2/paper_search/academic_platforms/semantic.py +531 -0
- paper_search_cli-1.0.2/paper_search/academic_platforms/ssrn.py +365 -0
- paper_search_cli-1.0.2/paper_search/academic_platforms/unpaywall.py +227 -0
- paper_search_cli-1.0.2/paper_search/academic_platforms/zenodo.py +271 -0
- paper_search_cli-1.0.2/paper_search/cli.py +227 -0
- paper_search_cli-1.0.2/paper_search/config.py +89 -0
- paper_search_cli-1.0.2/paper_search/engine.py +341 -0
- paper_search_cli-1.0.2/paper_search/paper.py +59 -0
- paper_search_cli-1.0.2/paper_search/utils.py +8 -0
- paper_search_cli-1.0.2/pyproject.toml +46 -0
- paper_search_cli-1.0.2/tests/__init__.py +0 -0
- paper_search_cli-1.0.2/tests/conftest.py +1 -0
- paper_search_cli-1.0.2/tests/e2e_test.py +472 -0
- paper_search_cli-1.0.2/tests/functional_test.py +146 -0
- paper_search_cli-1.0.2/tests/test.pubmed.py +25 -0
- paper_search_cli-1.0.2/tests/test_acm.py +74 -0
- paper_search_cli-1.0.2/tests/test_arxiv.py +18 -0
- paper_search_cli-1.0.2/tests/test_base.py +105 -0
- paper_search_cli-1.0.2/tests/test_biorxiv.py +63 -0
- paper_search_cli-1.0.2/tests/test_citeseerx.py +86 -0
- paper_search_cli-1.0.2/tests/test_config_env.py +73 -0
- paper_search_cli-1.0.2/tests/test_crossref.py +105 -0
- paper_search_cli-1.0.2/tests/test_dblp.py +155 -0
- paper_search_cli-1.0.2/tests/test_doaj.py +84 -0
- paper_search_cli-1.0.2/tests/test_fallback.py +39 -0
- paper_search_cli-1.0.2/tests/test_google_scholar.py +59 -0
- paper_search_cli-1.0.2/tests/test_hal.py +73 -0
- paper_search_cli-1.0.2/tests/test_iacr.py +307 -0
- paper_search_cli-1.0.2/tests/test_ieee.py +76 -0
- paper_search_cli-1.0.2/tests/test_medrxiv.py +59 -0
- paper_search_cli-1.0.2/tests/test_openaire.py +206 -0
- paper_search_cli-1.0.2/tests/test_sci_hub.py +182 -0
- paper_search_cli-1.0.2/tests/test_semantic.py +295 -0
- paper_search_cli-1.0.2/tests/test_server.py +42 -0
- paper_search_cli-1.0.2/tests/test_ssrn.py +97 -0
- paper_search_cli-1.0.2/tests/test_unpaywall.py +88 -0
- paper_search_cli-1.0.2/tests/test_unpaywall_source.py +48 -0
- paper_search_cli-1.0.2/tests/test_zenodo.py +81 -0
- paper_search_cli-1.0.2/uv.lock +432 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# paper-search-cli environment configuration
|
|
2
|
+
# Copy this file to .env and fill in the values you need.
|
|
3
|
+
# Preferred format: PAPER_SEARCH_<NAME>
|
|
4
|
+
# Legacy format PAPER_SEARCH_MCP_<NAME> is also supported.
|
|
5
|
+
|
|
6
|
+
# Core optional keys/tokens
|
|
7
|
+
PAPER_SEARCH_SEMANTIC_SCHOLAR_API_KEY=
|
|
8
|
+
PAPER_SEARCH_CORE_API_KEY=
|
|
9
|
+
PAPER_SEARCH_UNPAYWALL_EMAIL=
|
|
10
|
+
PAPER_SEARCH_DOAJ_API_KEY=
|
|
11
|
+
PAPER_SEARCH_ZENODO_ACCESS_TOKEN=
|
|
12
|
+
PAPER_SEARCH_GOOGLE_SCHOLAR_PROXY_URL=
|
|
13
|
+
|
|
14
|
+
# Optional provider-specific keys
|
|
15
|
+
PAPER_SEARCH_OPENAIRE_API_KEY=
|
|
16
|
+
PAPER_SEARCH_CITESEERX_API_KEY=
|
|
17
|
+
PAPER_SEARCH_IEEE_API_KEY=
|
|
18
|
+
PAPER_SEARCH_ACM_API_KEY=
|
|
19
|
+
|
|
20
|
+
# Optional: override env file path if needed
|
|
21
|
+
# PAPER_SEARCH_ENV_FILE=/absolute/path/to/.env
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
name: Auto Publish
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
paths-ignore:
|
|
7
|
+
- '*.md'
|
|
8
|
+
- 'LICENSE'
|
|
9
|
+
- '.gitignore'
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
test:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
strategy:
|
|
15
|
+
matrix:
|
|
16
|
+
python-version: ['3.10', '3.12', '3.13']
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/checkout@v4
|
|
19
|
+
|
|
20
|
+
- uses: actions/setup-python@v5
|
|
21
|
+
with:
|
|
22
|
+
python-version: ${{ matrix.python-version }}
|
|
23
|
+
|
|
24
|
+
- uses: astral-sh/setup-uv@v4
|
|
25
|
+
|
|
26
|
+
- name: Install dependencies
|
|
27
|
+
run: |
|
|
28
|
+
uv pip install --system -e ".[dev]" 2>/dev/null || uv pip install --system -e .
|
|
29
|
+
uv pip install --system pytest
|
|
30
|
+
|
|
31
|
+
- name: Run tests
|
|
32
|
+
run: python -m pytest tests/ -x -q --tb=short
|
|
33
|
+
|
|
34
|
+
bump-and-publish:
|
|
35
|
+
needs: test
|
|
36
|
+
runs-on: ubuntu-latest
|
|
37
|
+
environment: pypi
|
|
38
|
+
permissions:
|
|
39
|
+
contents: write
|
|
40
|
+
id-token: write
|
|
41
|
+
steps:
|
|
42
|
+
- uses: actions/checkout@v4
|
|
43
|
+
with:
|
|
44
|
+
fetch-depth: 0
|
|
45
|
+
token: ${{ secrets.GITHUB_TOKEN }}
|
|
46
|
+
|
|
47
|
+
- uses: actions/setup-python@v5
|
|
48
|
+
with:
|
|
49
|
+
python-version: '3.12'
|
|
50
|
+
|
|
51
|
+
- uses: astral-sh/setup-uv@v4
|
|
52
|
+
|
|
53
|
+
- uses: actions/setup-node@v4
|
|
54
|
+
with:
|
|
55
|
+
node-version: '20'
|
|
56
|
+
registry-url: 'https://registry.npmjs.org'
|
|
57
|
+
|
|
58
|
+
# --- Auto bump version ---
|
|
59
|
+
- name: Bump version
|
|
60
|
+
id: bump
|
|
61
|
+
run: |
|
|
62
|
+
# Read current version from pyproject.toml
|
|
63
|
+
CURRENT=$(grep '^version' pyproject.toml | head -1 | sed 's/.*"\(.*\)".*/\1/')
|
|
64
|
+
echo "Current version: $CURRENT"
|
|
65
|
+
|
|
66
|
+
# Bump patch version
|
|
67
|
+
IFS='.' read -r MAJOR MINOR PATCH <<< "$CURRENT"
|
|
68
|
+
NEW_PATCH=$((PATCH + 1))
|
|
69
|
+
NEW_VERSION="${MAJOR}.${MINOR}.${NEW_PATCH}"
|
|
70
|
+
echo "New version: $NEW_VERSION"
|
|
71
|
+
|
|
72
|
+
# Update pyproject.toml
|
|
73
|
+
sed -i "s/^version = \"$CURRENT\"/version = \"$NEW_VERSION\"/" pyproject.toml
|
|
74
|
+
|
|
75
|
+
# Update version in cli.py
|
|
76
|
+
sed -i "s/%(prog)s $CURRENT/%(prog)s $NEW_VERSION/" paper_search/cli.py 2>/dev/null || true
|
|
77
|
+
|
|
78
|
+
echo "version=$NEW_VERSION" >> "$GITHUB_OUTPUT"
|
|
79
|
+
|
|
80
|
+
- name: Commit version bump
|
|
81
|
+
run: |
|
|
82
|
+
git config user.name "github-actions[bot]"
|
|
83
|
+
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
84
|
+
git add pyproject.toml paper_search/cli.py
|
|
85
|
+
git diff --cached --quiet || git commit -m "chore: bump version to ${{ steps.bump.outputs.version }}"
|
|
86
|
+
git tag "v${{ steps.bump.outputs.version }}"
|
|
87
|
+
git push && git push --tags
|
|
88
|
+
|
|
89
|
+
# --- Publish to PyPI ---
|
|
90
|
+
- name: Build Python package
|
|
91
|
+
run: uv build
|
|
92
|
+
|
|
93
|
+
- name: Publish to PyPI
|
|
94
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
95
|
+
|
|
96
|
+
# --- Publish to npm ---
|
|
97
|
+
- name: Prepare npm package
|
|
98
|
+
run: |
|
|
99
|
+
VERSION="${{ steps.bump.outputs.version }}"
|
|
100
|
+
mkdir -p npm-pkg/bin
|
|
101
|
+
|
|
102
|
+
# Create the npm wrapper script
|
|
103
|
+
cat > npm-pkg/bin/paper-search <<'SCRIPT'
|
|
104
|
+
#!/usr/bin/env node
|
|
105
|
+
const { execFileSync } = require("child_process");
|
|
106
|
+
const args = process.argv.slice(2);
|
|
107
|
+
|
|
108
|
+
// Try system-installed paper-search first, then fall back to uvx
|
|
109
|
+
try {
|
|
110
|
+
execFileSync("paper-search", args, { stdio: "inherit" });
|
|
111
|
+
} catch {
|
|
112
|
+
try {
|
|
113
|
+
execFileSync("uvx", ["paper-search-cli", ...args], { stdio: "inherit" });
|
|
114
|
+
} catch {
|
|
115
|
+
console.error(
|
|
116
|
+
"paper-search-cli is not installed.\n" +
|
|
117
|
+
"Install with: pip install paper-search-cli OR uv tool install paper-search-cli"
|
|
118
|
+
);
|
|
119
|
+
process.exit(1);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
SCRIPT
|
|
123
|
+
chmod +x npm-pkg/bin/paper-search
|
|
124
|
+
|
|
125
|
+
# Create package.json
|
|
126
|
+
cat > npm-pkg/package.json <<EOF
|
|
127
|
+
{
|
|
128
|
+
"name": "paper-search-cli",
|
|
129
|
+
"version": "$VERSION",
|
|
130
|
+
"description": "CLI tool for searching and downloading academic papers from 20+ sources",
|
|
131
|
+
"bin": { "paper-search": "bin/paper-search" },
|
|
132
|
+
"keywords": ["academic", "papers", "search", "arxiv", "cli", "claude-skill"],
|
|
133
|
+
"license": "MIT",
|
|
134
|
+
"repository": {
|
|
135
|
+
"type": "git",
|
|
136
|
+
"url": "https://github.com/openags/paper-search-cli"
|
|
137
|
+
},
|
|
138
|
+
"author": "P.S Zhang <pengsongzhang96@gmail.com>"
|
|
139
|
+
}
|
|
140
|
+
EOF
|
|
141
|
+
|
|
142
|
+
# Create README for npm
|
|
143
|
+
cat > npm-pkg/README.md <<'EOF'
|
|
144
|
+
# paper-search-cli
|
|
145
|
+
|
|
146
|
+
CLI tool for searching and downloading academic papers from 20+ sources.
|
|
147
|
+
|
|
148
|
+
## Usage via npx
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
npx paper-search-cli search "transformer architecture"
|
|
152
|
+
npx paper-search-cli sources
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
## Prerequisite
|
|
156
|
+
|
|
157
|
+
Requires Python 3.10+ with `paper-search-cli` installed:
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
pip install paper-search-cli
|
|
161
|
+
# or
|
|
162
|
+
uv tool install paper-search-cli
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
See https://github.com/openags/paper-search-cli for full documentation.
|
|
166
|
+
EOF
|
|
167
|
+
|
|
168
|
+
- name: Publish to npm
|
|
169
|
+
working-directory: npm-pkg
|
|
170
|
+
run: npm publish --access public
|
|
171
|
+
env:
|
|
172
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
173
|
+
|
|
174
|
+
# --- GitHub Release ---
|
|
175
|
+
- name: Create GitHub Release
|
|
176
|
+
uses: softprops/action-gh-release@v2
|
|
177
|
+
with:
|
|
178
|
+
tag_name: "v${{ steps.bump.outputs.version }}"
|
|
179
|
+
generate_release_notes: true
|
|
180
|
+
files: dist/*
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
.DS_Store
|
|
2
|
+
scratch/
|
|
3
|
+
|
|
4
|
+
# Byte-compiled / optimized / DLL files
|
|
5
|
+
__pycache__/
|
|
6
|
+
*.py[cod]
|
|
7
|
+
*$py.class
|
|
8
|
+
|
|
9
|
+
# C extensions
|
|
10
|
+
*.so
|
|
11
|
+
|
|
12
|
+
# Distribution / packaging
|
|
13
|
+
.Python
|
|
14
|
+
build/
|
|
15
|
+
develop-eggs/
|
|
16
|
+
dist/
|
|
17
|
+
downloads/
|
|
18
|
+
eggs/
|
|
19
|
+
.eggs/
|
|
20
|
+
lib/
|
|
21
|
+
lib64/
|
|
22
|
+
parts/
|
|
23
|
+
sdist/
|
|
24
|
+
var/
|
|
25
|
+
wheels/
|
|
26
|
+
share/python-wheels/
|
|
27
|
+
*.egg-info/
|
|
28
|
+
.installed.cfg
|
|
29
|
+
*.egg
|
|
30
|
+
MANIFEST
|
|
31
|
+
|
|
32
|
+
# PyInstaller
|
|
33
|
+
# Usually these files are written by a python script from a template
|
|
34
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
35
|
+
*.manifest
|
|
36
|
+
*.spec
|
|
37
|
+
|
|
38
|
+
# Installer logs
|
|
39
|
+
pip-log.txt
|
|
40
|
+
pip-delete-this-directory.txt
|
|
41
|
+
|
|
42
|
+
# Unit test / coverage reports
|
|
43
|
+
htmlcov/
|
|
44
|
+
.tox/
|
|
45
|
+
.nox/
|
|
46
|
+
.coverage
|
|
47
|
+
.coverage.*
|
|
48
|
+
.cache
|
|
49
|
+
nosetests.xml
|
|
50
|
+
coverage.xml
|
|
51
|
+
*.cover
|
|
52
|
+
*.py,cover
|
|
53
|
+
.hypothesis/
|
|
54
|
+
.pytest_cache/
|
|
55
|
+
cover/
|
|
56
|
+
|
|
57
|
+
# Translations
|
|
58
|
+
*.mo
|
|
59
|
+
*.pot
|
|
60
|
+
|
|
61
|
+
# Django stuff:
|
|
62
|
+
*.log
|
|
63
|
+
local_settings.py
|
|
64
|
+
db.sqlite3
|
|
65
|
+
db.sqlite3-journal
|
|
66
|
+
|
|
67
|
+
# Flask stuff:
|
|
68
|
+
instance/
|
|
69
|
+
.webassets-cache
|
|
70
|
+
|
|
71
|
+
# Scrapy stuff:
|
|
72
|
+
.scrapy
|
|
73
|
+
|
|
74
|
+
# Sphinx documentation
|
|
75
|
+
docs/_build/
|
|
76
|
+
|
|
77
|
+
# PyBuilder
|
|
78
|
+
.pybuilder/
|
|
79
|
+
target/
|
|
80
|
+
|
|
81
|
+
# Jupyter Notebook
|
|
82
|
+
.ipynb_checkpoints
|
|
83
|
+
|
|
84
|
+
# IPython
|
|
85
|
+
profile_default/
|
|
86
|
+
ipython_config.py
|
|
87
|
+
|
|
88
|
+
# pyenv
|
|
89
|
+
# For a library or package, you might want to ignore these files since the code is
|
|
90
|
+
# intended to run in multiple environments; otherwise, check them in:
|
|
91
|
+
# .python-version
|
|
92
|
+
|
|
93
|
+
# pipenv
|
|
94
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
95
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
96
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
97
|
+
# install all needed dependencies.
|
|
98
|
+
#Pipfile.lock
|
|
99
|
+
|
|
100
|
+
# poetry
|
|
101
|
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
|
102
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
103
|
+
# commonly ignored for libraries.
|
|
104
|
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
|
105
|
+
#poetry.lock
|
|
106
|
+
|
|
107
|
+
# pdm
|
|
108
|
+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
|
109
|
+
#pdm.lock
|
|
110
|
+
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
|
111
|
+
# in version control.
|
|
112
|
+
# https://pdm.fming.dev/latest/usage/project/#working-with-version-control
|
|
113
|
+
.pdm.toml
|
|
114
|
+
.pdm-python
|
|
115
|
+
.pdm-build/
|
|
116
|
+
|
|
117
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
|
118
|
+
__pypackages__/
|
|
119
|
+
|
|
120
|
+
# Celery stuff
|
|
121
|
+
celerybeat-schedule
|
|
122
|
+
celerybeat.pid
|
|
123
|
+
|
|
124
|
+
# SageMath parsed files
|
|
125
|
+
*.sage.py
|
|
126
|
+
|
|
127
|
+
# Environments
|
|
128
|
+
.env
|
|
129
|
+
!.env.example
|
|
130
|
+
.venv
|
|
131
|
+
env/
|
|
132
|
+
venv/
|
|
133
|
+
ENV/
|
|
134
|
+
env.bak/
|
|
135
|
+
venv.bak/
|
|
136
|
+
|
|
137
|
+
# Spyder project settings
|
|
138
|
+
.spyderproject
|
|
139
|
+
.spyproject
|
|
140
|
+
|
|
141
|
+
# Rope project settings
|
|
142
|
+
.ropeproject
|
|
143
|
+
|
|
144
|
+
# mkdocs documentation
|
|
145
|
+
/site
|
|
146
|
+
|
|
147
|
+
# mypy
|
|
148
|
+
.mypy_cache/
|
|
149
|
+
.dmypy.json
|
|
150
|
+
dmypy.json
|
|
151
|
+
|
|
152
|
+
# Pyre type checker
|
|
153
|
+
.pyre/
|
|
154
|
+
|
|
155
|
+
# pytype static type analyzer
|
|
156
|
+
.pytype/
|
|
157
|
+
|
|
158
|
+
# Cython debug symbols
|
|
159
|
+
cython_debug/
|
|
160
|
+
|
|
161
|
+
# PyCharm
|
|
162
|
+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
|
163
|
+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
|
164
|
+
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
|
165
|
+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
|
166
|
+
#.idea/
|
|
167
|
+
|
|
168
|
+
# vscode
|
|
169
|
+
.vscode/
|
|
170
|
+
**/CLAUDE.local.md
|
|
171
|
+
|
|
172
|
+
./downloads
|
|
173
|
+
./test_downloads
|
|
174
|
+
downloads/
|
|
175
|
+
test_downloads/
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
FROM python:3.12-slim AS builder
|
|
2
|
+
|
|
3
|
+
WORKDIR /app
|
|
4
|
+
COPY pyproject.toml README.md LICENSE ./
|
|
5
|
+
COPY paper_search/ paper_search/
|
|
6
|
+
|
|
7
|
+
RUN pip install --no-cache-dir build \
|
|
8
|
+
&& python -m build --wheel \
|
|
9
|
+
&& pip install --no-cache-dir dist/*.whl
|
|
10
|
+
|
|
11
|
+
FROM python:3.12-slim
|
|
12
|
+
|
|
13
|
+
WORKDIR /app
|
|
14
|
+
COPY --from=builder /usr/local/lib/python3.12/site-packages /usr/local/lib/python3.12/site-packages
|
|
15
|
+
COPY --from=builder /usr/local/bin/paper-search /usr/local/bin/paper-search
|
|
16
|
+
|
|
17
|
+
ENV PAPER_SEARCH_UNPAYWALL_EMAIL=""
|
|
18
|
+
ENV PAPER_SEARCH_CORE_API_KEY=""
|
|
19
|
+
ENV PAPER_SEARCH_SEMANTIC_SCHOLAR_API_KEY=""
|
|
20
|
+
ENV PAPER_SEARCH_ZENODO_ACCESS_TOKEN=""
|
|
21
|
+
ENV PAPER_SEARCH_DOAJ_API_KEY=""
|
|
22
|
+
ENV PAPER_SEARCH_GOOGLE_SCHOLAR_PROXY_URL=""
|
|
23
|
+
ENV PAPER_SEARCH_IEEE_API_KEY=""
|
|
24
|
+
ENV PAPER_SEARCH_ACM_API_KEY=""
|
|
25
|
+
|
|
26
|
+
ENTRYPOINT ["paper-search"]
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 OPENAGS
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: paper-search-cli
|
|
3
|
+
Version: 1.0.2
|
|
4
|
+
Summary: CLI tool for searching and downloading academic papers from 20+ sources.
|
|
5
|
+
Project-URL: Homepage, https://github.com/openags/paper-search-cli
|
|
6
|
+
Project-URL: Repository, https://github.com/openags/paper-search-cli
|
|
7
|
+
Project-URL: Issues, https://github.com/openags/paper-search-cli/issues
|
|
8
|
+
Author-email: "P.S Zhang" <pengsongzhang96@gmail.com>
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: academic,arxiv,claude-skill,cli,papers,pubmed,search,semantic-scholar
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: Intended Audience :: Science/Research
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Topic :: Scientific/Engineering
|
|
22
|
+
Requires-Python: >=3.10
|
|
23
|
+
Requires-Dist: beautifulsoup4>=4.12.0
|
|
24
|
+
Requires-Dist: feedparser
|
|
25
|
+
Requires-Dist: httpx[socks]>=0.28.1
|
|
26
|
+
Requires-Dist: lxml>=4.9.0
|
|
27
|
+
Requires-Dist: pypdf2>=3.0.0
|
|
28
|
+
Requires-Dist: requests
|
|
29
|
+
Description-Content-Type: text/markdown
|
|
30
|
+
|
|
31
|
+
# paper-search-cli
|
|
32
|
+
|
|
33
|
+
A CLI tool for searching and downloading academic papers from 20+ sources. Also works as a **Claude Code Skill** for AI-assisted research.
|
|
34
|
+
|
|
35
|
+
## Features
|
|
36
|
+
|
|
37
|
+
- **20+ academic sources**: arXiv, PubMed, Semantic Scholar, CrossRef, OpenAlex, CORE, bioRxiv, medRxiv, and more
|
|
38
|
+
- **Concurrent search**: searches multiple sources in parallel with automatic deduplication
|
|
39
|
+
- **Smart download**: multi-stage fallback chain (source -> OA repositories -> Unpaywall -> Sci-Hub)
|
|
40
|
+
- **PDF text extraction**: download and extract text from papers in one step
|
|
41
|
+
- **JSON output**: machine-readable output for scripting and AI integration
|
|
42
|
+
- **Claude Code Skill**: use as a slash command in Claude Code
|
|
43
|
+
|
|
44
|
+
## Installation
|
|
45
|
+
|
|
46
|
+
### pip
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
pip install paper-search-cli
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### uv
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
uv tool install paper-search-cli
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### From source
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
git clone https://github.com/openags/paper-search-cli.git
|
|
62
|
+
cd paper-search-cli
|
|
63
|
+
uv sync
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Docker
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
docker build -t paper-search .
|
|
70
|
+
docker run paper-search search "transformer architecture"
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Usage
|
|
74
|
+
|
|
75
|
+
### Search papers
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
# Search all sources
|
|
79
|
+
paper-search search "transformer architecture"
|
|
80
|
+
|
|
81
|
+
# Search specific sources
|
|
82
|
+
paper-search search "quantum computing" --sources arxiv,semantic --max-results 5
|
|
83
|
+
|
|
84
|
+
# Filter by year (Semantic Scholar)
|
|
85
|
+
paper-search search "large language models" --sources semantic --year 2023-2024
|
|
86
|
+
|
|
87
|
+
# JSON output (for scripting / AI tools)
|
|
88
|
+
paper-search search "CRISPR" --json
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Download a paper
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
paper-search download 2106.12345 --source arxiv
|
|
95
|
+
paper-search download 2106.12345 --source arxiv --output-dir ./papers
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Download with fallback chain
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
paper-search download-fallback 2106.12345 --source arxiv \
|
|
102
|
+
--doi 10.48550/arXiv.2106.12345 --title "Paper Title"
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Read (download + extract text)
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
paper-search read 2106.12345 --source arxiv
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### List available sources
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
paper-search sources
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Claude Code Skill
|
|
118
|
+
|
|
119
|
+
This tool can be used as a [Claude Code Skill](https://docs.anthropic.com/en/docs/claude-code/skills) for AI-assisted academic research.
|
|
120
|
+
|
|
121
|
+
### Setup
|
|
122
|
+
|
|
123
|
+
Copy the skill file to your project:
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
mkdir -p .claude/commands
|
|
127
|
+
cp claude-skill/paper-search.md .claude/commands/paper-search.md
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Or for global access (all projects):
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
mkdir -p ~/.claude/commands
|
|
134
|
+
cp claude-skill/paper-search.md ~/.claude/commands/paper-search.md
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Then in Claude Code, use:
|
|
138
|
+
|
|
139
|
+
```
|
|
140
|
+
/paper-search transformer architecture in NLP
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Available Sources
|
|
144
|
+
|
|
145
|
+
| Source | Search | Download | Read | Notes |
|
|
146
|
+
|--------|--------|----------|------|-------|
|
|
147
|
+
| arXiv | yes | yes | yes | Open API, reliable |
|
|
148
|
+
| PubMed | yes | no | no | Metadata only |
|
|
149
|
+
| bioRxiv | yes | yes | yes | Category-based search |
|
|
150
|
+
| medRxiv | yes | yes | yes | Category-based search |
|
|
151
|
+
| Google Scholar | limited | no | no | Bot-detection active |
|
|
152
|
+
| IACR | yes | yes | yes | Cryptography focus |
|
|
153
|
+
| Semantic Scholar | yes | OA | OA | Year filter support |
|
|
154
|
+
| CrossRef | yes | no | no | DOI metadata |
|
|
155
|
+
| OpenAlex | yes | no | no | Broad metadata |
|
|
156
|
+
| PMC | yes | OA | OA | Open access only |
|
|
157
|
+
| CORE | yes | yes | yes | API key recommended |
|
|
158
|
+
| Europe PMC | yes | OA | OA | Open access only |
|
|
159
|
+
| dblp | yes | no | no | CS bibliography |
|
|
160
|
+
| OpenAIRE | yes | no | no | EU research |
|
|
161
|
+
| CiteSeerX | limited | yes | limited | Intermittent |
|
|
162
|
+
| DOAJ | yes | limited | limited | Open access journals |
|
|
163
|
+
| BASE | limited | yes | yes | OAI-PMH based |
|
|
164
|
+
| Zenodo | yes | yes | yes | Record-dependent |
|
|
165
|
+
| HAL | yes | yes | yes | French archives |
|
|
166
|
+
| SSRN | limited | limited | limited | Metadata only |
|
|
167
|
+
| Unpaywall | DOI | no | no | DOI lookup only |
|
|
168
|
+
| Sci-Hub | limited | yes | no | Optional fallback |
|
|
169
|
+
| IEEE | key | key | key | Requires API key |
|
|
170
|
+
| ACM | key | key | key | Requires API key |
|
|
171
|
+
|
|
172
|
+
## Environment Variables
|
|
173
|
+
|
|
174
|
+
All environment variables are optional. Set them in a `.env` file or export them.
|
|
175
|
+
|
|
176
|
+
| Variable | Purpose |
|
|
177
|
+
|----------|---------|
|
|
178
|
+
| `PAPER_SEARCH_UNPAYWALL_EMAIL` | Required for Unpaywall DOI resolution |
|
|
179
|
+
| `PAPER_SEARCH_CORE_API_KEY` | Better rate limits for CORE |
|
|
180
|
+
| `PAPER_SEARCH_SEMANTIC_SCHOLAR_API_KEY` | Better rate limits for Semantic Scholar |
|
|
181
|
+
| `PAPER_SEARCH_ZENODO_ACCESS_TOKEN` | Access embargoed Zenodo records |
|
|
182
|
+
| `PAPER_SEARCH_DOAJ_API_KEY` | Higher rate limits for DOAJ |
|
|
183
|
+
| `PAPER_SEARCH_GOOGLE_SCHOLAR_PROXY_URL` | Proxy for Google Scholar |
|
|
184
|
+
| `PAPER_SEARCH_IEEE_API_KEY` | Enable IEEE Xplore |
|
|
185
|
+
| `PAPER_SEARCH_ACM_API_KEY` | Enable ACM Digital Library |
|
|
186
|
+
|
|
187
|
+
Legacy `PAPER_SEARCH_MCP_*` prefix is also supported for backward compatibility.
|
|
188
|
+
|
|
189
|
+
## License
|
|
190
|
+
|
|
191
|
+
MIT
|