itables 2.2.1__tar.gz → 2.2.3__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 (131) hide show
  1. {itables-2.2.1 → itables-2.2.3}/.github/workflows/continuous-integration.yml +3 -3
  2. {itables-2.2.1 → itables-2.2.3}/PKG-INFO +4 -3
  3. {itables-2.2.1 → itables-2.2.3}/README.md +2 -2
  4. {itables-2.2.1 → itables-2.2.3}/docs/_toc.yml +1 -1
  5. {itables-2.2.1 → itables-2.2.3}/docs/changelog.md +23 -0
  6. {itables-2.2.1 → itables-2.2.3}/docs/quick_start.md +1 -1
  7. {itables-2.2.1 → itables-2.2.3}/docs/select.md +1 -1
  8. itables-2.2.3/docs/shiny.md +128 -0
  9. itables-2.2.1/docs/ipywidgets.md → itables-2.2.3/docs/widget.md +7 -1
  10. {itables-2.2.1 → itables-2.2.3}/environment.yml +1 -1
  11. {itables-2.2.1 → itables-2.2.3}/packages/itables_for_streamlit/package-lock.json +13 -13
  12. {itables-2.2.1 → itables-2.2.3}/pyproject.toml +2 -1
  13. itables-2.2.3/src/itables/html/column_filters/pre_dt_code.js +8 -0
  14. {itables-2.2.1 → itables-2.2.3}/src/itables/html/datatables_template.html +3 -0
  15. {itables-2.2.1 → itables-2.2.3}/src/itables/javascript.py +9 -17
  16. {itables-2.2.1 → itables-2.2.3}/src/itables/version.py +1 -1
  17. {itables-2.2.1 → itables-2.2.3}/tests/test_documentation_notebooks_run.py +2 -0
  18. itables-2.2.1/docs/shiny.md +0 -22
  19. itables-2.2.1/src/itables/html/column_filters/pre_dt_code.js +0 -9
  20. itables-2.2.1/tests/sample_python_apps/itables_in_a_shiny_app.py +0 -41
  21. itables-2.2.1/tests/sample_python_apps/itables_in_a_shiny_app_with_tabs.py +0 -17
  22. itables-2.2.1/tests/test_sample_python_apps.py +0 -34
  23. {itables-2.2.1 → itables-2.2.3}/.github/codecov.yml +0 -0
  24. {itables-2.2.1 → itables-2.2.3}/.github/workflows/comment-pr.yml +0 -0
  25. {itables-2.2.1 → itables-2.2.3}/.github/workflows/publish-book.yml +0 -0
  26. {itables-2.2.1 → itables-2.2.3}/.github/workflows/publish.yml +0 -0
  27. {itables-2.2.1 → itables-2.2.3}/.gitignore +0 -0
  28. {itables-2.2.1 → itables-2.2.3}/.pre-commit-config.yaml +0 -0
  29. {itables-2.2.1 → itables-2.2.3}/.pylintrc +0 -0
  30. {itables-2.2.1 → itables-2.2.3}/LICENSE +0 -0
  31. {itables-2.2.1 → itables-2.2.3}/binder/labconfig/default_setting_overrides.json +0 -0
  32. {itables-2.2.1 → itables-2.2.3}/binder/postBuild +0 -0
  33. {itables-2.2.1 → itables-2.2.3}/binder/requirements.txt +0 -0
  34. {itables-2.2.1 → itables-2.2.3}/docs/_config.yml +0 -0
  35. {itables-2.2.1 → itables-2.2.3}/docs/advanced_parameters.md +0 -0
  36. {itables-2.2.1 → itables-2.2.3}/docs/contributing.md +0 -0
  37. {itables-2.2.1 → itables-2.2.3}/docs/custom_css.md +0 -0
  38. {itables-2.2.1 → itables-2.2.3}/docs/custom_extensions.md +0 -0
  39. {itables-2.2.1 → itables-2.2.3}/docs/dark_mode.md +0 -0
  40. {itables-2.2.1 → itables-2.2.3}/docs/dash.md +0 -0
  41. {itables-2.2.1 → itables-2.2.3}/docs/developing.md +0 -0
  42. {itables-2.2.1 → itables-2.2.3}/docs/df_example.png +0 -0
  43. {itables-2.2.1 → itables-2.2.3}/docs/downsampling.md +0 -0
  44. {itables-2.2.1 → itables-2.2.3}/docs/extensions.md +0 -0
  45. {itables-2.2.1 → itables-2.2.3}/docs/formatting.md +0 -0
  46. {itables-2.2.1 → itables-2.2.3}/docs/html_export.md +0 -0
  47. {itables-2.2.1 → itables-2.2.3}/docs/images/code.png +0 -0
  48. {itables-2.2.1 → itables-2.2.3}/docs/images/colab.png +0 -0
  49. {itables-2.2.1 → itables-2.2.3}/docs/images/html.png +0 -0
  50. {itables-2.2.1 → itables-2.2.3}/docs/images/lab.png +0 -0
  51. {itables-2.2.1 → itables-2.2.3}/docs/images/notebook.png +0 -0
  52. {itables-2.2.1 → itables-2.2.3}/docs/images/pycharm.png +0 -0
  53. {itables-2.2.1 → itables-2.2.3}/docs/pandas_style.md +0 -0
  54. {itables-2.2.1 → itables-2.2.3}/docs/polars_dataframes.md +0 -0
  55. {itables-2.2.1 → itables-2.2.3}/docs/quarto/quarto_html.qmd +0 -0
  56. {itables-2.2.1 → itables-2.2.3}/docs/quarto/quarto_revealjs.qmd +0 -0
  57. {itables-2.2.1 → itables-2.2.3}/docs/quarto.md +0 -0
  58. {itables-2.2.1 → itables-2.2.3}/docs/references.md +0 -0
  59. {itables-2.2.1 → itables-2.2.3}/docs/sample_dataframes.md +0 -0
  60. {itables-2.2.1 → itables-2.2.3}/docs/show_df.png +0 -0
  61. {itables-2.2.1 → itables-2.2.3}/docs/streamlit.md +0 -0
  62. {itables-2.2.1 → itables-2.2.3}/docs/supported_editors.md +0 -0
  63. {itables-2.2.1 → itables-2.2.3}/docs/troubleshooting.md +0 -0
  64. {itables-2.2.1 → itables-2.2.3}/packages/dt_for_itables/CHANGELOG.md +0 -0
  65. {itables-2.2.1 → itables-2.2.3}/packages/dt_for_itables/LICENSE +0 -0
  66. {itables-2.2.1 → itables-2.2.3}/packages/dt_for_itables/README.md +0 -0
  67. {itables-2.2.1 → itables-2.2.3}/packages/dt_for_itables/package-lock.json +0 -0
  68. {itables-2.2.1 → itables-2.2.3}/packages/dt_for_itables/package.json +0 -0
  69. {itables-2.2.1 → itables-2.2.3}/packages/dt_for_itables/src/index.css +0 -0
  70. {itables-2.2.1 → itables-2.2.3}/packages/dt_for_itables/src/index.d.ts +0 -0
  71. {itables-2.2.1 → itables-2.2.3}/packages/dt_for_itables/src/index.js +0 -0
  72. {itables-2.2.1 → itables-2.2.3}/packages/itables_anywidget/README.md +0 -0
  73. {itables-2.2.1 → itables-2.2.3}/packages/itables_anywidget/js/widget.css +0 -0
  74. {itables-2.2.1 → itables-2.2.3}/packages/itables_anywidget/js/widget.ts +0 -0
  75. {itables-2.2.1 → itables-2.2.3}/packages/itables_anywidget/package-lock.json +0 -0
  76. {itables-2.2.1 → itables-2.2.3}/packages/itables_anywidget/package.json +0 -0
  77. {itables-2.2.1 → itables-2.2.3}/packages/itables_anywidget/tsconfig.json +0 -0
  78. {itables-2.2.1 → itables-2.2.3}/packages/itables_for_streamlit/README.md +0 -0
  79. {itables-2.2.1 → itables-2.2.3}/packages/itables_for_streamlit/package.json +0 -0
  80. {itables-2.2.1 → itables-2.2.3}/packages/itables_for_streamlit/public/index.html +0 -0
  81. {itables-2.2.1 → itables-2.2.3}/packages/itables_for_streamlit/src/index.tsx +0 -0
  82. {itables-2.2.1 → itables-2.2.3}/packages/itables_for_streamlit/tsconfig.json +0 -0
  83. {itables-2.2.1 → itables-2.2.3}/packages/package-lock.json +0 -0
  84. {itables-2.2.1 → itables-2.2.3}/packages/package.json +0 -0
  85. {itables-2.2.1 → itables-2.2.3}/src/itables/__init__.py +0 -0
  86. {itables-2.2.1 → itables-2.2.3}/src/itables/datatables_format.py +0 -0
  87. {itables-2.2.1 → itables-2.2.3}/src/itables/downsample.py +0 -0
  88. {itables-2.2.1 → itables-2.2.3}/src/itables/html/column_filters/initComplete.js +0 -0
  89. {itables-2.2.1 → itables-2.2.3}/src/itables/html/dt_bundle.css +0 -0
  90. {itables-2.2.1 → itables-2.2.3}/src/itables/html/dt_bundle.js +0 -0
  91. {itables-2.2.1 → itables-2.2.3}/src/itables/html/init_datatables.html +0 -0
  92. {itables-2.2.1 → itables-2.2.3}/src/itables/interactive.py +0 -0
  93. {itables-2.2.1 → itables-2.2.3}/src/itables/itables_for_streamlit/asset-manifest.json +0 -0
  94. {itables-2.2.1 → itables-2.2.3}/src/itables/itables_for_streamlit/index.html +0 -0
  95. {itables-2.2.1 → itables-2.2.3}/src/itables/itables_for_streamlit/static/css/main.b5025928.css +0 -0
  96. {itables-2.2.1 → itables-2.2.3}/src/itables/itables_for_streamlit/static/css/main.b5025928.css.map +0 -0
  97. {itables-2.2.1 → itables-2.2.3}/src/itables/itables_for_streamlit/static/js/main.f651d116.js +0 -0
  98. {itables-2.2.1 → itables-2.2.3}/src/itables/itables_for_streamlit/static/js/main.f651d116.js.LICENSE.txt +0 -0
  99. {itables-2.2.1 → itables-2.2.3}/src/itables/itables_for_streamlit/static/js/main.f651d116.js.map +0 -0
  100. {itables-2.2.1 → itables-2.2.3}/src/itables/logo/loading.svg +0 -0
  101. {itables-2.2.1 → itables-2.2.3}/src/itables/logo/logo.svg +0 -0
  102. {itables-2.2.1 → itables-2.2.3}/src/itables/logo/text.svg +0 -0
  103. {itables-2.2.1 → itables-2.2.3}/src/itables/logo/wide.svg +0 -0
  104. {itables-2.2.1 → itables-2.2.3}/src/itables/logo/with_text.svg +0 -0
  105. {itables-2.2.1 → itables-2.2.3}/src/itables/options.py +0 -0
  106. {itables-2.2.1 → itables-2.2.3}/src/itables/sample_dfs.py +0 -0
  107. {itables-2.2.1 → itables-2.2.3}/src/itables/samples/countries.csv +0 -0
  108. {itables-2.2.1 → itables-2.2.3}/src/itables/samples/indicators.csv +0 -0
  109. {itables-2.2.1 → itables-2.2.3}/src/itables/samples/population.csv +0 -0
  110. {itables-2.2.1 → itables-2.2.3}/src/itables/shiny.py +0 -0
  111. {itables-2.2.1 → itables-2.2.3}/src/itables/streamlit.py +0 -0
  112. {itables-2.2.1 → itables-2.2.3}/src/itables/utils.py +0 -0
  113. {itables-2.2.1 → itables-2.2.3}/src/itables/widget/__init__.py +0 -0
  114. {itables-2.2.1 → itables-2.2.3}/src/itables/widget/static/widget.css +0 -0
  115. {itables-2.2.1 → itables-2.2.3}/src/itables/widget/static/widget.js +0 -0
  116. {itables-2.2.1 → itables-2.2.3}/tests/__init__.py +0 -0
  117. {itables-2.2.1 → itables-2.2.3}/tests/conftest.py +0 -0
  118. {itables-2.2.1 → itables-2.2.3}/tests/test_changelog.py +0 -0
  119. {itables-2.2.1 → itables-2.2.3}/tests/test_connected_notebook_is_small.py +0 -0
  120. {itables-2.2.1 → itables-2.2.3}/tests/test_datatables_format.py +0 -0
  121. {itables-2.2.1 → itables-2.2.3}/tests/test_downsample.py +0 -0
  122. {itables-2.2.1 → itables-2.2.3}/tests/test_extension_arguments.py +0 -0
  123. {itables-2.2.1 → itables-2.2.3}/tests/test_html_in_table_header.py +0 -0
  124. {itables-2.2.1 → itables-2.2.3}/tests/test_init.py +0 -0
  125. {itables-2.2.1 → itables-2.2.3}/tests/test_javascript.py +0 -0
  126. {itables-2.2.1 → itables-2.2.3}/tests/test_json_dumps.py +0 -0
  127. {itables-2.2.1 → itables-2.2.3}/tests/test_notebook.ipynb +0 -0
  128. {itables-2.2.1 → itables-2.2.3}/tests/test_pandas_style.py +0 -0
  129. {itables-2.2.1 → itables-2.2.3}/tests/test_polars.py +0 -0
  130. {itables-2.2.1 → itables-2.2.3}/tests/test_sample_dfs.py +0 -0
  131. {itables-2.2.1 → itables-2.2.3}/tests/test_update_samples.py +0 -0
