Sparkless
PySpark-compatible DataFrames in Python—no JVM, no cluster.
Drop-in replacement for local development and testing. Same API, 10–100× faster feedback.
Before you adopt: Read caveats — UDF limits, parity gaps, not a Spark cluster replacement.
- Python 3.8+ · PySpark 3.2–3.5 compatible · MIT
In 30 seconds
# Swap the import—everything else stays the same.
from sparkless.sql import SparkSession, functions as F
spark = SparkSession.builder.app_name("demo").get_or_create()
df = spark.createDataFrame([{"x": 1}, {"x": 2}])
df.filter(F.col("x") > 1).show()
pip install "sparkless>=4,<5"
No Java, no Spark install, no 30-second session startup. Ideal for unit tests and CI.
Why Sparkless?
| If you… | Sparkless gives you… |
|---|---|
| Test PySpark code | Same SparkSession / DataFrame / Column API; tests run in seconds without a JVM |
| Run in CI | No Java, no Spark distribution, no flaky cluster; just pip install and pytest |
| Develop locally | Fast iteration with Parquet, CSV, JSON, Delta, SQL, temp views—no cluster needed |
| Need real PySpark sometimes | Use sparkless.testing: one test suite, run with sparkless or SPARKLESS_TEST_MODE=pyspark |
v4 uses the robin-sparkless Rust engine (Polars under the hood). No Polars Python dependency at runtime—just a small native extension.
Installation
From PyPI (recommended)
pip install "sparkless>=4,<5"
Prebuilt wheels are provided for common platforms (Linux, macOS, Windows).
For development from the robin-sparkless repo:
# From repo root
pip install ./python
Contributors should use the uv setup and native build workflow.
Optional extras
| Extra | Use case |
|---|---|
pip install "sparkless[dev]" |
pytest, pandas, hypothesis, pytest-xdist |
pip install "sparkless[jdbc]" |
JDBC integration tests (testcontainers, drivers) |
pip install "sparkless[pyspark]" |
Run tests against real PySpark (SPARKLESS_TEST_MODE=pyspark) |
Supported platforms
Prebuilt wheels are published for CI targets on each release (see PyPI files):
| OS | Architectures | Notes |
|---|---|---|
| Linux | x86_64, aarch64 | glibc manylinux; musl (Alpine) wheels where available |
| macOS | arm64, x86_64 | Universal coverage via separate wheels |
| Windows | x86_64, arm64 | Prebuilt extension modules |
Python: 3.8, 3.9, 3.10, 3.11, 3.12 (cp38–cp312 ABI tags on wheels).
If no wheel matches your platform, follow the source build instructions.
Quick start
Basic usage
from sparkless.sql import SparkSession, functions as F
spark = SparkSession.builder.app_name("MyApp").get_or_create()
data = [{"name": "Alice", "age": 25}, {"name": "Bob", "age": 30}]
df = spark.createDataFrame(data)
df.filter(F.col("age") > 25).select("name").show()
# +----+
# |name|
# +----+
# | Bob|
# +----+
result = df.filter(F.col("age") > 25).select("name").collect()
# [Row(name='Bob')]
In tests (pytest)
import pytest
from sparkless.sql import SparkSession, functions as F
def test_high_scores():
spark = SparkSession.builder.app_name("test").get_or_create()
df = spark.createDataFrame([{"score": 95}, {"score": 87}, {"score": 92}])
high = df.filter(F.col("score") > 90)
assert high.count() == 2
assert high.agg(F.avg("score")).collect()[0][0] == 93.5
spark.stop()
SQL and temp views
df = spark.createDataFrame([{"name": "Alice", "salary": 50000}, {"name": "Bob", "salary": 60000}])
df.createOrReplaceTempView("employees")
spark.sql("SELECT name, salary FROM employees WHERE salary > 50000").show()
Bounded Arrow export
toArrow() still returns a materialized PyArrow Table. Use toArrowBatches() to stream
RecordBatches from the query plan with row and byte limits:
with df.toArrowBatches(max_rows=1024, max_bytes=8 * 1024 * 1024) as batches:
for batch in batches:
consume(batch) # batch is a pyarrow.RecordBatch
if should_stop():
break
Each batch stays within both values (max_bytes is checked against RecordBatch.nbytes);
if a single row is larger than max_bytes, iteration raises ValueError. The defaults are
10,000 rows and 64 MiB. Close the iterator (or use it as a context manager) after an early stop
so the query stops producing batches.
JDBC (PostgreSQL, SQLite, MySQL, etc.)
# Read
url = "jdbc:postgresql://localhost:5432/mydb"
df = spark.read.jdbc(url=url, table="users", properties={"user": "u", "password": "p"})
# Write
df.write.jdbc(url=url, table="users_backup", properties={"user": "u", "password": "p"}, mode="overwrite")
Supported: PostgreSQL, SQLite, MySQL, MariaDB, SQL Server, Oracle, DB2. Same options as PySpark (sessionInitStatement, batchsize, truncate, etc.).
API at a glance
| Area | Supported |
|---|---|
| SparkSession | builder, createDataFrame, table, sql, range, read_csv / read_parquet / read_json / read_delta, temp/global temp views, catalog, stop |
| DataFrame | filter, select, withColumn, show, collect, toArrow, toArrowBatches, count, groupBy, orderBy, limit, drop, distinct, join, union, unionByName, write, createOrReplaceTempView |
| Column / functions | col, lit, when/then/otherwise, comparison/aggregation/string/window functions; F.col("x") > 1, F.upper("name"), etc. |
| GroupedData | count, sum, avg, min, max, agg, pivot |
| Read/Write | Parquet, CSV, JSON, Delta; saveAsTable; JDBC with standard options |
Detailed parity and differences: PYSPARK_DIFFERENCES.md, PARITY_STATUS.md.
Dual-mode testing (sparkless + PySpark)
Use sparkless.testing to run the same tests with the sparkless backend (fast) or real PySpark (parity check).
1. Register the plugin (e.g. in conftest.py):
pytest_plugins = ["sparkless.testing"]
2. Write tests using the spark and optional spark_imports fixtures:
def test_filter(spark):
df = spark.createDataFrame([{"id": 1}, {"id": 2}])
assert df.filter(df.id > 1).count() == 1
def test_upper(spark, spark_imports):
F = spark_imports.F
df = spark.createDataFrame([{"name": "alice"}])
assert df.select(F.upper("name")).collect()[0][0] == "ALICE"
3. Run
# Default: sparkless backend (no JVM)
pytest tests/ -v
# Parallel
pytest tests/ -n 12 -v
# Against real PySpark (requires Java + pip install pyspark)
SPARKLESS_TEST_MODE=pyspark pytest tests/ -v
Fixtures: spark, spark_mode, spark_imports, isolated_session, table_prefix
Markers: @pytest.mark.sparkless_only, @pytest.mark.pyspark_only, @pytest.mark.delta
Helpers: assert_dataframes_equal(), compare_dataframes()
Full details: TESTING_GUIDE.md.
Requirements
- Python 3.8+
- Sparkless mode: No Java or Spark required.
- PySpark mode (optional): Java and
pip install pysparkforSPARKLESS_TEST_MODE=pyspark.
Development
Follow CONTRIBUTING.md to create the root .venv, install
development dependencies with uv, and build the native extension. From the repository root:
# Rebuild after changing Rust or PyO3 code
(
cd python
uv run --no-project --python ../.venv/bin/python \
python -m maturin develop --uv --locked --release
)
# Run a focused test against the rebuilt extension
uv run --no-project --python .venv/bin/python \
python -m pytest tests/unit/test_external_catalog_provider.py -q
For wheels and PySpark parity runs, see the contributor guide. Rust engine, UDFs, embedding: see the main README and docs.
Limitations
- UDFs: Use built-in functions and expressions; Python UDFs are not exposed. Rust UDFs are supported in the engine (UDF_GUIDE).
- Compatibility: Some APIs or behaviors differ from PySpark; see PYSPARK_DIFFERENCES.md.
Optional security hardening
For production or multi-tenant use, set SPARKLESS_HARDENED=1 and/or:
SPARKLESS_JDBC_ALLOW_ARBITRARY_SQL=false— disallow arbitrary JDBC SQL; usedbtableonlySPARKLESS_FILES_BASE=/path/to/sandbox— confineread/writefile paths to that directory
See PYSPARK_DIFFERENCES.md — Security hardening for resource limits and multiprocessing notes.
Version history: v3 vs v4
| Sparkless v3 | Sparkless v4 (this package) | |
|---|---|---|
| Backend | Polars (Python) | robin-sparkless (Rust + Polars) |
| Repo | sparkless | robin-sparkless |
| Install | pip install sparkless |
pip install "sparkless>=4,<5" or pip install ./python |
| Runtime | Polars Python | Native extension only; no Polars Python |
Same from sparkless.sql import SparkSession in both. v4 is the current major release.
Links
- This repo: github.com/eddiethedean/robin-sparkless — Rust engine + Python package
- Docs: robin-sparkless.readthedocs.io
- Sparkless v3: github.com/eddiethedean/sparkless
- License: MIT (LICENSE in main repo)
Metadata
Release files for sparkless 4.16.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| sparkless-4.16.0.tar.gz | 735.0 kB | With provenance | Details for sparkless-4.16.0.tar.gz |
Built distributions (wheels)
Total release size: 407.2 MB
Release files / sparkless-4.16.0.tar.gz
| Download URL | sparkless-4.16.0.tar.gz |
|---|---|
| Size | 735.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c0f000e09d7e8e8a3f0dbf3d5bb3d139c8fc76cef42fab115b059d13e088cc8f
|
|
BLAKE2b-256 checksum How to use checksums |
b3a54d16bccc00001e7bf90a9f2fa2933b636a9a0a6c738480b0387c650dabf6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.
Transparency logRelease files / sparkless-4.16.0-cp38-abi3-win_arm64.whl
| Download URL | sparkless-4.16.0-cp38-abi3-win_arm64.whl |
|---|---|
| Size | 40.1 MB |
| Tags | CPython 3.8 Windows ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
1bb898365a9abba46f4cd17dce805a9a04545fe0db139f8aab8e2ca37a7b3ada
|
|
BLAKE2b-256 checksum How to use checksums |
07041d7744a2e01337522cb35154701dfd36fa87527d7c3d3f828c1dbdbd43f4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.
Transparency logRelease files / sparkless-4.16.0-cp38-abi3-win_amd64.whl
| Download URL | sparkless-4.16.0-cp38-abi3-win_amd64.whl |
|---|---|
| Size | 43.8 MB |
| Tags | CPython 3.8 Windows x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
3a7077008b849d3e146e0225205d0f2d68d86922c496355d5edef6336ed4eafe
|
|
BLAKE2b-256 checksum How to use checksums |
5b8cb8ecd4028cd1eb7f6c9a1048a61921b517acf8ecc586657123e2ee0d00ee
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.
Transparency logRelease files / sparkless-4.16.0-cp38-abi3-musllinux_1_2_x86_64.whl
| Download URL | sparkless-4.16.0-cp38-abi3-musllinux_1_2_x86_64.whl |
|---|---|
| Size | 41.7 MB |
| Tags | CPython 3.8 Linux musl 1.2+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
643094663386646a3346d9bb51b974dbaaba31bad56b0e82ebe3558544a8c86c
|
|
BLAKE2b-256 checksum How to use checksums |
1decfb91e735d5dfbaa4ecb857ced95e5c8ea126e706909195c5e7194e75e259
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.
Transparency logRelease files / sparkless-4.16.0-cp38-abi3-musllinux_1_2_aarch64.whl
| Download URL | sparkless-4.16.0-cp38-abi3-musllinux_1_2_aarch64.whl |
|---|---|
| Size | 38.8 MB |
| Tags | CPython 3.8 Linux musl 1.2+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
829f8daa33fead6df824c4411e5f5c2e49e12fed8afa2beb4702059cb35f383e
|
|
BLAKE2b-256 checksum How to use checksums |
6a70e9fa6bbafe5db77f17139c4db3827d26af4f934adda9eb8bc87c864eefba
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.
Transparency logRelease files / sparkless-4.16.0-cp38-abi3-manylinux_2_28_aarch64.whl
| Download URL | sparkless-4.16.0-cp38-abi3-manylinux_2_28_aarch64.whl |
|---|---|
| Size | 38.9 MB |
| Tags | CPython 3.8 Linux glibc 2.28+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
17099dec9e9a90424501a1abf7db957b7d9ffcf3822ac457893ea3664f47f466
|
|
BLAKE2b-256 checksum How to use checksums |
2ae7ed57408224a8ed12bbf01da3991feda43ea8b8829282851ba2a10a9688b8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.
Transparency logRelease files / sparkless-4.16.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | sparkless-4.16.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 41.7 MB |
| Tags | CPython 3.8 Linux glibc 2.17+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
e1ec469c199ddc10e194174b922554fc5c48d6466b48f674d0a8216f0c718cbb
|
|
BLAKE2b-256 checksum How to use checksums |
5e71452cc1bd0276c95e487b03384f2bfa3d80c07b9a733cab9b2cf83141b4bc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.
Transparency logRelease files / sparkless-4.16.0-cp38-abi3-macosx_11_0_arm64.whl
| Download URL | sparkless-4.16.0-cp38-abi3-macosx_11_0_arm64.whl |
|---|---|
| Size | 83.1 MB |
| Tags | CPython 3.8 abi3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
90a6b4055c9e51040c3c99ba7cc00fe756556e73e568232280210a59f34cda3c
|
|
BLAKE2b-256 checksum How to use checksums |
8db5bd952017f86b336def380278ba89a6d8c29b2b8f96606312ca2e6253c976
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.
Transparency logRelease files / sparkless-4.16.0-cp38-abi3-macosx_10_12_x86_64.whl
| Download URL | sparkless-4.16.0-cp38-abi3-macosx_10_12_x86_64.whl |
|---|---|
| Size | 78.3 MB |
| Tags | CPython 3.8 abi3 macOS 10.12+ x86-64 |
|
SHA-256 checksum How to use checksums |
6d4ec9e7b9ed7a0bf5126e3a0ce5581fbc76989e13e359574879452f97e05d8f
|
|
BLAKE2b-256 checksum How to use checksums |
20e11a0b0e22ab7297f122e29dc5ce2606adb81e434800404a8c357fb58add13
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.
Transparency logSecurity for sparkless 4.16.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 9 files in this release have been uploaded with provenance metadata.
Attestation for sparkless-4.16.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.