moseslukeprismagraphpy 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.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Moses Luke
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,150 @@
1
+ Metadata-Version: 2.4
2
+ Name: moseslukeprismagraphpy
3
+ Version: 0.1.0
4
+ Summary: Create PRISMA 2020 systematic review flow diagrams in Python (PNG, SVG, PDF and interactive HTML).
5
+ Author: Moses Luke
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/Moses-L/prismaflow
8
+ Project-URL: Issues, https://github.com/Moses-L/prismaflow/issues
9
+ Keywords: PRISMA,PRISMA 2020,systematic review,meta-analysis,flow diagram,evidence synthesis
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3.10
12
+ Classifier: Programming Language :: Python :: 3.11
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Classifier: Programming Language :: Python :: 3.13
15
+ Classifier: Intended Audience :: Science/Research
16
+ Classifier: Topic :: Scientific/Engineering :: Medical Science Apps.
17
+ Requires-Python: >=3.10
18
+ Description-Content-Type: text/markdown
19
+ License-File: LICENSE
20
+ Requires-Dist: graphviz>=0.20
21
+ Provides-Extra: dev
22
+ Requires-Dist: pytest>=7; extra == "dev"
23
+ Dynamic: license-file
24
+
25
+ # moseslukeprismagraphpy
26
+
27
+ Create **PRISMA 2020** systematic review flow diagrams in Python. Give it your screening counts (in code or a CSV) and it produces a publication-ready diagram as PNG, SVG or PDF, plus an **interactive HTML** version in which readers can hover for tooltips and click boxes to open supporting files.
28
+
29
+ It is built on Graphviz, so it runs in scripts, notebooks and CI pipelines without a browser.
30
+
31
+ `pip install moseslukeprismagraphpy`, then `import moseslukeprismagraphpy` in Python or run the `prismagraph` command in a terminal. The source lives in the GitHub repository `Moses-L/prismaflow`.
32
+
33
+ ## Why this exists
34
+
35
+ The [PRISMA2020 R package and Shiny app](https://doi.org/10.1002/cl2.1230) (Haddaway et al., 2022) made PRISMA 2020 diagrams easy for R users. `moseslukeprismagraphpy` offers the same kind of workflow for Python users. It is an independent reimplementation, not a port of that code, and it is not affiliated with the PRISMA group or the R package authors. Please also cite the original tool and the PRISMA 2020 statement if they informed your work (see [Citing](#citing)).
36
+
37
+ ## Features
38
+
39
+ - PRISMA 2020 layout for new reviews, with optional **previous studies** and **other methods** (websites, organisations, citation searching) arms
40
+ - Downstream numbers (screened, sought, assessed, included totals) are calculated for you, and impossible counts raise a clear error
41
+ - Warns when the number of included reports does not match your assessed and excluded counts
42
+ - CSV template so counts can be shared, versioned and re-run
43
+ - Outputs: PNG, SVG, PDF, interactive HTML, Graphviz DOT
44
+ - Command-line tool and Python API
45
+
46
+ ## Install
47
+
48
+ ```bash
49
+ pip install moseslukeprismagraphpy
50
+ ```
51
+
52
+ `moseslukeprismagraphpy` needs the Graphviz program (not only the Python wrapper):
53
+
54
+ | System | Command |
55
+ |---|---|
56
+ | Ubuntu / Debian | `sudo apt install graphviz` |
57
+ | macOS | `brew install graphviz` |
58
+ | Windows | Installer from [graphviz.org/download](https://graphviz.org/download/); tick the option to add Graphviz to PATH, then restart the terminal |
59
+ | conda | `conda install -c conda-forge graphviz` |
60
+
61
+ Until it is on PyPI, install from source: `pip install git+https://github.com/Moses-L/prismaflow`.
62
+
63
+ ## Example output
64
+
65
+ ![Example PRISMA 2020 diagram with previous and other-methods arms](examples/example_full.png)
66
+
67
+ ## Quick start
68
+
69
+ ### From the command line
70
+
71
+ ```bash
72
+ prismagraph template -o my_review.csv # blank template
73
+ # fill in the n column, then:
74
+ prismagraph draw my_review.csv -o figures/prisma -f png svg html
75
+ prismagraph draw --example -o demo -f png # built-in worked example
76
+ ```
77
+
78
+ ### From Python
79
+
80
+ ```python
81
+ from moseslukeprismagraphpy import PrismaData, render
82
+
83
+ data = PrismaData(
84
+ counts={
85
+ "identified_databases": 1200,
86
+ "identified_registers": 40,
87
+ "duplicates": 250,
88
+ "excluded_automatic": 10,
89
+ "excluded_screening": 900,
90
+ "not_retrieved": 5,
91
+ "new_studies": 40,
92
+ "new_reports": 47,
93
+ },
94
+ reasons_db={"Wrong population": 20, "No outcome of interest": 25, "Wrong design": 15},
95
+ urls={"identified_databases": "https://osf.io/your-search-strategy"},
96
+ tooltips={"identified_databases": "PubMed, Embase, CENTRAL; searched 1 Nov 2026"},
97
+ )
98
+ print(data.validate()) # list of warnings; raises on impossible counts
99
+ render(data, "figures/prisma", formats=["png", "svg", "html"])
100
+ ```
101
+
102
+ ## CSV format
103
+
104
+ Columns: `data, label, n, url, tooltip` (extra columns such as `notes` are ignored).
105
+
106
+ | `data` value | Meaning |
107
+ |---|---|
108
+ | `identified_databases`, `identified_registers` | Records identified |
109
+ | `duplicates`, `excluded_automatic`, `excluded_other` | Records removed before screening |
110
+ | `excluded_screening` | Records excluded at title/abstract |
111
+ | `not_retrieved` | Reports not retrieved |
112
+ | `reason_db` | One row per full-text exclusion reason: put the reason in `label` and the count in `n` |
113
+ | `new_studies`, `new_reports` | Studies and reports included |
114
+ | `previous_studies`, `previous_reports` | Turns on the previous-version arm |
115
+ | `other_websites`, `other_organisations`, `other_citation_searching` | Turns on the other-methods arm |
116
+ | `other_sought`, `other_not_retrieved`, `reason_other` | Other-methods retrieval and exclusions |
117
+ | `screened`, `sought`, `assessed`, `excluded_fulltext`, `other_assessed`, `other_excluded`, `total_studies` | Calculated boxes: leave `n` empty and use only `url` and `tooltip` |
118
+
119
+ ## Interactive HTML
120
+
121
+ Add a `url` and/or `tooltip` to any row. In the HTML output, hovering shows the tooltip and clicking opens the link. SVG and PDF keep the links too; PNG does not. Link to your own protocols, search strategies or lists of DOIs. Avoid linking to exported database records or abstracts, because database terms of use and copyright may not allow sharing them.
122
+
123
+ ## Limitations
124
+
125
+ - Phase labels ("Identification", "Screening", "Included") are horizontal boxes, not the rotated side banners of the official template.
126
+ - Layout is automatic. Very long exclusion-reason lists make wide boxes, so keep reason text short.
127
+ - Only the new-review templates with previous and other-methods arms are implemented. Please open an issue if you need something else.
128
+
129
+ ## Examples
130
+
131
+ The `examples/` folder has a filled-in `example.csv`, a blank `template.csv`, and the matching PNG, SVG and interactive HTML output.
132
+
133
+ ## Development
134
+
135
+ ```bash
136
+ git clone https://github.com/Moses-L/prismaflow && cd prismaflow
137
+ pip install -e ".[dev]"
138
+ pytest
139
+ ```
140
+
141
+ ## Citing
142
+
143
+ If you use `moseslukeprismagraphpy`, please cite this software (see `CITATION.cff`) and the PRISMA 2020 statement:
144
+
145
+ - Page MJ, McKenzie JE, Bossuyt PM, et al. The PRISMA 2020 statement: an updated guideline for reporting systematic reviews. *BMJ* 2021;372:n71. https://doi.org/10.1136/bmj.n71
146
+ - Haddaway NR, Page MJ, Pritchard CC, McGuinness LA. PRISMA2020: An R package and Shiny app for producing PRISMA 2020-compliant flow diagrams, with interactivity for optimised digital transparency and Open Synthesis. *Campbell Systematic Reviews* 2022;18:e1230. https://doi.org/10.1002/cl2.1230
147
+
148
+ ## Licence
149
+
150
+ MIT. See `LICENSE`.
@@ -0,0 +1,126 @@
1
+ # moseslukeprismagraphpy
2
+
3
+ Create **PRISMA 2020** systematic review flow diagrams in Python. Give it your screening counts (in code or a CSV) and it produces a publication-ready diagram as PNG, SVG or PDF, plus an **interactive HTML** version in which readers can hover for tooltips and click boxes to open supporting files.
4
+
5
+ It is built on Graphviz, so it runs in scripts, notebooks and CI pipelines without a browser.
6
+
7
+ `pip install moseslukeprismagraphpy`, then `import moseslukeprismagraphpy` in Python or run the `prismagraph` command in a terminal. The source lives in the GitHub repository `Moses-L/prismaflow`.
8
+
9
+ ## Why this exists
10
+
11
+ The [PRISMA2020 R package and Shiny app](https://doi.org/10.1002/cl2.1230) (Haddaway et al., 2022) made PRISMA 2020 diagrams easy for R users. `moseslukeprismagraphpy` offers the same kind of workflow for Python users. It is an independent reimplementation, not a port of that code, and it is not affiliated with the PRISMA group or the R package authors. Please also cite the original tool and the PRISMA 2020 statement if they informed your work (see [Citing](#citing)).
12
+
13
+ ## Features
14
+
15
+ - PRISMA 2020 layout for new reviews, with optional **previous studies** and **other methods** (websites, organisations, citation searching) arms
16
+ - Downstream numbers (screened, sought, assessed, included totals) are calculated for you, and impossible counts raise a clear error
17
+ - Warns when the number of included reports does not match your assessed and excluded counts
18
+ - CSV template so counts can be shared, versioned and re-run
19
+ - Outputs: PNG, SVG, PDF, interactive HTML, Graphviz DOT
20
+ - Command-line tool and Python API
21
+
22
+ ## Install
23
+
24
+ ```bash
25
+ pip install moseslukeprismagraphpy
26
+ ```
27
+
28
+ `moseslukeprismagraphpy` needs the Graphviz program (not only the Python wrapper):
29
+
30
+ | System | Command |
31
+ |---|---|
32
+ | Ubuntu / Debian | `sudo apt install graphviz` |
33
+ | macOS | `brew install graphviz` |
34
+ | Windows | Installer from [graphviz.org/download](https://graphviz.org/download/); tick the option to add Graphviz to PATH, then restart the terminal |
35
+ | conda | `conda install -c conda-forge graphviz` |
36
+
37
+ Until it is on PyPI, install from source: `pip install git+https://github.com/Moses-L/prismaflow`.
38
+
39
+ ## Example output
40
+
41
+ ![Example PRISMA 2020 diagram with previous and other-methods arms](examples/example_full.png)
42
+
43
+ ## Quick start
44
+
45
+ ### From the command line
46
+
47
+ ```bash
48
+ prismagraph template -o my_review.csv # blank template
49
+ # fill in the n column, then:
50
+ prismagraph draw my_review.csv -o figures/prisma -f png svg html
51
+ prismagraph draw --example -o demo -f png # built-in worked example
52
+ ```
53
+
54
+ ### From Python
55
+
56
+ ```python
57
+ from moseslukeprismagraphpy import PrismaData, render
58
+
59
+ data = PrismaData(
60
+ counts={
61
+ "identified_databases": 1200,
62
+ "identified_registers": 40,
63
+ "duplicates": 250,
64
+ "excluded_automatic": 10,
65
+ "excluded_screening": 900,
66
+ "not_retrieved": 5,
67
+ "new_studies": 40,
68
+ "new_reports": 47,
69
+ },
70
+ reasons_db={"Wrong population": 20, "No outcome of interest": 25, "Wrong design": 15},
71
+ urls={"identified_databases": "https://osf.io/your-search-strategy"},
72
+ tooltips={"identified_databases": "PubMed, Embase, CENTRAL; searched 1 Nov 2026"},
73
+ )
74
+ print(data.validate()) # list of warnings; raises on impossible counts
75
+ render(data, "figures/prisma", formats=["png", "svg", "html"])
76
+ ```
77
+
78
+ ## CSV format
79
+
80
+ Columns: `data, label, n, url, tooltip` (extra columns such as `notes` are ignored).
81
+
82
+ | `data` value | Meaning |
83
+ |---|---|
84
+ | `identified_databases`, `identified_registers` | Records identified |
85
+ | `duplicates`, `excluded_automatic`, `excluded_other` | Records removed before screening |
86
+ | `excluded_screening` | Records excluded at title/abstract |
87
+ | `not_retrieved` | Reports not retrieved |
88
+ | `reason_db` | One row per full-text exclusion reason: put the reason in `label` and the count in `n` |
89
+ | `new_studies`, `new_reports` | Studies and reports included |
90
+ | `previous_studies`, `previous_reports` | Turns on the previous-version arm |
91
+ | `other_websites`, `other_organisations`, `other_citation_searching` | Turns on the other-methods arm |
92
+ | `other_sought`, `other_not_retrieved`, `reason_other` | Other-methods retrieval and exclusions |
93
+ | `screened`, `sought`, `assessed`, `excluded_fulltext`, `other_assessed`, `other_excluded`, `total_studies` | Calculated boxes: leave `n` empty and use only `url` and `tooltip` |
94
+
95
+ ## Interactive HTML
96
+
97
+ Add a `url` and/or `tooltip` to any row. In the HTML output, hovering shows the tooltip and clicking opens the link. SVG and PDF keep the links too; PNG does not. Link to your own protocols, search strategies or lists of DOIs. Avoid linking to exported database records or abstracts, because database terms of use and copyright may not allow sharing them.
98
+
99
+ ## Limitations
100
+
101
+ - Phase labels ("Identification", "Screening", "Included") are horizontal boxes, not the rotated side banners of the official template.
102
+ - Layout is automatic. Very long exclusion-reason lists make wide boxes, so keep reason text short.
103
+ - Only the new-review templates with previous and other-methods arms are implemented. Please open an issue if you need something else.
104
+
105
+ ## Examples
106
+
107
+ The `examples/` folder has a filled-in `example.csv`, a blank `template.csv`, and the matching PNG, SVG and interactive HTML output.
108
+
109
+ ## Development
110
+
111
+ ```bash
112
+ git clone https://github.com/Moses-L/prismaflow && cd prismaflow
113
+ pip install -e ".[dev]"
114
+ pytest
115
+ ```
116
+
117
+ ## Citing
118
+
119
+ If you use `moseslukeprismagraphpy`, please cite this software (see `CITATION.cff`) and the PRISMA 2020 statement:
120
+
121
+ - Page MJ, McKenzie JE, Bossuyt PM, et al. The PRISMA 2020 statement: an updated guideline for reporting systematic reviews. *BMJ* 2021;372:n71. https://doi.org/10.1136/bmj.n71
122
+ - Haddaway NR, Page MJ, Pritchard CC, McGuinness LA. PRISMA2020: An R package and Shiny app for producing PRISMA 2020-compliant flow diagrams, with interactivity for optimised digital transparency and Open Synthesis. *Campbell Systematic Reviews* 2022;18:e1230. https://doi.org/10.1002/cl2.1230
123
+
124
+ ## Licence
125
+
126
+ MIT. See `LICENSE`.
@@ -0,0 +1,40 @@
1
+ [build-system]
2
+ requires = ["setuptools>=77"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "moseslukeprismagraphpy"
7
+ version = "0.1.0"
8
+ description = "Create PRISMA 2020 systematic review flow diagrams in Python (PNG, SVG, PDF and interactive HTML)."
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ license = "MIT"
12
+ license-files = ["LICENSE"]
13
+ authors = [{ name = "Moses Luke" }]
14
+ keywords = ["PRISMA", "PRISMA 2020", "systematic review", "meta-analysis", "flow diagram", "evidence synthesis"]
15
+ classifiers = [
16
+ "Programming Language :: Python :: 3",
17
+ "Programming Language :: Python :: 3.10",
18
+ "Programming Language :: Python :: 3.11",
19
+ "Programming Language :: Python :: 3.12",
20
+ "Programming Language :: Python :: 3.13",
21
+ "Intended Audience :: Science/Research",
22
+ "Topic :: Scientific/Engineering :: Medical Science Apps.",
23
+ ]
24
+ dependencies = ["graphviz>=0.20"]
25
+
26
+ [project.optional-dependencies]
27
+ dev = ["pytest>=7"]
28
+
29
+ [project.scripts]
30
+ prismagraph = "moseslukeprismagraphpy.cli:main"
31
+
32
+ [project.urls]
33
+ Homepage = "https://github.com/Moses-L/prismaflow"
34
+ Issues = "https://github.com/Moses-L/prismaflow/issues"
35
+
36
+ [tool.setuptools.packages.find]
37
+ where = ["src"]
38
+
39
+ [tool.pytest.ini_options]
40
+ testpaths = ["tests"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,7 @@
1
+ """moseslukeprismagraphpy: PRISMA 2020 flow diagrams in Python."""
2
+
3
+ from .data import PrismaData, example_data
4
+ from .render import build_graph, render, to_html, to_svg
5
+
6
+ __version__ = "0.1.0"
7
+ __all__ = ["PrismaData", "example_data", "build_graph", "render", "to_html", "to_svg", "__version__"]
@@ -0,0 +1,54 @@
1
+ """Command-line interface: ``prismagraph template`` and ``prismagraph draw``."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import argparse
6
+ import sys
7
+
8
+ from . import __version__
9
+ from .data import PrismaData, example_data
10
+ from .render import ALL_FORMATS, render
11
+
12
+
13
+ def main(argv=None) -> int:
14
+ p = argparse.ArgumentParser(prog="prismagraph", description="PRISMA 2020 flow diagrams from a CSV.")
15
+ p.add_argument("--version", action="version", version=f"prismagraph {__version__}")
16
+ sub = p.add_subparsers(dest="cmd", required=True)
17
+
18
+ t = sub.add_parser("template", help="write a blank CSV template")
19
+ t.add_argument("-o", "--output", default="prisma_template.csv")
20
+
21
+ d = sub.add_parser("draw", help="draw a diagram from a filled-in CSV")
22
+ d.add_argument("csv", nargs="?", help="input CSV (omit with --example)")
23
+ d.add_argument("-o", "--output", default="prisma_flow", help="output path stem (default: prisma_flow)")
24
+ d.add_argument("-f", "--format", nargs="+", default=["png"], choices=ALL_FORMATS, help="one or more formats")
25
+ d.add_argument("--dpi", type=int, default=300, help="PNG resolution (default 300)")
26
+ d.add_argument("--title", default=None)
27
+ d.add_argument("--example", action="store_true", help="draw the built-in worked example")
28
+
29
+ args = p.parse_args(argv)
30
+
31
+ if args.cmd == "template":
32
+ PrismaData.write_template(args.output)
33
+ print(f"Wrote {args.output}")
34
+ return 0
35
+
36
+ if not args.example and not args.csv:
37
+ d.error("provide a CSV file or use --example")
38
+ try:
39
+ data = example_data() if args.example else PrismaData.from_csv(args.csv)
40
+ for w in data.validate():
41
+ print(f"warning: {w}", file=sys.stderr)
42
+ for path in render(data, args.output, args.format, dpi=args.dpi, title=args.title):
43
+ print(f"Wrote {path}")
44
+ except FileNotFoundError as exc:
45
+ print(f"error: file not found: {exc.filename}", file=sys.stderr)
46
+ return 1
47
+ except (ValueError, RuntimeError) as exc:
48
+ print(f"error: {exc}", file=sys.stderr)
49
+ return 1
50
+ return 0
51
+
52
+
53
+ if __name__ == "__main__":
54
+ sys.exit(main())