Metadata-Version: 2.4
Name: spiraldb
Version: 0.15.2
Classifier: Development Status :: 2 - Pre-Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Rust
Classifier: Topic :: Database
Requires-Dist: pyarrow>=19.0.0
Requires-Dist: tqdm>=4.67.1
Requires-Dist: duckdb ; extra == 'duckdb'
Requires-Dist: pandas ; extra == 'pandas'
Requires-Dist: polars ; extra == 'polars'
Provides-Extra: duckdb
Provides-Extra: pandas
Provides-Extra: polars
Summary: Python Client for SpiralDB.
Home-Page: https://spiraldb.com
Author-email: SpiralDB <hello@spiraldb.com>
License: Apache-2.0
Requires-Python: >=3.11
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM

# spiraldb

Python bindings for `spiral-engine`.

This package exposes the first lazy Python API over the engine relation layer:

```python
import spiraldb

sp = spiraldb.Spiral()

relation = (
    sp.values([{"id": 1, "region": "east"}, {"id": 2, "region": "west"}])
    .filter(spiraldb.path("id").eq(1))
    .select({"id": spiraldb.path("id")})
    .sort("id")
    .limit(10)
)

print(relation.logical_plan())
print(relation.explain())

preview = relation.preview(16)
assert not preview.is_complete
print(preview.schema)
display(preview)
```

`Spiral` owns a default SPQL-enabled engine session. `Relation` methods return
new lazy relation plans. In Jupyter, a `Relation` renders as a lazy schema card:
it shows the key, dtype, Arrow schema when available, and logical plan without
executing the query. Use `Spiral.sql(...)` for SQL and `Spiral.values(...)` for
in-memory Python or PyArrow data; `values` accepts Arrow tables or batches,
column mappings, Arrow arrays, row dictionaries, and tuple rows with `names=`.
`Relation.preview(n)` is the explicit execution boundary; it executes a bounded
limit and returns an incomplete `RelationResult` backed internally by a
materialized Vortex array plus a `pyarrow.Table`. In notebooks, `RelationResult`
renders through the `spql.viz.Table` component in the `spiral-ui-wasm` WebAssembly
runtime, with selected-row detail for drilling down to one row. Unbounded
materialization is intentionally not exposed yet; the future full-result API
should be an explicit export or streaming method.

PyTorch export is exposed as a bounded streaming terminal:

```python
for batch in relation.to_pytorch(device="cpu", transfer="copy", prefetch=2):
    print(batch["id"])
```

`to_pytorch` requires PyTorch at runtime. Numeric and tensor-shaped fields are
converted to `torch.Tensor` values; non-numeric metadata fields remain Python
lists. Tensor extension fields request physical buffer placement before
streaming, but the current implementation still uses CPU Arrow/Python values as
the interchange path. DLPack zero-copy export and native GPU buffers are not
implemented yet; CUDA and MPS/Metal placement requests fail explicitly until
device buffers are available.

The package also includes a prototype notebook display object for a GPUI
component compiled into the aggregate `spiral-ui-wasm` WebAssembly runtime:

```sh
rustup target add wasm32-unknown-unknown
cargo run -p engine-xtask -- build-spiral-web-wasm
```

```python
import spiraldb

spiraldb.example_viz(
    [3, 7, 4, 9, 5, 8],
    labels=["decode", "filter", "join", "group", "sort", "sink"],
)
```

Displaying the returned object in Jupyter embeds the generated JavaScript/WASM
runtime into a sandboxed iframe and starts the GPUI web window lazily when the
output is rendered.

The generic path is `spiraldb.viz.render(...)`. JSON config stays in the control
plane; Arrow IPC, Vortex, or component-specific preview bytes are passed as
binary buffers:

```python
spiraldb.viz.render(
    "spql.viz.example.bar_chart",
    data_format="arrow.ipc.stream",
    buffers=[arrow_ipc_bytes],
    config={"title": "Preview"},
)
```

### Scoped JPEG display demo

`notebooks/jpeg_blob_cell_demo.ipynb` demonstrates the scoped display path for
lazy JPEG values. The relation table renders `spql.image.Jpeg[Cell]` as
`spql.io.Blob[Cell]` metadata, while a selected row renders the same value as
`spql.viz.ImageView`.

From the repository root:

```sh
cargo run -p engine-xtask -- build-spiral-web-wasm
cd lang/python/spiral-engine
uv run maturin develop
uv run --with jupyterlab jupyter lab notebooks/jpeg_blob_cell_demo.ipynb
```

## Development

```sh
uv run --package spiraldb pytest tests
uv build --package spiraldb --wheel
```

