Coverage for src/lilbee/cli/commands/dataset.py: 100%
44 statements
« prev ^ index » next coverage.py v7.15.2, created at 2026-08-14 11:46 +0000
« prev ^ index » next coverage.py v7.15.2, created at 2026-08-14 11:46 +0000
1"""Export and import the per-page text dataset."""
3from __future__ import annotations
5import asyncio
6from pathlib import Path
7from typing import NoReturn
9import typer
11from lilbee.cli import theme
12from lilbee.cli.app import apply_overrides, console, data_dir_option, global_option
13from lilbee.cli.helpers import json_output, sigint_cancel
14from lilbee.core.config import cfg
15from lilbee.runtime.cancellation import TaskCancelledError
17_export_output_argument = typer.Argument(
18 Path("pages.parquet"),
19 help="Output file (suffix sets the format unless --format is given).",
20)
21_import_dataset_argument = typer.Argument(
22 ...,
23 help="Dataset file to import (parquet or jsonl).",
24)
25_format_option = typer.Option(
26 "",
27 "--format",
28 help="Dataset format: parquet or jsonl. Inferred from the file suffix when omitted.",
29)
30_export_source_option = typer.Option(
31 None,
32 "--source",
33 help="Export only this source (default: every source).",
34)
37def _fail(message: str) -> NoReturn:
38 """Emit *message* as an error in the active output mode and exit non-zero."""
39 if cfg.json_mode:
40 json_output({"error": message})
41 else:
42 console.print(f"[{theme.ERROR}]Error:[/{theme.ERROR}] {message}")
43 raise SystemExit(1)
46def export_cmd(
47 output: Path = _export_output_argument,
48 fmt: str = _format_option,
49 source: str | None = _export_source_option,
50 data_dir: Path | None = data_dir_option,
51 use_global: bool = global_option,
52) -> None:
53 """Write a per-page {source, page, text} dataset (drops vectors)."""
54 apply_overrides(data_dir=data_dir, use_global=use_global)
55 from lilbee.app.dataset import DatasetError, export_to_path
57 try:
58 with sigint_cancel() as cancel:
59 summary = export_to_path(output, fmt, source, cancel=cancel)
60 except TaskCancelledError:
61 _fail("Export cancelled; the partial file was removed.")
62 except DatasetError as exc:
63 _fail(str(exc))
65 if cfg.json_mode:
66 json_output(summary.model_dump())
67 return
68 console.print(
69 f"Wrote [{theme.LABEL}]{summary.pages}[/{theme.LABEL}] pages from "
70 f"[{theme.LABEL}]{summary.sources}[/{theme.LABEL}] source(s) to "
71 f"[{theme.ACCENT}]{output}[/{theme.ACCENT}]"
72 )
75def import_cmd(
76 dataset: Path = _import_dataset_argument,
77 fmt: str = _format_option,
78 data_dir: Path | None = data_dir_option,
79 use_global: bool = global_option,
80) -> None:
81 """Import a per-page text dataset, re-embedding it with the current model."""
82 apply_overrides(data_dir=data_dir, use_global=use_global)
83 from lilbee.app.dataset import DatasetError, import_from_path
85 try:
86 summary = asyncio.run(import_from_path(dataset, fmt))
87 except DatasetError as exc:
88 _fail(str(exc))
90 if cfg.json_mode:
91 json_output(summary.model_dump())
92 return
93 console.print(
94 f"Imported [{theme.LABEL}]{len(summary.sources)}[/{theme.LABEL}] source(s) "
95 f"([{theme.LABEL}]{summary.pages}[/{theme.LABEL}] pages, "
96 f"[{theme.LABEL}]{summary.chunks}[/{theme.LABEL}] chunks)"
97 )