diff --git a/pyproject.toml b/pyproject.toml index 9e44f196a..b5a1d7f13 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -47,7 +47,7 @@ dependencies = [ "prompt-toolkit;platform_system!='Emscripten'", "python-multipart>=0.0.7;platform_system!='Emscripten'", "setuptools;python_version>='3.12'", - "narwhals>=1.9.1", + "narwhals>=1.9.3", "orjson>=3.10.7", ] @@ -87,6 +87,11 @@ test = [ "faicons", "ridgeplot", "great_tables", + "modin[all]", + "polars", + "dask[dataframe]", + "pyarrow", + "pyarrow-stubs", ] dev = [ "black>=24.0", diff --git a/tests/playwright/shiny/components/data_frame/data_type/app.py b/tests/playwright/shiny/components/data_frame/data_type/app.py index d3f3aaeb2..50c76b952 100644 --- a/tests/playwright/shiny/components/data_frame/data_type/app.py +++ b/tests/playwright/shiny/components/data_frame/data_type/app.py @@ -1,23 +1,38 @@ from __future__ import annotations +import modin.pandas as mpd # pyright: ignore[reportMissingTypeStubs] import narwhals.stable.v1 as nw import palmerpenguins # pyright: ignore[reportMissingTypeStubs] +import polars as pl +import pyarrow as pa from shiny.express import render, ui pd_df = palmerpenguins.load_penguins_raw().iloc[0:2, 0:2] nw_df = nw.from_native(pd_df, eager_only=True) +pa_df = pa.table(pd_df) # pyright: ignore[reportUnknownMemberType] +mpd_df = mpd.DataFrame(pd_df) +pl_df = pl.DataFrame(pd_df) + with ui.layout_columns(): with ui.card(): - ui.h2("Original Pandas Data") @render.data_frame def pd_df_original(): - return pd_df + return render.DataGrid( + data=pd_df, # pyright: ignore[reportUnknownArgumentType] + selection_mode="row", + ) + + "Selected row:" + + @render.data_frame + def selected_pandas_row(): + return pd_df_original.data_view(selected=True) "Data type:" @@ -48,7 +63,16 @@ def pd_data_view_selected(): @render.data_frame def nw_df_original(): - return nw_df + return render.DataGrid( + data=nw_df, + selection_mode="row", + ) + + "Selected row:" + + @render.data_frame + def selected_nw_row(): + return nw_df_original.data_view(selected=True) "Data type:" @@ -73,3 +97,123 @@ def nw_data_view(): @render.code def nw_data_view_selected(): return str(type(nw_df_original.data_view(selected=True))) + + with ui.card(): + ui.h2("Original PyArrow Data") + + @render.data_frame + def pa_df_original(): + return render.DataGrid( + data=pa_df, + selection_mode="row", + ) + + "Selected row:" + + @render.data_frame + def selected_pa_row(): + return pa_df_original.data_view(selected=True) + + "Data type:" + + @render.code + def pa_type(): + return str(type(pa_df)) + + ui.markdown("`.data()` type:") + + @render.code + def pa_data(): + return str(type(pa_df_original.data())) + + ui.markdown("`.data_view()` type:") + + @render.code + def pa_data_view(): + return str(type(pa_df_original.data_view())) + + ui.markdown("`.data_view(selected=True)` type:") + + @render.code + def pa_data_view_selected(): + return str(type(pa_df_original.data_view(selected=True))) + + with ui.card(): + ui.h2("Modin Data") + + @render.data_frame + def mpd_df_original(): + return render.DataGrid( + data=mpd_df, + selection_mode="row", + ) + + "Selected row:" + + @render.data_frame + def selected_mpd_row(): + return mpd_df_original.data_view(selected=True) + + "Data type:" + + @render.code + def mpd_type(): + return str(type(mpd_df)) + + ui.markdown("`.data()` type:") + + @render.code + def mpd_data(): + return str(type(mpd_df_original.data())) + + ui.markdown("`.data_view()` type:") + + @render.code + def mpd_data_view(): + return str(type(mpd_df_original.data_view())) + + ui.markdown("`.data_view(selected=True)` type:") + + @render.code + def mpd_data_view_selected(): + return str(type(mpd_df_original.data_view(selected=True))) + + with ui.card(): + ui.h2("Polars Data") + + @render.data_frame + def pl_df_original(): + return render.DataGrid( + data=pl_df, + selection_mode="row", + ) + + "Selected row:" + + @render.data_frame + def selected_pl_row(): + return pl_df_original.data_view(selected=True) + + "Data type:" + + @render.code + def pl_type(): + return str(type(pl_df)) + + ui.markdown("`.data()` type:") + + @render.code + def pl_data(): + return str(type(pl_df_original.data())) + + ui.markdown("`.data_view()` type:") + + @render.code + def pl_data_view(): + return str(type(pl_df_original.data_view())) + + ui.markdown("`.data_view(selected=True)` type:") + + @render.code + def pl_data_view_selected(): + return str(type(pl_df_original.data_view(selected=True))) diff --git a/tests/playwright/shiny/components/data_frame/data_type/test_df_data_type.py b/tests/playwright/shiny/components/data_frame/data_type/test_df_data_type.py index c3eb5431d..d3c24e130 100644 --- a/tests/playwright/shiny/components/data_frame/data_type/test_df_data_type.py +++ b/tests/playwright/shiny/components/data_frame/data_type/test_df_data_type.py @@ -5,23 +5,64 @@ from shiny.playwright import controller from shiny.run import ShinyAppProc +backends = [ + { + "name": "pandas", + "prefix": "pd", + "df_original": "pd_df_original", + "selected_row": "selected_pandas_row", + }, + { + "name": "narwhals", + "prefix": "nw", + "df_original": "nw_df_original", + "selected_row": "selected_nw_row", + }, + { + "name": "pyarrow", + "prefix": "pa", + "df_original": "pa_df_original", + "selected_row": "selected_pa_row", + }, + { + "name": "polars", + "prefix": "pl", + "df_original": "pl_df_original", + "selected_row": "selected_pl_row", + }, + { + "name": "modin", + "prefix": "mpd", + "df_original": "mpd_df_original", + "selected_row": "selected_mpd_row", + }, +] + def test_data_frame_data_type( page: Page, local_app: ShinyAppProc, ) -> None: page.goto(local_app.url) + # Iterate over the backends + for backend in backends: + # Perform output code tests + controller.OutputCode(page, f"{backend['prefix']}_type").expect_value( + re.compile(backend["name"]) + ) + controller.OutputCode(page, f"{backend['prefix']}_data").expect_value( + re.compile(backend["name"]) + ) + controller.OutputCode(page, f"{backend['prefix']}_data_view").expect_value( + re.compile(backend["name"]) + ) + controller.OutputCode( + page, f"{backend['prefix']}_data_view_selected" + ).expect_value(re.compile(backend["name"])) - controller.OutputCode(page, "pd_type").expect_value(re.compile(r"pandas")) - controller.OutputCode(page, "pd_data").expect_value(re.compile(r"pandas")) - controller.OutputCode(page, "pd_data_view").expect_value(re.compile(r"pandas")) - controller.OutputCode(page, "pd_data_view_selected").expect_value( - re.compile(r"pandas") - ) - - controller.OutputCode(page, "nw_type").expect_value(re.compile(r"narwhals")) - controller.OutputCode(page, "nw_data").expect_value(re.compile(r"narwhals")) - controller.OutputCode(page, "nw_data_view").expect_value(re.compile(r"narwhals")) - controller.OutputCode(page, "nw_data_view_selected").expect_value( - re.compile(r"narwhals") - ) + # Perform output dataframe tests + controller.OutputDataFrame(page, backend["selected_row"]).expect_column_labels( + ["studyName", "Sample Number"] + ) + controller.OutputDataFrame(page, backend["df_original"]).select_rows([1]) + controller.OutputDataFrame(page, backend["selected_row"]).expect_nrow(1) diff --git a/tests/playwright/shiny/components/table/app.py b/tests/playwright/shiny/components/table/app.py index 509ce39e9..1a2a2a4e9 100644 --- a/tests/playwright/shiny/components/table/app.py +++ b/tests/playwright/shiny/components/table/app.py @@ -1,5 +1,6 @@ from __future__ import annotations +import modin.pandas as md # pyright: ignore[reportMissingTypeStubs] import narwhals.stable.v1 as nw import palmerpenguins # pyright: ignore[reportMissingTypeStubs] @@ -9,6 +10,8 @@ nw_df = nw.from_native(pd_df, eager_only=True) +md_df = md.DataFrame(pd_df) + with ui.card(): ui.h2("Polars Pandas Data") @@ -22,3 +25,18 @@ def nw_table(): @render.code def nw_df_type(): return str(type(nw_df)) + + +with ui.card(): + + ui.h2("Modin dataframe Data") + + @render.table + def md_table(): + return md_df + + "Data type:" + + @render.code + def md_df_type(): + return str(type(md_df)) diff --git a/tests/playwright/shiny/components/table/test_table.py b/tests/playwright/shiny/components/table/test_table.py index 78a561c5b..d04bcd39d 100644 --- a/tests/playwright/shiny/components/table/test_table.py +++ b/tests/playwright/shiny/components/table/test_table.py @@ -9,8 +9,8 @@ def test_table_data_support(page: Page, local_app: ShinyAppProc) -> None: page.goto(local_app.url) - table = controller.OutputTable(page, "nw_table") - - table.expect_nrow(2) - + controller.OutputTable(page, "nw_table").expect_nrow(2) controller.OutputCode(page, "nw_df_type").expect_value(re.compile("narwhals")) + + controller.OutputTable(page, "md_table").expect_nrow(2) + controller.OutputCode(page, "md_df_type").expect_value(re.compile("modin"))