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.
Files changed (37) hide show
  1. {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/.coverage +0 -0
  2. {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/LOG.md +9 -0
  3. {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/PKG-INFO +1 -1
  4. {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/pyproject.toml +1 -1
  5. {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/src/fauxdata/__init__.py +1 -1
  6. {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/src/fauxdata/commands/generate.py +16 -1
  7. {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/src/fauxdata/commands/init.py +26 -13
  8. {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/src/fauxdata/main.py +47 -10
  9. fauxdata_cli-0.1.4/tasks/todo.md +38 -0
  10. {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/uv.lock +1 -1
  11. {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/.claude/settings.local.json +0 -0
  12. {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/.gitignore +0 -0
  13. {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/.python-version +0 -0
  14. {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/LICENSE +0 -0
  15. {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/README.md +0 -0
  16. {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/docs/deployment.md +0 -0
  17. {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/docs/index.html +0 -0
  18. {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/docs/share.png +0 -0
  19. {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/schemas/events.yml +0 -0
  20. {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/schemas/orders.yml +0 -0
  21. {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/schemas/people.yml +0 -0
  22. {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/share.png +0 -0
  23. {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/src/fauxdata/commands/__init__.py +0 -0
  24. {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/src/fauxdata/commands/preview.py +0 -0
  25. {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/src/fauxdata/commands/validate.py +0 -0
  26. {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/src/fauxdata/generator.py +0 -0
  27. {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/src/fauxdata/output.py +0 -0
  28. {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/src/fauxdata/schema.py +0 -0
  29. {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/src/fauxdata/validator.py +0 -0
  30. {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/tests/__init__.py +0 -0
  31. {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/tests/conftest.py +0 -0
  32. {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/tests/test_cli.py +0 -0
  33. {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/tests/test_generator.py +0 -0
  34. {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/tests/test_new_fields.py +0 -0
  35. {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/tests/test_output.py +0 -0
  36. {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/tests/test_schema.py +0 -0
  37. {fauxdata_cli-0.1.3 → fauxdata_cli-0.1.4}/tests/test_validator.py +0 -0
@@ -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
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fauxdata-cli
3
- Version: 0.1.3
3
+ Version: 0.1.4
4
4
  Summary: CLI for generating and validating fake datasets
5
5
  Project-URL: Homepage, https://aborruso.github.io/fauxdata/
6
6
  Project-URL: Repository, https://github.com/aborruso/fauxdata
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "fauxdata-cli"
3
- version = "0.1.3"
3
+ version = "0.1.4"
4
4
  description = "CLI for generating and validating fake datasets"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
@@ -1,3 +1,3 @@
1
1
  """fauxdata - CLI for generating and validating fake datasets."""
2
2
 
3
- __version__ = "0.1.3"
3
+ __version__ = "0.1.4"
@@ -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"\n[green]Saved[/green] [bold]{saved}[/bold] ([dim]{output_fmt}, {n} rows[/dim])")
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(name: str | None = None):
79
- """Interactive schema template creator."""
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
- description = questionary.text(
91
- "Short description:",
92
- default=f"{schema_name} dataset",
93
- ).ask() or ""
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
- rows = questionary.text("Default number of rows:", default="1000").ask() or "1000"
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
- fmt = questionary.select(
98
- "Default output format:",
99
- choices=["csv", "parquet", "json", "jsonl"],
100
- ).ask() or "csv"
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=description, rows=rows, fmt=fmt)
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("init")
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 interactively."""
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("generate")
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("validate")
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("preview")
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`)
@@ -250,7 +250,7 @@ wheels = [
250
250
 
251
251
  [[package]]
252
252
  name = "fauxdata-cli"
253
- version = "0.1.3"
253
+ version = "0.1.4"
254
254
  source = { editable = "." }
255
255
  dependencies = [
256
256
  { name = "pointblank" },
File without changes
File without changes
File without changes
File without changes