pysyrev 0.1.0__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.
- pysyrev-0.1.0/LICENSE +21 -0
- pysyrev-0.1.0/PKG-INFO +222 -0
- pysyrev-0.1.0/README.md +170 -0
- pysyrev-0.1.0/pysyrev/__init__.py +6 -0
- pysyrev-0.1.0/pysyrev/__main__.py +81 -0
- pysyrev-0.1.0/pysyrev/bibdata.py +492 -0
- pysyrev-0.1.0/pysyrev/config_examples/config_abm.yaml +358 -0
- pysyrev-0.1.0/pysyrev/config_examples/config_justice.yaml +362 -0
- pysyrev-0.1.0/pysyrev/core/__init__.py +0 -0
- pysyrev-0.1.0/pysyrev/core/api/__init__.py +12 -0
- pysyrev-0.1.0/pysyrev/core/api/openalex_client.py +290 -0
- pysyrev-0.1.0/pysyrev/core/api/wos_client.py +267 -0
- pysyrev-0.1.0/pysyrev/core/berteley/__init__.py +10 -0
- pysyrev-0.1.0/pysyrev/core/berteley/berteley_stopwords.csv +67 -0
- pysyrev-0.1.0/pysyrev/core/berteley/models.py +163 -0
- pysyrev-0.1.0/pysyrev/core/berteley/preprocessing.py +151 -0
- pysyrev-0.1.0/pysyrev/core/bib.py +313 -0
- pysyrev-0.1.0/pysyrev/core/clean.py +234 -0
- pysyrev-0.1.0/pysyrev/core/config.py +794 -0
- pysyrev-0.1.0/pysyrev/core/llm.py +674 -0
- pysyrev-0.1.0/pysyrev/core/mappers.py +240 -0
- pysyrev-0.1.0/pysyrev/core/merge_bibs.py +256 -0
- pysyrev-0.1.0/pysyrev/core/network.py +162 -0
- pysyrev-0.1.0/pysyrev/core/parsers/__init__.py +5 -0
- pysyrev-0.1.0/pysyrev/core/parsers/read_bib.py +740 -0
- pysyrev-0.1.0/pysyrev/core/references.py +340 -0
- pysyrev-0.1.0/pysyrev/core/report.py +593 -0
- pysyrev-0.1.0/pysyrev/core/report_data.py +972 -0
- pysyrev-0.1.0/pysyrev/core/topic.py +268 -0
- pysyrev-0.1.0/pysyrev/network.py +210 -0
- pysyrev-0.1.0/pysyrev/pipeline.py +136 -0
- pysyrev-0.1.0/pysyrev/review.py +164 -0
- pysyrev-0.1.0/pysyrev/templates/config.yaml +374 -0
- pysyrev-0.1.0/pysyrev/topic_model.py +260 -0
- pysyrev-0.1.0/pysyrev/topic_report.py +162 -0
- pysyrev-0.1.0/pysyrev.egg-info/PKG-INFO +222 -0
- pysyrev-0.1.0/pysyrev.egg-info/SOURCES.txt +49 -0
- pysyrev-0.1.0/pysyrev.egg-info/dependency_links.txt +1 -0
- pysyrev-0.1.0/pysyrev.egg-info/entry_points.txt +2 -0
- pysyrev-0.1.0/pysyrev.egg-info/requires.txt +26 -0
- pysyrev-0.1.0/pysyrev.egg-info/top_level.txt +2 -0
- pysyrev-0.1.0/setup.cfg +4 -0
- pysyrev-0.1.0/setup.py +63 -0
- pysyrev-0.1.0/tests/__init__.py +0 -0
- pysyrev-0.1.0/tests/conftest.py +280 -0
- pysyrev-0.1.0/tests/test_berteley_models.py +115 -0
- pysyrev-0.1.0/tests/test_berteley_preprocessing.py +223 -0
- pysyrev-0.1.0/tests/test_cli.py +121 -0
- pysyrev-0.1.0/tests/test_pipeline_integration.py +250 -0
- pysyrev-0.1.0/tests/test_report.py +280 -0
- pysyrev-0.1.0/tests/test_report_sections.py +566 -0
pysyrev-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Benjamin Pillot
|
|
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.
|
pysyrev-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pysyrev
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: LLM-assisted PRISMA workflow for systematic literature review
|
|
5
|
+
Author: Benjamin Pillot
|
|
6
|
+
Author-email: benjamin.pillot@ird.fr
|
|
7
|
+
License: MIT
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Classifier: Topic :: Scientific/Engineering :: Information Analysis
|
|
12
|
+
Classifier: Intended Audience :: Science/Research
|
|
13
|
+
Requires-Python: >=3.10
|
|
14
|
+
Description-Content-Type: text/markdown
|
|
15
|
+
License-File: LICENSE
|
|
16
|
+
Requires-Dist: pandas>=2.0
|
|
17
|
+
Requires-Dist: numpy>=1.24
|
|
18
|
+
Requires-Dist: pyyaml>=6.0
|
|
19
|
+
Requires-Dist: python-dotenv>=1.0
|
|
20
|
+
Requires-Dist: rapidfuzz>=3.0
|
|
21
|
+
Requires-Dist: requests>=2.28
|
|
22
|
+
Requires-Dist: tqdm>=4.64
|
|
23
|
+
Requires-Dist: nest-asyncio>=1.5
|
|
24
|
+
Requires-Dist: pydantic>=2.0
|
|
25
|
+
Requires-Dist: litellm>=1.0
|
|
26
|
+
Requires-Dist: networkx>=3.0
|
|
27
|
+
Requires-Dist: reportlab>=4.0
|
|
28
|
+
Requires-Dist: bertopic>=0.16
|
|
29
|
+
Requires-Dist: hdbscan>=0.8
|
|
30
|
+
Requires-Dist: umap-learn>=0.5
|
|
31
|
+
Requires-Dist: sentence-transformers>=2.0
|
|
32
|
+
Requires-Dist: gensim>=4.3.0
|
|
33
|
+
Requires-Dist: octis>=1.0
|
|
34
|
+
Requires-Dist: nltk>=3.8
|
|
35
|
+
Requires-Dist: spacy>=3.0
|
|
36
|
+
Requires-Dist: beautifulsoup4>=4.11
|
|
37
|
+
Requires-Dist: contractions>=0.1
|
|
38
|
+
Provides-Extra: plotly
|
|
39
|
+
Requires-Dist: plotly>=5.0; extra == "plotly"
|
|
40
|
+
Requires-Dist: kaleido>=0.2; extra == "plotly"
|
|
41
|
+
Dynamic: author
|
|
42
|
+
Dynamic: author-email
|
|
43
|
+
Dynamic: classifier
|
|
44
|
+
Dynamic: description
|
|
45
|
+
Dynamic: description-content-type
|
|
46
|
+
Dynamic: license
|
|
47
|
+
Dynamic: license-file
|
|
48
|
+
Dynamic: provides-extra
|
|
49
|
+
Dynamic: requires-dist
|
|
50
|
+
Dynamic: requires-python
|
|
51
|
+
Dynamic: summary
|
|
52
|
+
|
|
53
|
+
<div align="center">
|
|
54
|
+
<img src="docs/logo.png" alt="pysyrev" width="350"/>
|
|
55
|
+
</div>
|
|
56
|
+
|
|
57
|
+
<div align="center">
|
|
58
|
+
|
|
59
|
+
[](https://github.com/benjaminpillot/pysyrev/actions/workflows/tests.yml)
|
|
60
|
+
[](https://pysyrev.readthedocs.io/en/latest/)
|
|
61
|
+
[](LICENSE)
|
|
62
|
+
[](https://www.python.org/)
|
|
63
|
+
|
|
64
|
+
</div>
|
|
65
|
+
|
|
66
|
+
**pysyrev** (PYthon SYstematic REView) is an automated, LLM-assisted PRISMA workflow for systematic literature reviews. It covers the full pipeline — from raw bibliographic records to screened, deduplicated, and thematically structured corpora — and produces a PDF report at the end.
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## Features
|
|
71
|
+
|
|
72
|
+
- **Multi-source ingestion** — Web of Science (file or REST API), OpenAlex (file or REST API), Scopus, PubMed
|
|
73
|
+
- **Automatic deduplication** — fuzzy title matching across sources
|
|
74
|
+
- **LLM-based title/abstract screening** — multi-reviewer workflows with majority or mean voting, powered by any provider supported by LiteLLM (Anthropic, OpenAI, Ollama, LiteLLM proxy…)
|
|
75
|
+
- **Bibliographic network analysis** — bibliographic coupling and co-citation graphs exported as GraphML
|
|
76
|
+
- **Topic modelling** — BERTopic-based clustering with UMAP + HDBSCAN grid search, ranked by coherence scores
|
|
77
|
+
- **PDF report generation** — declarative, theme-aware PDF engine built on ReportLab
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## Pipeline stages
|
|
82
|
+
|
|
83
|
+
| Stage | Key | Description |
|
|
84
|
+
|---|---|---|
|
|
85
|
+
| Bibliography | `bib` | Fetch, clean, filter, deduplicate, and optionally resolve references |
|
|
86
|
+
| LLM review | `review` | Screen documents against inclusion/exclusion criteria with one or more LLM reviewers |
|
|
87
|
+
| Bibliographic network | `bib-network` | Build coupling and co-citation networks from the included corpus |
|
|
88
|
+
| Topic modelling | `topic-model` | Cluster documents into topics using BERTopic; rank configurations by coherence |
|
|
89
|
+
| Report | `topic-report` | Generate a PDF report from the selected topic model run |
|
|
90
|
+
|
|
91
|
+
All sections are optional — only the stages declared in the config file are executed. Each stage auto-detects the most recent output of the previous one when run standalone.
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## Installation
|
|
96
|
+
|
|
97
|
+
> **Prerequisite:** Python ≥ 3.10.
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
# 1. Clone the repository
|
|
101
|
+
git clone <repo-url>
|
|
102
|
+
cd pysyrev
|
|
103
|
+
|
|
104
|
+
# 2. Install dependencies
|
|
105
|
+
pip install -r requirements.txt
|
|
106
|
+
|
|
107
|
+
# 3. Install pysyrev itself (editable mode recommended for development)
|
|
108
|
+
pip install -e .
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
To enable Plotly figure embedding in PDF reports, install the optional extras:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
pip install -e ".[plotly]"
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Documentation
|
|
118
|
+
Documentation is available from [here](https://pysyrev.readthedocs.io/en/latest/)
|
|
119
|
+
|
|
120
|
+
## Quick start
|
|
121
|
+
|
|
122
|
+
### CLI
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
# Run all configured stages (only stages present in the config are executed)
|
|
126
|
+
python -m pysyrev config.yaml
|
|
127
|
+
|
|
128
|
+
# Run a single stage
|
|
129
|
+
python -m pysyrev config.yaml --stage bib
|
|
130
|
+
python -m pysyrev config.yaml --stage review
|
|
131
|
+
python -m pysyrev config.yaml --stage bib-network
|
|
132
|
+
python -m pysyrev config.yaml --stage topic-model
|
|
133
|
+
python -m pysyrev config.yaml --stage topic-report
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
If installed via `setup.py`, the `pysyrev` command is also available directly:
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
pysyrev config.yaml --stage topic-report
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### Python API
|
|
143
|
+
|
|
144
|
+
```python
|
|
145
|
+
from pysyrev import Pipeline
|
|
146
|
+
|
|
147
|
+
# Full pipeline in one call — runs only the stages declared in the config
|
|
148
|
+
pipeline = Pipeline.from_config("config.yaml")
|
|
149
|
+
pipeline.run()
|
|
150
|
+
|
|
151
|
+
# Or stage by stage — results persist on the instance between calls
|
|
152
|
+
pipeline.run(stages=["bib"])
|
|
153
|
+
pipeline.run(stages=["review"]) # uses pipeline.bib.dataset automatically
|
|
154
|
+
pipeline.run(stages=["topic-report"]) # generates the PDF report
|
|
155
|
+
|
|
156
|
+
# Access results
|
|
157
|
+
df_all = pipeline.bib.dataset # pd.DataFrame — all collected documents
|
|
158
|
+
df_kept = pipeline.review.included_docs # pd.DataFrame — LLM-screened inclusions
|
|
159
|
+
network = pipeline.network # BibNetwork
|
|
160
|
+
topic = pipeline.topic # TopicModel
|
|
161
|
+
report = pipeline.report # TopicReport
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### Report-only run
|
|
165
|
+
|
|
166
|
+
A config containing only the `topic_report` (and optionally `report` and `llm`) sections is valid. This lets you generate or regenerate a report from a previous topic-model run without re-running the full pipeline:
|
|
167
|
+
|
|
168
|
+
```yaml
|
|
169
|
+
# report_only.yaml
|
|
170
|
+
topic_report:
|
|
171
|
+
run_dir: /path/to/topic_modeling/run_2026-05-01T120000/ # or leave blank to auto-detect
|
|
172
|
+
model_index: 0
|
|
173
|
+
export_to: /path/to/output/report/
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
python -m pysyrev report_only.yaml
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
## Configuration
|
|
183
|
+
|
|
184
|
+
A single YAML file controls all stages. Copy `pysyrev/config_examples/config_template.yaml` and fill in the sections you need. Sections not present in the file are simply skipped.
|
|
185
|
+
|
|
186
|
+
Key auto-detection rules (when fields are left blank):
|
|
187
|
+
|
|
188
|
+
| Blank field | Auto-detected from |
|
|
189
|
+
|---|---|
|
|
190
|
+
| `review.doc_dataset` | latest run in `bib.export.export_dir` |
|
|
191
|
+
| `bib_network.doc_dataset` | latest run in `review.export.export_dir` |
|
|
192
|
+
| `topic_model.doc_dataset` | latest run in `review.export.export_dir` |
|
|
193
|
+
| `topic_report.run_dir` | latest run in `topic_model.export.export_dir` |
|
|
194
|
+
| bib-network graphs in report | latest run in `bib_network.export.export_dir` |
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
## Getting started
|
|
199
|
+
|
|
200
|
+
See the `tutorials/` folder for step-by-step Jupyter notebooks and annotated configuration examples covering each pipeline stage.
|
|
201
|
+
|
|
202
|
+
---
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
<div align="center">
|
|
207
|
+
<img src="docs/espace-dev-ird.png" alt="organizations" width="600"/>
|
|
208
|
+
</div>
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
## Contributing
|
|
213
|
+
|
|
214
|
+
### Development and improvement
|
|
215
|
+
|
|
216
|
+
- Benjamin Pillot
|
|
217
|
+
- Théo Chamarande
|
|
218
|
+
- Kevin Chapuis
|
|
219
|
+
|
|
220
|
+
### Conceptualization and Coordination
|
|
221
|
+
|
|
222
|
+
- Benjamin Pillot
|
pysyrev-0.1.0/README.md
ADDED
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
<img src="docs/logo.png" alt="pysyrev" width="350"/>
|
|
3
|
+
</div>
|
|
4
|
+
|
|
5
|
+
<div align="center">
|
|
6
|
+
|
|
7
|
+
[](https://github.com/benjaminpillot/pysyrev/actions/workflows/tests.yml)
|
|
8
|
+
[](https://pysyrev.readthedocs.io/en/latest/)
|
|
9
|
+
[](LICENSE)
|
|
10
|
+
[](https://www.python.org/)
|
|
11
|
+
|
|
12
|
+
</div>
|
|
13
|
+
|
|
14
|
+
**pysyrev** (PYthon SYstematic REView) is an automated, LLM-assisted PRISMA workflow for systematic literature reviews. It covers the full pipeline — from raw bibliographic records to screened, deduplicated, and thematically structured corpora — and produces a PDF report at the end.
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Features
|
|
19
|
+
|
|
20
|
+
- **Multi-source ingestion** — Web of Science (file or REST API), OpenAlex (file or REST API), Scopus, PubMed
|
|
21
|
+
- **Automatic deduplication** — fuzzy title matching across sources
|
|
22
|
+
- **LLM-based title/abstract screening** — multi-reviewer workflows with majority or mean voting, powered by any provider supported by LiteLLM (Anthropic, OpenAI, Ollama, LiteLLM proxy…)
|
|
23
|
+
- **Bibliographic network analysis** — bibliographic coupling and co-citation graphs exported as GraphML
|
|
24
|
+
- **Topic modelling** — BERTopic-based clustering with UMAP + HDBSCAN grid search, ranked by coherence scores
|
|
25
|
+
- **PDF report generation** — declarative, theme-aware PDF engine built on ReportLab
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Pipeline stages
|
|
30
|
+
|
|
31
|
+
| Stage | Key | Description |
|
|
32
|
+
|---|---|---|
|
|
33
|
+
| Bibliography | `bib` | Fetch, clean, filter, deduplicate, and optionally resolve references |
|
|
34
|
+
| LLM review | `review` | Screen documents against inclusion/exclusion criteria with one or more LLM reviewers |
|
|
35
|
+
| Bibliographic network | `bib-network` | Build coupling and co-citation networks from the included corpus |
|
|
36
|
+
| Topic modelling | `topic-model` | Cluster documents into topics using BERTopic; rank configurations by coherence |
|
|
37
|
+
| Report | `topic-report` | Generate a PDF report from the selected topic model run |
|
|
38
|
+
|
|
39
|
+
All sections are optional — only the stages declared in the config file are executed. Each stage auto-detects the most recent output of the previous one when run standalone.
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## Installation
|
|
44
|
+
|
|
45
|
+
> **Prerequisite:** Python ≥ 3.10.
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
# 1. Clone the repository
|
|
49
|
+
git clone <repo-url>
|
|
50
|
+
cd pysyrev
|
|
51
|
+
|
|
52
|
+
# 2. Install dependencies
|
|
53
|
+
pip install -r requirements.txt
|
|
54
|
+
|
|
55
|
+
# 3. Install pysyrev itself (editable mode recommended for development)
|
|
56
|
+
pip install -e .
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
To enable Plotly figure embedding in PDF reports, install the optional extras:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
pip install -e ".[plotly]"
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Documentation
|
|
66
|
+
Documentation is available from [here](https://pysyrev.readthedocs.io/en/latest/)
|
|
67
|
+
|
|
68
|
+
## Quick start
|
|
69
|
+
|
|
70
|
+
### CLI
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
# Run all configured stages (only stages present in the config are executed)
|
|
74
|
+
python -m pysyrev config.yaml
|
|
75
|
+
|
|
76
|
+
# Run a single stage
|
|
77
|
+
python -m pysyrev config.yaml --stage bib
|
|
78
|
+
python -m pysyrev config.yaml --stage review
|
|
79
|
+
python -m pysyrev config.yaml --stage bib-network
|
|
80
|
+
python -m pysyrev config.yaml --stage topic-model
|
|
81
|
+
python -m pysyrev config.yaml --stage topic-report
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
If installed via `setup.py`, the `pysyrev` command is also available directly:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
pysyrev config.yaml --stage topic-report
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Python API
|
|
91
|
+
|
|
92
|
+
```python
|
|
93
|
+
from pysyrev import Pipeline
|
|
94
|
+
|
|
95
|
+
# Full pipeline in one call — runs only the stages declared in the config
|
|
96
|
+
pipeline = Pipeline.from_config("config.yaml")
|
|
97
|
+
pipeline.run()
|
|
98
|
+
|
|
99
|
+
# Or stage by stage — results persist on the instance between calls
|
|
100
|
+
pipeline.run(stages=["bib"])
|
|
101
|
+
pipeline.run(stages=["review"]) # uses pipeline.bib.dataset automatically
|
|
102
|
+
pipeline.run(stages=["topic-report"]) # generates the PDF report
|
|
103
|
+
|
|
104
|
+
# Access results
|
|
105
|
+
df_all = pipeline.bib.dataset # pd.DataFrame — all collected documents
|
|
106
|
+
df_kept = pipeline.review.included_docs # pd.DataFrame — LLM-screened inclusions
|
|
107
|
+
network = pipeline.network # BibNetwork
|
|
108
|
+
topic = pipeline.topic # TopicModel
|
|
109
|
+
report = pipeline.report # TopicReport
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Report-only run
|
|
113
|
+
|
|
114
|
+
A config containing only the `topic_report` (and optionally `report` and `llm`) sections is valid. This lets you generate or regenerate a report from a previous topic-model run without re-running the full pipeline:
|
|
115
|
+
|
|
116
|
+
```yaml
|
|
117
|
+
# report_only.yaml
|
|
118
|
+
topic_report:
|
|
119
|
+
run_dir: /path/to/topic_modeling/run_2026-05-01T120000/ # or leave blank to auto-detect
|
|
120
|
+
model_index: 0
|
|
121
|
+
export_to: /path/to/output/report/
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
python -m pysyrev report_only.yaml
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## Configuration
|
|
131
|
+
|
|
132
|
+
A single YAML file controls all stages. Copy `pysyrev/config_examples/config_template.yaml` and fill in the sections you need. Sections not present in the file are simply skipped.
|
|
133
|
+
|
|
134
|
+
Key auto-detection rules (when fields are left blank):
|
|
135
|
+
|
|
136
|
+
| Blank field | Auto-detected from |
|
|
137
|
+
|---|---|
|
|
138
|
+
| `review.doc_dataset` | latest run in `bib.export.export_dir` |
|
|
139
|
+
| `bib_network.doc_dataset` | latest run in `review.export.export_dir` |
|
|
140
|
+
| `topic_model.doc_dataset` | latest run in `review.export.export_dir` |
|
|
141
|
+
| `topic_report.run_dir` | latest run in `topic_model.export.export_dir` |
|
|
142
|
+
| bib-network graphs in report | latest run in `bib_network.export.export_dir` |
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## Getting started
|
|
147
|
+
|
|
148
|
+
See the `tutorials/` folder for step-by-step Jupyter notebooks and annotated configuration examples covering each pipeline stage.
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
<div align="center">
|
|
155
|
+
<img src="docs/espace-dev-ird.png" alt="organizations" width="600"/>
|
|
156
|
+
</div>
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## Contributing
|
|
161
|
+
|
|
162
|
+
### Development and improvement
|
|
163
|
+
|
|
164
|
+
- Benjamin Pillot
|
|
165
|
+
- Théo Chamarande
|
|
166
|
+
- Kevin Chapuis
|
|
167
|
+
|
|
168
|
+
### Conceptualization and Coordination
|
|
169
|
+
|
|
170
|
+
- Benjamin Pillot
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
from pysyrev.pipeline import Pipeline, ALL_STAGES
|
|
2
|
+
from pysyrev.bibdata import BibDataset, WosDataset, OpenAlexDataset, ScopusDataset, PubmedDataset
|
|
3
|
+
from pysyrev.topic_model import TopicModel
|
|
4
|
+
from pysyrev.network import BibNetwork
|
|
5
|
+
from pysyrev.topic_report import TopicReport
|
|
6
|
+
from pysyrev.review import LLMReview, ReviewedDataset
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"""
|
|
2
|
+
pysyrev CLI — run the literature review pipeline from a YAML config.
|
|
3
|
+
|
|
4
|
+
Usage
|
|
5
|
+
-----
|
|
6
|
+
# Run all configured stages (only stages present in the config are executed)
|
|
7
|
+
python -m pysyrev config.yaml
|
|
8
|
+
|
|
9
|
+
# Individual stages
|
|
10
|
+
python -m pysyrev config.yaml --stage bib
|
|
11
|
+
python -m pysyrev config.yaml --stage review
|
|
12
|
+
python -m pysyrev config.yaml --stage bib-network
|
|
13
|
+
python -m pysyrev config.yaml --stage topic-model
|
|
14
|
+
python -m pysyrev config.yaml --stage topic-report
|
|
15
|
+
|
|
16
|
+
When running a single stage, the input dataset is read from the
|
|
17
|
+
``doc_dataset`` field of that stage's config section. If ``doc_dataset``
|
|
18
|
+
is left blank, Config.load falls back to auto-detecting the most recent
|
|
19
|
+
output of the previous stage (e.g. the latest ``reviewed_included.csv``
|
|
20
|
+
for bib-network / topic-model, or the latest topic_model run for
|
|
21
|
+
topic-report).
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
import argparse
|
|
25
|
+
|
|
26
|
+
from pysyrev import ALL_STAGES, Pipeline
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def _print_stage_result(stage, pipeline):
|
|
30
|
+
if stage == 'bib' and pipeline.bib is not None:
|
|
31
|
+
print(f"[bib] Done — {len(pipeline.bib.dataset)} documents.")
|
|
32
|
+
elif stage == 'review' and pipeline.review is not None:
|
|
33
|
+
print(f"[review] Done — {len(pipeline.review.included_docs)} documents included.")
|
|
34
|
+
elif stage == 'bib-network' and pipeline.network is not None:
|
|
35
|
+
net = pipeline.network
|
|
36
|
+
if pipeline.config.bib_network.export is not None:
|
|
37
|
+
print(
|
|
38
|
+
f"[bib-network] Done — coupling: {net.n_coupling_nodes} nodes / "
|
|
39
|
+
f"{net.n_coupling_edges} edges, "
|
|
40
|
+
f"co-citation: {net.n_cocitation_nodes} nodes / "
|
|
41
|
+
f"{net.n_cocitation_edges} edges."
|
|
42
|
+
)
|
|
43
|
+
else:
|
|
44
|
+
print("[bib-network] Done (no export configured).")
|
|
45
|
+
elif stage == 'topic-model':
|
|
46
|
+
print("[topic-model] Done.")
|
|
47
|
+
elif stage == 'topic-report' and pipeline.report is not None:
|
|
48
|
+
print(f"[topic-report] Done — report written to {pipeline.report.export_to}")
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def main():
|
|
52
|
+
parser = argparse.ArgumentParser(
|
|
53
|
+
prog='python -m pysyrev',
|
|
54
|
+
description='Systematic literature review pipeline.',
|
|
55
|
+
)
|
|
56
|
+
parser.add_argument('config', help='Path to the YAML pipeline config file.')
|
|
57
|
+
parser.add_argument(
|
|
58
|
+
'--stage',
|
|
59
|
+
choices=ALL_STAGES + ['all'],
|
|
60
|
+
default='all',
|
|
61
|
+
metavar='STAGE',
|
|
62
|
+
help=(
|
|
63
|
+
'Stage to run: bib | review | bib-network | topic-model | topic-report | all '
|
|
64
|
+
'(default: all — runs only the stages present in the config file).'
|
|
65
|
+
),
|
|
66
|
+
)
|
|
67
|
+
args = parser.parse_args()
|
|
68
|
+
|
|
69
|
+
pipeline = Pipeline.from_config(args.config)
|
|
70
|
+
|
|
71
|
+
if args.stage == 'all':
|
|
72
|
+
print("Starting pipeline…")
|
|
73
|
+
pipeline.run()
|
|
74
|
+
else:
|
|
75
|
+
print(f"[{args.stage}] Starting…")
|
|
76
|
+
pipeline.run(stages=[args.stage])
|
|
77
|
+
_print_stage_result(args.stage, pipeline)
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
if __name__ == '__main__':
|
|
81
|
+
main()
|