fsspec adapter for reading S4 gateway-written objects (S4F2 framed + compressed) directly from the backend — no gateway required. Read-only by design.
Project description
s4fs — fsspec filesystem for S4 objects (no gateway required)
s4fs lets pandas / pyarrow / DuckDB / Polars (anything fsspec-aware) read
S4 gateway-written objects directly
from the S3 backend. Objects are transparently decompressed on read,
ls/info report the original (decompressed) sizes, and range reads use the
<key>.s4index sidecar to fetch + decode only the frames that overlap the
requested range. Objects that never went through the gateway pass through
byte-for-byte. This is the lock-in escape hatch: if you stop running the
gateway, your data stays readable.
Install
pip install -e python/s4fs[s3] # from a source checkout
# requires the s4-codec wheel: cd crates/s4-codec-py && maturin build --release
Use
import pandas as pd
opts = {"target_options": {"endpoint_url": "http://backend:9000"}}
df = pd.read_parquet("s4://bucket/data.parquet", storage_options=opts)
import fsspec, pyarrow.parquet as pq
fs = fsspec.filesystem("s4", target_options={"endpoint_url": "http://backend:9000"})
table = pq.read_table("bucket/data.parquet", filesystem=fs)
import duckdb
con = duckdb.connect(); con.register_filesystem(fs)
con.sql("SELECT count(*) FROM read_parquet('s4://bucket/data.parquet')")
Any underlying fsspec filesystem can be injected instead of s3fs:
S4FileSystem(fs=my_fs) (used by the unit tests with an in-memory stub).
Decoded formats
- S4F2-framed objects (single-PUT and multipart), S4P1 padding skipped
- codecs:
passthrough,cpu-zstd,cpu-gzip,cpu-zstd-dict(dictionaries are fetched from.s4dict/<id>and fingerprint-verified) - unframed gateway objects carrying a metadata manifest (
cpu-gzip, legacy raw zstd,passthrough) .s4indexsidecars v1/v2/v3 with ETag staleness checks (a stale sidecar falls back to a full-object read)
Limitations
- Read-only. All write APIs raise
NotImplementedError— write through the S4 gateway, which owns the framing / sidecar / metadata contract. - GPU frames are refused loudly.
nvcomp-*/dietgpu-ansframes raiseNotImplementedError(decode them through the gateway); s4fs never returns silently-wrong bytes. - SSE-encrypted objects are refused loudly. Reads raise
NotImplementedError(the keyring / KMS / SSE-C key lives in the gateway — read encrypted objects through the gateway). Detection is threefold: thes4-encryptedobject metadata stamp, the sidecar's v3 SSE binding, and theS4E1–S4E6envelope magic in the body; s4fs never returns ciphertext as if it were data. - Exact-size resolution in
ls/infomay cost one extra backend request per object (sidecar GET or metadata HEAD); results are cached per filesystem instance. - Range reads on framed objects without a usable sidecar fall back to a full-object read (with a warning when the object is multi-frame). Legacy v1 sidecars (no source ETag/size binding) are treated as unusable — they cannot be tied to the live object.
open()refuses framed objects whose original size is inexact (no usable sidecar, nos4-original-sizemetadata) instead of silently truncating buffered reads at the compressed size; opt back in withS4FileSystem(allow_inexact_open=True).cat_file()is unaffected.
Tests
pytest python/s4fs/tests # unit (gateway-captured fixtures)
pytest python/s4fs/tests/test_e2e_minio.py -m e2e # docker + MinIO + real gateway
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file s4fs-1.1.0.tar.gz.
File metadata
- Download URL: s4fs-1.1.0.tar.gz
- Upload date:
- Size: 21.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6ef627b9c4af27c7ece46fb2187c2769bd708fe124fa4222b5b1bf0ad518a29a
|
|
| MD5 |
a7039dcf34d71c972e6bd7e568c44e66
|
|
| BLAKE2b-256 |
ec817e4c651beef8cf3772a5faa85804b8e99916331f7d9dca736ee8493cdc87
|
File details
Details for the file s4fs-1.1.0-py3-none-any.whl.
File metadata
- Download URL: s4fs-1.1.0-py3-none-any.whl
- Upload date:
- Size: 12.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b6fa67ac18bfb932e57a0d9432efa355d399d72d7a489d4439b7e5e2675ae372
|
|
| MD5 |
1f1e75a121febe681cccca10929a9c96
|
|
| BLAKE2b-256 |
fb629ef537679dcdbdc6847b6c8ffed823db3e38d2488787e53e8ec9ba053456
|