Table¶
Click Extra provides a way to render tables in the terminal.
Here how to use the standalone table rendering option decorator:
import click
from click_extra import pass_context, table_format_option, style, Color
@click.command
@table_format_option
@pass_context
def table_command(ctx):
headers = ("Day", "Temperature")
data = (
(1, 42.9),
("2", None),
(style("Friday", fg=Color.blue), style("Hot 🥵", fg=Color.red, bold=True)),
)
ctx.print_table(data, headers)
As you can see above, this option registers a ready-to-use print_table() method to the context object.
The default help message for this option list all available table formats:
$ table --help
Usage: table [OPTIONS]
Options:
--table-format [aligned|asciidoc|colon-grid|csv|csv-excel|csv-excel-tab|csv-unix|double-grid|double-outline|fancy-grid|fancy-outline|github|grid|heavy-grid|heavy-outline|hjson|html|jira|json|json5|jsonc|latex|latex-booktabs|latex-longtable|latex-raw|mediawiki|mixed-grid|mixed-outline|moinmoin|orgtbl|outline|pipe|plain|presto|pretty|psql|rounded-grid|rounded-outline|rst|simple|simple-grid|simple-outline|textile|toml|tsv|unsafehtml|vertical|xml|yaml|youtrack]
Rendering style of tables.
--help Show this message and exit.
So you can use the --table-format option to change the table format:
$ table --table-format fancy-outline
╒════════╤═════════════╕
│ Day │ Temperature │
╞════════╪═════════════╡
│ 1 │ 42.9 │
│ 2 │ │
│ Friday │ Hot 🥵 │
╘════════╧═════════════╛
$ table --table-format asciidoc
[cols="<8,<13",options="header"]
|====
| Day | Temperature
| 1 | 42.9
| 2 |
| Friday | Hot 🥵
|====
Tip
This example has been selected so you can see how print_table() handles:
Mixed data types (integers, floats,
None, strings)ANSI color codes (added with the
click_extra.style()function)Unicode characters (like the emojis)
Hint
There’s another method called render_table() that is registered in the context alongside print_table().
It works the same way, but instead of printing the table to the console, it returns the rendered table as a string.
Table formats¶
Table formats are aggregated from these sources:
Python’s
csvmodule from the standard libraryPython’s
jsonmodule from the standard libraryhjson(requires the[hjson]extra)tomlkit(requires the[toml]extra)xmltodict(requires the[xml]extra)PyYAML(requires the[yaml]extra)
They’re divided in 2 categories:
Formats that produce plain text output (like ASCII tables, grid tables, etc.) and are often composed of Unicode box-drawing characters, to be displayed in a terminal.
Formats that produce markup language output (like HTML, Markdown, LaTeX, etc.) and are expected to be rendered by a supporting viewer. This category also includes CSV, TSV, and structured serialization formats (HJSON, JSON, JSON5, JSONC, TOML, XML, YAML), which are plain text but meant to be processed by other tools.
Format ID |
Description |
Implementation |
Markup |
|---|---|---|---|
|
Compact table with single-space column separators and no borders |
Click Extra |
❌ |
|
|
✅ |
|
|
|
✅ |
|
|
CSV with Excel dialect |
|
✅ |
|
CSV with Excel tab dialect |
|
✅ |
|
CSV with Unix dialect |
|
✅ |
|
Double-line grid table |
|
❌ |
|
Double-line outline table |
|
❌ |
|
Grid with Unicode box-drawing characters |
|
❌ |
|
Outline with Unicode box-drawing characters |
|
❌ |
|
|
✅ |
|
|
Grid table with ASCII characters, also supported by Pandoc and reStructuredText |
|
❌ |
|
Heavy-line grid table |
|
❌ |
|
Heavy-line outline table |
|
❌ |
|
HJSON array of objects |
✅ |
|
|
|
✅ |
|
|
|
✅ |
|
|
JSON array of objects |
|
✅ |
|
Alias for |
|
✅ |
|
Alias for |
|
✅ |
|
|
✅ |
|
|
|
✅ |
|
|
|
✅ |
|
|
LaTeX table without escaping |
|
✅ |
|
|
✅ |
|
|
Mixed-line grid table |
|
❌ |
|
Mixed-line outline table |
|
❌ |
|
|
✅ |
|
|
|
✅ |
|
|
Simple outline table |
|
❌ |
|
|
✅ |
|
|
Plain text, no formatting |
|
❌ |
|
Presto SQL output style |
|
❌ |
|
Pretty ASCII table |
|
❌ |
|
PostgreSQL output style |
|
❌ |
|
Rounded grid table |
|
❌ |
|
Rounded outline table |
|
❌ |
|
|
✅ |
|
|
Simple table with spaces, also supported by Pandoc |
|
❌ |
|
Simple grid table |
|
❌ |
|
Simple outline table |
|
❌ |
|
|
✅ |
|
|
TOML array of tables |
✅ |
|
|
|
✅ |
|
|
HTML table without escaping |
|
✅ |
|
Vertical table layout |
|
❌ |
|
XML document |
✅ |
|
|
YAML sequence of mappings |
✅ |
|
|
|
✅ |
Attention
By default, markup formats strip ANSI color codes from the output, to avoid injecting escape sequences into structured content like HTML, LaTeX, or CSV.
If you want to keep them, force the --color option when invoking the command.
Tip
Use the built-in click-extra render-matrix command to verify how ANSI codes are handled by each format:
$ uvx click-extra --table-format github render-matrix styles
$ uvx click-extra --table-format json render-matrix colors
Plain-text formats preserve ANSI styling. Markup formats strip it unless --color is passed explicitly.
$ table --table-format aligned
Day Temperature
1 42.9
2
Friday Hot 🥵
$ table --table-format asciidoc
[cols="<8,<13",options="header"]
|====
| Day | Temperature
| 1 | 42.9
| 2 |
| Friday | Hot 🥵
|====
$ table --table-format csv
Day,Temperature
1,42.9
2,
Friday,Hot 🥵
$ table --table-format csv-excel
Day,Temperature
1,42.9
2,
Friday,Hot 🥵
$ table --table-format csv-excel-tab
Day Temperature
1 42.9
2
Friday Hot 🥵
$ table --table-format csv-unix
"Day","Temperature"
"1","42.9"
"2",""
"Friday","Hot 🥵"
$ table --table-format double-grid
╔════════╦═════════════╗
║ Day ║ Temperature ║
╠════════╬═════════════╣
║ 1 ║ 42.9 ║
╠════════╬═════════════╣
║ 2 ║ ║
╠════════╬═════════════╣
║ Friday ║ Hot 🥵 ║
╚════════╩═════════════╝
$ table --table-format double-outline
╔════════╦═════════════╗
║ Day ║ Temperature ║
╠════════╬═════════════╣
║ 1 ║ 42.9 ║
║ 2 ║ ║
║ Friday ║ Hot 🥵 ║
╚════════╩═════════════╝
$ table --table-format fancy-grid
╒════════╤═════════════╕
│ Day │ Temperature │
╞════════╪═════════════╡
│ 1 │ 42.9 │
├────────┼─────────────┤
│ 2 │ │
├────────┼─────────────┤
│ Friday │ Hot 🥵 │
╘════════╧═════════════╛
$ table --table-format fancy-outline
╒════════╤═════════════╕
│ Day │ Temperature │
╞════════╪═════════════╡
│ 1 │ 42.9 │
│ 2 │ │
│ Friday │ Hot 🥵 │
╘════════╧═════════════╛
$ table --table-format github
| Day | Temperature |
| :----- | :---------- |
| 1 | 42.9 |
| 2 | |
| Friday | Hot 🥵 |
$ table --table-format grid
+--------+-------------+
| Day | Temperature |
+========+=============+
| 1 | 42.9 |
+--------+-------------+
| 2 | |
+--------+-------------+
| Friday | Hot 🥵 |
+--------+-------------+
$ table --table-format heavy-grid
┏━━━━━━━━┳━━━━━━━━━━━━━┓
┃ Day ┃ Temperature ┃
┣━━━━━━━━╋━━━━━━━━━━━━━┫
┃ 1 ┃ 42.9 ┃
┣━━━━━━━━╋━━━━━━━━━━━━━┫
┃ 2 ┃ ┃
┣━━━━━━━━╋━━━━━━━━━━━━━┫
┃ Friday ┃ Hot 🥵 ┃
┗━━━━━━━━┻━━━━━━━━━━━━━┛
$ table --table-format heavy-outline
┏━━━━━━━━┳━━━━━━━━━━━━━┓
┃ Day ┃ Temperature ┃
┣━━━━━━━━╋━━━━━━━━━━━━━┫
┃ 1 ┃ 42.9 ┃
┃ 2 ┃ ┃
┃ Friday ┃ Hot 🥵 ┃
┗━━━━━━━━┻━━━━━━━━━━━━━┛
$ table --table-format hjson
[
{
Day: 1
Temperature: 42.9
}
{
Day: "2"
Temperature: null
}
{
Day: Friday
Temperature: Hot 🥵
}
]
$ table --table-format html
<table>
<thead>
<tr><th>Day </th><th>Temperature</th></tr>
</thead>
<tbody>
<tr><td>1 </td><td>42.9 </td></tr>
<tr><td>2 </td><td> </td></tr>
<tr><td>Friday</td><td>Hot 🥵 </td></tr>
</tbody>
</table>
$ table --table-format jira
|| Day || Temperature ||
| 1 | 42.9 |
| 2 | |
| Friday | Hot 🥵 |
$ table --table-format json
[
{
"Day": 1,
"Temperature": 42.9
},
{
"Day": "2",
"Temperature": null
},
{
"Day": "Friday",
"Temperature": "Hot 🥵"
}
]
$ table --table-format json5
[
{
"Day": 1,
"Temperature": 42.9
},
{
"Day": "2",
"Temperature": null
},
{
"Day": "Friday",
"Temperature": "Hot 🥵"
}
]
$ table --table-format jsonc
[
{
"Day": 1,
"Temperature": 42.9
},
{
"Day": "2",
"Temperature": null
},
{
"Day": "Friday",
"Temperature": "Hot 🥵"
}
]
$ table --table-format latex
\begin{tabular}{ll}
\hline
Day & Temperature \\
\hline
1 & 42.9 \\
2 & \\
Friday & Hot 🥵 \\
\hline
\end{tabular}
$ table --table-format latex-booktabs
\begin{tabular}{ll}
\toprule
Day & Temperature \\
\midrule
1 & 42.9 \\
2 & \\
Friday & Hot 🥵 \\
\bottomrule
\end{tabular}
$ table --table-format latex-longtable
\begin{longtable}{ll}
\hline
Day & Temperature \\
\hline
\endhead
1 & 42.9 \\
2 & \\
Friday & Hot 🥵 \\
\hline
\end{longtable}
$ table --table-format latex-raw
\begin{tabular}{ll}
\hline
Day & Temperature \\
\hline
1 & 42.9 \\
2 & \\
Friday & Hot 🥵 \\
\hline
\end{tabular}
$ table --table-format mediawiki
{| class="wikitable" style="text-align: left;"
|+ <!-- caption -->
|-
! Day !! Temperature
|-
| 1 || 42.9
|-
| 2 ||
|-
| Friday || Hot 🥵
|}
$ table --table-format mixed-grid
┍━━━━━━━━┯━━━━━━━━━━━━━┑
│ Day │ Temperature │
┝━━━━━━━━┿━━━━━━━━━━━━━┥
│ 1 │ 42.9 │
├────────┼─────────────┤
│ 2 │ │
├────────┼─────────────┤
│ Friday │ Hot 🥵 │
┕━━━━━━━━┷━━━━━━━━━━━━━┙
$ table --table-format mixed-outline
┍━━━━━━━━┯━━━━━━━━━━━━━┑
│ Day │ Temperature │
┝━━━━━━━━┿━━━━━━━━━━━━━┥
│ 1 │ 42.9 │
│ 2 │ │
│ Friday │ Hot 🥵 │
┕━━━━━━━━┷━━━━━━━━━━━━━┙
$ table --table-format moinmoin
|| ''' Day ''' || ''' Temperature ''' ||
|| 1 || 42.9 ||
|| 2 || ||
|| Friday || Hot 🥵 ||
$ table --table-format orgtbl
| Day | Temperature |
|--------+-------------|
| 1 | 42.9 |
| 2 | |
| Friday | Hot 🥵 |
$ table --table-format outline
+--------+-------------+
| Day | Temperature |
+========+=============+
| 1 | 42.9 |
| 2 | |
| Friday | Hot 🥵 |
+--------+-------------+
$ table --table-format pipe
| Day | Temperature |
| :----- | :---------- |
| 1 | 42.9 |
| 2 | |
| Friday | Hot 🥵 |
$ table --table-format plain
Day Temperature
1 42.9
2
Friday Hot 🥵
$ table --table-format presto
Day | Temperature
--------+-------------
1 | 42.9
2 |
Friday | Hot 🥵
$ table --table-format pretty
+--------+-------------+
| Day | Temperature |
+--------+-------------+
| 1 | 42.9 |
| 2 | |
| Friday | Hot 🥵 |
+--------+-------------+
$ table --table-format psql
+--------+-------------+
| Day | Temperature |
|--------+-------------|
| 1 | 42.9 |
| 2 | |
| Friday | Hot 🥵 |
+--------+-------------+
$ table --table-format rounded-grid
╭────────┬─────────────╮
│ Day │ Temperature │
├────────┼─────────────┤
│ 1 │ 42.9 │
├────────┼─────────────┤
│ 2 │ │
├────────┼─────────────┤
│ Friday │ Hot 🥵 │
╰────────┴─────────────╯
$ table --table-format rounded-outline
╭────────┬─────────────╮
│ Day │ Temperature │
├────────┼─────────────┤
│ 1 │ 42.9 │
│ 2 │ │
│ Friday │ Hot 🥵 │
╰────────┴─────────────╯
$ table --table-format rst
====== ===========
Day Temperature
====== ===========
1 42.9
2
Friday Hot 🥵
====== ===========
$ table --table-format simple
Day Temperature
------ -----------
1 42.9
2
Friday Hot 🥵
$ table --table-format simple-grid
┌────────┬─────────────┐
│ Day │ Temperature │
├────────┼─────────────┤
│ 1 │ 42.9 │
├────────┼─────────────┤
│ 2 │ │
├────────┼─────────────┤
│ Friday │ Hot 🥵 │
└────────┴─────────────┘
$ table --table-format simple-outline
┌────────┬─────────────┐
│ Day │ Temperature │
├────────┼─────────────┤
│ 1 │ 42.9 │
│ 2 │ │
│ Friday │ Hot 🥵 │
└────────┴─────────────┘
$ table --table-format textile
|_. Day |_. Temperature |
|<. 1 |<. 42.9 |
|<. 2 |<. |
|<. Friday |<. Hot 🥵 |
$ table --table-format toml
[[record]]
Day = 1
Temperature = 42.9
[[record]]
Day = "2"
[[record]]
Day = "Friday"
Temperature = "Hot 🥵"
$ table --table-format tsv
Day Temperature
1 42.9
2
Friday Hot 🥵
$ table --table-format unsafehtml
<table>
<thead>
<tr><th>Day </th><th>Temperature</th></tr>
</thead>
<tbody>
<tr><td>1 </td><td>42.9 </td></tr>
<tr><td>2 </td><td> </td></tr>
<tr><td>Friday</td><td>Hot 🥵 </td></tr>
</tbody>
</table>
$ table --table-format vertical
***************************[ 1. row ]***************************
Day | 1
Temperature | 42.9
***************************[ 2. row ]***************************
Day | 2
Temperature |
***************************[ 3. row ]***************************
Day | Friday
Temperature | Hot 🥵
$ table --table-format xml
<records>
<record>
<Day>1</Day>
<Temperature>42.9</Temperature>
</record>
<record>
<Day>2</Day>
</record>
<record>
<Day>Friday</Day>
<Temperature>Hot 🥵</Temperature>
</record>
</records>
$ table --table-format yaml
- Day: 1
Temperature: 42.9
- Day: '2'
Temperature: null
- Day: Friday
Temperature: Hot 🥵
$ table --table-format youtrack
|| Day || Temperature ||
| 1 | 42.9 |
| 2 | |
| Friday | Hot 🥵 |
Get table format¶
You can get the ID of the current table format from the context:
import click
from click_extra import echo, pass_context, table_format_option
@click.command
@table_format_option
@pass_context
def vanilla_command(ctx):
format_id = ctx.meta["click_extra.table_format"]
echo(f"Table format: {format_id}")
data = ((1, 87), (2, 80), (3, 79))
headers = ("day", "temperature")
ctx.print_table(data, headers)
$ vanilla --table-format fancy-outline
Table format: fancy-outline
╒═════╤═════════════╕
│ day │ temperature │
╞═════╪═════════════╡
│ 1 │ 87 │
│ 2 │ 80 │
│ 3 │ 79 │
╘═════╧═════════════╛
Data serialization¶
print_data() and serialize_data() handle arbitrary data structures (nested dicts, lists, scalars), unlike print_table() which expects tabular rows and headers. They support the structured serialization formats: JSON, HJSON, YAML, TOML, and XML.
from click_extra import command, pass_context, table_format_option
from click_extra.table import print_data
@command
@table_format_option
@pass_context
def data_command(ctx):
"""Serialize nested data."""
data = {
"city": "Paris",
"population": 2161000,
"landmarks": ["Eiffel Tower", "Louvre", "Notre-Dame"],
}
table_format = ctx.meta["click_extra.table_format"]
print_data(data, table_format)
$ data --table-format json
{
"city": "Paris",
"population": 2161000,
"landmarks": [
"Eiffel Tower",
"Louvre",
"Notre-Dame"
]
}
/home/runner/work/click-extra/click-extra/.venv/lib/python3.14/site-packages/click/core.py:1223: UserWarning: The parameter --table-format is used more than once. Remove its duplicate as parameters should be unique.
parser = self.make_parser(ctx)
/home/runner/work/click-extra/click-extra/.venv/lib/python3.14/site-packages/cloup/constraints/_support.py:183: UserWarning: The parameter --table-format is used more than once. Remove its duplicate as parameters should be unique.
args = super().parse_args(ctx, args) # type: ignore
/home/runner/work/click-extra/click-extra/click_extra/parameters.py:415: UserWarning: The parameter --table-format is used more than once. Remove its duplicate as parameters should be unique.
for keys, param in self.walk_params():
$ data --table-format yaml
city: Paris
landmarks:
- Eiffel Tower
- Louvre
- Notre-Dame
population: 2161000
serialize_data() returns the serialized string instead of printing it:
Sorted tables¶
SortByOption adds a --sort-by CLI option whose choices are derived from column definitions. Column definitions are (label, column_id) tuples. Columns with column_id=None are displayed but not offered as sort choices.
The option can be repeated to define a multi-column sort priority: --sort-by name --sort-by age sorts by name first, then breaks ties by age.
When active, SortByOption replaces ctx.print_table with a sorted variant, so the command body doesn’t need any sorting logic.
from click_extra import command, pass_context, table_format_option
from click_extra.table import SortByOption
sort_opt = SortByOption(
("Fruit", "fruit"),
("Count", "count"),
("Notes", None),
)
@command(params=[sort_opt])
@table_format_option
@pass_context
def inventory(ctx):
"""Sortable fruit inventory."""
header_defs = (("Fruit", "fruit"), ("Count", "count"), ("Notes", None))
data = [
["Cherry", "50", "seasonal"],
["Apple", "120", ""],
["Banana", "80", "organic"],
]
ctx.print_table(header_defs, data)
$ inventory --help
Usage: inventory [OPTIONS]
Sortable fruit inventory.
Options:
--sort-by [fruit|count] Sort table by this column. Repeat to set priority.
[default: fruit]
--table-format [aligned|asciidoc|colon-grid|csv|csv-excel|csv-excel-tab|csv-unix|double-grid|double-outline|fancy-grid|fancy-outline|github|grid|heavy-grid|heavy-outline|hjson|html|jira|json|json5|jsonc|latex|latex-booktabs|latex-longtable|latex-raw|mediawiki|mixed-grid|mixed-outline|moinmoin|orgtbl|outline|pipe|plain|presto|pretty|psql|rounded-grid|rounded-outline|rst|simple|simple-grid|simple-outline|textile|toml|tsv|unsafehtml|vertical|xml|yaml|youtrack]
Rendering style of tables. [default: rounded-
outline]
-h, --help Show this message and exit.
$ inventory --table-format rounded-outline --sort-by fruit
╭────────┬───────┬──────────╮
│ Fruit │ Count │ Notes │
├────────┼───────┼──────────┤
│ Apple │ 120 │ │
│ Banana │ 80 │ organic │
│ Cherry │ 50 │ seasonal │
╰────────┴───────┴──────────╯
$ inventory --table-format rounded-outline --sort-by count
╭────────┬───────┬──────────╮
│ Fruit │ Count │ Notes │
├────────┼───────┼──────────┤
│ Apple │ 120 │ │
│ Cherry │ 50 │ seasonal │
│ Banana │ 80 │ organic │
╰────────┴───────┴──────────╯
Repeating --sort-by sets multi-column priority. Here, rows are sorted by count first, then ties broken by fruit name:
$ inventory --table-format rounded-outline --sort-by count --sort-by fruit
╭────────┬───────┬──────────╮
│ Fruit │ Count │ Notes │
├────────┼───────┼──────────┤
│ Apple │ 120 │ │
│ Cherry │ 50 │ seasonal │
│ Banana │ 80 │ organic │
╰────────┴───────┴──────────╯
For programmatic use without a CLI option, render_table() accepts a sort_key callable:
from click_extra import command, echo
from click_extra.table import render_table, TableFormat
@command
def sorted_demo():
"""Render a table sorted alphabetically."""
data = [["Cherry", "50"], ["Apple", "120"], ["Banana", "80"]]
output = render_table(
data,
headers=["Fruit", "Count"],
table_format=TableFormat.ROUNDED_OUTLINE,
sort_key=lambda row: row[0],
)
echo(output)
$ sorted-demo
╭────────┬───────╮
│ Fruit │ Count │
├────────┼───────┤
│ Apple │ 120 │
│ Banana │ 80 │
│ Cherry │ 50 │
╰────────┴───────╯
click_extra.table API¶
classDiagram
Enum <|-- TableFormat
ExtraOption <|-- SortByOption
ExtraOption <|-- TableFormatOption
Collection of table rendering utilities.
- class click_extra.table.TableFormat(*values)[source]¶
Bases:
EnumEnumeration of supported table formats.
Hard-coded to be in alphabetical order. Content of this enum is checked in unit tests.
Warning
The
youtrackformat is missing in action from any official JetBrains documentation. It will be removed in python-tabulate v0.11.- ALIGNED = 'aligned'¶
- ASCIIDOC = 'asciidoc'¶
- COLON_GRID = 'colon-grid'¶
- CSV = 'csv'¶
- CSV_EXCEL = 'csv-excel'¶
- CSV_EXCEL_TAB = 'csv-excel-tab'¶
- CSV_UNIX = 'csv-unix'¶
- DOUBLE_GRID = 'double-grid'¶
- DOUBLE_OUTLINE = 'double-outline'¶
- FANCY_GRID = 'fancy-grid'¶
- FANCY_OUTLINE = 'fancy-outline'¶
- GITHUB = 'github'¶
- GRID = 'grid'¶
- HEAVY_GRID = 'heavy-grid'¶
- HEAVY_OUTLINE = 'heavy-outline'¶
- HJSON = 'hjson'¶
- HTML = 'html'¶
- JIRA = 'jira'¶
- JSON = 'json'¶
- JSON5 = 'json5'¶
- JSONC = 'jsonc'¶
- LATEX = 'latex'¶
- LATEX_BOOKTABS = 'latex-booktabs'¶
- LATEX_LONGTABLE = 'latex-longtable'¶
- LATEX_RAW = 'latex-raw'¶
- MEDIAWIKI = 'mediawiki'¶
- MIXED_GRID = 'mixed-grid'¶
- MIXED_OUTLINE = 'mixed-outline'¶
- MOINMOIN = 'moinmoin'¶
- ORGTBL = 'orgtbl'¶
- OUTLINE = 'outline'¶
- PIPE = 'pipe'¶
- PLAIN = 'plain'¶
- PRESTO = 'presto'¶
- PRETTY = 'pretty'¶
- PSQL = 'psql'¶
- ROUNDED_GRID = 'rounded-grid'¶
- ROUNDED_OUTLINE = 'rounded-outline'¶
- RST = 'rst'¶
- SIMPLE = 'simple'¶
- SIMPLE_GRID = 'simple-grid'¶
- SIMPLE_OUTLINE = 'simple-outline'¶
- TEXTILE = 'textile'¶
- TOML = 'toml'¶
- TSV = 'tsv'¶
- UNSAFEHTML = 'unsafehtml'¶
- VERTICAL = 'vertical'¶
- XML = 'xml'¶
- YAML = 'yaml'¶
- YOUTRACK = 'youtrack'¶
- click_extra.table.MARKUP_FORMATS = frozenset({TableFormat.ASCIIDOC, TableFormat.CSV, TableFormat.CSV_EXCEL, TableFormat.CSV_EXCEL_TAB, TableFormat.CSV_UNIX, TableFormat.GITHUB, TableFormat.HJSON, TableFormat.HTML, TableFormat.JIRA, TableFormat.JSON, TableFormat.JSON5, TableFormat.JSONC, TableFormat.LATEX, TableFormat.LATEX_BOOKTABS, TableFormat.LATEX_LONGTABLE, TableFormat.LATEX_RAW, TableFormat.MEDIAWIKI, TableFormat.MOINMOIN, TableFormat.ORGTBL, TableFormat.PIPE, TableFormat.RST, TableFormat.TEXTILE, TableFormat.TOML, TableFormat.TSV, TableFormat.UNSAFEHTML, TableFormat.XML, TableFormat.YAML, TableFormat.YOUTRACK})¶
Subset of table formats that are considered as markup rendering.
- click_extra.table.DEFAULT_FORMAT = TableFormat.ROUNDED_OUTLINE¶
Default table format, if none is specified.
- click_extra.table.RECORD_KEY = 'record'¶
Key used for each record in structured formats that require named containers (TOML
[[record]], XML<record>).
- click_extra.table.XML_ROOT_KEY = 'records'¶
Root element name for XML table output.
- click_extra.table.SERIALIZATION_FORMATS = frozenset({TableFormat.HJSON, TableFormat.JSON, TableFormat.JSON5, TableFormat.JSONC, TableFormat.TOML, TableFormat.XML, TableFormat.YAML})¶
Structured serialization formats whose renderers escape raw ESC bytes, making post-render
strip_ansi()ineffective.
- click_extra.table.render_table(table_data, headers=None, table_format=None, sort_key=None, **kwargs)[source]¶
Render a table and return it as a string.
- click_extra.table.print_table(table_data, headers=None, table_format=None, sort_key=None, **kwargs)[source]¶
Render a table and print it to the console.
For markup formats, ANSI color codes are stripped from cell values before rendering unless
--coloris explicitly set.
- click_extra.table.serialize_data(data, table_format, *, default=None, root_element='records', **kwargs)[source]¶
Serialize arbitrary Python data to a structured format.
Unlike
render_table()which expects tabular rows and headers, this function accepts any JSON-compatible data structure (dicts, lists, nested combinations) and serializes it to the requested format.Only formats in
SERIALIZATION_FORMATSare supported.- Parameters:
data (
Any) – Arbitrary data to serialize (dicts, lists, scalars).table_format (
TableFormat) – Target serialization format.default (
Callable|None) – Fallback serializer for types not natively supported. Defaults tostr(), soPathand similar types are stringified automatically. Set to a custom callable for different behavior.root_element (
str) – Root element name for XML output.kwargs – Extra keyword arguments forwarded to the underlying serializer (e.g.
sort_keys,indentfor JSON).
- Raises:
ValueError – If the format is not a serialization format.
- Return type:
- click_extra.table.print_data(data, table_format, *, default=None, root_element='records', package='click-extra', **kwargs)[source]¶
Serialize arbitrary Python data and print it to the console.
Wraps
serialize_data()with user-friendly error handling for missing optional dependencies.- Parameters:
data (
Any) – Arbitrary data to serialize.table_format (
TableFormat) – Target serialization format.default (
Callable|None) – Fallback serializer for custom types. Defaults tostr().root_element (
str) – Root element name for XML output.package (
str) – Package name for install instructions in error messages.kwargs – Extra keyword arguments forwarded to the underlying serializer.
- Return type:
- class click_extra.table.TableFormatOption(param_decls=None, type=EnumChoice('aligned', 'asciidoc', 'colon-grid', 'csv', 'csv-excel', 'csv-excel-tab', 'csv-unix', 'double-grid', 'double-outline', 'fancy-grid', 'fancy-outline', 'github', 'grid', 'heavy-grid', 'heavy-outline', 'hjson', 'html', 'jira', 'json', 'json5', 'jsonc', 'latex', 'latex-booktabs', 'latex-longtable', 'latex-raw', 'mediawiki', 'mixed-grid', 'mixed-outline', 'moinmoin', 'orgtbl', 'outline', 'pipe', 'plain', 'presto', 'pretty', 'psql', 'rounded-grid', 'rounded-outline', 'rst', 'simple', 'simple-grid', 'simple-outline', 'textile', 'toml', 'tsv', 'unsafehtml', 'vertical', 'xml', 'yaml', 'youtrack'), default=TableFormat.ROUNDED_OUTLINE, expose_value=False, is_eager=True, help='Rendering style of tables.', **kwargs)[source]¶
Bases:
ExtraOptionA pre-configured option that is adding a
--table-formatflag to select the rendering style of a table.The selected table format ID is made available in the context in
ctx.meta["click_extra.table_format"], and two helper methods are added to the context: -ctx.render_table(table_data, headers, **kwargs): renders and returnsthe table as a string,
ctx.print_table(table_data, headers, **kwargs): renders and prints the table to the console.
Where: -
table_datais a 2-dimensional iterable of iterables for rows and cells values, -headersis a list of string to be used as column headers, -**kwargsare any extra keyword arguments supported by the underlying tableformatting function.
- click_extra.table.print_sorted_table(header_defs, table_data, sort_columns=None, table_format=None, *, cell_key=None, **kwargs)[source]¶
Sort and print a table using named column definitions.
header_defsis an ordered sequence of(label, column_id)tuples. Columns withcolumn_id=Noneare not selectable for sorting but still participate in tie-breaking.- Parameters:
header_defs (
Sequence[tuple[str,str|None]]) – Column definitions as(label, column_id)pairs.table_data (
Sequence[Sequence[str|None]]) – Rows of cell values.sort_columns (
Sequence[str] |None) – Column IDs to sort by, in priority order. Falls back to natural header order.table_format (
TableFormat|None) – Rendering format.cell_key (
Callable[[str|None],Any] |None) – Per-cell comparison key. Defaults to ANSI-stripped, case-folded string comparison.
- Return type:
- class click_extra.table.SortByOption(*header_defs, param_decls=None, default=None, expose_value=False, cell_key=None, help='Sort table by this column. Repeat to set priority.', **kwargs)[source]¶
Bases:
ExtraOptionA
--sort-byoption whose choices are derived from column definitions.Stores the selected column IDs in
ctx.meta["click_extra.sort_by"]and replacesctx.print_tablewithprint_sorted_table()so that table output is automatically sorted. The option acceptsmultiple=True, so users can repeat--sort-byto define a multi-column sort priority.@command @table_format_option @sort_by_option( ("Package ID", "package_id"), ("Name", "package_name"), ("Manager", "manager_id"), ("Version", None), ) @pass_context def my_cmd(ctx): ctx.print_table(header_defs, rows)