Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tests(dataframe): Add additional backends to test dataframe compatibility #1723

Merged
merged 11 commits into from
Oct 11, 2024
7 changes: 6 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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",
]

Expand Down Expand Up @@ -87,6 +87,11 @@ test = [
"faicons",
"ridgeplot",
"great_tables",
"modin[all]",
"polars",
"dask[dataframe]",
"pyarrow",
"pyarrow-stubs",
]
dev = [
"black>=24.0",
Expand Down
150 changes: 147 additions & 3 deletions tests/playwright/shiny/components/data_frame/data_type/app.py
Original file line number Diff line number Diff line change
@@ -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:"

Expand Down Expand Up @@ -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:"

Expand All @@ -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)))
Original file line number Diff line number Diff line change
Expand Up @@ -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)
18 changes: 18 additions & 0 deletions tests/playwright/shiny/components/table/app.py
Original file line number Diff line number Diff line change
@@ -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]

Expand All @@ -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")
Expand All @@ -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))
8 changes: 4 additions & 4 deletions tests/playwright/shiny/components/table/test_table.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"))
Loading