tha-csv-runner 0.2.0__tar.gz → 0.2.2__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tha-csv-runner
3
- Version: 0.2.0
3
+ Version: 0.2.2
4
4
  Summary: Run a function over every row of a CSV — with progress, header validation, and structured per-row errors.
5
5
  Project-URL: Homepage, https://github.com/tha-guy-nate/tha-csv-runner
6
6
  Project-URL: Issues, https://github.com/tha-guy-nate/tha-csv-runner/issues
@@ -47,7 +47,7 @@ def process(row: dict) -> None:
47
47
 
48
48
  runner = ThaCSV()
49
49
 
50
- runner.read("Step 1 of 1", "data.csv", ["name", "email"], process)
50
+ rows = runner.read("Step 1 of 1", "data.csv", ["name", "email"], process)
51
51
  runner.write("Step 1 of 1", "output.csv")
52
52
  ```
53
53
 
@@ -55,7 +55,7 @@ runner.write("Step 1 of 1", "output.csv")
55
55
 
56
56
  1. Opens the CSV and validates that all `required_headers` are present — raises immediately if any are missing
57
57
  2. Iterates every row with a `tqdm` progress bar labelled with `desc`
58
- 3. Calls your `processor(row)` function — if it raises, that row is marked as an error and processing continues
58
+ 3. Calls your `validator(row)` function — if it raises, that row is marked as an error and processing continues
59
59
  4. Appends three columns to every row: `row number`, `row status`, and `message`
60
60
  - On success: `row status` and `message` are blank
61
61
  - On error: `row status = "error"`, `message = str(exception)`
@@ -76,15 +76,14 @@ runner.read(
76
76
  "Step 2 of 10", # progress bar label — pass None to use the filename
77
77
  "data.csv", # path to input CSV
78
78
  ["a", "b"], # columns that must exist — raises ConfigError if missing
79
- processor=my_func, # optional: callable(row: dict) -> None
80
- sample=100, # optional: process only the first N rows
79
+ validator=my_func, # optional: callable(row: dict) -> None
81
80
  enrich=True, # optional: set False to skip row number/status/message columns
82
81
  )
83
82
  ```
84
83
 
85
- Reads and processes all rows. Results are stored in `runner.rows` as a list of dicts.
84
+ Reads and processes all rows. Returns the rows as a `list[dict]` (same object as `runner.rows`).
86
85
 
87
- When `enrich=False`, processor exceptions are re-raised instead of captured.
86
+ When `enrich=False`, validator exceptions are re-raised instead of captured.
88
87
 
89
88
  ### `runner.write()`
90
89
 
@@ -22,7 +22,7 @@ def process(row: dict) -> None:
22
22
 
23
23
  runner = ThaCSV()
24
24
 
25
- runner.read("Step 1 of 1", "data.csv", ["name", "email"], process)
25
+ rows = runner.read("Step 1 of 1", "data.csv", ["name", "email"], process)
26
26
  runner.write("Step 1 of 1", "output.csv")
27
27
  ```
28
28
 
@@ -30,7 +30,7 @@ runner.write("Step 1 of 1", "output.csv")
30
30
 
31
31
  1. Opens the CSV and validates that all `required_headers` are present — raises immediately if any are missing
32
32
  2. Iterates every row with a `tqdm` progress bar labelled with `desc`
33
- 3. Calls your `processor(row)` function — if it raises, that row is marked as an error and processing continues
33
+ 3. Calls your `validator(row)` function — if it raises, that row is marked as an error and processing continues
34
34
  4. Appends three columns to every row: `row number`, `row status`, and `message`
35
35
  - On success: `row status` and `message` are blank
36
36
  - On error: `row status = "error"`, `message = str(exception)`
@@ -51,15 +51,14 @@ runner.read(
51
51
  "Step 2 of 10", # progress bar label — pass None to use the filename
52
52
  "data.csv", # path to input CSV
53
53
  ["a", "b"], # columns that must exist — raises ConfigError if missing
54
- processor=my_func, # optional: callable(row: dict) -> None
55
- sample=100, # optional: process only the first N rows
54
+ validator=my_func, # optional: callable(row: dict) -> None
56
55
  enrich=True, # optional: set False to skip row number/status/message columns
57
56
  )
58
57
  ```
59
58
 
60
- Reads and processes all rows. Results are stored in `runner.rows` as a list of dicts.
59
+ Reads and processes all rows. Returns the rows as a `list[dict]` (same object as `runner.rows`).
61
60
 
