Core API Quickstart¶
Strata Core is the programmatic materialization and artifact layer. Use this when you want the materialize() API, artifact caching, lineage tracking, or snapshot-aware Iceberg table scanning, without the notebook UI on top.
The primitive¶
This gives you:
- Immutable, versioned artifacts
- Provenance-based deduplication (same inputs + transform = cache hit)
- Explicit lineage
- Safe reuse across runs and processes
Reading from an Iceberg table is itself a materialize call with the built-in scan@v1 transform: inputs are the table URIs, params hold optional projections and filters. The cache key includes the table's snapshot ID, so once you've scanned a snapshot the result is reusable forever, there's no invalidation problem.
1. Start the server¶
2. Run the demo¶
This creates a local Iceberg table with 100K rows and times three reads against it:
Cold run (no cache) ~500ms , read Parquet, cache as Arrow IPC
Warm run (in-memory cache hit) ~50ms , serve from process memory
Restart run (disk cache hit) ~60ms , serve from on-disk Arrow IPC
Same inputs, same transform, three different cache states, and the third is still ~10× faster than the first because the disk cache survives restarts.
3. Materialize a result¶
Table URIs use the form <scheme>://<warehouse-path>#<namespace>.<table>:
<scheme>is the storage scheme -file://for a local Iceberg warehouse,s3:///gs:///az://for cloud blob storage.<warehouse-path>is the path to the warehouse root (the directory containing Iceberg metadata).- The fragment after
#names the Iceberg table inside the warehouse, as<namespace>.<table>.
For the demo above, the warehouse lives at /warehouse and contains the events table in the db namespace, so the URI is file:///warehouse#db.events.
from strata_client import StrataClient
client = StrataClient()
artifact = client.materialize(
inputs=["file:///warehouse#db.events"],
transform={
"executor": "scan@v1",
"params": {
"columns": ["id", "value"],
"filters": [{"column": "value", "op": ">", "value": 100}],
},
},
)
print(f"URI: {artifact.uri}")
print(f"Cache hit: {artifact.cache_hit}")
Re-running the same call returns the same URI with Cache hit: True.
filters prune, they do not filter rows
Strata is not a query engine. A filter is a pruning hint: it skips whole data files (via Iceberg manifest stats) and whole row groups (via Parquet min/max), which is what makes a large scan cheap. Rows inside a row group that survives pruning are returned as they are, so the result is a superset of the rows matching your predicate. Apply the predicate yourself on the result if you need exactly the matching rows.
Pruning is deliberately conservative: when Strata cannot prove a file or row group is safe to skip, it reads it. That keeps a filter from ever dropping a row you asked for.
4. Fetch the result¶
id value
0 101 142.50
1 102 178.30
2 103 215.75
3 104 311.20
4 105 168.40
5. Integration with data libraries¶
Core behaviors¶
- Same inputs + transform → existing artifact, no recomputation
- Artifacts are immutable and versioned
- Names are mutable pointers to specific artifact versions
- Provenance hash is derived from pinned inputs and transform identity
What's next¶
- Configuration all environment variables (cache, fetcher, S3 / GCS / Azure, auth, timeouts)
- Deployment Modes
personalvsservicemode and the auth boundary - REST API notebook protocol surface (separate from the
/v1/materializeendpoint this page calls into)