Skip to content

buckaroo.server hard-imports polars, forcing polars install for pandas/xorq-only tauri users #754

@paddymul

Description

@paddymul

Problem

buckaroo/server/data_loading.py:5 does import polars as pl at module top:

```python
import pandas as pd
import polars as pl # ← unconditional
from buckaroo.serialization_utils import to_parquet, pd_to_obj, check_and_fix_df
```

This propagates upward — buckaroo.server.app, buckaroo.server.handlers, and ultimately python -m buckaroo.server all fail to import without polars installed:

```
ModuleNotFoundError: No module named 'polars'
```

For the buckaroo-tauri integration, this means users who only want to view pandas (or xorq) data are forced to install polars. That's wrong: pandas is structurally required (the widget materializes pandas frames internally), but polars should be optional, just like xorq is.

Surfaced while building xorq-desktop's integration. The Tauri sidecar should start on a pandas-only install; today it can't.

Polars usage in data_loading.py is already isolated to the lazy codepath

pl.* is referenced only at lines 113-189 — load_file_lazy, get_metadata_lazy, get_display_state_lazy, handle_infinite_request_lazy. Everything above (the pandas codepath) doesn't touch polars. So the import is structurally optional with zero refactor needed:

```
$ grep -nE "\bpl.|polars" buckaroo/server/data_loading.py
5:import polars as pl
113:def load_file_lazy(path: str) -> pl.LazyFrame:
117: return pl.scan_parquet(path)

185: select_exprs = [pl.col("index")]
188: select_exprs.append(pl.col(orig).alias(rw))
```

Precedent: buckaroo already has the pattern

Three existing modules use try: import polars for the same reason:

  • buckaroo/__init__.py:115-116
  • buckaroo/marimo_utils.py:38-39, 50-51
  • buckaroo/artifact.py:100-101, 153-154

data_loading.py should follow the same idiom.

Suggested fix

Option A (minimal — matches the marimo_utils pattern): move import polars as pl to a function-local import inside each *_lazy function. The non-lazy codepath continues to import the module successfully without polars.

Option B (slightly cleaner — matches the __init__.py pattern): module-level guarded import + a sentinel:

```python
try:
import polars as pl
HAS_POLARS = True
except ImportError:
pl = None
HAS_POLARS = False
```

…then raise a clear ImportError("polars required for *_lazy paths; pip install polars") at the top of each *_lazy function. Better user-facing message than the deep stack on first call.

Either way the fix is ~10 lines.

Follow-up: [tauri-essentials] extra (#753)

This bug is the reason #753's [tauri-essentials] extra currently pulls polars. Once data_loading.py is fixed, that extra should drop polars>=1.24.0 from its required list — polars-using buckaroo-tauri consumers would add buckaroo[tauri-essentials,polars] themselves.

I'll hold off rebasing #753 until the direction here is settled. If you'd prefer #753 land first and then this fix follow, that works too — they're independently mergeable.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions