itables 2.3.0__tar.gz → 2.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 (76) hide show
  1. {itables-2.3.0 → itables-2.4.0}/PKG-INFO +38 -15
  2. {itables-2.3.0 → itables-2.4.0}/README.md +14 -11
  3. {itables-2.3.0 → itables-2.4.0}/itables/__init__.py +2 -7
  4. {itables-2.3.0 → itables-2.4.0}/itables/dash.py +1 -7
  5. itables-2.4.0/itables/datatables_format.py +160 -0
  6. {itables-2.3.0 → itables-2.4.0}/itables/downsample.py +14 -11
  7. itables-2.4.0/itables/html/datatables_template.html +14 -0
  8. itables-2.4.0/itables/html/dt_bundle.css +1 -0
  9. itables-2.4.0/itables/html/dt_bundle.js +144 -0
  10. itables-2.4.0/itables/html/init_datatables.html +4 -0
  11. itables-2.4.0/itables/itables_for_streamlit/asset-manifest.json +13 -0
  12. {itables-2.3.0 → itables-2.4.0}/itables/itables_for_streamlit/index.html +1 -1
  13. itables-2.4.0/itables/itables_for_streamlit/static/css/main.fffc57ef.css +2 -0
  14. itables-2.4.0/itables/itables_for_streamlit/static/css/main.fffc57ef.css.map +1 -0
  15. itables-2.4.0/itables/itables_for_streamlit/static/js/main.15cf0d5c.js +3 -0
  16. itables-2.3.0/itables/itables_for_streamlit/static/js/main.8b03a1d9.js.LICENSE.txt → itables-2.4.0/itables/itables_for_streamlit/static/js/main.15cf0d5c.js.LICENSE.txt +1 -1
  17. itables-2.4.0/itables/itables_for_streamlit/static/js/main.15cf0d5c.js.map +1 -0
  18. itables-2.4.0/itables/javascript.py +815 -0
  19. itables-2.4.0/itables/options.py +99 -0
  20. {itables-2.3.0 → itables-2.4.0}/itables/sample_dfs.py +43 -29
  21. {itables-2.3.0 → itables-2.4.0}/itables/shiny.py +14 -10
  22. itables-2.4.0/itables/streamlit.py +20 -0
  23. itables-2.4.0/itables/typing.py +199 -0
  24. {itables-2.3.0 → itables-2.4.0}/itables/utils.py +1 -1
  25. {itables-2.3.0 → itables-2.4.0}/itables/version.py +1 -1
  26. itables-2.4.0/itables/widget/__init__.py +108 -0
  27. itables-2.4.0/itables/widget/static/widget.css +1 -0
  28. itables-2.4.0/itables/widget/static/widget.js +144 -0
  29. {itables-2.3.0 → itables-2.4.0}/itables_for_dash/ITable.py +19 -26
  30. itables-2.4.0/itables_for_dash/__init__.py +59 -0
  31. itables-2.4.0/itables_for_dash/async-ITable.js +3 -0
  32. {itables-2.3.0 → itables-2.4.0}/itables_for_dash/async-ITable.js.LICENSE.txt +1 -1
  33. itables-2.4.0/itables_for_dash/async-ITable.js.map +1 -0
  34. itables-2.4.0/itables_for_dash/itables_for_dash.min.js +2 -0
  35. itables-2.4.0/itables_for_dash/itables_for_dash.min.js.map +1 -0
  36. itables-2.4.0/itables_for_dash/metadata.json +1 -0
  37. {itables-2.3.0 → itables-2.4.0}/itables_for_dash/package-info.json +5 -5
  38. itables-2.4.0/itables_for_dash/properties.py +83 -0
  39. {itables-2.3.0 → itables-2.4.0}/pyproject.toml +8 -8
  40. itables-2.3.0/itables/datatables_format.py +0 -146
  41. itables-2.3.0/itables/html/column_filters/initComplete.js +0 -14
  42. itables-2.3.0/itables/html/column_filters/pre_dt_code.js +0 -8
  43. itables-2.3.0/itables/html/datatables_template.html +0 -20
  44. itables-2.3.0/itables/html/dt_bundle.css +0 -1
  45. itables-2.3.0/itables/html/dt_bundle.js +0 -144
  46. itables-2.3.0/itables/html/init_datatables.html +0 -25
  47. itables-2.3.0/itables/itables_for_streamlit/asset-manifest.json +0 -13
  48. itables-2.3.0/itables/itables_for_streamlit/static/css/main.2bc6c309.css +0 -2
  49. itables-2.3.0/itables/itables_for_streamlit/static/css/main.2bc6c309.css.map +0 -1
  50. itables-2.3.0/itables/itables_for_streamlit/static/js/main.8b03a1d9.js +0 -3
  51. itables-2.3.0/itables/itables_for_streamlit/static/js/main.8b03a1d9.js.map +0 -1
  52. itables-2.3.0/itables/javascript.py +0 -979
  53. itables-2.3.0/itables/options.py +0 -75
  54. itables-2.3.0/itables/streamlit.py +0 -13
  55. itables-2.3.0/itables/widget/__init__.py +0 -121
  56. itables-2.3.0/itables/widget/static/widget.css +0 -1
  57. itables-2.3.0/itables/widget/static/widget.js +0 -144
  58. itables-2.3.0/itables_for_dash/__init__.py +0 -53
  59. itables-2.3.0/itables_for_dash/async-ITable.js +0 -3
  60. itables-2.3.0/itables_for_dash/async-ITable.js.map +0 -1
  61. itables-2.3.0/itables_for_dash/itables_for_dash.min.js +0 -2
  62. itables-2.3.0/itables_for_dash/itables_for_dash.min.js.map +0 -1
  63. itables-2.3.0/itables_for_dash/metadata.json +0 -1
  64. itables-2.3.0/itables_for_dash/properties.py +0 -77
  65. {itables-2.3.0 → itables-2.4.0}/.gitignore +0 -0
  66. {itables-2.3.0 → itables-2.4.0}/LICENSE +0 -0
  67. {itables-2.3.0 → itables-2.4.0}/itables/interactive.py +0 -0
  68. {itables-2.3.0 → itables-2.4.0}/itables/logo/loading.svg +0 -0
  69. {itables-2.3.0 → itables-2.4.0}/itables/logo/logo.svg +0 -0
  70. {itables-2.3.0 → itables-2.4.0}/itables/logo/text.svg +0 -0
  71. {itables-2.3.0 → itables-2.4.0}/itables/logo/wide.svg +0 -0
  72. {itables-2.3.0 → itables-2.4.0}/itables/logo/with_text.svg +0 -0
  73. {itables-2.3.0 → itables-2.4.0}/itables/samples/countries.csv +0 -0
  74. {itables-2.3.0 → itables-2.4.0}/itables/samples/indicators.csv +0 -0
  75. {itables-2.3.0 → itables-2.4.0}/itables/samples/population.csv +0 -0
  76. {itables-2.3.0 → itables-2.4.0}/itables_for_dash/_imports_.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: itables
