risforge
Clean, deduplicate, and enrich RIS bibliographic files for systematic reviews.
risforge transforms messy, overlapping .ris exports from Scopus, PubMed, Web of Science, or EndNote into a single, clean, and metadata-rich file ready for screening.
How it works
| Stage | What it does | What it doesn't do |
|---|---|---|
| Merge | Combines multiple .ris files into one. |
Decide if records are duplicates. |
| Clean | Deduplicates via DOI and fuzzy title/author matching. Zero data loss. | Fetch new data from the internet. |
| Enrich | Fills missing metadata (abstracts, PDFs, keywords) via Crossref, OpenAlex, Semantic Scholar, and Unpaywall. | Overwrite your existing data. |
Features
- Smart Deduplication: DOI-first clustering with a normalized title + first-author fallback.
- Zero Data Loss: Merges duplicate clusters by keeping the most complete record and appending missing fields from others.
- Non-Destructive Enrichment: Only fills empty fields; existing metadata is never overwritten.
- Resilient HTTP: Automatic retries, exponential backoff, and a 7-day on-disk cache.
- Flexible Interfaces: Use it as a Python library, a CLI tool, or a cross-platform desktop GUI.
Installation
Requires Python 3.10+.
# Core library and CLI
pip install risforge
# With the optional desktop GUI
pip install "risforge[gui]"
Quick Start
Desktop GUI
Launch the graphical interface for a drag-and-drop workflow:
risforge-gui
Command Line
Run the full pipeline (merge, clean, and enrich) in a single command:
risforge pipeline scopus.ris pubmed.ris wos.ris \
--email you@example.com \
--output final.ris
Note: An email is required for API "polite pool" access. It is only sent in request headers and never stored.
Run individual steps if you need to inspect intermediate files:
risforge merge scopus.ris pubmed.ris wos.ris merged.ris
risforge clean merged.ris clean.ris
risforge enrich clean.ris enriched.ris --email you@example.com
Python API
from risforge import risforge
# Automatically merges multiple files, cleans, and enriches
result = risforge(
input_paths=["scopus.ris", "pubmed.ris", "wos.ris"],
dedup_path="clean.ris",
enriched_path="enriched.ris",
email="you@example.com",
)
print(f"Merged: {result.merged_record_count}")
print(f"Unique: {result.cleaned_record_count}")
print(f"Enriched: {result.enrichment_stats['enriched']}")
Good to Know
- Unresolved DOIs: Records without a DOI that fail title-matching are left unmodified and logged to
failed_records.json. - Merge vs. Clean:
mergesimply concatenates files. Runcleanafterward to actually collapse duplicates. - Caching: API responses are cached for 7 days. Re-running the pipeline on the same data is nearly instant.
Contributing
- Clone and install dev dependencies:
pip install -e ".[dev,gui]" - Run tests:
pytest - Open a PR. Please include tests for behavioral changes and update
CHANGELOG.md. Predictability is a core feature; silent behavior changes are treated as bugs.
License
MIT — see LICENSE.
Metadata
Release files for risforge 0.4.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| risforge-0.4.0.tar.gz | 38.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| risforge-0.4.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 73.9 kB
Release files / risforge-0.4.0.tar.gz
| Download URL | risforge-0.4.0.tar.gz |
|---|---|
| Size | 38.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
8f32ebbacd822dd4827dd417e355e3499173692a87b10ec21be732d13963f3bb
|
|
BLAKE2b-256 checksum How to use checksums |
dd7408104ceef3c213e627f96e649e3c0b03ec52885557e468d815f31628682e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 25, 2026.
Transparency logRelease files / risforge-0.4.0-py3-none-any.whl
| Download URL | risforge-0.4.0-py3-none-any.whl |
|---|---|
| Size | 35.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
08905a25c41666fa915439b0ee8fb7e9bf17727ce3ed38dde93ad923640740cb
|
|
BLAKE2b-256 checksum How to use checksums |
e5836e0c99fa5122d60794d552a49368d2f951a018bf8ef74ee6b1fb82c4a4b2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 25, 2026.
Transparency log