62
- When `enrich=False`, processor exceptions are re-raised instead of captured.
61
+ When `enrich=False`, validator exceptions are re-raised instead of captured.
63
62
 
64
63
  ### `runner.write()`
65
64
 
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "tha-csv-runner"
7
- version = "0.2.0"
7
+ version = "0.2.2"
8
8
  description = "Run a function over every row of a CSV — with progress, header validation, and structured per-row errors."
9
9
  readme = "README.md"
10
10
  license = { text = "MIT" }
@@ -3,5 +3,5 @@
3
3
  from .errors import ConfigError
4
4
  from .runner import ThaCSV
5
5
 
6
- __version__ = "0.2.0"
6
+ __version__ = "0.2.2"
7
7
  __all__ = ["ConfigError", "ThaCSV"]
@@ -27,10 +27,9 @@ class ThaCSV:
27
27
  desc: str | None,
28
28
  input_path: str | Path,
29
29
  required_headers: list[str],
30
- processor: Callable[[dict], None] | None = None,
31
- sample: int | None = None,
30
+ validator: Callable[[dict], None] | None = None,
32
31
  enrich: bool = True,
33
- ) -> None:
32
+ ) -> list[dict]:
34
33
  self._input_path = Path(input_path)
35
34
 
36
35
  with open(self._input_path, newline="", encoding="utf-8") as f:
@@ -42,9 +41,6 @@ class ThaCSV:
42
41
  raise ConfigError(f"Missing required headers: {missing}")
43
42
  raw_rows = list(reader)
44
43
 
45
- if sample is not None:
46
- raw_rows = raw_rows[:sample]
47
-
48
44
  self.rows = []
49
45
  self._read = True
50
46
 
@@ -55,8 +51,8 @@ class ThaCSV:
55
51
  else:
56
52
  enriched = dict(row)
57
53
  try:
58
- if processor is not None:
59
- processor(enriched)
54
+ if validator is not None:
55
+ validator(enriched)
60
56
  except Exception as exc:
61
57
  if enrich:
62
58
  enriched["row status"] = "error"
@@ -65,6 +61,8 @@ class ThaCSV:
65
61
  raise
66
62
  self.rows.append(enriched)
67
63
 
64
+ return self.rows
65
+
68
66
  def write(
69
67
  self,
70
68
  desc: str | None,
@@ -23,6 +23,13 @@ def test_happy_path(simple_csv: Path) -> None:
23
23
  assert all(r["row status"] == "" for r in runner.rows)
24
24
 
25
25
 
26
+ def test_read_returns_rows(simple_csv: Path) -> None:
27
+ runner = ThaCSV()
28
+ result = runner.read(None, simple_csv, ["name"])
29
+ assert result is runner.rows
30
+ assert len(result) == 3
31
+
32
+
26
33
  def test_row_number_injected(simple_csv: Path) -> None:
27
34
  runner = ThaCSV()
28
35
  runner.read(None, simple_csv, ["name"])
@@ -58,11 +65,6 @@ def test_missing_required_header_raises(simple_csv: Path) -> None:
58
65
  runner.read(None, simple_csv, ["id", "phone"])
59
66
 
60
67
 
61
- def test_sample_limits_rows(simple_csv: Path) -> None:
62
- runner = ThaCSV()
63
- runner.read(None, simple_csv, ["name"], sample=2)
64
- assert len(runner.rows) == 2
65
-
66
68
 
67
69
  def test_original_columns_preserved(simple_csv: Path) -> None:
68
70
  runner = ThaCSV()
@@ -217,7 +219,7 @@ def test_enrich_false_preserves_original_columns(simple_csv: Path) -> None:
217
219
  assert runner.rows[0]["email"] == "alice@example.com"
218
220
 
219
221
 
220
- def test_enrich_false_processor_error_still_raises(simple_csv: Path) -> None:
222
+ def test_enrich_false_validator_error_still_raises(simple_csv: Path) -> None:
221
223
  runner = ThaCSV()
222
224
  with pytest.raises(ValueError, match="Bob is not allowed"):
223
225
  runner.read(None, simple_csv, ["name"], fail_on_bob, enrich=False)
@@ -308,7 +308,7 @@ wheels = [
308
308
 
309
309
  [[package]]
310
310
  name = "tha-csv-runner"
311
- version = "0.2.0"
311
+ version = "0.2.2"
312
312
  source = { editable = "." }
313
313
  dependencies = [
314
314
  { name = "tqdm" },
File without changes