3
- Version: 2.3.0
3
+ Version: 2.4.0
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
@@ -39,31 +39,39 @@ Classifier: Intended Audience :: Science/Research
39
39
  Classifier: License :: OSI Approved :: MIT License
40
40
  Classifier: Programming Language :: Python
41
41
  Classifier: Programming Language :: Python :: 3
42
- Classifier: Programming Language :: Python :: 3.7
43
- Classifier: Programming Language :: Python :: 3.8
44
42
  Classifier: Programming Language :: Python :: 3.9
45
43
  Classifier: Programming Language :: Python :: 3.10
46
44
  Classifier: Programming Language :: Python :: 3.11
47
45
  Classifier: Programming Language :: Python :: 3.12
48
46
  Classifier: Programming Language :: Python :: 3.13
49
- Requires-Python: >=3.7
47
+ Requires-Python: >=3.9
50
48
  Requires-Dist: ipython
51
49
  Requires-Dist: numpy
52
50
  Requires-Dist: pandas
53
51
  Provides-Extra: all
54
52
  Requires-Dist: anywidget; extra == 'all'
53
+ Requires-Dist: dash; extra == 'all'
55
54
  Requires-Dist: matplotlib; extra == 'all'
56
55
  Requires-Dist: polars; extra == 'all'
57
56
  Requires-Dist: pyarrow; extra == 'all'
