Core typed relational planning layer for Python DataFrames.
This project has been archived.
The maintainers of this project have marked this project as archived. No new releases are expected.
Project description
planframe
Core package for PlanFrame (typed planning layer). Import as planframe.
Documentation (ReadTheDocs):
- Core (adapter authors):
https://planframe.readthedocs.io/en/latest/planframe/ - Migrating since v1.1.0 (v1.2.0+):
https://planframe.readthedocs.io/en/latest/planframe/guides/migrating-since-1-1/ - Design docs:
https://planframe.readthedocs.io/en/latest/planframe/design/ - Light API reference:
https://planframe.readthedocs.io/en/latest/planframe/reference/api/ - Streaming rows:
https://planframe.readthedocs.io/en/latest/planframe/guides/streaming-rows/ - Adapter conformance kit (third-party
BaseAdapterCI):https://planframe.readthedocs.io/en/latest/planframe/guides/adapter-conformance/ - Optional API skins: PySpark-like (
planframe.spark), pandas-like (planframe.pandas)
Install
planframe is backend-agnostic; you typically install an adapter package like planframe-polars or planframe-pandas.
If you only want the core planning layer:
pip install planframe
What you get
planframe.Frame: immutable, schema-aware transformation plan (always lazy)planframe.expr: typed expression IR (col,lit, arithmetic/compare/boolean ops,coalesce,if_else, etc.); operator overloads onExpr(==,!=,&,|,~, …) build IR nodes—see Typing design. Aggregation wrappers forgroup_by(...).agg(...):agg_sum,agg_mean,agg_min,agg_max,agg_count,agg_n_unique(these buildAggExprnodes)planframe.groupby.GroupedFrame: produced byFrame.group_by;group_byaccepts column names and/or expressions (expression keys show up as__pf_g0,__pf_g1, … in the result schema).aggaccepts(op, column)tuples and/orAggExprvalues—not arbitrary bare expressionsplanframe.schema: schema reflection (dataclass + Pydantic) and materializationplanframe.spark: optional PySpark-likeSparkFrame/Column/functions(importfrom planframe.spark import SparkFrame, orfrom planframe import spark)planframe.pandas: optional pandas-likePandasLikeFrame/Series(importfrom planframe.pandas import PandasLikeFrame, orfrom planframe import pandas); mix with anyFramesubclass for familiar naming without new backend dependenciesplanframe.adapter_conformance: minimalrun_minimal_adapter_conformancehelper for adapter authors; optional extraplanframe[adapter-dev]includes pytest for local runs
Common transforms
Some commonly used Frame transforms:
with_row_index(name="row_nr", offset=0): add a monotonically increasing row number column.clip(lower=..., upper=..., subset=...): clamp numeric columns (ifsubset=None, clamps all numeric schema fields).drop_nulls(subset=..., how="any"|"all", threshold=...): drop rows by null pattern over a column subset.select_schema(selector, strict=True): schema-only selectors (backend-independent);ColumnSelectoris runtime-checkable.cast_many(mapping, strict=True)/cast_subset(*columns, dtype, strict=True): multi-column cast helpers.fill_null_subset(value|strategy, *columns)/fill_null_many(mapping, strict=True): multi-column fill-null helpers.rename_upper/lower/title/strip(...): schema-driven rename helpers.pivot_longer(...)/pivot_wider(...): reshape convenience wrappers aroundunpivot/pivot.
Materialization accepts optional ExecutionOptions on collect / to_dicts / to_dict (and async counterparts). JoinOptions on Frame.join carries execution hints (including engine_streaming where the backend supports it).
planframe.materialize: materialize_columns / materialize_into (and amaterialize_*) forward the same options as Frame.to_dict / ato_dict—useful for adapter and host-library boundaries (Creating an adapter — columnar helpers).
execute_plan / execute_plan_async: the supported plan interpreters; execute_plan_async runs the sync interpreter in asyncio.to_thread so you can await without blocking the event loop (Core layout).
Note on backends
planframe is backend-agnostic. It does not execute anything until collect() (even for eager backends). To execute plans you need an adapter package (e.g. planframe-polars).
For async stacks, use Frame.acollect() / ato_dicts() / ato_dict() or the discoverable aliases collect_async, to_dicts_async, to_dict_async (same behavior). These await adapter hooks (BaseAdapter.acollect and friends); defaults run sync methods in a thread pool. See Backend adapter design and Creating an adapter — Async execution.
Typing
PlanFrame includes py.typed plus generated stubs (notably planframe/frame/__init__.pyi) to improve static typing in editors and Pyright.
If you modify the Frame API, regenerate stubs from the repo root:
python scripts/generate_typing_stubs.py
python scripts/generate_typing_stubs.py --check
Project details
Release history Release notifications | RSS feed
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 planframe-1.2.0.tar.gz.
File metadata
- Download URL: planframe-1.2.0.tar.gz
- Upload date:
- Size: 59.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5aea25a162ecbc8634dc883a2b09b9d0134b038a807360ff4b9912dee4ac62b9
|
|
| MD5 |
3967ba49a01281eb392467660ed9e4a9
|
|
| BLAKE2b-256 |
1e083bcf379491df4360f5a7769613081d5c96fa0b3263cb89363f16df396190
|
File details
Details for the file planframe-1.2.0-py3-none-any.whl.
File metadata
- Download URL: planframe-1.2.0-py3-none-any.whl
- Upload date:
- Size: 80.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1a926835d33239825d7197a0bd857f806d4451a6b2ce902c02e8ab4492a6d098
|
|
| MD5 |
140b903d0eb4530147f13e9dceaf5ad6
|
|
| BLAKE2b-256 |
69aaff3ab65ca5eb0ba1c47b784854c7ea496e7fa516d35bf035e5fd7b7d6a84
|