Tables
Show the data behind a decision as a table in a Python trace, with highlighted rows, summary rows and labelled sections.
The recount.table() builder constructs a single TableData dict. Call .build() to get a value ready to pass directly as span input or output.
Basic usage
recount.add_span("table", "Policy checks", {
"output": recount.table("Validation Results")
.from_records([
{"check": "Policy active", "result": "Pass"},
{"check": "Cover active at incident", "result": "Pass"},
{"check": "Comprehensive cover", "result": "Pass"},
])
.highlight_rows(lambda row: "success" if row["result"] == "Pass" else "danger")
.build(),
})recount.table(title=None)
Returns a TableBuilder. Chain methods and call .build() to get a TableData dict, ready to use as span input or output.
Data sources
.from_records(data)
Build from a list of dicts. Column names are the dict keys as-is (taken from the first record).
recount.table("Users") \
.from_records([
{"name": "Alice", "score": 98.5},
{"name": "Bob", "score": 72.1},
]) \
.build().from_object(data)
Build a key-value table from a plain dict. Renders as two columns: Key and Value.
recount.table("Config") \
.from_object({"timeout": 5000, "retries": 3, "env": "production"}) \
.build()Column selection
.pick(*keys)
Only include the specified columns, in order.
.pick("name", "email", "role")Labels & formatting
.label(mapping)
Override column display labels.
.label({"usageKwh": "Usage (kWh)", "ratePerKwh": "Rate ($/kWh)"}).round(decimals)
Round all numeric values to decimals decimal places.
.round(2).transform_values(mapping)
Apply a transform function to values in specific columns.
.transform_values({
"status": lambda v: str(v).upper(),
"createdAt": lambda v: datetime.fromisoformat(v).strftime("%Y-%m-%d"),
})Highlighting
.highlight_column(key, highlight)
Apply a highlight color to an entire column header and cells.
.highlight_column("revenue", "success").highlight_rows(fn)
Apply a per-row highlight based on the row's data.
def highlight(row):
if row["errorRate"] > 0.1:
return "danger"
if row["errorRate"] > 0.05:
return "warn"
return None
.highlight_rows(highlight).highlight_cells(key, fn)
Apply a per-cell highlight for a specific column.
def highlight_status(v):
if v == "error":
return "danger"
if v == "ok":
return "success"
return None
.highlight_cells("status", highlight_status)Highlight values: 'danger' | 'warn' | 'success' | 'info' | 'muted'
Column spans
.span_column(key, span)
Make a column header span multiple columns.
.span_column("metrics", 3)Extra rows
.append_row(cells, highlight=None)
Append a summary row at the bottom of the table.
.append_row(["Total", 450, 890], "info")Use recount.span_cell(value, span) to create a cell that spans multiple columns:
.append_row([recount.span_cell("Grand total: $1,234", 4)], "success").summary(stats)
Define stats shown when this table is collapsed in the dashboard. Each stat has a text string and an optional highlight color.
.summary([
{"text": "$64.70", "highlight": "info"},
{"text": "28.8% less", "highlight": "success"},
])Highlight values: 'danger' | 'warn' | 'success' | 'info' | 'muted'
.build_section()
Returns a TableSection (rows and optional highlights/summary, without column definitions). Used as input to recount.table_sections() when building sectioned tables.
section = recount.table("Active policies") \
.from_records(active_policies) \
.highlight_rows(lambda row: "danger" if row["overdue"] else None) \
.build_section()recount.table_sections(sections, columns=None, title=None)
Builds a single table with named sections that share the same columns. Use this when you want to group rows under labelled headings within one table span.
recount.add_span("table", "Plan comparison", {
"output": recount.table_sections(
[
recount.table("Medical").from_records([
{"Benefit": "Hospital", "Current plan": "$500", "Recommended plan": "$250"},
{"Benefit": "Specialist", "Current plan": "Not covered", "Recommended plan": "$50"},
]).highlight_rows(
lambda row: "warn" if row["Recommended plan"] == "Not covered" else None
),
recount.table("Extras").from_records([
{"Benefit": "Dental", "Current plan": "Not covered", "Recommended plan": "80%"},
{"Benefit": "Optical", "Current plan": "50%", "Recommended plan": "80%"},
]),
],
title="Coverage breakdown",
columns=["Benefit", "Current plan", "Recommended plan"],
),
})Parameters
| Parameter | Type | Description |
|---|---|---|
sections | list[TableBuilder | TableSection] | At least one section. Pass TableBuilder instances (built via .build_section() internally) or raw TableSection dicts |
columns | list[TableColumn] | Column definitions shared across all sections. Can be omitted when the first section is a TableBuilder; columns are derived from it automatically |
title | str | Optional title for the whole table |
sections is required and positional; columns and title are keyword-only in practice. When columns is omitted, the first section must be a TableBuilder instance, not a plain dict.
Raw TableSection dicts
Sections can also be plain dicts instead of builder instances:
recount.table_sections(
[
{
"title": "Q1",
"rows": [
["NSW", 142, "$4,200"],
["VIC", 98, "$3,800"],
],
},
{
"title": "Q2",
"rows": [
["NSW", 167, "$4,500"],
["VIC", 110, "$4,100"],
],
},
],
columns=["Region", "Claims", "Avg settlement"],
)recount.span_cell(value, span)
Creates a cell that spans span columns. Only useful inside .append_row().
recount.span_cell("Total Cost: $99.00", 3)Multiple tables
To display multiple tables that share the same columns as labelled sections, use recount.table_sections().
To display distinct tables together, use a group span. Each table is its own span inside the group:
def build_group(g):
g.span("table", "Summary", {
"output": recount.table_from_object({
"claimId": "CLM-2024-03941",
"decision": "Approved",
"settlement": "$6,840.00",
}, title="Summary"),
})
g.span("table", "Breakdown", {
"output": recount.table("Breakdown")
.from_records([
{"item": "Vehicle repairs", "amount": 5200},
{"item": "Rental car", "amount": 840},
{"item": "Medical", "amount": 800},
])
.round(2)
.build(),
})
recount.add_group("Claim report", build_group)Shorthand exports
For simple cases where you don't need to chain builder methods, two direct exports are available:
recount.table_from_records(data, title=None)
Equivalent to recount.table(title).from_records(data).build(). Returns TableData directly.
recount.add_span("table", "Policy checks", {
"output": recount.table_from_records(
[
{"check": "Policy active", "result": "Pass"},
{"check": "Cover active at incident", "result": "Pass"},
],
title="Validation Results",
),
})recount.table_from_object(data, title=None)
Equivalent to recount.table(title).from_object(data).build(). Returns TableData directly.
recount.add_span("table", "Claim summary", {
"output": recount.table_from_object(
{
"claimId": "CLM-2024-03941",
"vehicle": "2019 Toyota Camry",
"decision": "Approved",
},
title="Claim Details",
),
})