pyvis-optimized 4.3.1__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.
- pyvis_optimized-4.3.1/CHANGELOG.md +338 -0
- pyvis_optimized-4.3.1/LICENSE_BSD.txt +27 -0
- pyvis_optimized-4.3.1/MANIFEST.in +26 -0
- pyvis_optimized-4.3.1/PKG-INFO +269 -0
- pyvis_optimized-4.3.1/README.md +216 -0
- pyvis_optimized-4.3.1/examples/edge_attribute_editing_example.py +52 -0
- pyvis_optimized-4.3.1/examples/shiny_demo.py +1096 -0
- pyvis_optimized-4.3.1/examples/shiny_editor_demo.py +592 -0
- pyvis_optimized-4.3.1/examples/shiny_simple_demo.py +85 -0
- pyvis_optimized-4.3.1/notebooks/01_basics.ipynb +198 -0
- pyvis_optimized-4.3.1/notebooks/02_networkx.ipynb +208 -0
- pyvis_optimized-4.3.1/notebooks/03_typed_options.ipynb +399 -0
- pyvis_optimized-4.3.1/notebooks/04_advanced.ipynb +230 -0
- pyvis_optimized-4.3.1/notebooks/NetworkOfThrones.csv +354 -0
- pyvis_optimized-4.3.1/notebooks/test.dot +9 -0
- pyvis_optimized-4.3.1/pyproject.toml +143 -0
- pyvis_optimized-4.3.1/pyvis/__init__.py +2 -0
- pyvis_optimized-4.3.1/pyvis/_version.py +1 -0
- pyvis_optimized-4.3.1/pyvis/edge.py +26 -0
- pyvis_optimized-4.3.1/pyvis/network.py +1498 -0
- pyvis_optimized-4.3.1/pyvis/node.py +35 -0
- pyvis_optimized-4.3.1/pyvis/shiny/__init__.py +213 -0
- pyvis_optimized-4.3.1/pyvis/shiny/bindings.js +1310 -0
- pyvis_optimized-4.3.1/pyvis/shiny/styles.css +382 -0
- pyvis_optimized-4.3.1/pyvis/shiny/wrapper.py +1368 -0
- pyvis_optimized-4.3.1/pyvis/templates/lib/bindings/utils.js +189 -0
- pyvis_optimized-4.3.1/pyvis/templates/lib/tom-select/tom-select.complete.min.js +5021 -0
- pyvis_optimized-4.3.1/pyvis/templates/lib/tom-select/tom-select.css +2 -0
- pyvis_optimized-4.3.1/pyvis/templates/lib/vis-10.0.2/vis-network.min.css +2 -0
- pyvis_optimized-4.3.1/pyvis/templates/lib/vis-10.0.2/vis-network.min.js +78 -0
- pyvis_optimized-4.3.1/pyvis/templates/template.html +911 -0
- pyvis_optimized-4.3.1/pyvis/types/__init__.py +59 -0
- pyvis_optimized-4.3.1/pyvis/types/base.py +109 -0
- pyvis_optimized-4.3.1/pyvis/types/common.py +74 -0
- pyvis_optimized-4.3.1/pyvis/types/configure.py +13 -0
- pyvis_optimized-4.3.1/pyvis/types/edges.py +139 -0
- pyvis_optimized-4.3.1/pyvis/types/interaction.py +42 -0
- pyvis_optimized-4.3.1/pyvis/types/layout.py +34 -0
- pyvis_optimized-4.3.1/pyvis/types/manipulation.py +18 -0
- pyvis_optimized-4.3.1/pyvis/types/network.py +34 -0
- pyvis_optimized-4.3.1/pyvis/types/nodes.py +158 -0
- pyvis_optimized-4.3.1/pyvis/types/physics.py +90 -0
- pyvis_optimized-4.3.1/pyvis/utils.py +26 -0
- pyvis_optimized-4.3.1/pyvis/vis_config.py +24 -0
- pyvis_optimized-4.3.1/pyvis_optimized.egg-info/PKG-INFO +269 -0
- pyvis_optimized-4.3.1/pyvis_optimized.egg-info/SOURCES.txt +48 -0
- pyvis_optimized-4.3.1/pyvis_optimized.egg-info/dependency_links.txt +1 -0
- pyvis_optimized-4.3.1/pyvis_optimized.egg-info/requires.txt +27 -0
- pyvis_optimized-4.3.1/pyvis_optimized.egg-info/top_level.txt +1 -0
- pyvis_optimized-4.3.1/setup.cfg +4 -0
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are documented in this file.
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
## [4.3.1] - 2026-09-06
|
|
8
|
+
|
|
9
|
+
Packaging-only release. 4.3.0 was tagged but never published: both publish
|
|
10
|
+
jobs failed, so no artifact for it exists on PyPI or anaconda.org. Everything
|
|
11
|
+
described under 4.3.0 below ships here instead.
|
|
12
|
+
|
|
13
|
+
### Breaking Changes
|
|
14
|
+
- **The PyPI distribution is now `pyvis-optimized`.** The `pyvis` name on PyPI
|
|
15
|
+
belongs to the upstream WestHealth project, which this fork cannot publish
|
|
16
|
+
under. Install with `pip install pyvis-optimized` (and
|
|
17
|
+
`pyvis-optimized[shiny]`, `[notebook]`, `[dev]`, `[test]`, `[all]` for the
|
|
18
|
+
extras). **The import package is unchanged** — `from pyvis.network import
|
|
19
|
+
Network` still works, so no code changes are needed. The conda package on
|
|
20
|
+
anaconda.org keeps its existing name, `razinka/pyvis`.
|
|
21
|
+
|
|
22
|
+
### Fixed
|
|
23
|
+
- The conda release job failed with `conda: error: argument COMMAND: invalid
|
|
24
|
+
choice: 'build'` on conda 26, which dispatches `conda build` through a
|
|
25
|
+
plugin that is not reliably registered in the session that installs it. The
|
|
26
|
+
workflow now calls the `conda-build` entry point directly and verifies the
|
|
27
|
+
built artifact exists before uploading.
|
|
28
|
+
|
|
29
|
+
## [4.3.0] - 2026-09-06
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
### Security
|
|
33
|
+
- pass font_color to template and validate against CSS injection
|
|
34
|
+
|
|
35
|
+
### Fixed
|
|
36
|
+
- preserve per-node font_color through from_nx
|
|
37
|
+
- validate every Literal field, correct font align and arrow type sets
|
|
38
|
+
- release listeners and registry entries when a network output is cleared or removed
|
|
39
|
+
- null args, command queueing, container sizing, config fallback and configChange
|
|
40
|
+
- keep numeric node ids intact in updateData, search restore and edge editing
|
|
41
|
+
- drop unsupported cluster() and omit absent arguments instead of sending null
|
|
42
|
+
- correct update_data and package docstrings, pin the output config attribute
|
|
43
|
+
- resolve module namespaces for controller and standalone network commands
|
|
44
|
+
- apply module physics toggle on a copy and only when the control is rendered
|
|
45
|
+
- build module networks from the documented dict spec
|
|
46
|
+
- drop dead configure plumbing and repair the edge editing example
|
|
47
|
+
- isolate get_network_json, harden edge keys and from_nx, correct docstrings
|
|
48
|
+
- copy local lib resources beside the HTML file and refresh stale copies
|
|
49
|
+
- detect cycles and validate dict keys in from_nx numpy coercion
|
|
50
|
+
- recurse into lists/dicts when coercing numpy scalars in from_nx
|
|
51
|
+
- accept plain dict options in add_node/add_edge and apply font_color on the typed path
|
|
52
|
+
- coerce numpy scalars in from_nx instead of dropping attributes
|
|
53
|
+
- load the notebook template lazily in generate_html
|
|
54
|
+
- render when physics is a bool or a node title is not a string
|
|
55
|
+
- parameterize collection types, constrain Literal fields, add type guard tests, fix layout doctype
|
|
56
|
+
- CI subshell bug, duplicate tests, float string conversion, addEventListener, legend validation, renames cache, recipe guards
|
|
57
|
+
- add error context to write_html file operations
|
|
58
|
+
- use package version for HTMLDependency, remove self.html state, improve layout param
|
|
59
|
+
- warn on non-serializable NX attributes, fix animation_template CDN URLs
|
|
60
|
+
- use 3-component semver, add parse_version error handling and subprocess timeouts
|
|
61
|
+
- add missing params to get_network_json, merge font_color, warn on stripped keys
|
|
62
|
+
- use options= path for typed add_nodes, warn on duplicate nodes
|
|
63
|
+
- validate highlight_degree type and escape template CSS injections
|
|
64
|
+
- handle legacy font_color=False as None in validation
|
|
65
|
+
- improve auto_version.py error handling and encoding
|
|
66
|
+
- **Core rendering:** `from_nx()` now detects cycles and coerces numpy scalars
|
|
67
|
+
recursively inside nested lists/dicts instead of silently dropping attributes;
|
|
68
|
+
edge keys and dict-based `add_node()`/`add_edge()` options are validated and
|
|
69
|
+
applied correctly (including `font_color` on the typed path).
|
|
70
|
+
- **Core rendering:** a per-node `font_color` attribute on a networkx graph now
|
|
71
|
+
survives `from_nx()` instead of being silently discarded, and
|
|
72
|
+
`add_node(..., font_color=...)` is accepted as a per-node override of the
|
|
73
|
+
network-wide `Network(font_color=...)` (it previously raised
|
|
74
|
+
`TypeError: got multiple values for keyword argument 'font_color'`).
|
|
75
|
+
- **Core rendering:** `get_network_json()` is isolated from caller mutation;
|
|
76
|
+
`generate_html()` loads the notebook template lazily; nodes render correctly
|
|
77
|
+
when `physics` is a bare `bool` or a title is not a `str`.
|
|
78
|
+
- **Packaging:** local `lib/` resources are copied beside the generated HTML file
|
|
79
|
+
and refreshed when stale, instead of silently going missing or going stale.
|
|
80
|
+
- **Shiny module:** the network output releases its listeners and registry entry
|
|
81
|
+
when cleared or removed, preventing leaks across re-renders; null command
|
|
82
|
+
arguments, command queueing, container sizing, config fallback, and
|
|
83
|
+
`configChange` handling were all corrected.
|
|
84
|
+
- **Shiny module:** numeric node ids survive `updateData`, search-restore, and
|
|
85
|
+
edge-editing round trips; the physics toggle is applied to a copy of the
|
|
86
|
+
options and only when the control is actually rendered.
|
|
87
|
+
- **Shiny module:** module networks are now built from the documented dict spec;
|
|
88
|
+
dead `configure()` plumbing was removed and the edge-editing example repaired.
|
|
89
|
+
`PyVisNetworkController` now delegates to the standalone `network_*` functions
|
|
90
|
+
instead of duplicating their logic, and module/controller namespace resolution
|
|
91
|
+
was fixed.
|
|
92
|
+
- **Typed options:** every `Literal` field is now validated at construction time
|
|
93
|
+
and raises `ValueError` on an invalid value (previously only a couple of
|
|
94
|
+
fields were checked); `Font` align values and arrow-type sets were corrected.
|
|
95
|
+
- **Docs:** README and API reference examples were corrected (`update_data`
|
|
96
|
+
and package docstrings, the output config attribute name, stale dataclass
|
|
97
|
+
counts, stale session summaries, and drifted method signatures — now pinned
|
|
98
|
+
by a test that parses every documented parameter, not just the first on a
|
|
99
|
+
line).
|
|
100
|
+
|
|
101
|
+
### Added
|
|
102
|
+
- add edge background, locale, controlNodeStyle and string colour variants to typed options
|
|
103
|
+
- add filter_exclude parameter for configurable filter exclusions
|
|
104
|
+
- add select_node_options parameter for TomSelect customization
|
|
105
|
+
- add tooltip_link_override parameter for tooltip control
|
|
106
|
+
- add highlight_degree parameter for neighborhood highlight depth
|
|
107
|
+
- add validate_version.py and fix recipe.yaml version sync
|
|
108
|
+
- add auto_version.py with conventional commits support
|
|
109
|
+
|
|
110
|
+
### Changed
|
|
111
|
+
- make PyVisNetworkController delegate to the standalone network_* functions
|
|
112
|
+
- **Behavior:** `Network(height=...)` no longer sizes the Shiny output
|
|
113
|
+
container — `output_pyvis_network(height=...)` does. This also fixes
|
|
114
|
+
`fill=True`, which could never work reliably before. Note that
|
|
115
|
+
`@render_pyvis_network(height=...)` only sizes the container in Shiny
|
|
116
|
+
Express mode, where Shiny calls the renderer's `auto_output_ui()`; in a
|
|
117
|
+
classic app the container is whatever `output_pyvis_network()` declares, so
|
|
118
|
+
set the height there.
|
|
119
|
+
- **Behavior:** unset renderer options now inherit from the output's
|
|
120
|
+
`data-pyvis-config` instead of the renderer's old hard-coded defaults.
|
|
121
|
+
- **Behavior:** `add_node()`/`add_edge()` now raise `TypeError` when `options=`
|
|
122
|
+
is neither a dict nor an object with `to_dict()`, instead of silently
|
|
123
|
+
ignoring it; a plain `dict` passed as `options=` is now applied, where it
|
|
124
|
+
used to be dropped.
|
|
125
|
+
- **Shiny module:** `pyvis_network_ui()` no longer renders a `node_spacing`
|
|
126
|
+
slider — its value was never read by anything.
|
|
127
|
+
- **Packaging:** `ipython` moved from a hard dependency to the `pyvis[notebook]`
|
|
128
|
+
extra on PyPI (still bundled by conda). `Network.show()` still defaults to
|
|
129
|
+
`notebook=True`, so after a plain `pip install pyvis` a bare
|
|
130
|
+
`net.show("x.html")` now requires `pyvis[notebook]` and otherwise raises a
|
|
131
|
+
clear `ImportError` naming the extra. Pass `notebook=False` (as the docs
|
|
132
|
+
examples now do) to render without IPython.
|
|
133
|
+
- **Packaging:** Python floor is now consistently 3.9 across `pyproject.toml`,
|
|
134
|
+
CI, and docs; the CI matrix was widened and a `pyvis[test]` extra was added.
|
|
135
|
+
- **Release tooling:** explicit version bumps now update `CHANGELOG.md` and use
|
|
136
|
+
a conventional commit type; `## [Unreleased]` sections are folded into the
|
|
137
|
+
new release heading automatically. The release CI validates the tag against
|
|
138
|
+
the package version and fails on missing secrets; conda publishing now runs
|
|
139
|
+
from the tag workflow.
|
|
140
|
+
|
|
141
|
+
### Documentation
|
|
142
|
+
- clear residual doc drift from the review-fixes branch
|
|
143
|
+
- correct notebook-extra examples, removed commands, and stale counts
|
|
144
|
+
- changelog entry for the 2026-09-05 review fixes
|
|
145
|
+
- align API reference signatures with the code and pin them with a test
|
|
146
|
+
- fix remaining stale dataclass count in README API Reference bullet
|
|
147
|
+
- remove stale session summaries and the unused animation template, fix README references
|
|
148
|
+
- add 2026-09-05 audit report and 30-task fix plan
|
|
149
|
+
- fix docstrings, remove dead comments, correct field counts
|
|
150
|
+
|
|
151
|
+
### Build
|
|
152
|
+
- align Python floor on 3.9, add notebook and test extras, widen CI matrix
|
|
153
|
+
- make explicit version bumps update the changelog and use a conventional commit type
|
|
154
|
+
- validate tag against version, fail on missing secrets, publish conda from the tag workflow
|
|
155
|
+
- expand CI matrix to 3.9-3.13, add _field_renames validation
|
|
156
|
+
- update release-notes skill to use auto_version.py, deprecate bump_version.py
|
|
157
|
+
- add release and conda publish workflows
|
|
158
|
+
- add GitHub Actions CI workflow with test, version validation, and commit lint
|
|
159
|
+
- add conventional commits git hook with mixed enforcement
|
|
160
|
+
|
|
161
|
+
### Other
|
|
162
|
+
- parse every documented parameter, not just the first on a line
|
|
163
|
+
- remove stray blank line left in .gitignore
|
|
164
|
+
- untrack committed artifacts and align .gitignore with tracked paths
|
|
165
|
+
- add fake-session harness pinning every Shiny command payload
|
|
166
|
+
- replace vacuous assertions and remove duplicated tests
|
|
167
|
+
- scope optional-dependency skips to the tests that need them
|
|
168
|
+
- run every test in a temp cwd with the browser stubbed
|
|
169
|
+
- make TestLogTaskException independent of the running event loop
|
|
170
|
+
- ignore .superpowers scratch workspace
|
|
171
|
+
- update bgcolor test to verify validation instead of escaping
|
|
172
|
+
- add directed graph, legend validation, deepcopy isolation, and comprehensive tests
|
|
173
|
+
- add tests for auto_version.py
|
|
174
|
+
Follow-up review pass over the 4.2 codebase: 30 tasks fixing rendering, the Shiny
|
|
175
|
+
integration, typed options, packaging, and docs, backed by a hardened test suite
|
|
176
|
+
(484 tests).
|
|
177
|
+
|
|
178
|
+
### Removed
|
|
179
|
+
- **Shiny module / JS bindings:** the `cluster()` command was removed from the
|
|
180
|
+
Shiny controller and the standalone command functions — vis.js requires a
|
|
181
|
+
`joinCondition` function for clustering, which cannot cross the JSON
|
|
182
|
+
boundary between Python and JavaScript, so it never actually worked.
|
|
183
|
+
`cluster_by_connection()`, `cluster_by_hubsize()`, and `open_cluster()`
|
|
184
|
+
remain and are unaffected.
|
|
185
|
+
- **Core rendering:** the `Network.conf` attribute and the `{% if conf %}`
|
|
186
|
+
blocks in the HTML templates were deleted. Setting `net.conf = True` no
|
|
187
|
+
longer renders the vis.js configure panel; use `set_options()` with an
|
|
188
|
+
explicit `configure` section instead.
|
|
189
|
+
- **Repo hygiene:** untracked build artifacts (`lib/`, generated HTML,
|
|
190
|
+
`__pycache__`) were removed from version control and `.gitignore` was
|
|
191
|
+
aligned with the tracked paths; stale session-summary docs and an unused
|
|
192
|
+
animation template were deleted.
|
|
193
|
+
|
|
194
|
+
### Testing
|
|
195
|
+
- Added a fake-session harness pinning every Shiny command payload, scoped
|
|
196
|
+
optional-dependency skips to only the tests that need them, replaced
|
|
197
|
+
vacuous assertions and duplicated tests, and made the whole suite run from
|
|
198
|
+
a temp `cwd` with the browser stubbed so it no longer depends on ambient
|
|
199
|
+
state. The suite now runs 484 tests, all passing.
|
|
200
|
+
|
|
201
|
+
## [4.2] - 2026-03-28
|
|
202
|
+
|
|
203
|
+
### Security
|
|
204
|
+
- **XSS Prevention:** Enabled Jinja2 `autoescape=True` on all template environments — user-supplied values (heading, bgcolor, node labels) are now HTML-escaped by default
|
|
205
|
+
- **Template hardening:** Added `|safe` only to trusted pre-built content (CDN URLs, JSON data) to prevent double-escaping
|
|
206
|
+
- **File input validation:** `from_DOT()` now validates file existence and rejects empty files with descriptive errors
|
|
207
|
+
|
|
208
|
+
### Fixed
|
|
209
|
+
- **Error handling:** `get_node()` raises `KeyError` with descriptive message instead of bare `KeyError`
|
|
210
|
+
- **Error handling:** `Network[node_id]` (`__getitem__`) raises `KeyError` with descriptive message
|
|
211
|
+
- **Error handling:** `add_edge()` raises `ValueError` (not `IndexError`) for missing nodes — `IndexError` was semantically wrong
|
|
212
|
+
- **Error handling:** `check_html()` raises `TypeError` for non-string input instead of crashing with `AttributeError`
|
|
213
|
+
- **Error handling:** `set_options()` wraps `JSONDecodeError` with descriptive `ValueError` mentioning the method name
|
|
214
|
+
- **Silent failure:** `prep_notebook(custom_template=True)` now raises `ValueError` when `custom_template_path` is not provided (previously fell back silently to the default template)
|
|
215
|
+
- **Data integrity:** `from_nx()` uses `float()` instead of `int()` for node size transforms — no more silent truncation of `15.7` to `15`
|
|
216
|
+
- **Shiny logging:** `_log_task_exception` upgraded from `WARNING` to `ERROR` with full traceback
|
|
217
|
+
- **Shiny race condition:** `render_network()` uses `copy.copy()` instead of temporarily mutating the original network's `cdn_resources`
|
|
218
|
+
- **Test reliability:** Fixed false-positive assertion in `test_add_nodes_with_options` — `assert(generator)` is always truthy
|
|
219
|
+
|
|
220
|
+
### Added
|
|
221
|
+
- **Type validation:** `NodeOptions` and `EdgeColor` validate `opacity` in `[0.0, 1.0]` via `__post_init__`
|
|
222
|
+
- **Type validation:** `Font.align` changed from `str` to `Literal['horizontal', 'left', 'center', 'right']` with runtime validation
|
|
223
|
+
- **Type system:** `OptionsBase._field_renames` mechanism replaces duplicated `to_dict()` overrides in `EdgeArrows` and `EdgeEndPointOffset`
|
|
224
|
+
- **Versioning:** `pyproject.toml` now reads version dynamically from `pyvis/_version.py` (single source of truth)
|
|
225
|
+
- **Versioning:** `bump_version.py` script for easy releases (`patch`, `minor`, `major`, or explicit version)
|
|
226
|
+
- **Tests:** 45 new tests across 5 new test modules: `test_utils.py`, `test_error_handling.py`, `test_security.py`, `test_types_validation.py`, `test_shiny_error_handling.py`
|
|
227
|
+
|
|
228
|
+
### Changed
|
|
229
|
+
- `Font.align` type narrowed from `Optional[str]` to `Optional[Literal[...]]` (breaking for code passing invalid strings)
|
|
230
|
+
- `add_edge()` exception type changed from `IndexError` to `ValueError` (breaking for code catching `IndexError`)
|
|
231
|
+
|
|
232
|
+
## [4.1] - 2026-02-28
|
|
233
|
+
|
|
234
|
+
### Fixed
|
|
235
|
+
- **Packaging:** Fixed MANIFEST.in with correct `pyvis/templates/lib` path, `LICENSE_BSD.txt` filename, and removed references to non-existent files
|
|
236
|
+
- **CDN:** Bootstrap CSS/JS no longer loads unconditionally from CDN — now conditional on `cdn_resources` mode (`remote`/`remote_esm` only)
|
|
237
|
+
- **CDN:** Animation template (`animation_template.html`) no longer hardcodes vis-network CDN URLs — uses same 4-mode conditional pattern as main template
|
|
238
|
+
- **Dependencies:** Upgraded tom-select from pre-release `2.0.0-rc.4` to stable `2.4.3` (local bundles and CDN URLs with updated SRI hashes)
|
|
239
|
+
- **Build:** Removed unused `setuptools_scm[toml]>=6.2` build dependency
|
|
240
|
+
- **Build:** Removed `pyvis.tests` from distributed packages — tests no longer installed to user site-packages
|
|
241
|
+
- **Build:** Anchored `.gitignore` `lib/` rule to repo root (`/lib/`) so `pyvis/templates/lib/` can be tracked
|
|
242
|
+
- **Packaging:** Added minimal inline Bootstrap CSS (~30 lines) for `local` and `in_line` modes, enabling fully offline usage
|
|
243
|
+
- **Template:** Removed duplicate `<h1>{{heading}}</h1>` and commented-out legacy `node_modules` references from `template.html`
|
|
244
|
+
- **Template:** Removed unused Bootstrap JS (modals already use inline styles)
|
|
245
|
+
- Resolved 5 critical issues from codebase review
|
|
246
|
+
- Resolved 6 high priority issues from codebase review
|
|
247
|
+
- Resolved 8 medium priority issues from codebase review
|
|
248
|
+
|
|
249
|
+
### Added
|
|
250
|
+
- **Conda:** Added runtime resource verification to conda recipe test (checks template.html, utils.js, tom-select.css exist)
|
|
251
|
+
|
|
252
|
+
### Changed
|
|
253
|
+
- Resolved 5 low priority issues from codebase review
|
|
254
|
+
|
|
255
|
+
### Removed
|
|
256
|
+
- Deleted root `lib/` directory (generated artifact from `write_html()` local mode, not source code)
|
|
257
|
+
|
|
258
|
+
## [4.0.1] - 2026-02-23
|
|
259
|
+
|
|
260
|
+
### Added
|
|
261
|
+
- `update_node()`, `update_edge()`, `remove_node()`, `remove_edge()` methods on Network
|
|
262
|
+
- Shiny editor demo with vis.js native manipulation toolbar
|
|
263
|
+
- Native manipulation modals for node/edge editing in Shiny bindings
|
|
264
|
+
- Edge edit mode switch and dark/light theme toggle in editor demo
|
|
265
|
+
- Template-from-existing mode for Add Node manipulation modal
|
|
266
|
+
|
|
267
|
+
### Fixed
|
|
268
|
+
- CSS toggling for manipulation toolbar to prevent vis.js rebuild bug
|
|
269
|
+
|
|
270
|
+
### Changed
|
|
271
|
+
- Replaced Selenium with Playwright in `test_html.py`
|
|
272
|
+
- Promoted manipulation commands to public API methods
|
|
273
|
+
|
|
274
|
+
## [4.0.0] - 2026-02-23
|
|
275
|
+
|
|
276
|
+
### Added
|
|
277
|
+
- **Typed Options System (`pyvis.types`):** Full dataclass hierarchy for vis.js options
|
|
278
|
+
- `NodeOptions`, `EdgeOptions`, `PhysicsOptions`, `NetworkOptions` and all sub-types
|
|
279
|
+
- `OptionsBase` mixin with recursive `to_dict()` for clean serialization
|
|
280
|
+
- Shared `Font`, `Shadow`, `Scaling` types
|
|
281
|
+
- `InteractionOptions`, `LayoutOptions`, `ConfigureOptions`, `ManipulationOptions`
|
|
282
|
+
- Typed options accepted in `Network.add_node()`, `add_edge()`, `add_nodes()`, `set_options()`
|
|
283
|
+
- Typed options accepted in `PyVisNetworkController` Shiny methods
|
|
284
|
+
- `network_set_theme()` standalone function for Shiny
|
|
285
|
+
- `options` parameter on `add_nodes()` for typed `NodeOptions`
|
|
286
|
+
- Conda recipe (`conda.recipe/meta.yaml`)
|
|
287
|
+
- Comprehensive API reference documentation
|
|
288
|
+
- Notebook tutorials: basics, NetworkX integration, typed options, advanced features
|
|
289
|
+
- Shiny simple demo (`shiny_simple_demo.py`)
|
|
290
|
+
- Typed Options (Styles) tab in Shiny demo
|
|
291
|
+
|
|
292
|
+
### Fixed
|
|
293
|
+
- Preserve falsy label values (`0`, `''`) in `add_node()`
|
|
294
|
+
- Close file handle in `from_DOT()` using context manager
|
|
295
|
+
- `from_nx()` edge weight logic and node size double-application
|
|
296
|
+
- Handle mixed `str`/`int` node IDs in undirected edge keys
|
|
297
|
+
- Identity checks (`is not None`) for `Layout.randomSeed`, `scale`/`position`/`node_ids` in Shiny
|
|
298
|
+
- `font_color` type changed from `Union[bool, str]` to `Optional[str]`
|
|
299
|
+
- Filter `self` from `locals()` in physics methods
|
|
300
|
+
- Validate edge tuple length in `add_edges()`
|
|
301
|
+
- Don't clear `_edge_set` in `__exit__`
|
|
302
|
+
- Don't mutate original NetworkX graph in `from_nx()`
|
|
303
|
+
- Warn on `add_edges()` tuples with more than 3 elements
|
|
304
|
+
- Reject invalid types in `set_options()`
|
|
305
|
+
- Notebook compatibility with NetworkX 3.4+
|
|
306
|
+
|
|
307
|
+
### Changed
|
|
308
|
+
- **Breaking:** Deleted legacy `Options`/`Physics` system — Network uses dict-only options
|
|
309
|
+
- Replaced `locals()` with explicit dicts in physics methods
|
|
310
|
+
- Use `isinstance(OptionsBase)` instead of `hasattr(to_dict)` in Shiny wrapper
|
|
311
|
+
- Use `str()` coercion for consistent edge dedup with mixed ID types
|
|
312
|
+
|
|
313
|
+
### Removed
|
|
314
|
+
- Legacy `Options` and `Physics` classes
|
|
315
|
+
- Debug `print(name)` from `show()`
|
|
316
|
+
- Dead `show_edge_weights` parameter from `from_nx()`
|
|
317
|
+
- Unused `import json` from `physics.py`
|
|
318
|
+
- Duplicate `toggle_physics` call in `pyvis_network_server`
|
|
319
|
+
- Scattered demo and test scaffold files
|
|
320
|
+
- Generated HTML output files
|
|
321
|
+
|
|
322
|
+
## [0.3.0] - 2026-02-22
|
|
323
|
+
|
|
324
|
+
### Added
|
|
325
|
+
- **Shiny Integration:** Direct rendering via `get_network_json()` (no iframe)
|
|
326
|
+
- `bindings.js` with direct DOM rendering
|
|
327
|
+
- CSS styles with light/dark theme support
|
|
328
|
+
- `PyVisNetworkController` wrapper for server-side control
|
|
329
|
+
- Multi-tab demo showcasing full PyVis Shiny API
|
|
330
|
+
- Dark Observatory theme for demo app
|
|
331
|
+
|
|
332
|
+
### Fixed
|
|
333
|
+
- Runtime bugs found during live demo testing
|
|
334
|
+
- Skip theme switch on init before network exists
|
|
335
|
+
- Deduplicate edges in starting graph
|
|
336
|
+
|
|
337
|
+
### Changed
|
|
338
|
+
- Initial fork from upstream pyvis with Shiny integration and template fixes
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
Copyright (c) 2018, West Health Institute
|
|
2
|
+
All rights reserved.
|
|
3
|
+
|
|
4
|
+
Redistribution and use in source and binary forms, with or without modification,
|
|
5
|
+
are permitted provided that the following conditions are met:
|
|
6
|
+
|
|
7
|
+
- Redistributions of source code must retain the above copyright notice,
|
|
8
|
+
this list of conditions and the following disclaimer.
|
|
9
|
+
|
|
10
|
+
- Redistributions in binary form must reproduce the above copyright notice,
|
|
11
|
+
this list of conditions and the following disclaimer in the documentation
|
|
12
|
+
and/or other materials provided with the distribution.
|
|
13
|
+
|
|
14
|
+
- Neither the name of West Health Institute nor the names of its contributors may
|
|
15
|
+
be used to endorse or promote products derived from this software without
|
|
16
|
+
specific prior written permission.
|
|
17
|
+
|
|
18
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
19
|
+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
20
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
21
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
|
22
|
+
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
23
|
+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
24
|
+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
|
25
|
+
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
26
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
27
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Include package data
|
|
2
|
+
recursive-include pyvis/templates *
|
|
3
|
+
recursive-include pyvis/templates/lib *
|
|
4
|
+
recursive-include pyvis/shiny *.js *.css
|
|
5
|
+
|
|
6
|
+
# Include documentation
|
|
7
|
+
include README.md
|
|
8
|
+
include LICENSE_BSD.txt
|
|
9
|
+
include CHANGELOG.md
|
|
10
|
+
include pyvis/_version.py
|
|
11
|
+
|
|
12
|
+
# Include examples and notebooks
|
|
13
|
+
recursive-include examples *.py
|
|
14
|
+
recursive-include notebooks *.ipynb *.csv *.dot
|
|
15
|
+
|
|
16
|
+
# Exclude development files
|
|
17
|
+
exclude .gitignore
|
|
18
|
+
exclude .coveragerc
|
|
19
|
+
recursive-exclude * __pycache__
|
|
20
|
+
recursive-exclude * *.py[co]
|
|
21
|
+
recursive-exclude * .pytest_cache
|
|
22
|
+
recursive-exclude .github *
|
|
23
|
+
recursive-exclude docs *
|
|
24
|
+
recursive-exclude examples *.html
|
|
25
|
+
recursive-exclude notebooks/lib *
|
|
26
|
+
recursive-exclude notebooks *.html
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pyvis-optimized
|
|
3
|
+
Version: 4.3.1
|
|
4
|
+
Summary: A Python network graph visualization library - Optimized Edition
|
|
5
|
+
Author-email: Jose Unpingco <datascience@westhealth.org>
|
|
6
|
+
Maintainer: PyVis Contributors
|
|
7
|
+
License: BSD
|
|
8
|
+
Project-URL: Homepage, https://github.com/razinkele/pyvis
|
|
9
|
+
Project-URL: Documentation, https://github.com/razinkele/pyvis#readme
|
|
10
|
+
Project-URL: Repository, https://github.com/razinkele/pyvis
|
|
11
|
+
Project-URL: Bug Tracker, https://github.com/razinkele/pyvis/issues
|
|
12
|
+
Project-URL: Changelog, https://github.com/razinkele/pyvis/blob/master/CHANGELOG.md
|
|
13
|
+
Keywords: network,visualization,graph,networkx,vis.js,interactive
|
|
14
|
+
Classifier: Development Status :: 4 - Beta
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: Intended Audience :: Science/Research
|
|
17
|
+
Classifier: License :: OSI Approved :: BSD License
|
|
18
|
+
Classifier: Operating System :: OS Independent
|
|
19
|
+
Classifier: Programming Language :: Python :: 3
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
24
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
25
|
+
Classifier: Topic :: Scientific/Engineering :: Visualization
|
|
26
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
27
|
+
Requires-Python: >=3.9
|
|
28
|
+
Description-Content-Type: text/markdown
|
|
29
|
+
License-File: LICENSE_BSD.txt
|
|
30
|
+
Requires-Dist: jinja2>=2.9.6
|
|
31
|
+
Requires-Dist: networkx>=1.11
|
|
32
|
+
Requires-Dist: jsonpickle>=1.4.1
|
|
33
|
+
Provides-Extra: shiny
|
|
34
|
+
Requires-Dist: shiny>=0.6.0; extra == "shiny"
|
|
35
|
+
Requires-Dist: htmltools; extra == "shiny"
|
|
36
|
+
Provides-Extra: notebook
|
|
37
|
+
Requires-Dist: ipython>=5.3.0; extra == "notebook"
|
|
38
|
+
Provides-Extra: dev
|
|
39
|
+
Requires-Dist: pytest>=6.0; extra == "dev"
|
|
40
|
+
Requires-Dist: pytest-cov; extra == "dev"
|
|
41
|
+
Requires-Dist: black; extra == "dev"
|
|
42
|
+
Requires-Dist: flake8; extra == "dev"
|
|
43
|
+
Requires-Dist: mypy; extra == "dev"
|
|
44
|
+
Provides-Extra: test
|
|
45
|
+
Requires-Dist: pytest>=6.0; extra == "test"
|
|
46
|
+
Requires-Dist: pytest-cov; extra == "test"
|
|
47
|
+
Requires-Dist: playwright>=1.40; extra == "test"
|
|
48
|
+
Requires-Dist: pytest-playwright>=0.4; extra == "test"
|
|
49
|
+
Requires-Dist: numpy; extra == "test"
|
|
50
|
+
Provides-Extra: all
|
|
51
|
+
Requires-Dist: pyvis-optimized[dev,notebook,shiny,test]; extra == "all"
|
|
52
|
+
Dynamic: license-file
|
|
53
|
+
|
|
54
|
+
# PyVis — Interactive Network Visualization for Python
|
|
55
|
+
|
|
56
|
+

