It pays to be polite.
One function, 40+ adapters, zero required dependencies. Pass any object—DataFrames, tensors, plots, sklearn pipelines—and get a clean summary plus structured metadata. Useful for debugging, fast exploration, and those moments where you forgot what your object even is.
Install
Zero required dependencies. Opt into extras when you're ready.
pip install pretty-little-summary
Ask nicely.
One function. Pass it anything. It figures out the rest.
import pretty_little_summary as pls # The object screaming errors at you messy_data = load_nightmare_csv() # print(messy_data) ← Rude. Useless. # messy_data.info() ← Too much drama. # Try asking nicely: result = pls.describe(messy_data) print(result.content)
What you get back
A Summary with human-readable content and structured metadata.
Columns: product, price, quantity
Structured metadata
result.meta # {"object_type": "pandas.DataFrame", # "shape": [3, 3], # "columns": ["product", "price", "quantity"]}
Summary object
Example gallery
Browse real inputs and the exact summaries they produce. Search by type, tags, or content.
40+ adapters
Type detection picks the right one. Works with whatever you have installed.
Data
Viz
ML
Builtins
Jupyter history
In notebooks, PLS traces the code that created your object. A tiny time machine.
result = pls.describe(df_filtered) print(result.history) # ['df = pd.read_csv("data.csv")', # 'df_clean = df.dropna()', # 'df_filtered = df_clean[df_clean["value"] > 100]']
How it works
Type detection
Sniffs the object, picks the right adapter.
Metadata extraction
Collects shape, dtypes, parameters—the useful stuff.
Summary generation
Formats readable content + structured meta payload.
History trace
In Jupyter, tracks code lineage so you can retrace your steps.