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.
Files changed (51) hide show
  1. pysyrev-0.1.0/LICENSE +21 -0
  2. pysyrev-0.1.0/PKG-INFO +222 -0
  3. pysyrev-0.1.0/README.md +170 -0
  4. pysyrev-0.1.0/pysyrev/__init__.py +6 -0
  5. pysyrev-0.1.0/pysyrev/__main__.py +81 -0
  6. pysyrev-0.1.0/pysyrev/bibdata.py +492 -0
  7. pysyrev-0.1.0/pysyrev/config_examples/config_abm.yaml +358 -0
  8. pysyrev-0.1.0/pysyrev/config_examples/config_justice.yaml +362 -0
  9. pysyrev-0.1.0/pysyrev/core/__init__.py +0 -0
  10. pysyrev-0.1.0/pysyrev/core/api/__init__.py +12 -0
  11. pysyrev-0.1.0/pysyrev/core/api/openalex_client.py +290 -0
  12. pysyrev-0.1.0/pysyrev/core/api/wos_client.py +267 -0
  13. pysyrev-0.1.0/pysyrev/core/berteley/__init__.py +10 -0
  14. pysyrev-0.1.0/pysyrev/core/berteley/berteley_stopwords.csv +67 -0
  15. pysyrev-0.1.0/pysyrev/core/berteley/models.py +163 -0
  16. pysyrev-0.1.0/pysyrev/core/berteley/preprocessing.py +151 -0
  17. pysyrev-0.1.0/pysyrev/core/bib.py +313 -0
  18. pysyrev-0.1.0/pysyrev/core/clean.py +234 -0
  19. pysyrev-0.1.0/pysyrev/core/config.py +794 -0
  20. pysyrev-0.1.0/pysyrev/core/llm.py +674 -0
  21. pysyrev-0.1.0/pysyrev/core/mappers.py +240 -0
  22. pysyrev-0.1.0/pysyrev/core/merge_bibs.py +256 -0
  23. pysyrev-0.1.0/pysyrev/core/network.py +162 -0
  24. pysyrev-0.1.0/pysyrev/core/parsers/__init__.py +5 -0
  25. pysyrev-0.1.0/pysyrev/core/parsers/read_bib.py +740 -0
  26. pysyrev-0.1.0/pysyrev/core/references.py +340 -0
  27. pysyrev-0.1.0/pysyrev/core/report.py +593 -0
  28. pysyrev-0.1.0/pysyrev/core/report_data.py +972 -0
  29. pysyrev-0.1.0/pysyrev/core/topic.py +268 -0
  30. pysyrev-0.1.0/pysyrev/network.py +210 -0
  31. pysyrev-0.1.0/pysyrev/pipeline.py +136 -0
  32. pysyrev-0.1.0/pysyrev/review.py +164 -0
  33. pysyrev-0.1.0/pysyrev/templates/config.yaml +374 -0
  34. pysyrev-0.1.0/pysyrev/topic_model.py +260 -0
  35. pysyrev-0.1.0/pysyrev/topic_report.py +162 -0
  36. pysyrev-0.1.0/pysyrev.egg-info/PKG-INFO +222 -0
  37. pysyrev-0.1.0/pysyrev.egg-info/SOURCES.txt +49 -0
  38. pysyrev-0.1.0/pysyrev.egg-info/dependency_links.txt +1 -0
  39. pysyrev-0.1.0/pysyrev.egg-info/entry_points.txt +2 -0
  40. pysyrev-0.1.0/pysyrev.egg-info/requires.txt +26 -0
  41. pysyrev-0.1.0/pysyrev.egg-info/top_level.txt +2 -0
  42. pysyrev-0.1.0/setup.cfg +4 -0
  43. pysyrev-0.1.0/setup.py +63 -0
  44. pysyrev-0.1.0/tests/__init__.py +0 -0
  45. pysyrev-0.1.0/tests/conftest.py +280 -0
  46. pysyrev-0.1.0/tests/test_berteley_models.py +115 -0
  47. pysyrev-0.1.0/tests/test_berteley_preprocessing.py +223 -0
  48. pysyrev-0.1.0/tests/test_cli.py +121 -0
  49. pysyrev-0.1.0/tests/test_pipeline_integration.py +250 -0
  50. pysyrev-0.1.0/tests/test_report.py +280 -0
  51. 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
+ [![tests](https://github.com/benjaminpillot/pysyrev/actions/workflows/tests.yml/badge.svg)](https://github.com/benjaminpillot/pysyrev/actions/workflows/tests.yml)
60
+ [![docs](https://readthedocs.org/projects/pysyrev/badge/?version=latest)](https://pysyrev.readthedocs.io/en/latest/)
61
+ [![license](https://img.shields.io/badge/license-MIT-blue)](LICENSE)
62
+ [![python](https://img.shields.io/badge/python-≥3.10-blue)](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
@@ -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
+ [![tests](https://github.com/benjaminpillot/pysyrev/actions/workflows/tests.yml/badge.svg)](https://github.com/benjaminpillot/pysyrev/actions/workflows/tests.yml)
8
+ [![docs](https://readthedocs.org/projects/pysyrev/badge/?version=latest)](https://pysyrev.readthedocs.io/en/latest/)
9
+ [![license](https://img.shields.io/badge/license-MIT-blue)](LICENSE)
10
+ [![python](https://img.shields.io/badge/python-≥3.10-blue)](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()