|
|
57
|
+
|
|
58
|
+
PyVis is a Python library for creating and visualizing interactive network graphs, built on top of the [vis.js](https://visjs.github.io/vis-network/docs/network/) JavaScript library. This edition adds type-safe configuration, Shiny for Python integration, security hardening, and performance optimizations over the [upstream project](https://github.com/WestHealth/pyvis).
|
|
59
|
+
|
|
60
|
+
## Features
|
|
61
|
+
|
|
62
|
+
- **Interactive visualizations** — Pan, zoom, drag nodes, hover tooltips, all in the browser
|
|
63
|
+
- **NetworkX integration** — Convert NetworkX graphs directly with `from_nx()`
|
|
64
|
+
- **Type-safe options** — 44 Python dataclasses covering 100% of the vis-network configuration surface
|
|
65
|
+
- **Shiny for Python** — Full bidirectional integration with event handling, viewport control, and live data updates
|
|
66
|
+
- **Multiple physics engines** — Barnes-Hut, Force Atlas 2, repulsion, and hierarchical repulsion
|
|
67
|
+
- **Jupyter support** — Render networks inline in Jupyter notebooks
|
|
68
|
+
- **Security hardened** — Jinja2 autoescape prevents XSS, input validation on file operations
|
|
69
|
+
- **Runtime validation** — Type-safe options with `__post_init__` checks for opacity, font alignment, and more
|
|
70
|
+
|
|
71
|
+
## Installation
|
|
72
|
+
|
|
73
|
+
**Requires Python >= 3.9**
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
pip install pyvis-optimized
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
With optional dependencies:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
pip install pyvis-optimized[shiny] # Shiny for Python integration
|
|
83
|
+
pip install pyvis-optimized[notebook] # Jupyter/IPython notebook support
|
|
84
|
+
pip install pyvis-optimized[dev] # Development tools (pytest, black, mypy)
|
|
85
|
+
pip install pyvis-optimized[test] # Test dependencies (pytest, playwright)
|
|
86
|
+
pip install pyvis-optimized[all] # Everything
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
The conda package always includes IPython; on PyPI it is the `notebook` extra.
|
|
90
|
+
|
|
91
|
+
Or from source:
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
pip install .
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Dependencies
|
|
98
|
+
|
|
99
|
+
| Package | Purpose |
|
|
100
|
+
|---------|---------|
|
|
101
|
+
| [networkx](https://networkx.github.io/) >= 1.11 | Graph data structures |
|
|
102
|
+
| [jinja2](https://jinja.palletsprojects.com/) >= 2.9.6 | HTML template rendering |
|
|
103
|
+
| [jsonpickle](https://jsonpickle.github.io/) >= 1.4.1 | JSON serialization |
|
|
104
|
+
|
|
105
|
+
Optional: [ipython](https://ipython.org/) >= 5.3.0 (`pyvis-optimized[notebook]`), [shiny](https://shiny.posit.co/py/) >= 0.6.0 and [htmltools](https://pypi.org/project/htmltools/) (`pyvis-optimized[shiny]`)
|
|
106
|
+
|
|
107
|
+
## Quick Start
|
|
108
|
+
|
|
109
|
+
```python
|
|
110
|
+
from pyvis.network import Network
|
|
111
|
+
|
|
112
|
+
net = Network()
|
|
113
|
+
net.add_node(1, label="Node 1", color="#97c2fc")
|
|
114
|
+
net.add_node(2, label="Node 2", color="#ffcc00")
|
|
115
|
+
net.add_edge(1, 2, width=2)
|
|
116
|
+
net.show("basic.html", notebook=False)
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### From NetworkX
|
|
120
|
+
|
|
121
|
+
```python
|
|
122
|
+
import networkx as nx
|
|
123
|
+
from pyvis.network import Network
|
|
124
|
+
|
|
125
|
+
G = nx.karate_club_graph()
|
|
126
|
+
net = Network()
|
|
127
|
+
net.from_nx(G)
|
|
128
|
+
net.show("karate.html", notebook=False)
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## Type-Safe Options
|
|
132
|
+
|
|
133
|
+
Configure every aspect of your network visualization with Python dataclasses that provide IDE autocompletion and type checking:
|
|
134
|
+
|
|
135
|
+
```python
|
|
136
|
+
from pyvis.network import Network
|
|
137
|
+
from pyvis.types import (
|
|
138
|
+
NetworkOptions, NodeOptions, EdgeOptions, PhysicsOptions,
|
|
139
|
+
BarnesHut, LayoutOptions, InteractionOptions, Font
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
options = NetworkOptions(
|
|
143
|
+
nodes=NodeOptions(
|
|
144
|
+
shape="dot",
|
|
145
|
+
font=Font(size=14, color="#333333"),
|
|
146
|
+
),
|
|
147
|
+
edges=EdgeOptions(
|
|
148
|
+
smooth=True,
|
|
149
|
+
color="#848484",
|
|
150
|
+
),
|
|
151
|
+
physics=PhysicsOptions(
|
|
152
|
+
solver="barnesHut",
|
|
153
|
+
barnesHut=BarnesHut(gravitationalConstant=-3000),
|
|
154
|
+
),
|
|
155
|
+
interaction=InteractionOptions(
|
|
156
|
+
hover=True,
|
|
157
|
+
tooltipDelay=200,
|
|
158
|
+
),
|
|
159
|
+
)
|
|
160
|
+
|
|
161
|
+
net = Network()
|
|
162
|
+
net.set_options(options)
|
|
163
|
+
net.add_node(1, label="A")
|
|
164
|
+
net.add_node(2, label="B")
|
|
165
|
+
net.add_edge(1, 2)
|
|
166
|
+
net.show("typed.html", notebook=False)
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
The `pyvis.types` module provides 44 dataclasses covering nodes, edges, physics, layout, interaction, configuration, and manipulation — the full vis-network API surface.
|
|
170
|
+
|
|
171
|
+
## Shiny for Python Integration
|
|
172
|
+
|
|
173
|
+
Build interactive web applications with bidirectional communication between Python and the network:
|
|
174
|
+
|
|
175
|
+
```python
|
|
176
|
+
from shiny import App, ui, render, reactive
|
|
177
|
+
from pyvis.network import Network
|
|
178
|
+
from pyvis.shiny import (
|
|
179
|
+
output_pyvis_network, render_pyvis_network,
|
|
180
|
+
PyVisNetworkController
|
|
181
|
+
)
|
|
182
|
+
|
|
183
|
+
app_ui = ui.page_fluid(
|
|
184
|
+
output_pyvis_network("network", height="600px"),
|
|
185
|
+
ui.input_action_button("fit", "Fit to View"),
|
|
186
|
+
ui.output_text_verbatim("selected")
|
|
187
|
+
)
|
|
188
|
+
|
|
189
|
+
def server(input, output, session):
|
|
190
|
+
ctrl = PyVisNetworkController("network", session)
|
|
191
|
+
|
|
192
|
+
@render_pyvis_network
|
|
193
|
+
def network():
|
|
194
|
+
net = Network(cdn_resources="remote")
|
|
195
|
+
net.add_node(1, label="Node 1")
|
|
196
|
+
net.add_node(2, label="Node 2")
|
|
197
|
+
net.add_edge(1, 2)
|
|
198
|
+
return net
|
|
199
|
+
|
|
200
|
+
@reactive.effect
|
|
201
|
+
@reactive.event(input.fit)
|
|
202
|
+
def _():
|
|
203
|
+
ctrl.fit()
|
|
204
|
+
|
|
205
|
+
@render.text
|
|
206
|
+
def selected():
|
|
207
|
+
event = input.network_selectNode()
|
|
208
|
+
return f"Selected: {event['nodeId']}" if event else "Click a node"
|
|
209
|
+
|
|
210
|
+
app = App(app_ui, server)
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### Shiny Capabilities
|
|
214
|
+
|
|
215
|
+
| Category | Functions |
|
|
216
|
+
|----------|-----------|
|
|
217
|
+
| **Events** | click, doubleClick, selectNode, selectEdge, hoverNode, dragStart, zoom, stabilized, and more |
|
|
218
|
+
| **Selection** | select_nodes, select_edges, unselect_all |
|
|
219
|
+
| **Viewport** | fit, focus, move_to |
|
|
220
|
+
| **Physics** | start_physics, stop_physics, stabilize |
|
|
221
|
+
| **Data** | add/update/remove nodes and edges, get_positions, get_all_data |
|
|
222
|
+
| **Clustering** | cluster_by_connection, cluster_by_hubsize, open_cluster |
|
|
223
|
+
| **Theming** | set_options, set_theme |
|
|
224
|
+
|
|
225
|
+
See the [Shiny Integration Guide](docs/SHINY_INTEGRATION_GUIDE.md) for complete documentation.
|
|
226
|
+
|
|
227
|
+
## Documentation
|
|
228
|
+
|
|
229
|
+
- **[API Reference](docs/API_REFERENCE.md)** — Complete reference for Network class, typed options (44 dataclasses), Shiny integration, and all public methods
|
|
230
|
+
- **[Shiny Integration Guide](docs/SHINY_INTEGRATION_GUIDE.md)** — Detailed guide for using PyVis with Shiny for Python
|
|
231
|
+
|
|
232
|
+
## Testing
|
|
233
|
+
|
|
234
|
+
```bash
|
|
235
|
+
pytest pyvis/tests/ --ignore=pyvis/tests/test_html.py -v
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
That command runs 480 tests covering core network operations, typed options, Shiny integration, security, error handling, and regression tests for edge cases. The full suite is 484 (run `pytest --co` for the current count); the four extra are the Playwright browser tests in `test_html.py`, which need `pip install pyvis-optimized[test]` followed by `python -m playwright install chromium`.
|
|
239
|
+
|
|
240
|
+
## Versioning
|
|
241
|
+
|
|
242
|
+
Version is managed from a single source of truth: `pyvis/_version.py`. Use the bump script for releases:
|
|
243
|
+
|
|
244
|
+
```bash
|
|
245
|
+
python auto_version.py # bump from conventional commits, update CHANGELOG, commit, tag
|
|
246
|
+
python auto_version.py minor # explicit bump; CHANGELOG still built from commits
|
|
247
|
+
python auto_version.py --no-commit # dry run: update files only
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
## Project Structure
|
|
251
|
+
|
|
252
|
+
```
|
|
253
|
+
pyvis/
|
|
254
|
+
network.py # Main Network class
|
|
255
|
+
node.py # Node representation
|
|
256
|
+
edge.py # Edge representation
|
|
257
|
+
_version.py # Single source of truth for version
|
|
258
|
+
utils.py # Validation utilities
|
|
259
|
+
types/ # Type-safe dataclass options (44 classes)
|
|
260
|
+
shiny/ # Shiny for Python integration
|
|
261
|
+
wrapper.py # Controller, standalone functions, rendering
|
|
262
|
+
bindings.js # JavaScript binding for vis-network
|
|
263
|
+
tests/ # 484 tests across 28 modules (see `pytest --co` for current count)
|
|
264
|
+
auto_version.py # Version bump + changelog + tag script
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
## License
|
|
268
|
+
|
|
269
|
+
BSD License. Based on [WestHealth/pyvis](https://github.com/WestHealth/pyvis).
|