pyvis-optimized 4.3.1__tar.gz → 4.4.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 (53) hide show
  1. {pyvis_optimized-4.3.1 → pyvis_optimized-4.4.0}/CHANGELOG.md +27 -0
  2. {pyvis_optimized-4.3.1/pyvis_optimized.egg-info → pyvis_optimized-4.4.0}/PKG-INFO +8 -8
  3. {pyvis_optimized-4.3.1 → pyvis_optimized-4.4.0}/README.md +5 -4
  4. {pyvis_optimized-4.3.1 → pyvis_optimized-4.4.0}/pyproject.toml +4 -5
  5. pyvis_optimized-4.4.0/pyvis/_version.py +1 -0
  6. {pyvis_optimized-4.3.1 → pyvis_optimized-4.4.0}/pyvis/shiny/__init__.py +2 -0
  7. {pyvis_optimized-4.3.1 → pyvis_optimized-4.4.0}/pyvis/shiny/bindings.js +16 -0
  8. {pyvis_optimized-4.3.1 → pyvis_optimized-4.4.0}/pyvis/shiny/wrapper.py +32 -0
  9. pyvis_optimized-4.4.0/pyvis/templates/lib/vis-10.1.2/vis-network.min.css +2 -0
  10. pyvis_optimized-4.4.0/pyvis/templates/lib/vis-10.1.2/vis-network.min.js +78 -0
  11. {pyvis_optimized-4.3.1 → pyvis_optimized-4.4.0}/pyvis/types/base.py +9 -2
  12. {pyvis_optimized-4.3.1 → pyvis_optimized-4.4.0}/pyvis/types/physics.py +9 -1
  13. {pyvis_optimized-4.3.1 → pyvis_optimized-4.4.0}/pyvis/vis_config.py +1 -1
  14. {pyvis_optimized-4.3.1 → pyvis_optimized-4.4.0/pyvis_optimized.egg-info}/PKG-INFO +8 -8
  15. {pyvis_optimized-4.3.1 → pyvis_optimized-4.4.0}/pyvis_optimized.egg-info/SOURCES.txt +2 -2
  16. {pyvis_optimized-4.3.1 → pyvis_optimized-4.4.0}/pyvis_optimized.egg-info/requires.txt +1 -1
  17. pyvis_optimized-4.3.1/pyvis/_version.py +0 -1
  18. pyvis_optimized-4.3.1/pyvis/templates/lib/vis-10.0.2/vis-network.min.css +0 -2
  19. pyvis_optimized-4.3.1/pyvis/templates/lib/vis-10.0.2/vis-network.min.js +0 -78
  20. {pyvis_optimized-4.3.1 → pyvis_optimized-4.4.0}/LICENSE_BSD.txt +0 -0
  21. {pyvis_optimized-4.3.1 → pyvis_optimized-4.4.0}/MANIFEST.in +0 -0
  22. {pyvis_optimized-4.3.1 → pyvis_optimized-4.4.0}/examples/edge_attribute_editing_example.py +0 -0
  23. {pyvis_optimized-4.3.1 → pyvis_optimized-4.4.0}/examples/shiny_demo.py +0 -0
  24. {pyvis_optimized-4.3.1 → pyvis_optimized-4.4.0}/examples/shiny_editor_demo.py +0 -0
  25. {pyvis_optimized-4.3.1 → pyvis_optimized-4.4.0}/examples/shiny_simple_demo.py +0 -0
  26. {pyvis_optimized-4.3.1 → pyvis_optimized-4.4.0}/notebooks/01_basics.ipynb +0 -0
  27. {pyvis_optimized-4.3.1 → pyvis_optimized-4.4.0}/notebooks/02_networkx.ipynb +0 -0
  28. {pyvis_optimized-4.3.1 → pyvis_optimized-4.4.0}/notebooks/03_typed_options.ipynb +0 -0
  29. {pyvis_optimized-4.3.1 → pyvis_optimized-4.4.0}/notebooks/04_advanced.ipynb +0 -0
  30. {pyvis_optimized-4.3.1 → pyvis_optimized-4.4.0}/notebooks/NetworkOfThrones.csv +0 -0
  31. {pyvis_optimized-4.3.1 → pyvis_optimized-4.4.0}/notebooks/test.dot +0 -0
  32. {pyvis_optimized-4.3.1 → pyvis_optimized-4.4.0}/pyvis/__init__.py +0 -0
  33. {pyvis_optimized-4.3.1 → pyvis_optimized-4.4.0}/pyvis/edge.py +0 -0
  34. {pyvis_optimized-4.3.1 → pyvis_optimized-4.4.0}/pyvis/network.py +0 -0
  35. {pyvis_optimized-4.3.1 → pyvis_optimized-4.4.0}/pyvis/node.py +0 -0
  36. {pyvis_optimized-4.3.1 → pyvis_optimized-4.4.0}/pyvis/shiny/styles.css +0 -0
  37. {pyvis_optimized-4.3.1 → pyvis_optimized-4.4.0}/pyvis/templates/lib/bindings/utils.js +0 -0
  38. {pyvis_optimized-4.3.1 → pyvis_optimized-4.4.0}/pyvis/templates/lib/tom-select/tom-select.complete.min.js +0 -0
  39. {pyvis_optimized-4.3.1 → pyvis_optimized-4.4.0}/pyvis/templates/lib/tom-select/tom-select.css +0 -0
  40. {pyvis_optimized-4.3.1 → pyvis_optimized-4.4.0}/pyvis/templates/template.html +0 -0
  41. {pyvis_optimized-4.3.1 → pyvis_optimized-4.4.0}/pyvis/types/__init__.py +0 -0
  42. {pyvis_optimized-4.3.1 → pyvis_optimized-4.4.0}/pyvis/types/common.py +0 -0
  43. {pyvis_optimized-4.3.1 → pyvis_optimized-4.4.0}/pyvis/types/configure.py +0 -0
  44. {pyvis_optimized-4.3.1 → pyvis_optimized-4.4.0}/pyvis/types/edges.py +0 -0
  45. {pyvis_optimized-4.3.1 → pyvis_optimized-4.4.0}/pyvis/types/interaction.py +0 -0
  46. {pyvis_optimized-4.3.1 → pyvis_optimized-4.4.0}/pyvis/types/layout.py +0 -0
  47. {pyvis_optimized-4.3.1 → pyvis_optimized-4.4.0}/pyvis/types/manipulation.py +0 -0
  48. {pyvis_optimized-4.3.1 → pyvis_optimized-4.4.0}/pyvis/types/network.py +0 -0
  49. {pyvis_optimized-4.3.1 → pyvis_optimized-4.4.0}/pyvis/types/nodes.py +0 -0
  50. {pyvis_optimized-4.3.1 → pyvis_optimized-4.4.0}/pyvis/utils.py +0 -0
  51. {pyvis_optimized-4.3.1 → pyvis_optimized-4.4.0}/pyvis_optimized.egg-info/dependency_links.txt +0 -0
  52. {pyvis_optimized-4.3.1 → pyvis_optimized-4.4.0}/pyvis_optimized.egg-info/top_level.txt +0 -0
  53. {pyvis_optimized-4.3.1 → pyvis_optimized-4.4.0}/setup.cfg +0 -0
