scholarcli 1.23__tar.gz → 1.26__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.
- {scholarcli-1.23 → scholarcli-1.26}/PKG-INFO +93 -4
- {scholarcli-1.23 → scholarcli-1.26}/README.md +92 -3
- {scholarcli-1.23 → scholarcli-1.26}/pyproject.toml +1 -1
- {scholarcli-1.23 → scholarcli-1.26}/src/scholar/__init__.py +3 -0
- {scholarcli-1.23 → scholarcli-1.26}/src/scholar/cli.py +798 -100
- {scholarcli-1.23 → scholarcli-1.26}/src/scholar/crossref.py +67 -11
- {scholarcli-1.23 → scholarcli-1.26}/src/scholar/enrich.py +30 -5
- {scholarcli-1.23 → scholarcli-1.26}/src/scholar/llm_review.py +202 -90
- {scholarcli-1.23 → scholarcli-1.26}/src/scholar/notes.py +34 -0
- {scholarcli-1.23 → scholarcli-1.26}/src/scholar/pdf.py +10 -41
- scholarcli-1.26/src/scholar/preprint.py +220 -0
- {scholarcli-1.23 → scholarcli-1.26}/src/scholar/providers.py +1489 -286
- scholarcli-1.26/src/scholar/ratelimit.py +481 -0
- {scholarcli-1.23 → scholarcli-1.26}/src/scholar/review.py +957 -240
- {scholarcli-1.23 → scholarcli-1.26}/src/scholar/scholar.py +152 -15
- {scholarcli-1.23 → scholarcli-1.26}/src/scholar/tui.py +15 -0
- scholarcli-1.26/src/scholar/unpaywall.py +203 -0
- {scholarcli-1.23 → scholarcli-1.26}/src/scholar/utils.py +102 -0
- {scholarcli-1.23 → scholarcli-1.26}/src/scholarcli.egg-info/PKG-INFO +93 -4
- {scholarcli-1.23 → scholarcli-1.26}/src/scholarcli.egg-info/SOURCES.txt +6 -0
- {scholarcli-1.23 → scholarcli-1.26}/tests/test_cli.py +901 -0
- {scholarcli-1.23 → scholarcli-1.26}/tests/test_crossref.py +88 -1
- {scholarcli-1.23 → scholarcli-1.26}/tests/test_enrich.py +90 -0
- {scholarcli-1.23 → scholarcli-1.26}/tests/test_llm_review.py +311 -0
- {scholarcli-1.23 → scholarcli-1.26}/tests/test_notes.py +59 -0
- {scholarcli-1.23 → scholarcli-1.26}/tests/test_pdf.py +20 -24
- scholarcli-1.26/tests/test_preprint.py +302 -0
- {scholarcli-1.23 → scholarcli-1.26}/tests/test_providers.py +1354 -55
- scholarcli-1.26/tests/test_ratelimit.py +396 -0
- {scholarcli-1.23 → scholarcli-1.26}/tests/test_review.py +635 -0
- {scholarcli-1.23 → scholarcli-1.26}/tests/test_scholar.py +227 -0
- scholarcli-1.26/tests/test_unpaywall.py +265 -0
- {scholarcli-1.23 → scholarcli-1.26}/tests/test_utils.py +65 -0
- {scholarcli-1.23 → scholarcli-1.26}/LICENSE +0 -0
- {scholarcli-1.23 → scholarcli-1.26}/setup.cfg +0 -0
- {scholarcli-1.23 → scholarcli-1.26}/src/scholar/__main__.py +0 -0
- {scholarcli-1.23 → scholarcli-1.26}/src/scholar/cache.py +0 -0
- {scholarcli-1.23 → scholarcli-1.26}/src/scholar/questionary.py +0 -0
- {scholarcli-1.23 → scholarcli-1.26}/src/scholarcli.egg-info/dependency_links.txt +0 -0
- {scholarcli-1.23 → scholarcli-1.26}/src/scholarcli.egg-info/entry_points.txt +0 -0
- {scholarcli-1.23 → scholarcli-1.26}/src/scholarcli.egg-info/requires.txt +0 -0
- {scholarcli-1.23 → scholarcli-1.26}/src/scholarcli.egg-info/top_level.txt +0 -0
- {scholarcli-1.23 → scholarcli-1.26}/src/snowball/__init__.py +0 -0
- {scholarcli-1.23 → scholarcli-1.26}/src/snowball/apis/__init__.py +0 -0
- {scholarcli-1.23 → scholarcli-1.26}/src/snowball/apis/aggregator.py +0 -0
- {scholarcli-1.23 → scholarcli-1.26}/src/snowball/apis/arxiv.py +0 -0
- {scholarcli-1.23 → scholarcli-1.26}/src/snowball/apis/base.py +0 -0
- {scholarcli-1.23 → scholarcli-1.26}/src/snowball/apis/crossref.py +0 -0
- {scholarcli-1.23 → scholarcli-1.26}/src/snowball/apis/google_scholar.py +0 -0
- {scholarcli-1.23 → scholarcli-1.26}/src/snowball/apis/openalex.py +0 -0
- {scholarcli-1.23 → scholarcli-1.26}/src/snowball/apis/opencitations.py +0 -0
- {scholarcli-1.23 → scholarcli-1.26}/src/snowball/apis/semantic_scholar.py +0 -0
- {scholarcli-1.23 → scholarcli-1.26}/src/snowball/cli.py +0 -0
- {scholarcli-1.23 → scholarcli-1.26}/src/snowball/exporters/__init__.py +0 -0
- {scholarcli-1.23 → scholarcli-1.26}/src/snowball/exporters/bibtex.py +0 -0
- {scholarcli-1.23 → scholarcli-1.26}/src/snowball/exporters/csv_exporter.py +0 -0
- {scholarcli-1.23 → scholarcli-1.26}/src/snowball/exporters/tikz.py +0 -0
- {scholarcli-1.23 → scholarcli-1.26}/src/snowball/filters/__init__.py +0 -0
- {scholarcli-1.23 → scholarcli-1.26}/src/snowball/filters/filter_engine.py +0 -0
- {scholarcli-1.23 → scholarcli-1.26}/src/snowball/models.py +0 -0
- {scholarcli-1.23 → scholarcli-1.26}/src/snowball/paper_utils.py +0 -0
- {scholarcli-1.23 → scholarcli-1.26}/src/snowball/parsers/__init__.py +0 -0
- {scholarcli-1.23 → scholarcli-1.26}/src/snowball/parsers/pdf_parser.py +0 -0
- {scholarcli-1.23 → scholarcli-1.26}/src/snowball/scoring/__init__.py +0 -0
- {scholarcli-1.23 → scholarcli-1.26}/src/snowball/scoring/base.py +0 -0
- {scholarcli-1.23 → scholarcli-1.26}/src/snowball/scoring/llm_scorer.py +0 -0
- {scholarcli-1.23 → scholarcli-1.26}/src/snowball/scoring/tfidf_scorer.py +0 -0
- {scholarcli-1.23 → scholarcli-1.26}/src/snowball/services.py +0 -0
- {scholarcli-1.23 → scholarcli-1.26}/src/snowball/snowballing.py +0 -0
- {scholarcli-1.23 → scholarcli-1.26}/src/snowball/storage/__init__.py +0 -0
- {scholarcli-1.23 → scholarcli-1.26}/src/snowball/storage/json_storage.py +0 -0
- {scholarcli-1.23 → scholarcli-1.26}/src/snowball/tui/__init__.py +0 -0
- {scholarcli-1.23 → scholarcli-1.26}/src/snowball/tui/app.py +0 -0
- {scholarcli-1.23 → scholarcli-1.26}/src/snowball/tui/dialogs.py +0 -0
- {scholarcli-1.23 → scholarcli-1.26}/src/snowball/tui/setup.py +0 -0
- {scholarcli-1.23 → scholarcli-1.26}/src/snowball/visualization.py +0 -0
- {scholarcli-1.23 → scholarcli-1.26}/src/tuxedo/__init__.py +0 -0
- {scholarcli-1.23 → scholarcli-1.26}/src/tuxedo/analysis.py +0 -0
- {scholarcli-1.23 → scholarcli-1.26}/src/tuxedo/cli.py +0 -0
- {scholarcli-1.23 → scholarcli-1.26}/src/tuxedo/clustering.py +0 -0
- {scholarcli-1.23 → scholarcli-1.26}/src/tuxedo/database.py +0 -0
- {scholarcli-1.23 → scholarcli-1.26}/src/tuxedo/grobid.py +0 -0
- {scholarcli-1.23 → scholarcli-1.26}/src/tuxedo/logging.py +0 -0
- {scholarcli-1.23 → scholarcli-1.26}/src/tuxedo/models.py +0 -0
- {scholarcli-1.23 → scholarcli-1.26}/src/tuxedo/project.py +0 -0
- {scholarcli-1.23 → scholarcli-1.26}/src/tuxedo/tui.py +0 -0
- {scholarcli-1.23 → scholarcli-1.26}/tests/test_cache.py +0 -0
- {scholarcli-1.23 → scholarcli-1.26}/tests/test_tui.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: scholarcli
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.26
|
|
4
4
|
Summary: A tool for structured literature searches across bibliographic databases
|
|
5
5
|
Author-email: Daniel Bosk <dbosk@kth.se>, Ric Glassey <glassey@kth.se>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -46,19 +46,36 @@ A command-line tool for conducting structured literature searches across multipl
|
|
|
46
46
|
|
|
47
47
|
### Multi-Database Search
|
|
48
48
|
|
|
49
|
-
Search across
|
|
49
|
+
Search across fifteen academic databases with a single query:
|
|
50
50
|
|
|
51
51
|
- **Semantic Scholar** - AI-powered research database with 200M+ papers
|
|
52
52
|
- **OpenAlex** - Open catalog of 250M+ scholarly works
|
|
53
53
|
- **DBLP** - Computer science bibliography
|
|
54
54
|
- **Web of Science** - Comprehensive citation index (requires API key)
|
|
55
55
|
- **IEEE Xplore** - IEEE technical literature (requires API key)
|
|
56
|
-
- **
|
|
56
|
+
- **Scopus** - Elsevier's abstract and citation database (requires API key)
|
|
57
|
+
- **arXiv** - Preprints in physics, math, CS (no API key)
|
|
58
|
+
- **HAL** - The French national open archive (no API key)
|
|
59
|
+
- **Preprint servers** - SSRN, bioRxiv, medRxiv, ChemRxiv, Research
|
|
60
|
+
Square, Preprints.org, and the IACR Cryptology ePrint Archive, each
|
|
61
|
+
searched through OpenAlex pinned to that server (none of them offers
|
|
62
|
+
a usable search API of its own)
|
|
63
|
+
|
|
64
|
+
The preprint-server providers are opt-in: a default search already finds
|
|
65
|
+
their papers through OpenAlex, so they run only when you name them —
|
|
66
|
+
either individually (`-p ssrn` scopes a search to SSRN) or all at once
|
|
67
|
+
with the `preprints` group.
|
|
57
68
|
|
|
58
69
|
```bash
|
|
59
70
|
# Search specific providers
|
|
60
71
|
scholar search "federated learning" -p s2 -p openalex
|
|
61
72
|
|
|
73
|
+
# Scope a search to one preprint server
|
|
74
|
+
scholar search "corporate governance" -p ssrn
|
|
75
|
+
|
|
76
|
+
# All preprint servers at once (arXiv, HAL, SSRN, bioRxiv, medRxiv, ...)
|
|
77
|
+
scholar search "diffusion models" -p preprints
|
|
78
|
+
|
|
62
79
|
# Start from a research question (LLM generates provider-specific queries)
|
|
63
80
|
scholar rq "How can privacy-preserving ML be evaluated?" \
|
|
64
81
|
--provider openalex --provider dblp \
|
|
@@ -109,6 +126,16 @@ scholar sessions resume "machine learning"
|
|
|
109
126
|
|
|
110
127
|
# Export session to reports
|
|
111
128
|
scholar sessions export "machine learning" -f all
|
|
129
|
+
|
|
130
|
+
# LaTeX report as an \input-able fragment (writes review.tex + review.bib)
|
|
131
|
+
scholar sessions export "machine learning" -f latex --no-standalone -o review
|
|
132
|
+
|
|
133
|
+
# Audit table for a backing appendix (one row per paper with the reason;
|
|
134
|
+
# always a fragment; --lang en|sv, --theme TAG=NAME gives themes readable names)
|
|
135
|
+
scholar sessions export "machine learning" -f table --lang sv --label sok-A \
|
|
136
|
+
--track "sökspår 1" --theme ml=maskininlärning -o review-full
|
|
137
|
+
# ... listing only the cited/supporting/qualifying rows, the rest as counts
|
|
138
|
+
scholar sessions export "machine learning" -f table --bearing-only -o review-bearing
|
|
112
139
|
```
|
|
113
140
|
|
|
114
141
|
### Paper Notes
|
|
@@ -139,6 +166,18 @@ scholar cache path # Print cache directory
|
|
|
139
166
|
|
|
140
167
|
PDF downloads are also cached for offline viewing.
|
|
141
168
|
|
|
169
|
+
### Rate-Limit and Quota Tracking
|
|
170
|
+
|
|
171
|
+
Provider rate limits and daily quotas (e.g. IEEE's 200 requests/day) are
|
|
172
|
+
tracked persistently across invocations: a provider whose budget is spent
|
|
173
|
+
is skipped with a warning naming the reset time instead of firing doomed
|
|
174
|
+
requests.
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
scholar providers limits # Show usage, remaining budget, reset times
|
|
178
|
+
scholar providers limits --reset ieee # Clear tracked state for one provider
|
|
179
|
+
```
|
|
180
|
+
|
|
142
181
|
## Quickstart
|
|
143
182
|
|
|
144
183
|
### Install
|
|
@@ -204,15 +243,34 @@ uv pip install scholarcli
|
|
|
204
243
|
|
|
205
244
|
## Configuration
|
|
206
245
|
|
|
246
|
+
Set `SCHOLAR_EMAIL` to a contact address: OpenAlex (and thus every
|
|
247
|
+
preprint-server provider), Crossref, and the polite pools use it for
|
|
248
|
+
faster responses, and Unpaywall (open-access lookup during
|
|
249
|
+
`scholar enrich` and `scholar pdf open <doi>`) requires it. `OPENALEX_EMAIL`
|
|
250
|
+
and `CROSSREF_MAILTO` are still honoured as per-service overrides.
|
|
251
|
+
|
|
252
|
+
OpenAlex meters requests against a daily budget (a search costs $0.001,
|
|
253
|
+
reset at midnight UTC). A free API key from
|
|
254
|
+
[openalex.org/settings/api](https://openalex.org/settings/api) raises the
|
|
255
|
+
budget tenfold; set it as `OPENALEX_API_KEY` and it is used by the
|
|
256
|
+
`openalex` provider and every preprint-server provider. `scholar
|
|
257
|
+
providers check` then shows how much of the day's budget is left, and a
|
|
258
|
+
search that hits the spent budget reports the reset time instead of a
|
|
259
|
+
bare 429.
|
|
260
|
+
|
|
207
261
|
Some providers require API keys set as environment variables:
|
|
208
262
|
|
|
209
263
|
| Provider | Environment Variable | Required | How to Get |
|
|
210
264
|
|----------|---------------------|----------|------------|
|
|
211
265
|
| Semantic Scholar | `S2_API_KEY` | No | [api.semanticscholar.org](https://api.semanticscholar.org) |
|
|
212
|
-
| OpenAlex | `
|
|
266
|
+
| OpenAlex | `OPENALEX_API_KEY`, `SCHOLAR_EMAIL` | No | [openalex.org/settings/api](https://openalex.org/settings/api) (10x daily budget); any email (polite pool) |
|
|
213
267
|
| DBLP | - | No | No key needed |
|
|
268
|
+
| arXiv | - | No | No key needed |
|
|
269
|
+
| HAL | - | No | No key needed |
|
|
270
|
+
| SSRN, bioRxiv, medRxiv, ChemRxiv, Research Square, Preprints.org, IACR | `SCHOLAR_EMAIL` | No | Any email (they search via OpenAlex) |
|
|
214
271
|
| Web of Science | `WOS_EXPANDED_API_KEY` or `WOS_STARTER_API_KEY` | Yes | [developer.clarivate.com](https://developer.clarivate.com) |
|
|
215
272
|
| IEEE Xplore | `IEEE_API_KEY` | Yes | [developer.ieee.org](https://developer.ieee.org) |
|
|
273
|
+
| Scopus | `SCOPUS_API_KEY` | Yes | [dev.elsevier.com](https://dev.elsevier.com) |
|
|
216
274
|
|
|
217
275
|
View provider status:
|
|
218
276
|
|
|
@@ -249,6 +307,15 @@ scholar sessions resume "privacy-ml-review"
|
|
|
249
307
|
|
|
250
308
|
# 4. Generate reports
|
|
251
309
|
scholar sessions export "privacy-ml-review" -f all
|
|
310
|
+
|
|
311
|
+
# 5. Synthesise the kept papers (needs a research context); the LaTeX
|
|
312
|
+
# document ends with the decision record as an appendix
|
|
313
|
+
scholar llm context "privacy-ml-review" "How is privacy preserved in ML?"
|
|
314
|
+
scholar llm synthesize "privacy-ml-review" -f latex -o synthesis.tex
|
|
315
|
+
|
|
316
|
+
# ... or as a fragment to \input into a thesis chapter (also writes
|
|
317
|
+
# synthesis.bib; add \addbibresource{synthesis.bib} to the preamble)
|
|
318
|
+
scholar llm synthesize "privacy-ml-review" -f latex --no-standalone -o synthesis.tex
|
|
252
319
|
```
|
|
253
320
|
|
|
254
321
|
### Enriching Results
|
|
@@ -263,6 +330,22 @@ scholar search "query" --enrich
|
|
|
263
330
|
scholar enrich "session-name"
|
|
264
331
|
```
|
|
265
332
|
|
|
333
|
+
When no PDF can be found for a paper, enrichment falls back to preprint
|
|
334
|
+
versions: authoritative links (OpenAlex's alternate locations and
|
|
335
|
+
Crossref's `has-preprint` relation) are always followed, and with
|
|
336
|
+
`--preprint-search` the preprint servers are additionally searched by
|
|
337
|
+
title and authors (exact match only). An adopted preprint *replaces*
|
|
338
|
+
the entry — its DOI, venue, and PDF — so exported citations point at
|
|
339
|
+
the version you actually read; the published DOI is kept on the entry
|
|
340
|
+
for provenance, and `scholar verify` reports such entries as
|
|
341
|
+
`preprint of <doi>` rather than superseded.
|
|
342
|
+
|
|
343
|
+
```bash
|
|
344
|
+
# Also search preprint servers for papers without a PDF
|
|
345
|
+
scholar enrich "session-name" --preprint-search
|
|
346
|
+
scholar search "query" --enrich --preprint-search
|
|
347
|
+
```
|
|
348
|
+
|
|
266
349
|
### PDF Management
|
|
267
350
|
|
|
268
351
|
```bash
|
|
@@ -299,6 +382,12 @@ For large result sets, Scholar can use LLMs to assist with paper classification:
|
|
|
299
382
|
# In the TUI, press 'L' to invoke LLM classification
|
|
300
383
|
# Or use the CLI command directly
|
|
301
384
|
scholar llm classify "session-name" --count 10
|
|
385
|
+
|
|
386
|
+
# Constrain the tags to a vocabulary (tags already in the session count too)
|
|
387
|
+
scholar llm classify "session-name" -t supports-claim -t qualifies-claim \
|
|
388
|
+
-t adjacent-subtopic -t off-topic-false-hit
|
|
389
|
+
# ... or let the model add tags of its own when none of them fits
|
|
390
|
+
scholar llm classify "session-name" --allow-new-tags
|
|
302
391
|
```
|
|
303
392
|
|
|
304
393
|
### How It Works
|
|
@@ -6,19 +6,36 @@ A command-line tool for conducting structured literature searches across multipl
|
|
|
6
6
|
|
|
7
7
|
### Multi-Database Search
|
|
8
8
|
|
|
9
|
-
Search across
|
|
9
|
+
Search across fifteen academic databases with a single query:
|
|
10
10
|
|
|
11
11
|
- **Semantic Scholar** - AI-powered research database with 200M+ papers
|
|
12
12
|
- **OpenAlex** - Open catalog of 250M+ scholarly works
|
|
13
13
|
- **DBLP** - Computer science bibliography
|
|
14
14
|
- **Web of Science** - Comprehensive citation index (requires API key)
|
|
15
15
|
- **IEEE Xplore** - IEEE technical literature (requires API key)
|
|
16
|
-
- **
|
|
16
|
+
- **Scopus** - Elsevier's abstract and citation database (requires API key)
|
|
17
|
+
- **arXiv** - Preprints in physics, math, CS (no API key)
|
|
18
|
+
- **HAL** - The French national open archive (no API key)
|
|
19
|
+
- **Preprint servers** - SSRN, bioRxiv, medRxiv, ChemRxiv, Research
|
|
20
|
+
Square, Preprints.org, and the IACR Cryptology ePrint Archive, each
|
|
21
|
+
searched through OpenAlex pinned to that server (none of them offers
|
|
22
|
+
a usable search API of its own)
|
|
23
|
+
|
|
24
|
+
The preprint-server providers are opt-in: a default search already finds
|
|
25
|
+
their papers through OpenAlex, so they run only when you name them —
|
|
26
|
+
either individually (`-p ssrn` scopes a search to SSRN) or all at once
|
|
27
|
+
with the `preprints` group.
|
|
17
28
|
|
|
18
29
|
```bash
|
|
19
30
|
# Search specific providers
|
|
20
31
|
scholar search "federated learning" -p s2 -p openalex
|
|
21
32
|
|
|
33
|
+
# Scope a search to one preprint server
|
|
34
|
+
scholar search "corporate governance" -p ssrn
|
|
35
|
+
|
|
36
|
+
# All preprint servers at once (arXiv, HAL, SSRN, bioRxiv, medRxiv, ...)
|
|
37
|
+
scholar search "diffusion models" -p preprints
|
|
38
|
+
|
|
22
39
|
# Start from a research question (LLM generates provider-specific queries)
|
|
23
40
|
scholar rq "How can privacy-preserving ML be evaluated?" \
|
|
24
41
|
--provider openalex --provider dblp \
|
|
@@ -69,6 +86,16 @@ scholar sessions resume "machine learning"
|
|
|
69
86
|
|
|
70
87
|
# Export session to reports
|
|
71
88
|
scholar sessions export "machine learning" -f all
|
|
89
|
+
|
|
90
|
+
# LaTeX report as an \input-able fragment (writes review.tex + review.bib)
|
|
91
|
+
scholar sessions export "machine learning" -f latex --no-standalone -o review
|
|
92
|
+
|
|
93
|
+
# Audit table for a backing appendix (one row per paper with the reason;
|
|
94
|
+
# always a fragment; --lang en|sv, --theme TAG=NAME gives themes readable names)
|
|
95
|
+
scholar sessions export "machine learning" -f table --lang sv --label sok-A \
|
|
96
|
+
--track "sökspår 1" --theme ml=maskininlärning -o review-full
|
|
97
|
+
# ... listing only the cited/supporting/qualifying rows, the rest as counts
|
|
98
|
+
scholar sessions export "machine learning" -f table --bearing-only -o review-bearing
|
|
72
99
|
```
|
|
73
100
|
|
|
74
101
|
### Paper Notes
|
|
@@ -99,6 +126,18 @@ scholar cache path # Print cache directory
|
|
|
99
126
|
|
|
100
127
|
PDF downloads are also cached for offline viewing.
|
|
101
128
|
|
|
129
|
+
### Rate-Limit and Quota Tracking
|
|
130
|
+
|
|
131
|
+
Provider rate limits and daily quotas (e.g. IEEE's 200 requests/day) are
|
|
132
|
+
tracked persistently across invocations: a provider whose budget is spent
|
|
133
|
+
is skipped with a warning naming the reset time instead of firing doomed
|
|
134
|
+
requests.
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
scholar providers limits # Show usage, remaining budget, reset times
|
|
138
|
+
scholar providers limits --reset ieee # Clear tracked state for one provider
|
|
139
|
+
```
|
|
140
|
+
|
|
102
141
|
## Quickstart
|
|
103
142
|
|
|
104
143
|
### Install
|
|
@@ -164,15 +203,34 @@ uv pip install scholarcli
|
|
|
164
203
|
|
|
165
204
|
## Configuration
|
|
166
205
|
|
|
206
|
+
Set `SCHOLAR_EMAIL` to a contact address: OpenAlex (and thus every
|
|
207
|
+
preprint-server provider), Crossref, and the polite pools use it for
|
|
208
|
+
faster responses, and Unpaywall (open-access lookup during
|
|
209
|
+
`scholar enrich` and `scholar pdf open <doi>`) requires it. `OPENALEX_EMAIL`
|
|
210
|
+
and `CROSSREF_MAILTO` are still honoured as per-service overrides.
|
|
211
|
+
|
|
212
|
+
OpenAlex meters requests against a daily budget (a search costs $0.001,
|
|
213
|
+
reset at midnight UTC). A free API key from
|
|
214
|
+
[openalex.org/settings/api](https://openalex.org/settings/api) raises the
|
|
215
|
+
budget tenfold; set it as `OPENALEX_API_KEY` and it is used by the
|
|
216
|
+
`openalex` provider and every preprint-server provider. `scholar
|
|
217
|
+
providers check` then shows how much of the day's budget is left, and a
|
|
218
|
+
search that hits the spent budget reports the reset time instead of a
|
|
219
|
+
bare 429.
|
|
220
|
+
|
|
167
221
|
Some providers require API keys set as environment variables:
|
|
168
222
|
|
|
169
223
|
| Provider | Environment Variable | Required | How to Get |
|
|
170
224
|
|----------|---------------------|----------|------------|
|
|
171
225
|
| Semantic Scholar | `S2_API_KEY` | No | [api.semanticscholar.org](https://api.semanticscholar.org) |
|
|
172
|
-
| OpenAlex | `
|
|
226
|
+
| OpenAlex | `OPENALEX_API_KEY`, `SCHOLAR_EMAIL` | No | [openalex.org/settings/api](https://openalex.org/settings/api) (10x daily budget); any email (polite pool) |
|
|
173
227
|
| DBLP | - | No | No key needed |
|
|
228
|
+
| arXiv | - | No | No key needed |
|
|
229
|
+
| HAL | - | No | No key needed |
|
|
230
|
+
| SSRN, bioRxiv, medRxiv, ChemRxiv, Research Square, Preprints.org, IACR | `SCHOLAR_EMAIL` | No | Any email (they search via OpenAlex) |
|
|
174
231
|
| Web of Science | `WOS_EXPANDED_API_KEY` or `WOS_STARTER_API_KEY` | Yes | [developer.clarivate.com](https://developer.clarivate.com) |
|
|
175
232
|
| IEEE Xplore | `IEEE_API_KEY` | Yes | [developer.ieee.org](https://developer.ieee.org) |
|
|
233
|
+
| Scopus | `SCOPUS_API_KEY` | Yes | [dev.elsevier.com](https://dev.elsevier.com) |
|
|
176
234
|
|
|
177
235
|
View provider status:
|
|
178
236
|
|
|
@@ -209,6 +267,15 @@ scholar sessions resume "privacy-ml-review"
|
|
|
209
267
|
|
|
210
268
|
# 4. Generate reports
|
|
211
269
|
scholar sessions export "privacy-ml-review" -f all
|
|
270
|
+
|
|
271
|
+
# 5. Synthesise the kept papers (needs a research context); the LaTeX
|
|
272
|
+
# document ends with the decision record as an appendix
|
|
273
|
+
scholar llm context "privacy-ml-review" "How is privacy preserved in ML?"
|
|
274
|
+
scholar llm synthesize "privacy-ml-review" -f latex -o synthesis.tex
|
|
275
|
+
|
|
276
|
+
# ... or as a fragment to \input into a thesis chapter (also writes
|
|
277
|
+
# synthesis.bib; add \addbibresource{synthesis.bib} to the preamble)
|
|
278
|
+
scholar llm synthesize "privacy-ml-review" -f latex --no-standalone -o synthesis.tex
|
|
212
279
|
```
|
|
213
280
|
|
|
214
281
|
### Enriching Results
|
|
@@ -223,6 +290,22 @@ scholar search "query" --enrich
|
|
|
223
290
|
scholar enrich "session-name"
|
|
224
291
|
```
|
|
225
292
|
|
|
293
|
+
When no PDF can be found for a paper, enrichment falls back to preprint
|
|
294
|
+
versions: authoritative links (OpenAlex's alternate locations and
|
|
295
|
+
Crossref's `has-preprint` relation) are always followed, and with
|
|
296
|
+
`--preprint-search` the preprint servers are additionally searched by
|
|
297
|
+
title and authors (exact match only). An adopted preprint *replaces*
|
|
298
|
+
the entry — its DOI, venue, and PDF — so exported citations point at
|
|
299
|
+
the version you actually read; the published DOI is kept on the entry
|
|
300
|
+
for provenance, and `scholar verify` reports such entries as
|
|
301
|
+
`preprint of <doi>` rather than superseded.
|
|
302
|
+
|
|
303
|
+
```bash
|
|
304
|
+
# Also search preprint servers for papers without a PDF
|
|
305
|
+
scholar enrich "session-name" --preprint-search
|
|
306
|
+
scholar search "query" --enrich --preprint-search
|
|
307
|
+
```
|
|
308
|
+
|
|
226
309
|
### PDF Management
|
|
227
310
|
|
|
228
311
|
```bash
|
|
@@ -259,6 +342,12 @@ For large result sets, Scholar can use LLMs to assist with paper classification:
|
|
|
259
342
|
# In the TUI, press 'L' to invoke LLM classification
|
|
260
343
|
# Or use the CLI command directly
|
|
261
344
|
scholar llm classify "session-name" --count 10
|
|
345
|
+
|
|
346
|
+
# Constrain the tags to a vocabulary (tags already in the session count too)
|
|
347
|
+
scholar llm classify "session-name" -t supports-claim -t qualifies-claim \
|
|
348
|
+
-t adjacent-subtopic -t off-topic-false-hit
|
|
349
|
+
# ... or let the model add tags of its own when none of them fits
|
|
350
|
+
scholar llm classify "session-name" --allow-new-tags
|
|
262
351
|
```
|
|
263
352
|
|
|
264
353
|
### How It Works
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "scholarcli"
|
|
3
|
-
version = "1.
|
|
3
|
+
version = "1.26"
|
|
4
4
|
description = "A tool for structured literature searches across bibliographic databases"
|
|
5
5
|
authors = [{ name = "Daniel Bosk", email = "dbosk@kth.se" },
|
|
6
6
|
{ name = "Ric Glassey", email = "glassey@kth.se" }]
|
|
@@ -4,6 +4,7 @@ Scholar package for structured literature searches.
|
|
|
4
4
|
|
|
5
5
|
from .scholar import Search, SearchResult, Paper, SearchFilters
|
|
6
6
|
from .scholar import search, filter_papers, deduplicate_papers
|
|
7
|
+
from .scholar import deduplicate_versions, merge_version_of
|
|
7
8
|
from .scholar import get_registry, isolated_registry
|
|
8
9
|
from .utils import safe_get_nested, ensure_list
|
|
9
10
|
|
|
@@ -15,6 +16,8 @@ __all__ = [
|
|
|
15
16
|
"search",
|
|
16
17
|
"filter_papers",
|
|
17
18
|
"deduplicate_papers",
|
|
19
|
+
"deduplicate_versions",
|
|
20
|
+
"merge_version_of",
|
|
18
21
|
"get_registry",
|
|
19
22
|
"isolated_registry",
|
|
20
23
|
"safe_get_nested",
|