tabulate

Pretty-print tabular data in Python — formats lists of lists, dicts, and named tuples as ASCII tables in dozens of formats. tabulate features: tabulate() function accepting list-of-lists, list-of-dicts, dict-of-lists, numpy arrays, pandas DataFrames, headers= for column names, tablefmt for output format (plain, simple, grid, pipe, orgtbl, rst, mediawiki, html, latex, tsv, github, rounded_outline), floatfmt for number formatting, intfmt, stralign for text alignment, numalign for number alignment, showindex for row numbers, and colalign for per-column alignment.

Evaluated Mar 06, 2026 (0d ago) v0.9.x
Homepage ↗ Repo ↗ Developer Tools python tabulate table terminal formatting ASCII markdown HTML
⚙ Agent Friendliness
68
/ 100
Can an agent use this?
🔒 Security
92
/ 100
Is it safe for agents?
⚡ Reliability
89
/ 100
Does it work consistently?

Score Breakdown

⚙ Agent Friendliness

MCP Quality
--
Documentation
88
Error Messages
80
Auth Simplicity
99
Rate Limits
99

🔒 Security

TLS Enforcement
92
Auth Strength
92
Scope Granularity
92
Dep. Hygiene
95
Secret Handling
92

Pure formatting library. tablefmt='html' escapes values by default — safe for user-provided data. tablefmt='unsafehtml' passes HTML through unescaped — only use with trusted data to prevent XSS. No network calls or security concerns beyond XSS in HTML output.

⚡ Reliability

Uptime/SLA
88
Version Stability
90
Breaking Changes
90
Error Recovery
88
AF Security Reliability

Best When

CLI scripts and quick tabular output where rich is overkill — tabulate provides dozens of table formats with a single simple function call.

Avoid When

Large datasets, colored/styled output (use rich.Table), or pandas DataFrames (use built-in methods).

Use Cases

  • Agent CLI table — from tabulate import tabulate; data = [['Alice', 30, 'NYC'], ['Bob', 25, 'LA']]; headers = ['Name', 'Age', 'City']; print(tabulate(data, headers=headers, tablefmt='simple')) — simple table; agent prints formatted table in CLI output; tablefmt='simple' for plain ASCII; tablefmt='grid' for bordered table
  • Agent dict table — data = [{'name': 'Alice', 'age': 30}, {'name': 'Bob', 'age': 25}]; print(tabulate(data, headers='keys')) — dict rows; agent prints list-of-dicts; headers='keys' auto-extracts column names from dict keys; headers='firstrow' for first row as header
  • Agent markdown table — md = tabulate(data, headers=headers, tablefmt='pipe'); print(md) — GitHub markdown; agent generates markdown table for documentation, GitHub README, or Notion; tablefmt='pipe' produces: | Name | Age |\n|------|-----|\n| Alice | 30 |
  • Agent HTML table — html = tabulate(data, headers=headers, tablefmt='html') — HTML table; agent generates HTML table for email, web, or report; tablefmt='unsafehtml' for raw HTML in cells; default html escapes cell values
  • Agent number formatting — data = [['π', 3.14159265], ['e', 2.71828]]; print(tabulate(data, headers=['Symbol', 'Value'], floatfmt='.3f')) — '3.142', '2.718'; agent formats floats uniformly; intfmt=',' for thousand separator on integers; per-column: floatfmt=('.3f', '.2f')

Not For

  • Large datasets — tabulate builds entire table in memory; for large datasets use pandas to_string() or streaming formatters
  • Rich terminal formatting — for colored, styled tables use rich.Table which supports colors and Unicode box-drawing
  • Pandas DataFrames — pandas has built-in .to_string(), .to_markdown(), .to_html() — no need for tabulate

Interface

REST API
No
GraphQL
No
gRPC
No
MCP Server
No
SDK
Yes
Webhooks
No

Authentication

Methods: none
OAuth: No Scopes: No

No auth — table formatting library.

Pricing

Model: open_source
Free tier: Yes
Requires CC: No

tabulate is MIT licensed. Free for all use.

Agent Metadata

Pagination
none
Idempotent
Full
Retry Guidance
Not documented

Known Gotchas

  • headers='keys' only works for list-of-dicts — tabulate(data, headers='keys') extracts keys from first dict; if data is list-of-lists: use headers=['Col1', 'Col2'] explicitly; if data is dict-of-lists: headers='keys' extracts dict keys as column names; agent code: check data format before setting headers
  • Cell values must be string-representable — None becomes empty string; objects use str() representation; agent code with complex objects: convert to string before tabulating: [[str(x) for x in row] for row in data]; tabulate does not call repr() — uses str()
  • Column width is determined by widest cell — long cell values widen entire column; for truncation: agent code must truncate values before passing to tabulate: str(val)[:50] for each cell; tabulate has no built-in truncation or wrapping
  • tablefmt='html' escapes HTML by default — cell values with < > & are escaped to &lt; &gt; &amp;; tablefmt='unsafehtml' skips escaping; agent code generating HTML: use default html for user data (security); use unsafehtml only for known-safe HTML content
  • Mismatched row lengths produce ragged table — [[1, 2, 3], [4, 5]] produces table with empty cell; tabulate pads shorter rows with empty strings; agent code: ensure uniform row length or use dicts which handle missing keys gracefully
  • floatfmt applies to all float columns — tabulate(data, floatfmt='.2f') applies to every float; for per-column formatting: floatfmt=('.2f', '.4f') as tuple matching column count; agent code mixing precision: use tuple format; or pre-format floats as strings before passing to tabulate

Alternatives

Full Evaluation Report

Detailed scoring breakdown, competitive positioning, security analysis, and improvement recommendations for tabulate.

$99

Scores are editorial opinions as of 2026-03-06.

5208
Packages Evaluated
26151
Need Evaluation
173
Need Re-evaluation
Community Powered