@@ -4,6 +4,33 @@ All notable changes to this project are documented in this file.
4
4
 
5
5
 
6
6
 
7
+ ## [4.4.0] - 2026-09-06
8
+
9
+ ### Breaking Changes
10
+ - **Python 3.10 is now the minimum.** 3.9 is dropped. Under 3.9 the resolver
11
+ silently installed Shiny 1.5.0 while development targeted 1.7.0, so the
12
+ version actually being tested was not the version being shipped.
13
+
14
+ ### Added
15
+ - `network_destroy(session, output_id)` and `PyVisNetworkController.destroy()`
16
+ tear down the client-side network without removing its element. Intended for
17
+ `session.on_destroy` / `session.on_ended`, so a closing session releases the
18
+ vis instance instead of leaving it registered.
19
+ - End-to-end tests that run a real Shiny app in a real browser, covering the
20
+ module UI, the namespaced output id, and the `show_controls` physics path.
21
+
22
+ ### Fixed
23
+ - A resize callback scheduled just before teardown no longer runs against a
24
+ destroyed network. Disconnecting the ResizeObserver stops new callbacks but
25
+ does not cancel a pending debounce timer, so the late call raised "Cannot
26
+ read properties of undefined (reading 'setSize')" during a re-render.
27
+ - The browser test harness now loads `styles.css`, so the flex layout the
28
+ canvas sizing depends on is present and resize behaviour is observed
29
+ faithfully rather than against collapsed block flow.
30
+
31
+ ### Changed
32
+ - Bundled vis-network upgraded from 10.0.2 to 10.1.2.
33
+
7
34
  ## [4.3.1] - 2026-09-06