58
57
  Requires-Dist: pytz; extra == 'all'
58
+ Requires-Dist: shiny; extra == 'all'
59
+ Requires-Dist: shinywidgets; extra == 'all'
60
+ Requires-Dist: streamlit; extra == 'all'
59
61
  Requires-Dist: traitlets; extra == 'all'
62
+ Requires-Dist: typeguard>=4.4.1; extra == 'all'
60
63
  Requires-Dist: world-bank-data; extra == 'all'
64
+ Provides-Extra: check-type
65
+ Requires-Dist: typeguard>=4.4.1; extra == 'check-type'
66
+ Provides-Extra: dash
67
+ Requires-Dist: dash; extra == 'dash'
61
68
  Provides-Extra: dev
62
69
  Requires-Dist: anywidget; extra == 'dev'
63
70
  Requires-Dist: dash; extra == 'dev'
64
71
  Requires-Dist: ipykernel; extra == 'dev'
65
72
  Requires-Dist: jupyterlab; extra == 'dev'
66
73
  Requires-Dist: jupytext; extra == 'dev'
74
+ Requires-Dist: marimo; extra == 'dev'
67
75
  Requires-Dist: matplotlib; extra == 'dev'
68
76
  Requires-Dist: nbconvert; extra == 'dev'
69
77
  Requires-Dist: polars; extra == 'dev'
@@ -73,7 +81,10 @@ Requires-Dist: pytest-cov; extra == 'dev'
73
81
  Requires-Dist: pytz; extra == 'dev'
74
82
  Requires-Dist: requests; extra == 'dev'
75
83
  Requires-Dist: shiny; extra == 'dev'
84
+ Requires-Dist: shinywidgets; extra == 'dev'
85
+ Requires-Dist: streamlit; extra == 'dev'
76
86
  Requires-Dist: traitlets; extra == 'dev'
87
+ Requires-Dist: typeguard>=4.4.1; extra == 'dev'
77
88
  Requires-Dist: watchfiles; extra == 'dev'
78
89
  Requires-Dist: world-bank-data; extra == 'dev'
79
90
  Provides-Extra: polars
@@ -82,6 +93,11 @@ Requires-Dist: pyarrow; extra == 'polars'
82
93
  Provides-Extra: samples
83
94
  Requires-Dist: pytz; extra == 'samples'
84
95
  Requires-Dist: world-bank-data; extra == 'samples'
96
+ Provides-Extra: shiny
97
+ Requires-Dist: shiny; extra == 'shiny'
98
+ Requires-Dist: shinywidgets; extra == 'shiny'
99
+ Provides-Extra: streamlit
100
+ Requires-Dist: streamlit; extra == 'streamlit'
85
101
  Provides-Extra: style
86
102
  Requires-Dist: matplotlib; extra == 'style'
87
103
  Provides-Extra: test
@@ -89,6 +105,7 @@ Requires-Dist: anywidget; extra == 'test'
89
105
  Requires-Dist: dash; extra == 'test'
90
106
  Requires-Dist: ipykernel; extra == 'test'
91
107
  Requires-Dist: jupytext; extra == 'test'
108
+ Requires-Dist: marimo; extra == 'test'
92
109
  Requires-Dist: matplotlib; extra == 'test'
