Skip to content

Commit ac57c4e

Browse files
committed
Document how to use ITable with Shiny
1 parent fae642d commit ac57c4e

File tree

7 files changed

+116
-100
lines changed

7 files changed

+116
-100
lines changed

docs/changelog.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ ITables ChangeLog
88
- We have fixed a HTML pop up warning when displaying Pandas Style objects in Quarto ([#317](https://github.com/mwouts/itables/issues/317))
99
- The dependencies of the Streamlit component have been updated ([#323](https://github.com/mwouts/itables/pull/323))
1010

11+
**Added**
12+
- We have documented how to use the `ITable` widget in a Shiny application and deployed a sample app ([#276](https://github.com/mwouts/itables/issues/276))
13+
1114

1215
2.2.1 (2024-09-22)
1316
------------------

docs/shiny.md

Lines changed: 112 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,109 @@
11
# Shiny
22

3-
You can use ITables in Web applications generated with [Shiny](https://shiny.rstudio.com/py/) for Python with e.g.
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_sidebar(
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+
4107
```python
5108
from shiny import ui
6109

@@ -9,14 +112,17 @@ from itables.shiny import DT, init_itables
9112

10113
# Load the datatables library and css from the ITables package
11114
# (use connected=True if you prefer to load it from the internet)
12-
ui.HTML(init_itables(connected=False))
115+
ui.HTML(init_itables())
13116

14117
# Render the table with DT
15118
ui.HTML(DT(get_countries(html=False)))
16119
```
17120

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).
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).
21124

22-
See also our [tested examples](https://github.com/mwouts/itables/tree/main/tests/sample_python_apps).
125+
```{div}
126+
<iframe src="https://itables.shinyapps.io/itables_DT?embed=true"
127+
style="height: 800px; width: 100%;"></iframe>
128+
```

environment.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ dependencies:
2424
- twine
2525
- ghp-import
2626
- shiny
27+
- shinywidgets
2728
- streamlit
2829
- anywidget
2930
- pip:

pyproject.toml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,6 @@ test = [
4444
"ipykernel",
4545
"nbconvert",
4646
"jupytext",
47-
# Shiny test app
48-
"shiny",
4947
# Test urls
5048
"requests",
5149
]

tests/sample_python_apps/itables_in_a_shiny_app.py

Lines changed: 0 additions & 41 deletions
This file was deleted.

tests/sample_python_apps/itables_in_a_shiny_app_with_tabs.py

Lines changed: 0 additions & 17 deletions
This file was deleted.

tests/test_sample_python_apps.py

Lines changed: 0 additions & 34 deletions
This file was deleted.

0 commit comments

Comments
 (0)