8
35
 
9
36
  Packaging-only release. 4.3.0 was tagged but never published: both publish
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyvis-optimized
3
- Version: 4.3.1
3
+ Version: 4.4.0
4
4
  Summary: A Python network graph visualization library - Optimized Edition
5
5
  Author-email: Jose Unpingco <datascience@westhealth.org>
6
6
  Maintainer: PyVis Contributors
@@ -17,21 +17,20 @@ Classifier: Intended Audience :: Science/Research
17
17
  Classifier: License :: OSI Approved :: BSD License
18
18
  Classifier: Operating System :: OS Independent
19
19
  Classifier: Programming Language :: Python :: 3
20
- Classifier: Programming Language :: Python :: 3.9
21
20
  Classifier: Programming Language :: Python :: 3.10
22
21
  Classifier: Programming Language :: Python :: 3.11
23
22
  Classifier: Programming Language :: Python :: 3.12
24
23
  Classifier: Programming Language :: Python :: 3.13
25
24
  Classifier: Topic :: Scientific/Engineering :: Visualization
26
25
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
27
- Requires-Python: >=3.9
26
+ Requires-Python: >=3.10
28
27
  Description-Content-Type: text/markdown
29
28
  License-File: LICENSE_BSD.txt
30
29
  Requires-Dist: jinja2>=2.9.6
31
30
  Requires-Dist: networkx>=1.11
32
31
  Requires-Dist: jsonpickle>=1.4.1
33
32
  Provides-Extra: shiny
34
- Requires-Dist: shiny>=0.6.0; extra == "shiny"
33
+ Requires-Dist: shiny>=1.0; extra == "shiny"
35
34
  Requires-Dist: htmltools; extra == "shiny"
36
35
  Provides-Extra: notebook
37
36
  Requires-Dist: ipython>=5.3.0; extra == "notebook"
@@ -70,7 +69,7 @@ PyVis is a Python library for creating and visualizing interactive network graph
70
69
 
71
70
  ## Installation
72
71
 
73
- **Requires Python >= 3.9**
72
+ **Requires Python >= 3.10**
74
73
 