@@ -40,7 +40,7 @@ jobs:
40
40
  strategy:
41
41
  fail-fast: false
42
42
  matrix:
43
- python-version: [3.7, 3.8, 3.9, "3.10", "3.11", "3.12"]
43
+ python-version: [3.7, 3.8, 3.9, "3.10", "3.11", "3.12", "3.13"]
44
44
  pandas-version: [latest]
45
45
  numpy-version: [latest]
46
46
  include:
@@ -49,10 +49,10 @@ jobs:
49
49
  - python-version: 3.9
50
50
  pandas-version: '<2.0'
51
51
  numpy-version: '<2.0'
52
- - python-version: "3.12"
52
+ - python-version: "3.13"
53
53
  pandas-version: pre
54
54
  polars: true
55
- - python-version: "3.12"
55
+ - python-version: "3.13"
56
56
  uninstall_jinja2: true
57
57
  runs-on: ubuntu-20.04
58
58
  steps:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: itables
3
- Version: 2.2.1
3
+ Version: 2.2.3
4
4
  Summary: Pandas and Polar DataFrames as interactive DataTables
5
5
  Project-URL: Homepage, https://mwouts.github.io/itables/
6
6
  Project-URL: Documentation, https://mwouts.github.io/itables
@@ -45,6 +45,7 @@ Classifier: Programming Language :: Python :: 3.9
45
45
  Classifier: Programming Language :: Python :: 3.10
