Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 15 additions & 4 deletions pkg-py/tests/playwright/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -359,9 +359,20 @@ def _stop_streamlit_server(process: subprocess.Popen) -> None:
process.kill()


@pytest.fixture(scope="module")
@pytest.fixture
def app_04_streamlit() -> Generator[str, None, None]:
"""Start the 04-streamlit-app.py Streamlit server for testing."""
"""
Start the 04-streamlit-app.py Streamlit server for testing.

Function-scoped (a fresh subprocess per test), unlike the Shiny/Gradio/Dash
app fixtures in this file. A single Streamlit server was observed to stop
re-running its script for new browser sessions after the first test's
session completed successfully -- the static page shell still loads, but
no reactive content (e.g. the chat greeting) ever streams in, with no
error on either side, and the condition persists for the rest of the
server's life (a fresh browser context/page doesn't recover it; only a
new server process does).
"""
app_path = str(EXAMPLES_DIR / "04-streamlit-app.py")

def start_factory():
Expand All @@ -381,9 +392,9 @@ def streamlit_cleanup(process, _):
_stop_streamlit_server(process)


@pytest.fixture(scope="module")
@pytest.fixture
def app_09_streamlit_custom() -> Generator[str, None, None]:
"""Start the 09-streamlit-custom-app.py Streamlit server for testing."""
"""Start the 09-streamlit-custom-app.py Streamlit server for testing. Function-scoped; see app_04_streamlit()."""
app_path = str(EXAMPLES_DIR / "09-streamlit-custom-app.py")

def start_factory():
Expand Down
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ classifiers = [
[project.optional-dependencies]
# For SQLAlchemySource and sample data, one of polars or pandas is required
pandas = ["pandas"]
polars = ["polars", "pyarrow"] # duckdb requires pyarrow for polars DataFrame registration
polars = ["polars", "pyarrow<25.0.0"] # duckdb requires pyarrow for polars DataFrame registration; pyarrow>=25.0.0 segfaults when its native conversion code runs on more than ~2 OS threads over a process's lifetime (e.g. Streamlit reruns each script on a fresh thread) -- see #268
ibis = ["ibis-framework>=9.0.0", "pandas"] # pandas required for ibis .execute() to return DataFrames
pins = ["pins>=0.9.1"]
# Web framework extras
Expand Down Expand Up @@ -101,7 +101,7 @@ dev = [
"tox-uv>=1.11.4",
"pytest>=8.4.0",
"polars>=1.0.0",
"pyarrow>=14.0.0",
"pyarrow<25.0.0", # see comment on the `polars` extra above
"ibis-framework[duckdb]>=9.0.0",
"ggsql>=0.3.2",
"altair>=6.0",
Expand Down
Loading