Export¶
3LC Tables can be exported to common formats like CSV, COCO, YOLO, and JSON using the Python API or the CLI. The built-in exporters handle the conversion, including weight-based row filtering, format inference, and format-specific options like image path handling.
If none of the built-in formats fit, you can write a custom exporter — as simple as a single method — and plug it in so it works with both the API and CLI automatically.
Quick Start¶
Python API¶
import tlc
table = tlc.Table.from_url("path/to/table")
# Format inferred from extension and table content
table.export("output.csv")
# Explicit format and options
table.export("annotations.json", format="coco", indent=2, image_folder="/images")
CLI¶
# Format inferred
3lc export path/to/table.json output.csv
# Explicit format and options
3lc export path/to/table.json annotations.json --format coco --coco-indent 2
3lc export path/to/table.json ./dataset --format yolo --yolo-split train
CLI options are auto-generated from each exporter’s parameters and prefixed by format name. Run 3lc export --help
to see all available options.
Built-in Formats¶
Format |
Extension |
Description |
|---|---|---|
|
|
Flat column export with configurable dialect |
|
|
Row-oriented JSON |
|
|
COCO object detection / segmentation / keypoints |
|
(directory) |
Ultralytics YOLO directory structure |
Format Inference¶
When no --format is specified, 3LC picks the best exporter by checking each exporter’s
can_export() method against the table content and output path. For
example, a table with bounding boxes exported to a .json file will automatically select the COCO exporter over the
generic JSON exporter. If multiple exporters match, the one with the highest
priority wins.
Priority values for the built-in formats:
Format |
Priority |
Notes |
|---|---|---|
|
3 |
Beats |
|
2 |
Directory output; picked for tables with bounding boxes when the output URL has no extension |
|
1 |
Default for |
|
1 |
Default for |
Custom exporters can set any integer priority — higher wins. If two registered formats tie at the highest priority
and both accept the table, Table.export() raises ValueError and asks you to specify format explicitly.
Format-Specific Options¶
Each exporter declares typed parameters that become keyword arguments in Python and CLI options on the command line:
table.export(
"annotations.json",
format="coco",
image_folder="/data/images", # Make image paths relative to this folder
absolute_image_paths=False, # Or make them absolute
annotation_column_name=None, # Auto-detected if omitted
image_column_name="image", # Column containing image URLs
per_image_extras=None, # Extra image-level columns to include
indent=4, # JSON indentation
)
table.export(
"./my_dataset",
format="yolo",
split="train", # Split name for directory structure
image_strategy="symlink", # "ignore", "copy", "move", or "symlink"
image_column_name="image", # Column containing image URLs
annotation_column_name=None, # Auto-detected if omitted
dataset_name="dataset", # Name for the YAML config file
)
table.export(
"output.csv",
format="csv",
dialect="excel", # Any csv.Dialect name
exclude_header=False, # Omit the header row
)
table.export(
"output.json",
format="json",
indent=4, # JSON indentation
)
Weight Filtering¶
All exporters support a weight_threshold parameter (default 0.0). Rows with a weight below this threshold are
excluded from the export. This lets you export only the rows you’ve marked as relevant in the Dashboard:
table.export("cleaned.csv", weight_threshold=0.5)
In-Memory Export¶
To export the data in a Table to a Pandas DataFrame:
df = table.to_pandas()
Listing Registered Exporters¶
To see which exporters are available in your environment:
3lc exporters list
Or from Python:
from tlc.export import list_exporters
for info in list_exporters():
print(f"{info['format']:10s} {info['source']}")
Each entry is an ExporterInfo dict with format, exporter_class,
module, and source (one of "builtin", "entrypoint", "config", or "runtime").
Custom Exporters¶
Do you need this section?
If you’re using a built-in format, you can skip this. Custom exporters are for adding new output formats — for example, exporting to a domain-specific annotation tool, a database, or a proprietary format.
There are three patterns, from simplest to most flexible:
RowExporter — One Row at a Time¶
The simplest option. Implement a single method that converts one row to a string, and the framework handles iteration, weight filtering, and file writing:
import json
from tlc.export import RowExporter, register_exporter
@register_exporter
class NdJsonExporter(RowExporter):
"""Export table rows as newline-delimited JSON."""
supported_format = "ndjson"
file_extensions = frozenset({".ndjson", ".jsonl"})
separator = "\n"
def export_row(self, row: dict, **kwargs: object) -> str:
return json.dumps(row, default=str)
SerializingExporter — Whole Table to String¶
When you need access to the full table (e.g. to write a header, or to produce a format that isn’t line-oriented),
implement serialize():
from tlc.export import SerializingExporter, register_exporter
@register_exporter
class MarkdownExporter(SerializingExporter):
"""Export a table as a Markdown table."""
supported_format = "markdown"
file_extensions = frozenset({".md"})
def serialize(self, table, output_url, weight_threshold: float = 0.0, **kwargs) -> str:
rows = list(self.remaining_table_rows(table, weight_threshold))
if not rows:
return ""
headers = list(rows[0].keys())
lines = ["| " + " | ".join(headers) + " |"]
lines.append("| " + " | ".join("---" for _ in headers) + " |")
for row in rows:
lines.append("| " + " | ".join(str(row.get(h, "")) for h in headers) + " |")
return "\n".join(lines)
Exporter — Full Control¶
For formats that write multiple files or directories (like YOLO), subclass tlc.export.exporter.Exporter
directly and override its internal export hooks (_do_export and _get_export_impl_method). The latter points the
CLI at your main method so its parameters are introspectable.
See the built-in YoloExporter for a complete example of this pattern.
Plugin Registration¶
Custom exporters defined in third-party packages can be discovered automatically via Python entry points:
# pyproject.toml
[project.entry-points."tlc.exporters"]
ndjson = "my_package.exporters:NdJsonExporter"
3LC discovers entry points lazily — your package just needs to be installed. The entry point should reference the
class (not an instance); 3LC will instantiate it automatically. Installed plugins show up in
3lc exporters list with source=entrypoint.
Alternatively, use the tlc.export.register_exporter decorator as shown above for exporters defined in your own codebase.
A minimal end-to-end plugin example — project layout, pyproject.toml, and the exporter class — lives in
3lc-examples/examples/tlc-ndjson-exporter.
CLI Option Naming¶
The 3lc export command auto-generates a CLI option for each format-specific parameter. The naming convention is:
--<format>-<argname-with-dashes>for regular values — e.g.--coco-image-folder /data/images,--yolo-split train.A bare flag
--<format>-<argname-with-dashes>for boolean parameters whose default isFalse— e.g.--csv-exclude-header,--coco-absolute-image-paths.
Boolean parameters whose default is None (tri-state, like --coco-include-segmentation) take an explicit
true/false/none argument.
Run 3lc export --help to see the exact options exposed by all registered exporters in your environment.
Errors and Troubleshooting¶
Unknown export format 'foo'. Available formats: ...The requested format is not registered. Run
3lc exporters list(orExporterRegistry.list_exporters()from Python) to see what is available. If you expected a third-party plugin to be present, confirm the package is installed in the same environment as3lcand that itspyproject.tomldeclares an entry point in thetlc.exportersgroup.Table {url} is not in the correct format for {fmt} export.The chosen exporter’s
can_export()returnedFalse. The most common cause is a missing annotation column — e.g. exporting to COCO from a table withoutbbs,segmentations, orkeypoints_2d. Check the exporter’s docstring for required columns, or use--format csv/--format jsonfor a format-agnostic export.Multiple export formats with the highest priority found ...Two registered exporters tied at the highest priority and both said
can_export=True. Pass--formatexplicitly to break the tie.- CLI
--helpis missing options you expected If a registered third-party exporter fails to import at CLI startup, its options are skipped and a warning is logged. Re-run with
--log-level DEBUGto see the traceback.
For further details, see the API reference.