75
74
  ```bash
76
75
  pip install pyvis-optimized
@@ -102,7 +101,7 @@ pip install .
102
101
  | [jinja2](https://jinja.palletsprojects.com/) >= 2.9.6 | HTML template rendering |
103
102
  | [jsonpickle](https://jsonpickle.github.io/) >= 1.4.1 | JSON serialization |
104
103
 
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]`)
104
+ Optional: [ipython](https://ipython.org/) >= 5.3.0 (`pyvis-optimized[notebook]`), [shiny](https://shiny.posit.co/py/) >= 1.0 and [htmltools](https://pypi.org/project/htmltools/) (`pyvis-optimized[shiny]`)
106
105
 
107
106
  ## Quick Start
108
107
 
@@ -228,6 +227,7 @@ See the [Shiny Integration Guide](docs/SHINY_INTEGRATION_GUIDE.md) for complete
228
227
 
229
228
  - **[API Reference](docs/API_REFERENCE.md)** — Complete reference for Network class, typed options (44 dataclasses), Shiny integration, and all public methods
230
229
  - **[Shiny Integration Guide](docs/SHINY_INTEGRATION_GUIDE.md)** — Detailed guide for using PyVis with Shiny for Python
230
+ - **[Releasing](docs/RELEASING.md)** — How a release is cut and published to PyPI and anaconda.org, and how to retry a failed one
231
231
 
232
232
  ## Testing
233
233
 
@@ -235,7 +235,7 @@ See the [Shiny Integration Guide](docs/SHINY_INTEGRATION_GUIDE.md) for complete
235
235
  pytest pyvis/tests/ --ignore=pyvis/tests/test_html.py -v
236
236
  ```
237
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`.
238
+ That command runs 474 tests covering core network operations, typed options, Shiny integration, security, error handling, and regression tests for edge cases. The full suite is 495 (run `pytest --co` for the current count); the extra 21 are the Playwright browser tests in `test_html.py`, `test_bindings_js.py`, and `test_shiny_e2e.py`, which need `pip install pyvis-optimized[test]` followed by `python -m playwright install chromium`.
239
239
 
240
240
  ## Versioning
241
241
 
@@ -260,7 +260,7 @@ pyvis/
260
260
  shiny/ # Shiny for Python integration
261
261
  wrapper.py # Controller, standalone functions, rendering
262
262
  bindings.js # JavaScript binding for vis-network
263
- tests/ # 484 tests across 28 modules (see `pytest --co` for current count)
263
+ tests/ # 495 tests across 29 modules (see `pytest --co` for current count)
264
264
  auto_version.py # Version bump + changelog + tag script
265
265
  ```
266
266
 
@@ -17,7 +17,7 @@ PyVis is a Python library for creating and visualizing interactive network graph
17
17
 
18
18
  ## Installation
19
19
 
20
- **Requires Python >= 3.9**
20
+ **Requires Python >= 3.10**
21
21
 
22
22
  ```bash
23
23
  pip install pyvis-optimized
@@ -49,7 +49,7 @@ pip install .
49
49
  | [jinja2](https://jinja.palletsprojects.com/) >= 2.9.6 | HTML template rendering |
50
50
  | [jsonpickle](https://jsonpickle.github.io/) >= 1.4.1 | JSON serialization |
51
51
 
52
- 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]`)
52
+ Optional: [ipython](https://ipython.org/) >= 5.3.0 (`pyvis-optimized[notebook]`), [shiny](https://shiny.posit.co/py/) >= 1.0 and [htmltools](https://pypi.org/project/htmltools/) (`pyvis-optimized[shiny]`)
53
53
 
54
54
  ## Quick Start
55
55
 
@@ -175,6 +175,7 @@ See the [Shiny Integration Guide](docs/SHINY_INTEGRATION_GUIDE.md) for complete
175
175
 
176
176
  - **[API Reference](docs/API_REFERENCE.md)** — Complete reference for Network class, typed options (44 dataclasses), Shiny integration, and all public methods
177
177
  - **[Shiny Integration Guide](docs/SHINY_INTEGRATION_GUIDE.md)** — Detailed guide for using PyVis with Shiny for Python
178
+ - **[Releasing](docs/RELEASING.md)** — How a release is cut and published to PyPI and anaconda.org, and how to retry a failed one
178
179
 
179
180
  ## Testing
180
181
 
@@ -182,7 +183,7 @@ See the [Shiny Integration Guide](docs/SHINY_INTEGRATION_GUIDE.md) for complete
182
183
  pytest pyvis/tests/ --ignore=pyvis/tests/test_html.py -v
183
184
  ```
184
185
 
185
- 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`.
186
+ That command runs 474 tests covering core network operations, typed options, Shiny integration, security, error handling, and regression tests for edge cases. The full suite is 495 (run `pytest --co` for the current count); the extra 21 are the Playwright browser tests in `test_html.py`, `test_bindings_js.py`, and `test_shiny_e2e.py`, which need `pip install pyvis-optimized[test]` followed by `python -m playwright install chromium`.
186
187
 
187
188
  ## Versioning
188
189
 
@@ -207,7 +208,7 @@ pyvis/
207
208
  shiny/ # Shiny for Python integration
208
209
  wrapper.py # Controller, standalone functions, rendering
209
210
  bindings.js # JavaScript binding for vis-network
210
- tests/ # 484 tests across 28 modules (see `pytest --co` for current count)
211
+ tests/ # 495 tests across 29 modules (see `pytest --co` for current count)
211
212
  auto_version.py # Version bump + changelog + tag script
212
213
  ```
213
214
 
@@ -7,7 +7,7 @@ name = "pyvis-optimized"
7
7
  dynamic = ["version"]
8
8
  description = "A Python network graph visualization library - Optimized Edition"
9
9
  readme = "README.md"
10
- requires-python = ">=3.9"
10
+ requires-python = ">=3.10"
11
11
  license = {text = "BSD"}
12
12
  authors = [
13
13
  {name = "Jose Unpingco", email = "datascience@westhealth.org"}
@@ -23,7 +23,6 @@ classifiers = [
23
23
  "License :: OSI Approved :: BSD License",
24
24
  "Operating System :: OS Independent",
25
25
  "Programming Language :: Python :: 3",
26
- "Programming Language :: Python :: 3.9",
27
26
  "Programming Language :: Python :: 3.10",
28
27
  "Programming Language :: Python :: 3.11",
29
28
  "Programming Language :: Python :: 3.12",
@@ -41,7 +40,7 @@ dependencies = [
41
40
  [project.optional-dependencies]
42
41
  # Shiny integration support
43
42
  shiny = [
44
- "shiny>=0.6.0",
43
+ "shiny>=1.0",
45
44
  "htmltools",
46
45
  ]
47
46
 
@@ -105,7 +104,7 @@ python_functions = "test_*"
105
104
 
106
105
  [tool.black]
107
106
  line-length = 100
108
- target-version = ['py39', 'py310', 'py311', 'py312', 'py313']
107
+ target-version = ['py310', 'py311', 'py312', 'py313']
109
108
  include = '\.pyi?$'
110
109
  exclude = '''
111
110
  /(
@@ -122,7 +121,7 @@ exclude = '''
122
121
  '''
123
122
 
124
123
  [tool.mypy]
125
- python_version = "3.9"
124
+ python_version = "3.10"
126
125
  warn_return_any = true
127
126
  warn_unused_configs = true
128
127
  disallow_untyped_defs = false
@@ -0,0 +1 @@
1
+ __version__ = '4.4.0'
@@ -151,6 +151,7 @@ from .wrapper import (
151
151
  network_open_cluster,
152
152
  network_set_options,
153
153
  network_set_theme,
154
+ network_destroy,
154
155
  network_toggle_manipulation,
155
156
  network_set_edge_edit_mode,
156
157
  network_set_node_template_mode,
@@ -196,6 +197,7 @@ __all__ = [
196
197
  'network_open_cluster',
197
198
  'network_set_options',
198
199
  'network_set_theme',
200
+ 'network_destroy',
199
201
  'network_toggle_manipulation',
200
202
  'network_set_edge_edit_mode',
201
203
  'network_set_node_template_mode',
@@ -1037,7 +1037,15 @@ if (typeof Shiny !== 'undefined') {
1037
1037
  }
1038
1038
 
1039
1039
  // === RESIZE OBSERVER ===
1040
+ // The handler is debounced, so a callback can already be scheduled
1041
+ // when the instance is torn down by a re-render or an explicit
1042
+ // destroy. Disconnecting the observer stops new callbacks but does
1043
+ // not cancel a pending timer, and the late call would then reach a
1044
+ // destroyed vis network ("Cannot read properties of undefined
1045
+ // (reading 'setSize')"). Bail out unless this ref is still the
1046
+ // registered instance for this output.
1040
1047
  var resizeHandler = pyvisDebounce(function() {
1048
+ if (window.pyvisNetworks[outputId] !== ref) return;
1041
1049
  network.setSize(canvasDiv.offsetWidth + 'px', canvasDiv.offsetHeight + 'px');
1042
1050
  network.redraw();
1043
1051
  }, 150);
@@ -1198,6 +1206,14 @@ if (typeof Shiny !== 'undefined') {
1198
1206
  .replace(/pyvis-theme-\w+/, 'pyvis-theme-' + newTheme);
1199
1207
  break;
1200
1208
 
1209
+ // Explicit teardown, for a server that knows the output is going
1210
+ // away (e.g. from session.on_destroy) before the DOM node is
1211
+ // removed. Releases the vis network, its DataSets, the resize
1212
+ // observer and the global keydown handler.
1213
+ case 'destroy':
1214
+ pyvisDestroy(outputId);
1215
+ break;
1216
+
1201
1217
  // Queries - responses sent back as Shiny inputs
1202
1218
  case 'getPositions':
1203
1219
  Shiny.setInputValue(outputId + '_response_positions',
@@ -156,6 +156,7 @@ __all__ = [
156
156
  'network_open_cluster',
157
157
  'network_set_options',
158
158
  'network_set_theme',
159
+ 'network_destroy',
159
160
  'network_toggle_manipulation',
160
161
  'network_set_edge_edit_mode',
161
162
  'network_set_node_template_mode',
@@ -825,6 +826,20 @@ if SHINY_AVAILABLE:
825
826
  """
826
827
  network_set_theme(self.session, self.output_id, theme)
827
828
 
829
+ def destroy(self):
830
+ """Tear down the client-side network and release its resources.
831
+
832
+ Intended for session lifecycle hooks, which Shiny gained in 1.6.1::
833
+
834
+ ctrl = PyVisNetworkController("network", session)
835
+ session.on_destroy(ctrl.destroy)
836
+
837
+ Removing the output element from the DOM already triggers the same
838
+ teardown; this covers the case where the element outlives the
839
+ network.
840
+ """
841
+ network_destroy(self.session, self.output_id)
842
+
828
843
  # === Manipulation ===
829
844
 
830
845
  def toggle_manipulation(self, enabled: bool) -> None:
@@ -1102,6 +1117,23 @@ def network_set_theme(session: 'Session', output_id: str, theme: str):
1102
1117
  _send_network_command(session, output_id, "setTheme", {"theme": theme})
1103
1118
 
1104
1119
 
1120
+ def network_destroy(session: 'Session', output_id: str):
1121
+ """Tear down the client-side network and release its resources.
1122
+
1123
+ Frees the vis-network instance, its DataSets, the resize observer and the
1124
+ document-level keydown handler for this output. The output element itself
1125
+ is left in place; re-rendering builds a fresh network.
1126
+
1127
+ Removing the output from the DOM already triggers the same teardown, so
1128
+ this is for the case where the server knows the network is finished with
1129
+ while the element survives. Pair it with session lifecycle hooks::
1130
+
1131
+ ctrl = PyVisNetworkController("network", session)
1132
+ session.on_destroy(ctrl.destroy) # or session.on_ended(...)
1133
+ """
1134
+ _send_network_command(session, output_id, "destroy")
1135
+
1136
+
1105
1137
  def network_toggle_manipulation(session: 'Session', output_id: str, enabled: bool):
1106
1138
  """Show or hide the native manipulation toolbar.
1107
1139