46
46
  Classifier: Programming Language :: Python :: 3.11
47
47
  Classifier: Programming Language :: Python :: 3.12
48
+ Classifier: Programming Language :: Python :: 3.13
48
49
  Requires-Python: >=3.7
49
50
  Requires-Dist: ipython
50
51
  Requires-Dist: numpy
@@ -110,7 +111,7 @@ Description-Content-Type: text/markdown
110
111
  [![Conda Version](https://img.shields.io/conda/vn/conda-forge/itables.svg)](https://anaconda.org/conda-forge/itables)
111
112
  [![pyversions](https://img.shields.io/pypi/pyversions/itables.svg)](https://pypi.python.org/pypi/itables)
112
113
  [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
113
- [![Jupyter Widget](https://img.shields.io/badge/Jupyter-Widget-F37626.svg?style=flat&logo=Jupyter)](https://mwouts.github.io/itables/ipywidgets.html)
114
+ [![Jupyter Widget](https://img.shields.io/badge/Jupyter-Widget-F37626.svg?style=flat&logo=Jupyter)](https://mwouts.github.io/itables/widget.html)
114
115
  [![Streamlit App](https://static.streamlit.io/badges/streamlit_badge_black_red.svg)](https://itables.streamlit.app)
115
116
 
116
117
  This packages changes how Pandas and Polars DataFrames are rendered in Jupyter Notebooks.
@@ -169,6 +170,6 @@ You can also use ITables in [Quarto](https://mwouts.github.io/itables/quarto.htm
169
170
  ITables works well in VS Code, both in Jupyter Notebooks and in interactive Python sessions.
170
171
 
171
172
  Last but not least, ITables is also available as
172
- - a [Jupyter Widget](https://mwouts.github.io/itables/ipywidgets.html)
173
+ - a [Jupyter Widget](https://mwouts.github.io/itables/widget.html)
173
174
  - a [Streamlit](https://mwouts.github.io/itables/streamlit.html) component,
174
175
  - and it also works in [Shiny](https://mwouts.github.io/itables/shiny.html) applications.
@@ -6,7 +6,7 @@
6
6
  [![Conda Version](https://img.shields.io/conda/vn/conda-forge/itables.svg)](https://anaconda.org/conda-forge/itables)
7
7
  [![pyversions](https://img.shields.io/pypi/pyversions/itables.svg)](https://pypi.python.org/pypi/itables)
8
8
  [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
9
- [![Jupyter Widget](https://img.shields.io/badge/Jupyter-Widget-F37626.svg?style=flat&logo=Jupyter)](https://mwouts.github.io/itables/ipywidgets.html)
9
+ [![Jupyter Widget](https://img.shields.io/badge/Jupyter-Widget-F37626.svg?style=flat&logo=Jupyter)](https://mwouts.github.io/itables/widget.html)
10
10
  [![Streamlit App](https://static.streamlit.io/badges/streamlit_badge_black_red.svg)](https://itables.streamlit.app)
11
11
 
12
12
  This packages changes how Pandas and Polars DataFrames are rendered in Jupyter Notebooks.
@@ -65,6 +65,6 @@ You can also use ITables in [Quarto](https://mwouts.github.io/itables/quarto.htm
65
65
  ITables works well in VS Code, both in Jupyter Notebooks and in interactive Python sessions.
66
66
 
67
67
  Last but not least, ITables is also available as
68
- - a [Jupyter Widget](https://mwouts.github.io/itables/ipywidgets.html)
68
+ - a [Jupyter Widget](https://mwouts.github.io/itables/widget.html)
69
69
  - a [Streamlit](https://mwouts.github.io/itables/streamlit.html) component,
70
70
  - and it also works in [Shiny](https://mwouts.github.io/itables/shiny.html) applications.
@@ -17,7 +17,7 @@ parts:
17
17
  - file: supported_editors
18
18
  - caption: ITables in Applications
19
19
  chapters:
20
- - file: ipywidgets
20
+ - file: widget
21
21
  - file: streamlit
22
22
  - file: shiny
23
23
  - file: dash
@@ -1,6 +1,29 @@
1
1
  ITables ChangeLog
2
2
  =================
3
3
 
4
+ 2.2.3 (2024-11-01)
5
+ ------------------
6
+
7
+ **Fixed**
8
+ - Table footers continue to work when the notebook is exported to HTML ([#331](https://github.com/mwouts/itables/issues/331))
9
+ - The dependencies of the Streamlit component have been updated ([#327](https://github.com/mwouts/itables/pull/327), [#330](https://github.com/mwouts/itables/pull/330))
10
+
11
+ **Added**
12
+ - ITables is now tested with Python 3.13
13
+
14
+
15
+ 2.2.2 (2024-09-29)
16
+ ------------------
17
+
18
+ **Fixed**
19
+ - We have fixed a HTML pop up warning when displaying Pandas Style objects in Quarto ([#317](https://github.com/mwouts/itables/issues/317))
20
+ - The dependencies of the Streamlit component have been updated ([#323](https://github.com/mwouts/itables/pull/323))
21
+
22
+ **Added**
23
+ - We have documented how to use the `ITable` widget in a Shiny application
24
+ - We have deployed a sample Shiny app ([#276](https://github.com/mwouts/itables/issues/276))
25
+
26
+
4
27
  2.2.1 (2024-09-22)
5
28
  ------------------
6
29
 
@@ -20,7 +20,7 @@ kernelspec:
20
20
  [![Conda Version](https://img.shields.io/conda/vn/conda-forge/itables.svg)](https://anaconda.org/conda-forge/itables)
21
21
  [![pyversions](https://img.shields.io/pypi/pyversions/itables.svg)](https://pypi.python.org/pypi/itables)
22
22
  [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
23
- [![Jupyter Widget](https://img.shields.io/badge/Jupyter-Widget-F37626.svg?style=flat&logo=Jupyter)](ipywidgets.md)
23
+ [![Jupyter Widget](https://img.shields.io/badge/Jupyter-Widget-F37626.svg?style=flat&logo=Jupyter)](widget.md)
24
24
  [![Streamlit App](https://static.streamlit.io/badges/streamlit_badge_black_red.svg)](https://itables.streamlit.app)
25
25
  <a class="github-button" href="https://github.com/mwouts/itables" data-icon="octicon-star" data-show-count="true"></a>
26
26
  <script src="https://buttons.github.io/buttons.js"></script>
@@ -68,7 +68,7 @@ show(
68
68
  ```{tip}
69
69
  It is possible to get the updated `selected_rows` back in Python but for this you will have to use,
70
70
  instead of `show`, either
71
- - the `ITable` [Jupyter Widget](ipywidgets.md)
71
+ - the `ITable` [Jupyter Widget](widget.md)
72
72
  - the `interactive_table` [Streamlit component](streamlit.md)
73
73
  - or `DT` in a [Shiny app](shiny.md).
74
74
  ```
@@ -0,0 +1,128 @@
1
+ # Shiny
2
+
3
+ ## Using `ITable` in Shiny
4
+
5
+ The recommended way to use `ITables` in a [Shiny for Python](https://shiny.rstudio.com/py/) application is with the [ITable Widget](widget.md).
6
+
7
+ In the Shiny Express syntax this is as simple as:
8
+ ```python
9
+ from shinywidgets import render_widget
10
+
11
+ from itables.widget import ITable
12
+
13
+
14
+ @render_widget
15
+ def my_table():
16
+ """
17
+ This function creates the "my_table" widget.
18
+ """
19
+ # Note: df is an optional argument
20
+ return ITable(caption="A table rendered with ITable")
21
+ ```
22
+
23
+ In the Shiny Core syntax you will need, in addition to the above,
24
+ to insert the table in the UI with `output_widget`:
25
+
26
+ ```python
27
+ from shiny import ui
28
+ from shinywidgets import output_widget
29
+
30
+ app_ui = ui.page_fluid(
31
+ # ...
32
+ output_widget("my_table"),
33
+ # ...
34
+ )
35
+ ```
36
+
37
+ ## Updating the widget
38
+
39
+ Rather than re-creating the widget each time the data changes, you can
40
+ call the `.update` method of the widget object, using the `@reactive.effect`
41
+ decorator:
42
+
43
+ ```python
44
+ from shiny import reactive
45
+ from shiny.express import input
46
+
47
+ from itables.sample_dfs import get_dict_of_test_dfs
48
+
49
+ dfs = get_dict_of_test_dfs()
50
+
51
+
52
+ @reactive.effect
53
+ def _():
54
+ """
55
+ This "reactive.effect" calls the "update" method of the ITable widget
56
+ to update the widget with the new inputs.
57
+ """
58
+ # Get the new inputs
59
+ df = dfs[input.table_selector()]
60
+ selected_rows = list(range(0, len(df), 3))
61
+
62
+ # Update the widget
63
+ my_table.widget.update(df, selected_rows=selected_rows)
64
+ ```
65
+
66
+ ## Accessing the `selected_rows` attribute
67
+
68
+ The `reactive_read` function lets you access the `selected_rows` attribute
69
+ of the `ITable` object. The code below displays the selected rows:
70
+
71
+ ```python
72
+ from shiny.express import render
73
+ from shinywidgets import reactive_read
74
+
75
+
76
+ @render.code
77
+ def selected_rows():
78
+ """
79
+ Here we read the "selected_rows" attribute of the ITable widget
80
+ """
81
+ return str(reactive_read(my_table.widget, "selected_rows"))
82
+ ```
83
+
84
+ ## An example application
85
+
86
+ This [repository](https://github.com/mwouts/demo_itables_in_shiny-py/) contains a simple
87
+ example of a Shiny application that uses the `ITable` widget.
88
+
89
+ The source code of the application
90
+ is at [`app.py`](https://github.com/mwouts/demo_itables_in_shiny-py/blob/main/itable_widget/app.py)
91
+ (Shiny Express) or [`app-core.py`](https://github.com/mwouts/demo_itables_in_shiny-py/blob/main/itable_widget/app-core.py)
92
+ (Shiny Core).
93
+
94
+ ```{div}
95
+ <iframe src="https://itables.shinyapps.io/itable_widget?embed=true"
96
+ style="height: 800px; width: 100%;"></iframe>
97
+ ```
98
+
99
+ ## Limitations
100
+
101
+ Compared to `show`, the `ITable` widget has the same limitations as the [Streamlit component](streamlit.md#limitations),
102
+ e.g. structured headers are not available, you can't pass JavaScript callback, etc.
103
+
104
+ The good news is that if you only want to _display_ the table, you do not need
105
+ the `ITable` widget. You can render the table using `HTML(DT(...))` as here:
106
+
107
+ ```python
108
+ from shiny import ui
109
+
110
+ from itables.sample_dfs import get_countries
111
+ from itables.shiny import DT, init_itables
112
+
113
+ # Load the datatables library and css from the ITables package
114
+ # (use connected=True if you prefer to load it from the internet)
115
+ ui.HTML(init_itables())
116
+
117
+ # Render the table with DT
118
+ ui.HTML(DT(get_countries(html=False)))
119
+ ```
120
+
121
+ An example for an application that uses `DT` is available at [`app.py`](https://github.com/mwouts/demo_itables_in_shiny-py/blob/main/itables_DT/app.py)
122
+ (Shiny Express) or [`app-core.py`](https://github.com/mwouts/demo_itables_in_shiny-py/blob/main/itables_DT/app-core.py)
123
+ (Shiny Core).
124
+
125
+ ```{div}
126
+ <iframe src="https://itables.shinyapps.io/itables_DT?embed=true"
127
+ style="height: 800px; width: 100%;"></iframe>
128
+ ```
@@ -37,6 +37,12 @@ table = ITable(df, selected_rows=[0, 2, 5], select=True)
37
37
  table
38
38
  ```
39
39
 
40
+ ```{tip}
41
+ The table shown above does not reflect the initial row selection.
42
+ This is because the `ITable` widget was updated with
43
+ more row selection commands, see below.
44
+ ```
45
+
40
46
  ## The `selected_rows` traits
41
47
 
42
48
  The `selected_rows` attribute of the `ITable` object provides a view on the
@@ -93,7 +99,7 @@ Compared to `show`, the `ITable` widget has the same limitations as the [Streaml
93
99
  e.g. structured headers are not available, you can't pass JavaScript callback, etc.
94
100
 
95
101
  The good news is that if you only want to _display_ the table, you do not need
96
- the `ITables` widget. Below is an example in which we use `show` to display a different
102
+ the `ITable` widget. Below is an example in which we use `show` to display a different
97
103
  table depending on the value of a drop-down component:
98
104
 
99
105
  ```python
@@ -1,6 +1,5 @@
1
1
  name: itables
2
2
  channels:
3
- - defaults
4
3
  - conda-forge
5
4
  dependencies:
6
5
  - nodejs
@@ -24,6 +23,7 @@ dependencies:
24
23
  - twine
25
24
  - ghp-import
26
25
  - shiny
26
+ - shinywidgets
27
27
  - streamlit
28
28
  - anywidget
29
29
  - pip:
@@ -6156,9 +6156,9 @@
6156
6156
  "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="
6157
6157
  },
6158
6158
  "node_modules/cookie": {
6159
- "version": "0.6.0",
6160
- "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz",
6161
- "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==",
6159
+ "version": "0.7.1",
6160
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz",
6161
+ "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==",
6162
6162
  "engines": {
6163
6163
  "node": ">= 0.6"
6164
6164
  }
@@ -8055,16 +8055,16 @@
8055
8055
  }
8056
8056
  },
8057
8057
  "node_modules/express": {
8058
- "version": "4.21.0",
8059
- "resolved": "https://registry.npmjs.org/express/-/express-4.21.0.tgz",
8060
- "integrity": "sha512-VqcNGcj/Id5ZT1LZ/cfihi3ttTn+NJmkli2eZADigjq29qTlWi/hAQ43t/VLPq8+UX06FCEx3ByOYet6ZFblng==",
8058
+ "version": "4.21.1",
8059
+ "resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz",
8060
+ "integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==",
8061
8061
  "dependencies": {
8062
8062
  "accepts": "~1.3.8",
8063
8063
  "array-flatten": "1.1.1",
8064
8064
  "body-parser": "1.20.3",
8065
8065
  "content-disposition": "0.5.4",
8066
8066
  "content-type": "~1.0.4",
8067
- "cookie": "0.6.0",
8067
+ "cookie": "0.7.1",
8068
8068
  "cookie-signature": "1.0.6",
8069
8069
  "debug": "2.6.9",
8070
8070
  "depd": "2.0.0",
@@ -9128,9 +9128,9 @@
9128
9128
  }
9129
9129
  },
9130
9130
  "node_modules/http-proxy-middleware": {
9131
- "version": "2.0.6",
9132
- "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz",
9133
- "integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==",
9131
+ "version": "2.0.7",
9132
+ "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.7.tgz",
9133
+ "integrity": "sha512-fgVY8AV7qU7z/MmXJ/rxwbrtQH4jBQ9m7kp3llF0liB7glmFeVZFBepQb32T3y8n8k2+AEYuMPCpinYW+/CuRA==",
9134
9134
  "dependencies": {
9135
9135
  "@types/http-proxy": "^1.17.8",
9136
9136
  "http-proxy": "^1.18.1",
@@ -15180,9 +15180,9 @@
15180
15180
  }
15181
15181
  },
15182
15182
  "node_modules/rollup": {
15183
- "version": "2.79.1",
15184
- "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz",
15185
- "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==",
15183
+ "version": "2.79.2",
15184
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.2.tgz",
15185
+ "integrity": "sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==",
15186
15186
  "bin": {
15187
15187
  "rollup": "dist/bin/rollup"
15188
15188
  },
@@ -24,6 +24,7 @@ classifiers = [
24
24
  "Programming Language :: Python :: 3.10",
25
25
  "Programming Language :: Python :: 3.11",
26
26
  "Programming Language :: Python :: 3.12",
27
+ "Programming Language :: Python :: 3.13",
27
28
  ]
28
29
  requires-python = ">= 3.7"
29
30
  dependencies = ["IPython", "pandas", "numpy"]
@@ -44,8 +45,8 @@ test = [
44
45
  "ipykernel",
45
46
  "nbconvert",
46
47
  "jupytext",
47
- # Shiny test app
48
48
  "shiny",
49
+ # "shinywidgets",
49
50
  # Test urls
50
51
  "requests",
51
52
  ]
@@ -0,0 +1,8 @@
1
+ // Setup - add a text input to each header or footer cell
2
+ $('#table_id:not(.dataTable) thead_or_tfoot th').each(function () {
3
+ var input = document.createElement("input");
4
+ input.type = "text";
5
+ input.placeholder = "Search " + $(this).text();
6
+
7
+ $(this).html(input);
8
+ });
@@ -4,6 +4,9 @@
4
4
  import {DataTable, jQuery as $} from 'https://www.unpkg.com/dt_for_itables/dt_bundle.js';
5
5
 
6
6
  document.querySelectorAll("#table_id:not(.dataTable)").forEach(table => {
7
+ if (!(table instanceof HTMLTableElement))
8
+ return;
9
+
7
10
  // Define the table data
8
11
  const data = [];
9
12
 
@@ -60,12 +60,7 @@ DEFAULT_LAYOUT_CONTROLS = set(DEFAULT_LAYOUT.values())
60
60
 
61
61
 
62
62
  try:
63
- import google.colab
64
-
65
- # I can't find out how to suppress the LGTM alert about unused-import
66
- # (Tried with # lgtm[py/unused-import] # noqa: F401)
67
- # So we use the import:
68
- assert google.colab.output
63
+ import google.colab # noqa: F401
69
64
 
70
65
  GOOGLE_COLAB = True
71
66
  except ImportError:
@@ -132,19 +127,17 @@ def generate_init_offline_itables_html(dt_bundle: Path):
132
127
  dt_css = dt_bundle.with_suffix(".css").read_text(encoding="utf-8")
133
128
  dt64 = b64encode(dt_src.encode("utf-8")).decode("ascii")
134
129
 
135
- id = "itables_init_notebook_mode_" + str(uuid.uuid4()).replace("-", "_")
136
-
137
130
  return f"""<style>{dt_css}</style>
138
- <div id="{id}" style="vertical-align:middle; text-align:left">
139
- {get_animated_logo(opt.display_logo_when_loading)}<div>
140
- This is the <code>init_notebook_mode</code> cell from ITables v{itables_version}<br>
141
- (you should not see this message - is your notebook <it>trusted</it>?)
142
- </div>
143
- </div>
131
+ <div style="vertical-align:middle; text-align:left">
144
132
  <script>
145
133
  window.{DATATABLES_SRC_FOR_ITABLES} = "data:text/javascript;base64,{dt64}";
146
- document.querySelectorAll("#{id}").forEach(e => e.remove());
147
134
  </script>
135
+ <noscript>
136
+ {get_animated_logo(opt.display_logo_when_loading)}
137
+ This is the <code>init_notebook_mode</code> cell from ITables v{itables_version}<br>
138
+ (you should not see this message - is your notebook <it>trusted</it>?)
139
+ </noscript>
140
+ </div>
148
141
  """
149
142
 
150
143
 
@@ -202,8 +195,7 @@ Loading ITables v{itables_version} from {itables_source}...
202
195
  footer = ""
203
196
 
204
197
  return """<table id="{table_id}" class="{classes}" data-quarto-disable-processing="true" {style}>
205
- {tags}{header}<tbody>{tbody}</tbody>
206
- {footer}
198
+ {tags}{header}{footer}<tbody>{tbody}</tbody>
207
199
  </table>""".format(
208
200
  table_id=table_id,
209
201
  classes=classes,
@@ -1,3 +1,3 @@
1
1
  """ITables' version number"""
2
2
 
3
- __version__ = "2.2.1"
3
+ __version__ = "2.2.3"
@@ -31,6 +31,8 @@ def test_run_documentation_notebooks(notebook):
31
31
  pytest.skip("Polars is not available")
32
32
  if "pandas_style" in notebook.stem and pd_style is None:
33
33
  pytest.skip("Pandas Style is not available")
34
+ if "shiny" in notebook.stem:
35
+ pytest.skip("shinywidgets makes the widget.md notebook fail")
34
36
 
35
37
  org_options = dir(opt)
36
38
 
@@ -1,22 +0,0 @@
1
- # Shiny
2
-
3
- You can use ITables in Web applications generated with [Shiny](https://shiny.rstudio.com/py/) for Python with e.g.
4
- ```python
5
- from shiny import ui
6
-
7
- from itables.sample_dfs import get_countries
8
- from itables.shiny import DT, init_itables
9
-
10
- # Load the datatables library and css from the ITables package
11
- # (use connected=True if you prefer to load it from the internet)
12
- ui.HTML(init_itables(connected=False))
13
-
14
- # Render the table with DT
15
- ui.HTML(DT(get_countries(html=False)))
16
- ```
17
-
18
- If you enable row selection and set an id on your table, e.g. `DT(df, table_id="my_table", select=True)` then
19
- ITables will provide the list of selected rows at `input.my_table_selected_rows()` (replace `my_table` with your
20
- own table id).
21
-
22
- See also our [tested examples](https://github.com/mwouts/itables/tree/main/tests/sample_python_apps).
@@ -1,9 +0,0 @@
1
- // Setup - add a text input to each header or footer cell
2
- $('#table_id:not(.dataTable) thead_or_tfoot th').each(function () {
3
- let title = $(this).text();
4
- $(this).html('<input type="text" placeholder="Search ' +
5
- // We use encodeURI to avoid this LGTM error:
6
- // https://lgtm.com/rules/1511866576920/
7
- encodeURI(title).replaceAll("%20", " ") +
8
- '" />');
9
- });
@@ -1,41 +0,0 @@
1
- # Run this app with "shiny run file.py"
2
- from shiny import App, Inputs, Outputs, Session, render, ui
3
-
4
- from itables.sample_dfs import get_countries
5
- from itables.shiny import DT, init_itables
6
-
7
- app_ui = ui.page_fluid(
8
- ui.HTML(init_itables()),
9
- ui.layout_columns(
10
- ui.value_box(
11
- "Selected rows",
12
- ui.output_ui("selected_rows"),
13
- ),
14
- fill=False,
15
- ),
16
- ui.layout_columns(
17
- ui.card(ui.output_ui("table"), full_screen=True),
18
- ),
19
- title="ITables in a Shiny App",
20
- )
21
-
22
-
23
- def server(input: Inputs, output: Outputs, session: Session):
24
- @render.ui
25
- def table():
26
- return ui.HTML(
27
- DT(
28
- get_countries(html=False),
29
- table_id="countries",
30
- select=True,
31
- selected_rows=[0, 1, 2, 207],
32
- )
33
- )
34
-
35
- @render.ui
36
- def selected_rows():
37
- selected_rows = list(input.countries_selected_rows())
38
- return f"You have selected {len(selected_rows)} rows: {selected_rows}"
39
-
40
-
41
- app = App(app_ui, server, debug=True)
@@ -1,17 +0,0 @@
1
- # Run this app with "shiny run file.py"
2
- from shiny import App, ui
3
-
4
- from itables.sample_dfs import get_dict_of_test_dfs
5
- from itables.shiny import DT
6
-
7
- app_ui = ui.page_fluid(
8
- # Display the different tables in different tabs
9
- ui.navset_tab(
10
- *[
11
- ui.nav_panel(name, ui.HTML(DT(df)))
12
- for name, df in get_dict_of_test_dfs().items()
13
- ]
14
- )
15
- )
16
-
17
- app = App(app_ui, server=None)
@@ -1,34 +0,0 @@
1
- import runpy
2
- from pathlib import Path
3
-
4
- import pytest
5
- from packaging.version import Version
6
-
7
- try:
8
- from shiny import __version__ as shiny_version
9
- except ImportError:
10
- shiny_version = "NA"
11
-
12
-
13
- def get_app_file_list():
14
- return [
15
- app_file
16
- for app_file in (Path(__file__).parent / "sample_python_apps").iterdir()
17
- ]
18
-
19
-
20
- def test_get_app_file_list():
21
- app_file_list = get_app_file_list()
22
- for app_file in app_file_list:
23
- assert app_file.suffix == ".py"
24
- assert "itables_in_a_shiny_app" in [app_file.stem for app_file in app_file_list]
25
-
26
-
27
- @pytest.mark.parametrize("app_file", get_app_file_list(), ids=lambda path: path.stem)
28
- @pytest.mark.skipif(
29
- shiny_version == "NA" or Version(shiny_version) < Version("1.0"),
30
- reason=f"This test requires shiny>=1.0, got {shiny_version}",
31
- )
32
- def test_app_file(app_file):
33
- print(f"This is shiny=={shiny_version}")
34
- runpy.run_path(str(app_file))
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes