fauxdata-cli 0.1.3__tar.gz → 0.1.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/.coverage +0 -0
- {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/LOG.md +9 -0
- {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/PKG-INFO +1 -1
- {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/pyproject.toml +1 -1
- {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/src/fauxdata/__init__.py +1 -1
- {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/src/fauxdata/commands/generate.py +16 -1
- {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/src/fauxdata/commands/init.py +26 -13
- {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/src/fauxdata/main.py +47 -10
- fauxdata_cli-0.1.4/tasks/todo.md +38 -0
- {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/uv.lock +1 -1
- {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/.claude/settings.local.json +0 -0
- {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/.gitignore +0 -0
- {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/.python-version +0 -0
- {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/LICENSE +0 -0
- {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/README.md +0 -0
- {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/docs/deployment.md +0 -0
- {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/docs/index.html +0 -0
- {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/docs/share.png +0 -0
- {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/schemas/events.yml +0 -0
- {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/schemas/orders.yml +0 -0
- {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/schemas/people.yml +0 -0
- {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/share.png +0 -0
- {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/src/fauxdata/commands/__init__.py +0 -0
- {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/src/fauxdata/commands/preview.py +0 -0
- {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/src/fauxdata/commands/validate.py +0 -0
- {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/src/fauxdata/generator.py +0 -0
- {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/src/fauxdata/output.py +0 -0
- {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/src/fauxdata/schema.py +0 -0
- {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/src/fauxdata/validator.py +0 -0
- {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/tests/__init__.py +0 -0
- {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/tests/conftest.py +0 -0
- {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/tests/test_cli.py +0 -0
- {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/tests/test_generator.py +0 -0
- {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/tests/test_new_fields.py +0 -0
- {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/tests/test_output.py +0 -0
- {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/tests/test_schema.py +0 -0
- {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/tests/test_validator.py +0 -0
|
Binary file
|
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# Log
|
|
2
2
|
|
|
3
|
+
## 2026-04-06 — agent-friendly CLI
|
|
4
|
+
|
|
5
|
+
- `init`: aggiunto `--description`, `--rows`, `--format`, `--yes`; questionary diventa fallback
|
|
6
|
+
- Tutti i comandi: `epilog` con esempi in `--help`
|
|
7
|
+
- `generate`: aggiunto `--dry-run` (mostra piano senza scrivere)
|
|
8
|
+
- `generate`: output su successo mostra `output_path`, `format`, `rows` come chiave: valore
|
|
9
|
+
- `init`: output su successo aggiunge `schema_path: <file>`
|
|
10
|
+
- Fix venv: ricreato con `uv venv --clear` (cartella rinominata da `real_fake_datasets`)
|
|
11
|
+
|
|
3
12
|
## 2026-03-06 — v0.1.3
|
|
4
13
|
|
|
5
14
|
- Add Python classifiers to pyproject.toml (3.11, 3.12, 3.13, MIT) — fixes pyversions badge
|
|
@@ -26,6 +26,7 @@ def run(
|
|
|
26
26
|
fmt: Optional[str] = None,
|
|
27
27
|
seed: Optional[int] = None,
|
|
28
28
|
validate: bool = False,
|
|
29
|
+
dry_run: bool = False,
|
|
29
30
|
):
|
|
30
31
|
"""Generate a fake dataset from a YAML schema."""
|
|
31
32
|
schema = load_schema(schema_path)
|
|
@@ -37,6 +38,18 @@ def run(
|
|
|
37
38
|
|
|
38
39
|
stdout_mode = output_path == "-"
|
|
39
40
|
|
|
41
|
+
if dry_run:
|
|
42
|
+
rprint(Panel(f"[bold cyan]fauxdata generate --dry-run[/bold cyan] [dim]{schema_path}[/dim]", expand=False))
|
|
43
|
+
rprint("[yellow]Dry run — no files will be written.[/yellow]\n")
|
|
44
|
+
rprint(f" schema: {schema_path}")
|
|
45
|
+
rprint(f" rows: {n}")
|
|
46
|
+
rprint(f" seed: {rng_seed}")
|
|
47
|
+
rprint(f" format: {output_fmt}")
|
|
48
|
+
rprint(f" output_path: {output_path}")
|
|
49
|
+
rprint(f" validate: {validate}")
|
|
50
|
+
rprint(f" columns: {', '.join(c.name for c in schema.columns)}")
|
|
51
|
+
return
|
|
52
|
+
|
|
40
53
|
if not stdout_mode:
|
|
41
54
|
rprint(Panel(f"[bold cyan]fauxdata generate[/bold cyan] [dim]{schema_path}[/dim]", expand=False))
|
|
42
55
|
|
|
@@ -51,7 +64,9 @@ def run(
|
|
|
51
64
|
_print_schema_table(schema, n, rng_seed)
|
|
52
65
|
|
|
53
66
|
saved = export_dataset(df, output_path, output_fmt)
|
|
54
|
-
rprint(f"\
|
|
67
|
+
rprint(f"\noutput_path: {saved}")
|
|
68
|
+
rprint(f"format: {output_fmt}")
|
|
69
|
+
rprint(f"rows: {n}")
|
|
55
70
|
|
|
56
71
|
if validate:
|
|
57
72
|
_run_validation(df, schema)
|
|
@@ -75,8 +75,14 @@ validation:
|
|
|
75
75
|
"""
|
|
76
76
|
|
|
77
77
|
|
|
78
|
-
def run(
|
|
79
|
-
|
|
78
|
+
def run(
|
|
79
|
+
name: str | None = None,
|
|
80
|
+
description: str | None = None,
|
|
81
|
+
rows: str | None = None,
|
|
82
|
+
fmt: str | None = None,
|
|
83
|
+
yes: bool = False,
|
|
84
|
+
):
|
|
85
|
+
"""Create a schema template."""
|
|
80
86
|
rprint(Panel("[bold cyan]fauxdata init[/bold cyan] — schema template creator", expand=False))
|
|
81
87
|
|
|
82
88
|
schema_name = name or questionary.text(
|
|
@@ -87,30 +93,37 @@ def run(name: str | None = None):
|
|
|
87
93
|
if schema_name is None:
|
|
88
94
|
raise typer.Abort()
|
|
89
95
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
96
|
+
desc = description if description is not None else (
|
|
97
|
+
questionary.text(
|
|
98
|
+
"Short description:",
|
|
99
|
+
default=f"{schema_name} dataset",
|
|
100
|
+
).ask() or ""
|
|
101
|
+
)
|
|
94
102
|
|
|
95
|
-
|
|
103
|
+
n_rows = rows if rows is not None else (
|
|
104
|
+
questionary.text("Default number of rows:", default="1000").ask() or "1000"
|
|
105
|
+
)
|
|
96
106
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
107
|
+
output_fmt = fmt if fmt is not None else (
|
|
108
|
+
questionary.select(
|
|
109
|
+
"Default output format:",
|
|
110
|
+
choices=["csv", "parquet", "json", "jsonl"],
|
|
111
|
+
).ask() or "csv"
|
|
112
|
+
)
|
|
101
113
|
|
|
102
114
|
output_file = f"{schema_name}.yml"
|
|
103
115
|
out_path = Path(output_file)
|
|
104
116
|
|
|
105
|
-
if out_path.exists():
|
|
117
|
+
if out_path.exists() and not yes:
|
|
106
118
|
overwrite = questionary.confirm(f"{output_file} already exists. Overwrite?", default=False).ask()
|
|
107
119
|
if not overwrite:
|
|
108
120
|
rprint("[yellow]Aborted.[/yellow]")
|
|
109
121
|
raise typer.Exit()
|
|
110
122
|
|
|
111
|
-
content = TEMPLATE.format(name=schema_name, description=
|
|
123
|
+
content = TEMPLATE.format(name=schema_name, description=desc, rows=n_rows, fmt=output_fmt)
|
|
112
124
|
out_path.write_text(content)
|
|
113
125
|
|
|
114
126
|
rprint(f"[green]Created[/green] [bold]{output_file}[/bold]")
|
|
115
127
|
rprint("[dim]Edit the schema then run:[/dim]")
|
|
116
128
|
rprint(f" [cyan]fauxdata generate {output_file} --validate[/cyan]")
|
|
129
|
+
rprint(f"schema_path: {output_file}")
|
|
@@ -44,30 +44,60 @@ def main(
|
|
|
44
44
|
rprint(ctx.get_help())
|
|
45
45
|
|
|
46
46
|
|
|
47
|
-
@app.command(
|
|
47
|
+
@app.command(
|
|
48
|
+
"init",
|
|
49
|
+
epilog=(
|
|
50
|
+
"Examples:\n\n"
|
|
51
|
+
" fauxdata init --name people\n\n"
|
|
52
|
+
" fauxdata init --name orders --rows 500 --format parquet\n\n"
|
|
53
|
+
" fauxdata init --name events --description 'clickstream events' --rows 10000 --format jsonl --yes\n"
|
|
54
|
+
),
|
|
55
|
+
)
|
|
48
56
|
def init_cmd(
|
|
49
57
|
name: Optional[str] = typer.Option(None, "--name", "-n", help="Schema name"),
|
|
58
|
+
description: Optional[str] = typer.Option(None, "--description", "-d", help="Short description"),
|
|
59
|
+
rows: Optional[str] = typer.Option(None, "--rows", "-r", help="Default number of rows (default: 1000)"),
|
|
60
|
+
fmt: Optional[str] = typer.Option(None, "--format", "-f", help="Output format: csv, parquet, json, jsonl (default: csv)"),
|
|
61
|
+
yes: bool = typer.Option(False, "--yes", "-y", help="Overwrite existing file without confirmation"),
|
|
50
62
|
):
|
|
51
|
-
"""Create a schema template
|
|
63
|
+
"""Create a schema template (interactive if flags are omitted)."""
|
|
52
64
|
from fauxdata.commands.init import run
|
|
53
|
-
run(name=name)
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
@app.command(
|
|
65
|
+
run(name=name, description=description, rows=rows, fmt=fmt, yes=yes)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
@app.command(
|
|
69
|
+
"generate",
|
|
70
|
+
epilog=(
|
|
71
|
+
"Examples:\n\n"
|
|
72
|
+
" fauxdata generate people.yml\n\n"
|
|
73
|
+
" fauxdata generate people.yml --rows 500 --format csv --out out.csv\n\n"
|
|
74
|
+
" fauxdata generate people.yml --seed 42 --validate\n\n"
|
|
75
|
+
" fauxdata generate people.yml --out - --format jsonl | jq .\n\n"
|
|
76
|
+
" fauxdata generate people.yml --dry-run\n"
|
|
77
|
+
),
|
|
78
|
+
)
|
|
57
79
|
def generate_cmd(
|
|
58
80
|
schema: str = typer.Argument(..., help="Path to YAML schema file"),
|
|
59
81
|
rows: Optional[int] = typer.Option(None, "--rows", "-r", help="Number of rows to generate"),
|
|
60
|
-
out: Optional[str] = typer.Option(None, "--out", "-o", help="Output file path"),
|
|
82
|
+
out: Optional[str] = typer.Option(None, "--out", "-o", help="Output file path (use - for stdout)"),
|
|
61
83
|
fmt: Optional[str] = typer.Option(None, "--format", "-f", help="Output format: csv, parquet, json, jsonl"),
|
|
62
84
|
seed: Optional[int] = typer.Option(None, "--seed", "-s", help="Random seed for reproducibility"),
|
|
63
85
|
validate: bool = typer.Option(False, "--validate", "-v", help="Run validation after generating"),
|
|
86
|
+
dry_run: bool = typer.Option(False, "--dry-run", help="Show what would be generated without writing files"),
|
|
64
87
|
):
|
|
65
88
|
"""Generate a fake dataset from a YAML schema."""
|
|
66
89
|
from fauxdata.commands.generate import run
|
|
67
|
-
run(schema_path=schema, rows=rows, out=out, fmt=fmt, seed=seed, validate=validate)
|
|
90
|
+
run(schema_path=schema, rows=rows, out=out, fmt=fmt, seed=seed, validate=validate, dry_run=dry_run)
|
|
68
91
|
|
|
69
92
|
|
|
70
|
-
@app.command(
|
|
93
|
+
@app.command(
|
|
94
|
+
"validate",
|
|
95
|
+
epilog=(
|
|
96
|
+
"Examples:\n\n"
|
|
97
|
+
" fauxdata validate people.csv people.yml\n\n"
|
|
98
|
+
" fauxdata validate out/orders.parquet schemas/orders.yml\n"
|
|
99
|
+
),
|
|
100
|
+
)
|
|
71
101
|
def validate_cmd(
|
|
72
102
|
dataset: str = typer.Argument(..., help="Path to dataset file (csv, parquet, json, jsonl)"),
|
|
73
103
|
schema: str = typer.Argument(..., help="Path to YAML schema file"),
|
|
@@ -77,7 +107,14 @@ def validate_cmd(
|
|
|
77
107
|
run(dataset_path=dataset, schema_path=schema)
|
|
78
108
|
|
|
79
109
|
|
|
80
|
-
@app.command(
|
|
110
|
+
@app.command(
|
|
111
|
+
"preview",
|
|
112
|
+
epilog=(
|
|
113
|
+
"Examples:\n\n"
|
|
114
|
+
" fauxdata preview people.csv\n\n"
|
|
115
|
+
" fauxdata preview people.parquet --rows 20\n"
|
|
116
|
+
),
|
|
117
|
+
)
|
|
81
118
|
def preview_cmd(
|
|
82
119
|
dataset: str = typer.Argument(..., help="Path to dataset file"),
|
|
83
120
|
rows: int = typer.Option(10, "--rows", "-r", help="Number of rows to preview"),
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Agent-friendly CLI improvements
|
|
2
|
+
|
|
3
|
+
## Obiettivo
|
|
4
|
+
Applicare i principi per CLI usabili dagli agenti AI.
|
|
5
|
+
|
|
6
|
+
## Fase 1 — Non-interactive `init`
|
|
7
|
+
|
|
8
|
+
- [ ] Aggiungere `--description`, `--rows`, `--format`, `--yes` come flag a `init_cmd` in `main.py`
|
|
9
|
+
- [ ] Aggiornare `run()` in `commands/init.py` per accettare questi parametri
|
|
10
|
+
- [ ] Rendere i prompt questionary fallback (solo quando il flag è None)
|
|
11
|
+
- [ ] `--yes` salta la conferma di sovrascrittura
|
|
12
|
+
|
|
13
|
+
## Fase 2 — Esempi in `--help`
|
|
14
|
+
|
|
15
|
+
- [ ] Aggiungere `epilog` con esempi a ogni comando in `main.py` (init, generate, validate, preview)
|
|
16
|
+
|
|
17
|
+
## Fase 3 — `--dry-run` per `generate`
|
|
18
|
+
|
|
19
|
+
- [ ] Aggiungere flag `--dry-run` a `generate_cmd` in `main.py`
|
|
20
|
+
- [ ] Implementare dry-run in `commands/generate.py`: mostra cosa farebbe senza scrivere file
|
|
21
|
+
|
|
22
|
+
## Fase 4 — Output strutturato su successo
|
|
23
|
+
|
|
24
|
+
- [ ] `generate`: output su successo mostra chiave=valore (output_path, format, rows)
|
|
25
|
+
- [ ] `init`: output su successo mostra schema_path
|
|
26
|
+
|
|
27
|
+
## Domande aperte
|
|
28
|
+
|
|
29
|
+
- Aggiungere anche `--quiet` / `--json` per output machine-readable?
|
|
30
|
+
- `validate` e `preview` hanno già flag, sufficienti?
|
|
31
|
+
|
|
32
|
+
## Review
|
|
33
|
+
|
|
34
|
+
- Tutte e 4 le fasi completate; 79/79 test passano, coverage 82%
|
|
35
|
+
- `init` ora fully non-interactive con `--name --description --rows --format --yes`
|
|
36
|
+
- `generate` ha `--dry-run` e output strutturato chiave: valore
|
|
37
|
+
- Ogni comando ha esempi nel `--help` via `epilog`
|
|
38
|
+
- Venv ricreato con `--clear` (cartella rinominata da `real_fake_datasets`)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|