93
110
  Requires-Dist: nbconvert; extra == 'test'
94
111
  Requires-Dist: polars; extra == 'test'
@@ -98,7 +115,10 @@ Requires-Dist: pytest-cov; extra == 'test'
98
115
  Requires-Dist: pytz; extra == 'test'
99
116
  Requires-Dist: requests; extra == 'test'
100
117
  Requires-Dist: shiny; extra == 'test'
118
+ Requires-Dist: shinywidgets; extra == 'test'
119
+ Requires-Dist: streamlit; extra == 'test'
101
120
  Requires-Dist: traitlets; extra == 'test'
121
+ Requires-Dist: typeguard>=4.4.1; extra == 'test'
102
122
  Requires-Dist: world-bank-data; extra == 'test'
103
123
  Provides-Extra: widget
104
124
  Requires-Dist: anywidget; extra == 'widget'
@@ -114,10 +134,11 @@ Description-Content-Type: text/markdown
114
134
  [![Conda Version](https://img.shields.io/conda/vn/conda-forge/itables.svg)](https://anaconda.org/conda-forge/itables)
115
135
  [![pyversions](https://img.shields.io/pypi/pyversions/itables.svg)](https://pypi.python.org/pypi/itables)
116
136
  [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
117
- [![Jupyter Widget](https://img.shields.io/badge/Jupyter-Widget-F37626.svg?style=flat&logo=Jupyter)](https://mwouts.github.io/itables/widget.html)
137
+ [![Jupyter Widget](https://img.shields.io/badge/Jupyter-Widget-F37626.svg?style=flat&logo=Jupyter)](https://mwouts.github.io/itables/apps/widget.html)
138
+ [![Dash Component](https://img.shields.io/badge/Dash-Plotly-1098F7.svg?style=flat&logo=Plotly)](https://mwouts.github.io/itables/apps/dash.html)
118
139
  [![Streamlit App](https://static.streamlit.io/badges/streamlit_badge_black_red.svg)](https://itables.streamlit.app)
119
140
 
120
- This packages changes how Pandas and Polars DataFrames are rendered in Jupyter Notebooks.
141
+ This packages changes how Pandas and Polars DataFrames are rendered in Python notebooks and applications.
121
142
  With `itables` you can display your tables as interactive [DataTables](https://datatables.net/)
122
143
  that you can sort, paginate, scroll or filter.
123
144
 
@@ -145,7 +166,7 @@ or
145
166
  conda install itables -c conda-forge
146
167
  ```
147
168
 
148
- Activate the interactive mode for all series and dataframes with
169
+ Activate the interactive mode for all series and dataframes in Jupyter with
149
170
  ```python
150
171
  import itables
151
172
 
@@ -157,14 +178,8 @@ and then render any DataFrame as an interactive table that you can sort, search
157
178
  If you prefer to render only selected DataFrames as interactive tables, call `itables.init_notebook_mode(all_interactive=False)`, then use `itables.show` to show just one Series or DataFrame as an interactive table:
158
179
  ![show](docs/show_df.png)
159
180
 
160
- Since ITables v1.0, the [jQuery](https://jquery.com/) and [DataTables](https://datatables.net/) libraries and CSS
161
- are injected in the notebook when you execute `init_notebook_mode` with its default argument `connected=False`.
162
- Thanks to this the interactive tables will work even without a connection to the internet.
163
181
 
164
- If you prefer to load the libraries dynamically (and keep the notebook lighter), use `connected=True` when you
165
- execute `init_notebook_mode`.
166
-
167
- ## Supported notebook environments
182
+ ## ITables in Notebooks
168
183
 
169
184
  ITables works in all the usual Jupyter Notebook environments, including Jupyter Notebook, Jupyter Lab, Jupyter nbconvert (i.e. the tables are still interactive in the HTML export of a notebook), Jupyter Book, Google Colab and Kaggle.
170
185
 
@@ -174,8 +189,16 @@ ITables works well in VS Code, both in Jupyter Notebooks and in interactive Pyth
174
189
 
175
190
  ## ITables in Python applications
176
191
 
177
- Last but not least, ITables is also available as
192
+ ITables is also available as
178
193
  - a [Jupyter Widget](https://mwouts.github.io/itables/widget.html)
179
194
  - a [Dash](https://mwouts.github.io/itables/dash.html) component
180
195
  - a [Streamlit](https://mwouts.github.io/itables/streamlit.html) component,
181
196
  - and it also works in [Shiny](https://mwouts.github.io/itables/shiny.html) applications.
197
+
198
+ ## Licence
199
+
200
+ ITables is developed by [Marc Wouts](https://github.com/mwouts) on [GitHub](https://github.com/mwouts/itables),
201
+ under a MIT license.
202
+
203
+ ITables is a wrapper for [datatables.net](https://datatables.net/) which is developed by Allan Jardine
204
+ [(sponsor him!)](https://github.com/sponsors/AllanJard), also under a MIT license.
@@ -7,10 +7,11 @@
7
7
  [![Conda Version](https://img.shields.io/conda/vn/conda-forge/itables.svg)](https://anaconda.org/conda-forge/itables)
8
8
  [![pyversions](https://img.shields.io/pypi/pyversions/itables.svg)](https://pypi.python.org/pypi/itables)
9
9
  [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
10
- [![Jupyter Widget](https://img.shields.io/badge/Jupyter-Widget-F37626.svg?style=flat&logo=Jupyter)](https://mwouts.github.io/itables/widget.html)
10
+ [![Jupyter Widget](https://img.shields.io/badge/Jupyter-Widget-F37626.svg?style=flat&logo=Jupyter)](https://mwouts.github.io/itables/apps/widget.html)
11
+ [![Dash Component](https://img.shields.io/badge/Dash-Plotly-1098F7.svg?style=flat&logo=Plotly)](https://mwouts.github.io/itables/apps/dash.html)
11
12
  [![Streamlit App](https://static.streamlit.io/badges/streamlit_badge_black_red.svg)](https://itables.streamlit.app)
12
13
 
13
- This packages changes how Pandas and Polars DataFrames are rendered in Jupyter Notebooks.
14
+ This packages changes how Pandas and Polars DataFrames are rendered in Python notebooks and applications.
14
15
  With `itables` you can display your tables as interactive [DataTables](https://datatables.net/)
15
16
  that you can sort, paginate, scroll or filter.
16
17
 
@@ -38,7 +39,7 @@ or
38
39
  conda install itables -c conda-forge
39
40
  ```
40
41
 
41
- Activate the interactive mode for all series and dataframes with
42
+ Activate the interactive mode for all series and dataframes in Jupyter with
42
43
  ```python
43
44
  import itables
44
45
 
@@ -50,14 +51,8 @@ and then render any DataFrame as an interactive table that you can sort, search
50
51
  If you prefer to render only selected DataFrames as interactive tables, call `itables.init_notebook_mode(all_interactive=False)`, then use `itables.show` to show just one Series or DataFrame as an interactive table:
51
52
  ![show](docs/show_df.png)
52
53
 
53
- Since ITables v1.0, the [jQuery](https://jquery.com/) and [DataTables](https://datatables.net/) libraries and CSS
54
- are injected in the notebook when you execute `init_notebook_mode` with its default argument `connected=False`.
55
- Thanks to this the interactive tables will work even without a connection to the internet.
56
54
 
57
- If you prefer to load the libraries dynamically (and keep the notebook lighter), use `connected=True` when you
58
- execute `init_notebook_mode`.
59
-
60
- ## Supported notebook environments
55
+ ## ITables in Notebooks
61
56
 
62
57
  ITables works in all the usual Jupyter Notebook environments, including Jupyter Notebook, Jupyter Lab, Jupyter nbconvert (i.e. the tables are still interactive in the HTML export of a notebook), Jupyter Book, Google Colab and Kaggle.
63
58
 
@@ -67,8 +62,16 @@ ITables works well in VS Code, both in Jupyter Notebooks and in interactive Pyth
67
62
 
68
63
  ## ITables in Python applications
69
64
 
70
- Last but not least, ITables is also available as
65
+ ITables is also available as
71
66
  - a [Jupyter Widget](https://mwouts.github.io/itables/widget.html)
72
67
  - a [Dash](https://mwouts.github.io/itables/dash.html) component
73
68
  - a [Streamlit](https://mwouts.github.io/itables/streamlit.html) component,
74
69
  - and it also works in [Shiny](https://mwouts.github.io/itables/shiny.html) applications.
70
+
71
+ ## Licence
72
+
73
+ ITables is developed by [Marc Wouts](https://github.com/mwouts) on [GitHub](https://github.com/mwouts/itables),
74
+ under a MIT license.
75
+
76
+ ITables is a wrapper for [datatables.net](https://datatables.net/) which is developed by Allan Jardine
77
+ [(sponsor him!)](https://github.com/sponsors/AllanJard), also under a MIT license.
@@ -1,12 +1,7 @@
1
1
  from itables import downsample, options, sample_dfs
2
2
 
3
- from .javascript import (
4
- JavascriptCode,
5
- JavascriptFunction,
6
- init_notebook_mode,
7
- show,
8
- to_html_datatable,
9
- )
3
+ from .javascript import init_notebook_mode, show, to_html_datatable
4
+ from .typing import JavascriptCode, JavascriptFunction
10
5
  from .version import __version__
11
6
 
12
7
  __all__ = [
@@ -1,21 +1,15 @@
1
+ from itables import __version__
1
2
  from itables_for_dash import (
2
3
  ITABLE_PROPERTIES,
3
4
  ITable,
4
- ITableComponent,
5
5
  ITableOutputs,
6
- __version__,
7
- get_itable_component_kwargs,
8
- itables_for_dash_is_available,
9
6
  updated_itable_outputs,
10
7
  )
11
8
 
12
9
  __all__ = [
13
10
  "ITable",
14
- "ITableComponent",
15
11
  "ITABLE_PROPERTIES",
16
- "get_itable_component_kwargs",
17
12
  "ITableOutputs",
18
13
  "updated_itable_outputs",
19
- "itables_for_dash_is_available",
20
14
  "__version__",
21
15
  ]
@@ -0,0 +1,160 @@
1
+ import json
2
+ import warnings
3
+ from typing import Optional
4
+
5
+ import numpy as np
6
+ import pandas as pd
7
+ import pandas.io.formats.format as fmt
8
+
9
+ try:
10
+ import polars as pl
11
+ except ImportError:
12
+ pl = None
13
+
14
+
15
+ def _format_column(x, escape_html: bool):
16
+ dtype_kind = x.dtype.kind
17
+ if dtype_kind in ["b", "i"]:
18
+ return x
19
+
20
+ if dtype_kind == "s":
21
+ if escape_html:
22
+ return x
23
+ return [escape_html_chars(i) for i in x]
24
+
25
+ try:
26
+ x = fmt.format_array(x._values, None, justify="all", leading_space=False) # type: ignore
27
+ except TypeError:
28
+ # Older versions of Pandas don't have 'leading_space'
29
+ x = fmt.format_array(x._values, None, justify="all") # type: ignore
30
+
31
+ if dtype_kind == "f":
32
+ try:
33
+ x = np.array(x).astype(float)
34
+ except ValueError:
35
+ pass
36
+
37
+ x = [escape_non_finite_float(f) for f in x]
38
+
39
+ if escape_html:
40
+ return [escape_html_chars(i) for i in x]
41
+
42
+ return x
43
+
44
+
45
+ def escape_non_finite_float(value):
46
+ """Encode non-finite float values to strings that will be parsed by parseJSON"""
47
+ if not isinstance(value, float):
48
+ return value
49
+ if np.isnan(value):
50
+ return "___NaN___"
51
+ if value == np.inf:
52
+ return "___Infinity___"
53
+ if value == -np.inf:
54
+ return "___-Infinity___"
55
+ return value
56
+
57
+
58
+ def escape_html_chars(value):
59
+ """Escape HTML special characters"""
60
+ if isinstance(value, str):
61
+ from pandas.io.formats.printing import pprint_thing # type: ignore
62
+
63
+ return pprint_thing(
64
+ value, escape_chars={"&": r"&amp;", "<": r"&lt;", ">": r"&gt;"}
65
+ ).strip()
66
+ return value
67
+
68
+
69
+ def generate_encoder(warn_on_unexpected_types=True):
70
+ class TableValuesEncoder(json.JSONEncoder):
71
+ def default(self, o):
72
+ if isinstance(o, (bool, int, float, str)):
73
+ return json.JSONEncoder.default(self, o)
74
+ if isinstance(o, np.bool_):
75
+ return bool(o)
76
+ if isinstance(o, np.integer):
77
+ return int(o)
78
+ if isinstance(o, np.floating):
79
+ return float(o)
80
+ try:
81
+ if o is pd.NA:
82
+ return str(o)
83
+ except AttributeError:
84
+ pass
85
+
86
+ if warn_on_unexpected_types:
87
+ warnings.warn(
88
+ f"Unexpected type '{type(o)}' for '{o}'.\n"
89
+ "You can report this warning at https://github.com/mwouts/itables/issues\n"
90
+ "To silence this warning, please run:\n"
91
+ " itables.options.warn_on_unexpected_types = False",
92
+ category=RuntimeWarning,
93
+ )
94
+ return str(o)
95
+
96
+ return TableValuesEncoder
97
+
98
+
99
+ def _isetitem(df, i, value):
100
+ """Older versions of Pandas don't have df.isetitem"""
101
+ try:
102
+ df.isetitem(i, value)
103
+ except AttributeError:
104
+ df.iloc[:, i] = value
105
+
106
+
107
+ def datatables_rows(
108
+ df,
109
+ column_count: Optional[int] = None,
110
+ warn_on_unexpected_types: bool = False,
111
+ escape_html: bool = True,
112
+ ):
113
+ """Format the values in the table and return the data, row by row, as requested by DataTables"""
114
+ # We iterate over columns using an index rather than the column name
115
+ # to avoid an issue in case of duplicated column names #89
116
+ if column_count is None or len(df.columns) == column_count:
117
+ empty_columns = []
118
+ else:
119
+ # When the header requires more columns (#141), we append empty columns on the left
120
+ missing_columns = column_count - len(df.columns)
121
+ assert missing_columns > 0
122
+ empty_columns = [[None] * len(df)] * missing_columns
123
+
124
+ try:
125
+ # Pandas DataFrame
126
+ data = list(
127
+ zip(
128
+ *(
129
+ empty_columns
130
+ + [_format_column(x, escape_html) for _, x in df.items()]
131
+ )
132
+ )
133
+ )
134
+ return json.dumps(
135
+ data,
136
+ cls=generate_encoder(warn_on_unexpected_types),
137
+ allow_nan=False,
138
+ )
139
+ except AttributeError:
140
+ # Polars DataFrame
141
+ assert pl is not None
142
+
143
+ # Convert Polars Struct to string #290
144
+ if any(isinstance(df[col].dtype, pl.Struct) for col in df.columns):
145
+ columns = {col: df[col] for col in df.columns}
146
+ for col in df.columns:
147
+ if isinstance(df[col].dtype, pl.Struct):
148
+ try:
149
+ columns[col] = df[col].cast(str)
150
+ except pl.exceptions.InvalidOperationError:
151
+ columns[col] = [str(x) for x in df[col]]
152
+ df = pl.DataFrame(columns)
153
+
154
+ data = df.rows()
155
+ data = [[escape_non_finite_float(f) for f in row] for row in data]
156
+
157
+ if escape_html:
158
+ data = [[escape_html_chars(i) for i in row] for row in data]
159
+
160
+ return json.dumps(data, cls=generate_encoder(False), allow_nan=False)
@@ -1,9 +1,8 @@
1
1
  import math
2
+ from typing import Union
2
3
 
3
4
  import pandas as pd
4
5
 
5
- from .datatables_format import _isetitem
6
-
7
6
 
8
7
  def nbytes(df):
9
8
  try:
@@ -31,7 +30,9 @@ def as_nbytes(mem):
31
30
  return int(float(mem))
32
31
 
33
32
 
34
- def downsample(df, max_rows=0, max_columns=0, max_bytes=0):
33
+ def downsample(
34
+ df, max_rows: int = 0, max_columns: int = 0, max_bytes: Union[int, str] = 0
35
+ ):
35
36
  """Return a subset of the dataframe that fits the limits"""
36
37
  org_rows, org_columns, org_bytes = len(df), len(df.columns), nbytes(df)
37
38
  max_bytes_numeric = as_nbytes(max_bytes)
@@ -113,16 +114,16 @@ def _downsample(df, max_rows=0, max_columns=0, max_bytes=0, target_aspect_ratio=
113
114
  first_half = max_columns - second_half
114
115
  assert first_half >= second_half
115
116
  if second_half:
116
- try:
117
+ if isinstance(df, pd.DataFrame):
117
118
  df = pd.concat(
118
119
  (df.iloc[:, :first_half], df.iloc[:, -second_half:]), axis=1
119
120
  )
120
- except AttributeError:
121
+ else:
121
122
  df = df[df.columns[:first_half]].hstack(df[df.columns[-second_half:]])
122
123
  else:
123
- try:
124
+ if isinstance(df, pd.DataFrame):
124
125
  df = df.iloc[:, :first_half]
125
- except AttributeError:
126
+ else:
126
127
  df = df[df.columns[:first_half]]
127
128
 
128
129
  df_nbytes = nbytes(df)
@@ -146,12 +147,14 @@ def _downsample(df, max_rows=0, max_columns=0, max_bytes=0, target_aspect_ratio=
146
147
  )
147
148
 
148
149
  # max_bytes is smaller than the average size of one cell
149
- try:
150
- df = df.iloc[:1, :1]
151
- _isetitem(df, 0, ["..."])
152
- except AttributeError:
150
+ if isinstance(df, pd.DataFrame):
151
+ return pd.DataFrame("...", index=df.index[:1], columns=df.columns[:1])
152
+
153
+ else:
153
154
  import polars as pl # noqa
154
155
 
156
+ assert isinstance(df, pl.DataFrame)
157
+
155
158
  df = pl.DataFrame({df.columns[0]: ["..."]})
156
159
  return df
157
160
 
@@ -0,0 +1,14 @@
1
+ <!--| quarto-html-table-processing: none -->
2
+ <table id="table_id"></table>
3
+ <link href="https://www.unpkg.com/dt_for_itables/dt_bundle.css" rel="stylesheet">
4
+ <script type="module">
5
+ import { ITable, jQuery as $ } from 'https://www.unpkg.com/dt_for_itables/dt_bundle.js';
6
+
7
+ document.querySelectorAll("#table_id:not(.dataTable)").forEach(table => {
8
+ if (!(table instanceof HTMLTableElement))
9
+ return;
10
+
11
+ let dt_args = {};
12
+ new ITable(table, dt_args);
13
+ });
14
+ </script>