dataeval-flow 0.2.1__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.
Files changed (112) hide show
  1. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/PKG-INFO +106 -26
  2. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/README.md +103 -23
  3. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/pyproject.toml +2 -4
  4. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/__main__.py +101 -1
  5. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/_version.py +2 -2
  6. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/runner.py +100 -36
  7. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/workflow/__init__.py +35 -3
  8. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/workflow/orchestrator.py +55 -16
  9. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/.gitignore +0 -0
  10. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/LICENSE +0 -0
  11. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/__init__.py +0 -0
  12. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/_app/__init__.py +0 -0
  13. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/_app/_model/__init__.py +0 -0
  14. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/_app/_model/_coerce.py +0 -0
  15. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/_app/_model/_discover.py +0 -0
  16. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/_app/_model/_execution.py +0 -0
  17. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/_app/_model/_introspect.py +0 -0
  18. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/_app/_model/_item.py +0 -0
  19. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/_app/_model/_registry.py +0 -0
  20. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/_app/_model/_state.py +0 -0
  21. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/_app/_model/_undo.py +0 -0
  22. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/_app/_panes/__init__.py +0 -0
  23. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/_app/_panes/_config_pane.py +0 -0
  24. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/_app/_panes/_result_pane.py +0 -0
  25. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/_app/_panes/_task_pane.py +0 -0
  26. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/_app/_panes/_widgets.py +0 -0
  27. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/_app/_screens/__init__.py +0 -0
  28. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/_app/_screens/_base.py +0 -0
  29. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/_app/_screens/_detail.py +0 -0
  30. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/_app/_screens/_model.py +0 -0
  31. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/_app/_screens/_params.py +0 -0
  32. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/_app/_screens/_pathpicker.py +0 -0
  33. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/_app/_screens/_section.py +0 -0
  34. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/_app/_screens/_settings.py +0 -0
  35. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/_app/_viewmodel/__init__.py +0 -0
  36. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/_app/_viewmodel/_builder_vm.py +0 -0
  37. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/_app/_viewmodel/_model_vm.py +0 -0
  38. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/_app/_viewmodel/_rendering.py +0 -0
  39. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/_app/_viewmodel/_result_vm.py +0 -0
  40. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/_app/_viewmodel/_section_vm.py +0 -0
  41. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/_app/app.py +0 -0
  42. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/_app/cli.py +0 -0
  43. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/_encoding_cli.py +0 -0
  44. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/_logging.py +0 -0
  45. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/binning.py +0 -0
  46. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/cache.py +0 -0
  47. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/config/__init__.py +0 -0
  48. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/config/_loader.py +0 -0
  49. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/config/_merge.py +0 -0
  50. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/config/_models.py +0 -0
  51. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/config/_paths.py +0 -0
  52. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/config/schemas/__init__.py +0 -0
  53. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/config/schemas/_dataset.py +0 -0
  54. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/config/schemas/_extractor.py +0 -0
  55. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/config/schemas/_metadata.py +0 -0
  56. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/config/schemas/_preprocessor.py +0 -0
  57. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/config/schemas/_task.py +0 -0
  58. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/config/schemas/_view.py +0 -0
  59. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/config/schemas/_workflow.py +0 -0
  60. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/dataset.py +0 -0
  61. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/embeddings.py +0 -0
  62. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/metadata.py +0 -0
  63. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/policy.py +0 -0
  64. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/preprocessing.py +0 -0
  65. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/preprocessors.py +0 -0
  66. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/py.typed +0 -0
  67. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/view.py +0 -0
  68. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/workflow/_text_report.py +0 -0
  69. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/workflow/base.py +0 -0
  70. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/workflows/__init__.py +0 -0
  71. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/workflows/_common.py +0 -0
  72. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/workflows/_ontology.py +0 -0
  73. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/workflows/analysis/__init__.py +0 -0
  74. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/workflows/analysis/outputs.py +0 -0
  75. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/workflows/analysis/params.py +0 -0
  76. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/workflows/analysis/workflow.py +0 -0
  77. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/workflows/cleaning/__init__.py +0 -0
  78. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/workflows/cleaning/_internal.py +0 -0
  79. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/workflows/cleaning/outputs.py +0 -0
  80. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/workflows/cleaning/params.py +0 -0
  81. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/workflows/cleaning/report.py +0 -0
  82. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/workflows/cleaning/workflow.py +0 -0
  83. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/workflows/coverage/__init__.py +0 -0
  84. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/workflows/coverage/ontology.py +0 -0
  85. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/workflows/coverage/outputs.py +0 -0
  86. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/workflows/coverage/params.py +0 -0
  87. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/workflows/coverage/report.py +0 -0
  88. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/workflows/coverage/workflow.py +0 -0
  89. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/workflows/drift/__init__.py +0 -0
  90. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/workflows/drift/outputs.py +0 -0
  91. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/workflows/drift/params.py +0 -0
  92. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/workflows/drift/report.py +0 -0
  93. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/workflows/drift/workflow.py +0 -0
  94. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/workflows/ood/__init__.py +0 -0
  95. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/workflows/ood/outputs.py +0 -0
  96. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/workflows/ood/params.py +0 -0
  97. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/workflows/ood/report.py +0 -0
  98. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/workflows/ood/workflow.py +0 -0
  99. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/workflows/parameter_sweep/__init__.py +0 -0
  100. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/workflows/parameter_sweep/outputs.py +0 -0
  101. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/workflows/parameter_sweep/params.py +0 -0
  102. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/workflows/parameter_sweep/workflow.py +0 -0
  103. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/workflows/prioritization/__init__.py +0 -0
  104. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/workflows/prioritization/outputs.py +0 -0
  105. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/workflows/prioritization/params.py +0 -0
  106. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/workflows/prioritization/report.py +0 -0
  107. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/workflows/prioritization/workflow.py +0 -0
  108. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/workflows/splitting/__init__.py +0 -0
  109. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/workflows/splitting/outputs.py +0 -0
  110. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/workflows/splitting/params.py +0 -0
  111. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/workflows/splitting/report.py +0 -0
  112. {dataeval_flow-0.2.1 → dataeval_flow-0.2.2}/src/dataeval_flow/workflows/splitting/workflow.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: dataeval-flow
3
- Version: 0.2.1
3
+ Version: 0.2.2
4
4
  Summary: DataEval Workflows container for data evaluation
5
5
  Project-URL: Homepage, https://github.com/aria-ml/dataeval-flow
6
6
  Project-URL: Documentation, https://dataeval-flow.readthedocs.io/
@@ -19,7 +19,7 @@ Classifier: Topic :: Scientific/Engineering
19
19
  Classifier: Typing :: Typed
20
20
  Requires-Python: <3.15,>=3.10
21
21
  Requires-Dist: click>=8.0
22
- Requires-Dist: dataeval==1.1.0-rc6
22
+ Requires-Dist: dataeval>=1.1.0
23
23
  Requires-Dist: datamaite[ic,od]==0.4.1
24
24
  Requires-Dist: numpy>=1.24.2
25
25
  Requires-Dist: pydantic>=2.0
@@ -49,7 +49,7 @@ Requires-Dist: onnx>=1.15; extra == 'onnx-cu130'
49
49
  Requires-Dist: onnxruntime-gpu>=1.27; (python_version >= '3.11' and extra != 'onnx-cu126') and extra == 'onnx-cu130'
50
50
  Requires-Dist: onnxruntime>=1.20; (python_version == '3.10' and extra != 'onnx-cu126') and extra == 'onnx-cu130'
51
51
  Provides-Extra: ontology
52
- Requires-Dist: dataeval[ontology]==1.1.0-rc6; extra == 'ontology'
52
+ Requires-Dist: dataeval[ontology]==1.1.0; extra == 'ontology'
53
53
  Provides-Extra: opencv
54
54
  Requires-Dist: opencv-python-headless>=4.8.0; extra == 'opencv'
55
55
  Provides-Extra: opencv-fips
@@ -192,7 +192,7 @@ docker pull harbor.jatic.net/aria/dataeval:cu126 # cpu / cu126 / cu130
192
192
  **Pinned release channel** — immutable, version-tagged images cut from `v*` git tags. Use these for reproducible workloads.
193
193
 
194
194
  ```bash
195
- docker pull harbor.jatic.net/aria/dataeval:0.1.0-cu126
195
+ docker pull harbor.jatic.net/aria/dataeval:0.2.1-cu126
196
196
  ```
197
197
 
198
198
  **Verifying the signature** — every published image is signed with
@@ -215,17 +215,23 @@ commands above with the fully-qualified `harbor.jatic.net/aria/dataeval:cu126`
215
215
 
216
216
  ## Requirements
217
217
 
218
- | Requirement | Version |
219
- | ------------- | --------------------- |
220
- | Docker | >= 20.10 |
221
- | NVIDIA GPU | Any (for GPU mode) |
222
- | NVIDIA Driver | >= 520 (for GPU mode) |
223
- | CUDA | 11.8.0 (for GPU mode) |
218
+ | Requirement | Version |
219
+ | ------------- | -------------------------------------------------------------- |
220
+ | Docker | >= 20.10 |
221
+ | NVIDIA GPU | Any (for GPU mode) |
222
+ | NVIDIA Driver | >= 525 for the `cu126` image; >= 580 for `cu130` (GPU mode) |
223
+ | CUDA | 12.6 (`cu126`) or 13.0 (`cu130`) bundled in the image |
224
+
225
+ The CUDA runtime libraries ship inside the image via PyTorch and `onnxruntime-gpu`, so
226
+ the host needs only the NVIDIA driver and the NVIDIA Container Toolkit — no host CUDA
227
+ install. The driver floors above are the CUDA major versions' minimums: any driver from
228
+ the 525 series up runs a CUDA 12.x image under minor-version compatibility, and CUDA 13.0
229
+ requires a 580-series or newer driver.
224
230
 
225
231
  ### Verify GPU Access
226
232
 
227
233
  ```bash
228
- docker run --rm --gpus all nvidia/cuda:11.8.0-base-ubuntu22.04 nvidia-smi
234
+ docker run --rm --gpus all nvidia/cuda:12.6.3-base-ubuntu24.04 nvidia-smi
229
235
  ```
230
236
 
231
237
  ## Volume Mounts
@@ -289,7 +295,10 @@ precedence over them (see [Input Precedence](#input-precedence) below).
289
295
 
290
296
  No secret mounts or credentials are required — DataEval Flow uses no API keys,
291
297
  tokens, or passwords. (`DATAEVAL_FLOW_VERSION` and `DATAEVAL_NOX_UV_EXTRAS_OVERRIDE`
292
- are build-time only and are not read at run time.)
298
+ are build-time only and are not read at run time. `UV_EXTRAS_OVERRIDE` and
299
+ `CONTAINER_MODE` are baked into the image by the build and read at run time by the
300
+ entrypoint, purely to label the help text and decide whether to run the GPU check —
301
+ neither is meant to be set by the caller.)
293
302
 
294
303
  ## Input Precedence
295
304
 
@@ -344,12 +353,20 @@ Dataset and model paths in config files are resolved relative to the data root (
344
353
 
345
354
  ## Dataset Formats
346
355
 
347
- Currently supported dataset structures:
356
+ A `datasets` entry selects its loader with `format`:
357
+
358
+ | `format` | Structure | Split selection |
359
+ | -------------- | ------------------------------------------------------------- | ---------------------------------- |
360
+ | `huggingface` | HuggingFace arrow dataset or dataset dict | `split:` (omit for a single split) |
361
+ | `image_folder` | Directory of images, optionally one subdirectory per class | n/a |
362
+ | `coco` | COCO images plus a JSON annotation file | `annotations_file:` + `images_dir:` |
363
+ | `yolo` | Ultralytics root — `data.yaml` plus image/label trees | `split:` (omit to load every split) |
348
364
 
349
- | Format | Structure | Example |
350
- | --------------- | -------------------------------------------------- | --------------- |
351
- | **Dataset** | Single split, used directly | `cifar10_test/` |
352
- | **DatasetDict** | Multiple splits (dict), configured via config YAML | `cifar10_full/` |
365
+ Both single-split datasets and multi-split dataset dicts are supported. In-memory MAITE
366
+ and TorchVision datasets are also accepted programmatically via `DatasetProtocolConfig`,
367
+ which is not serializable and so cannot be named in a config file. See the
368
+ [Run workflows in containers](https://dataeval-flow.readthedocs.io/en/latest/how_to/containerized_workflows.html)
369
+ guide for the full field list of each format.
353
370
 
354
371
  ## CPU Fallback
355
372
 
@@ -366,13 +383,53 @@ docker run \
366
383
 
367
384
  ## CLI Modes
368
385
 
369
- DataEval Flow has three modes:
386
+ DataEval Flow has four modes:
387
+
388
+ | Command | Purpose |
389
+ | ------------------------- | ------------------------------------------------------------------- |
390
+ | `dataeval-flow [opts]` | Headless execution — for automation and CI/CD pipelines |
391
+ | `dataeval-flow app` | Interactive TUI dashboard — configure, execute, and view results |
392
+ | `dataeval-flow config` | Simple CLI config builder — create/edit configs without the TUI |
393
+ | `dataeval-flow encoding` | Write the metadata encoding descriptor a result was computed under |
394
+ | `dataeval-flow workflows` | List the available workflow types, or print one's parameter schema |
395
+
396
+ `dataeval-flow --version` reports the installed build — useful for pinning down
397
+ which image produced a result.
398
+
399
+ ### Headless execution
400
+
401
+ ```bash
402
+ # Every enabled task in the config
403
+ dataeval-flow --config params.yaml --data . --output ./results
404
+
405
+ # One task by name, whether or not the config marks it enabled
406
+ dataeval-flow --config params.yaml --task clean_my_data
407
+
408
+ # Several, in the order given
409
+ dataeval-flow --config params.yaml --task clean_my_data --task analyze_my_data
410
+
411
+ # Stop the pipeline when a finding breaches its health threshold
412
+ dataeval-flow --config params.yaml --output ./results --fail-on-warning
413
+ ```
414
+
415
+ **Exit codes:** `0` when every task succeeded, `1` when any task failed. Health
416
+ warnings are reported but are not fatal unless you pass `--fail-on-warning`, which
417
+ turns them into an exit code of `1` as well. Every run's `result.json` carries a
418
+ `health` block per task (`status`, `warnings`, `findings`) so a pipeline can gate
419
+ on findings without parsing the text report.
420
+
421
+ ### Workflow Discovery (`workflows`)
370
422
 
371
- | Command | Purpose |
372
- | ---------------------- | ---------------------------------------------------------------- |
373
- | `dataeval-flow [opts]` | Headless execution — for automation and CI/CD pipelines |
374
- | `dataeval-flow app` | Interactive TUI dashboard — configure, execute, and view results |
375
- | `dataeval-flow config` | Simple CLI config builder — create/edit configs without the TUI |
423
+ For images that ship without the TUI extra:
424
+
425
+ ```bash
426
+ # What can this build run?
427
+ dataeval-flow workflows
428
+ dataeval-flow workflows --json
429
+
430
+ # What does a given workflow type accept?
431
+ dataeval-flow workflows data-cleaning
432
+ ```
376
433
 
377
434
  ### Interactive TUI (`app`)
378
435
 
@@ -408,12 +465,35 @@ python -m dataeval_flow config --config /path/to/params.yaml
408
465
 
409
466
  Configs can be saved as YAML or JSON.
410
467
 
468
+ ### Encoding Descriptor (`encoding`)
469
+
470
+ Extract the metadata encoding descriptor from an archived `result.json` and write it
471
+ where it can be reviewed and committed, so a later dataset is cut the same way:
472
+
473
+ ```bash
474
+ python -m dataeval_flow encoding output/results/result.json -o policy/factor_bins.json
475
+ python -m dataeval_flow encoding output/results/result.json --task clean_my_data
476
+ ```
477
+
478
+ Reference the committed descriptor from a metadata policy's `encoding` field. A run with
479
+ `-o` already writes `results/encoding.json` beside its results; this command recovers one
480
+ from a result archived earlier. See
481
+ [Configure metadata binning](https://dataeval-flow.readthedocs.io/en/latest/how_to/configure_metadata_binning.html).
482
+
411
483
  ## Dependencies
412
484
 
485
+ Declared runtime dependencies:
486
+
413
487
  - `dataeval` - Core evaluation library
414
- - `datamaite` - MAITE protocol dataset loaders
415
- - `maite` - MAITE protocol library
488
+ - `datamaite` - MAITE protocol dataset loaders (which brings in `maite` itself)
416
489
  - `pydantic` - Structural typing and schema validation
490
+ - `click` - Interactive prompts for the simple CLI config builder
491
+ - `pyyaml` - YAML config parsing
492
+ - `numpy` - Array handling
493
+
494
+ PyTorch arrives transitively through `dataeval`. Optional extras (`onnx`, `opencv`,
495
+ `app`, `ontology`, and the CUDA variants) are listed under
496
+ [Running Without Container](#running-without-container).
417
497
 
418
498
  ## Troubleshooting
419
499
 
@@ -469,7 +549,7 @@ pip install dataeval-flow
469
549
  `torchvision` is not installed by default — it is imported lazily and is only needed
470
550
  for preprocessing pipelines, the torchvision dataset adapter, and the TUI's transform
471
551
  discovery. Install it together with `torch` in step 1 so both come from the same index.
472
- Feature extras (`onnx`, `onnx-cu126`, `onnx-cu130`, `opencv`, `app`, `ontology`) work normally under
552
+ Feature extras (`onnx`, `onnx-cu126`, `onnx-cu130`, `opencv`, `opencv-fips`, `app`, `ontology`) work normally under
473
553
  pip and are independent of the PyTorch variant:
474
554
 
475
555
  ```bash
@@ -134,7 +134,7 @@ docker pull harbor.jatic.net/aria/dataeval:cu126 # cpu / cu126 / cu130
134
134
  **Pinned release channel** — immutable, version-tagged images cut from `v*` git tags. Use these for reproducible workloads.
135
135
 
136
136
  ```bash
137
- docker pull harbor.jatic.net/aria/dataeval:0.1.0-cu126
137
+ docker pull harbor.jatic.net/aria/dataeval:0.2.1-cu126
138
138
  ```
139
139
 
140
140
  **Verifying the signature** — every published image is signed with
@@ -157,17 +157,23 @@ commands above with the fully-qualified `harbor.jatic.net/aria/dataeval:cu126`
157
157
 
158
158
  ## Requirements
159
159
 
160
- | Requirement | Version |
161
- | ------------- | --------------------- |
162
- | Docker | >= 20.10 |
163
- | NVIDIA GPU | Any (for GPU mode) |
164
- | NVIDIA Driver | >= 520 (for GPU mode) |
165
- | CUDA | 11.8.0 (for GPU mode) |
160
+ | Requirement | Version |
161
+ | ------------- | -------------------------------------------------------------- |
162
+ | Docker | >= 20.10 |
163
+ | NVIDIA GPU | Any (for GPU mode) |
164
+ | NVIDIA Driver | >= 525 for the `cu126` image; >= 580 for `cu130` (GPU mode) |
165
+ | CUDA | 12.6 (`cu126`) or 13.0 (`cu130`) bundled in the image |
166
+
167
+ The CUDA runtime libraries ship inside the image via PyTorch and `onnxruntime-gpu`, so
168
+ the host needs only the NVIDIA driver and the NVIDIA Container Toolkit — no host CUDA
169
+ install. The driver floors above are the CUDA major versions' minimums: any driver from
170
+ the 525 series up runs a CUDA 12.x image under minor-version compatibility, and CUDA 13.0
171
+ requires a 580-series or newer driver.
166
172
 
167
173
  ### Verify GPU Access
168
174
 
169
175
  ```bash
170
- docker run --rm --gpus all nvidia/cuda:11.8.0-base-ubuntu22.04 nvidia-smi
176
+ docker run --rm --gpus all nvidia/cuda:12.6.3-base-ubuntu24.04 nvidia-smi
171
177
  ```
172
178
 
173
179
  ## Volume Mounts
@@ -231,7 +237,10 @@ precedence over them (see [Input Precedence](#input-precedence) below).
231
237
 
232
238
  No secret mounts or credentials are required — DataEval Flow uses no API keys,
233
239
  tokens, or passwords. (`DATAEVAL_FLOW_VERSION` and `DATAEVAL_NOX_UV_EXTRAS_OVERRIDE`
234
- are build-time only and are not read at run time.)
240
+ are build-time only and are not read at run time. `UV_EXTRAS_OVERRIDE` and
241
+ `CONTAINER_MODE` are baked into the image by the build and read at run time by the
242
+ entrypoint, purely to label the help text and decide whether to run the GPU check —
243
+ neither is meant to be set by the caller.)
235
244
 
236
245
  ## Input Precedence
237
246
 
@@ -286,12 +295,20 @@ Dataset and model paths in config files are resolved relative to the data root (
286
295
 
287
296
  ## Dataset Formats
288
297
 
289
- Currently supported dataset structures:
298
+ A `datasets` entry selects its loader with `format`:
299
+
300
+ | `format` | Structure | Split selection |
301
+ | -------------- | ------------------------------------------------------------- | ---------------------------------- |
302
+ | `huggingface` | HuggingFace arrow dataset or dataset dict | `split:` (omit for a single split) |
303
+ | `image_folder` | Directory of images, optionally one subdirectory per class | n/a |
304
+ | `coco` | COCO images plus a JSON annotation file | `annotations_file:` + `images_dir:` |
305
+ | `yolo` | Ultralytics root — `data.yaml` plus image/label trees | `split:` (omit to load every split) |
290
306
 
291
- | Format | Structure | Example |
292
- | --------------- | -------------------------------------------------- | --------------- |
293
- | **Dataset** | Single split, used directly | `cifar10_test/` |
294
- | **DatasetDict** | Multiple splits (dict), configured via config YAML | `cifar10_full/` |
307
+ Both single-split datasets and multi-split dataset dicts are supported. In-memory MAITE
308
+ and TorchVision datasets are also accepted programmatically via `DatasetProtocolConfig`,
309
+ which is not serializable and so cannot be named in a config file. See the
310
+ [Run workflows in containers](https://dataeval-flow.readthedocs.io/en/latest/how_to/containerized_workflows.html)
311
+ guide for the full field list of each format.
295
312
 
296
313
  ## CPU Fallback
297
314
 
@@ -308,13 +325,53 @@ docker run \
308
325
 
309
326
  ## CLI Modes
310
327
 
311
- DataEval Flow has three modes:
328
+ DataEval Flow has four modes:
329
+
330
+ | Command | Purpose |
331
+ | ------------------------- | ------------------------------------------------------------------- |
332
+ | `dataeval-flow [opts]` | Headless execution — for automation and CI/CD pipelines |
333
+ | `dataeval-flow app` | Interactive TUI dashboard — configure, execute, and view results |
334
+ | `dataeval-flow config` | Simple CLI config builder — create/edit configs without the TUI |
335
+ | `dataeval-flow encoding` | Write the metadata encoding descriptor a result was computed under |
336
+ | `dataeval-flow workflows` | List the available workflow types, or print one's parameter schema |
337
+
338
+ `dataeval-flow --version` reports the installed build — useful for pinning down
339
+ which image produced a result.
340
+
341
+ ### Headless execution
342
+
343
+ ```bash
344
+ # Every enabled task in the config
345
+ dataeval-flow --config params.yaml --data . --output ./results
346
+
347
+ # One task by name, whether or not the config marks it enabled
348
+ dataeval-flow --config params.yaml --task clean_my_data
349
+
350
+ # Several, in the order given
351
+ dataeval-flow --config params.yaml --task clean_my_data --task analyze_my_data
352
+
353
+ # Stop the pipeline when a finding breaches its health threshold
354
+ dataeval-flow --config params.yaml --output ./results --fail-on-warning
355
+ ```
356
+
357
+ **Exit codes:** `0` when every task succeeded, `1` when any task failed. Health
358
+ warnings are reported but are not fatal unless you pass `--fail-on-warning`, which
359
+ turns them into an exit code of `1` as well. Every run's `result.json` carries a
360
+ `health` block per task (`status`, `warnings`, `findings`) so a pipeline can gate
361
+ on findings without parsing the text report.
362
+
363
+ ### Workflow Discovery (`workflows`)
312
364
 
313
- | Command | Purpose |
314
- | ---------------------- | ---------------------------------------------------------------- |
315
- | `dataeval-flow [opts]` | Headless execution — for automation and CI/CD pipelines |
316
- | `dataeval-flow app` | Interactive TUI dashboard — configure, execute, and view results |
317
- | `dataeval-flow config` | Simple CLI config builder — create/edit configs without the TUI |
365
+ For images that ship without the TUI extra:
366
+
367
+ ```bash
368
+ # What can this build run?
369
+ dataeval-flow workflows
370
+ dataeval-flow workflows --json
371
+
372
+ # What does a given workflow type accept?
373
+ dataeval-flow workflows data-cleaning
374
+ ```
318
375
 
319
376
  ### Interactive TUI (`app`)
320
377
 
@@ -350,12 +407,35 @@ python -m dataeval_flow config --config /path/to/params.yaml
350
407
 
351
408
  Configs can be saved as YAML or JSON.
352
409
 
410
+ ### Encoding Descriptor (`encoding`)
411
+
412
+ Extract the metadata encoding descriptor from an archived `result.json` and write it
413
+ where it can be reviewed and committed, so a later dataset is cut the same way:
414
+
415
+ ```bash
416
+ python -m dataeval_flow encoding output/results/result.json -o policy/factor_bins.json
417
+ python -m dataeval_flow encoding output/results/result.json --task clean_my_data
418
+ ```
419
+
420
+ Reference the committed descriptor from a metadata policy's `encoding` field. A run with
421
+ `-o` already writes `results/encoding.json` beside its results; this command recovers one
422
+ from a result archived earlier. See
423
+ [Configure metadata binning](https://dataeval-flow.readthedocs.io/en/latest/how_to/configure_metadata_binning.html).
424
+
353
425
  ## Dependencies
354
426
 
427
+ Declared runtime dependencies:
428
+
355
429
  - `dataeval` - Core evaluation library
356
- - `datamaite` - MAITE protocol dataset loaders
357
- - `maite` - MAITE protocol library
430
+ - `datamaite` - MAITE protocol dataset loaders (which brings in `maite` itself)
358
431
  - `pydantic` - Structural typing and schema validation
432
+ - `click` - Interactive prompts for the simple CLI config builder
433
+ - `pyyaml` - YAML config parsing
434
+ - `numpy` - Array handling
435
+
436
+ PyTorch arrives transitively through `dataeval`. Optional extras (`onnx`, `opencv`,
437
+ `app`, `ontology`, and the CUDA variants) are listed under
438
+ [Running Without Container](#running-without-container).
359
439
 
360
440
  ## Troubleshooting
361
441
 
@@ -411,7 +491,7 @@ pip install dataeval-flow
411
491
  `torchvision` is not installed by default — it is imported lazily and is only needed
412
492
  for preprocessing pipelines, the torchvision dataset adapter, and the TUI's transform
413
493
  discovery. Install it together with `torch` in step 1 so both come from the same index.
414
- Feature extras (`onnx`, `onnx-cu126`, `onnx-cu130`, `opencv`, `app`, `ontology`) work normally under
494
+ Feature extras (`onnx`, `onnx-cu126`, `onnx-cu130`, `opencv`, `opencv-fips`, `app`, `ontology`) work normally under
415
495
  pip and are independent of the PyTorch variant:
416
496
 
417
497
  ```bash
@@ -19,7 +19,7 @@ classifiers = [
19
19
  ]
20
20
  dependencies = [
21
21
  "click>=8.0",
22
- "dataeval==1.1.0-rc6",
22
+ "dataeval>=1.1.0",
23
23
  "datamaite[ic,od]==0.4.1",
24
24
  "numpy>=1.24.2",
25
25
  "pydantic>=2.0",
@@ -54,7 +54,7 @@ onnx-cu130 = [
54
54
  opencv = ["opencv-python-headless>=4.8.0"]
55
55
  opencv-fips = ["opencv-python-headless>=4.8.0,<4.13.0"] # OpenCV 4.13 and higher are not FIPS compliant
56
56
  app = ["textual>=3.0"]
57
- ontology = ["dataeval[ontology]==1.1.0-rc6"]
57
+ ontology = ["dataeval[ontology]==1.1.0"]
58
58
 
59
59
  [project.urls]
60
60
  Homepage = "https://github.com/aria-ml/dataeval-flow"
@@ -216,8 +216,6 @@ torch = { version = ">=2.2.0", source = "pytorch-cpu", optional = true }
216
216
  torchvision = { version = ">=0.17.0", source = "pytorch-cpu", optional = true }
217
217
 
218
218
  [tool.pyproject2conda.dependencies]
219
- # Conda follows PEP versioning which deviates from PyPI semver
220
- dataeval = { skip = true, packages = "dataeval==1.1.0rc6" }
221
219
  datamaite = { pip = true }
222
220
 
223
221
  # --- Build System ---
@@ -13,11 +13,22 @@ _logger = logging.getLogger(__name__)
13
13
 
14
14
  def _build_parser() -> argparse.ArgumentParser:
15
15
  """Build the argument parser with subcommands."""
16
+ from dataeval_flow import __version__
17
+
16
18
  parser = argparse.ArgumentParser(
17
19
  prog="dataeval_flow",
18
20
  description="DataEval Flow - Data evaluation and monitoring pipelines",
19
21
  )
20
22
 
23
+ # Long form only: -v is --verbose, and a container asking which build it is running
24
+ # is a different question from how loudly it should report.
25
+ parser.add_argument(
26
+ "--version",
27
+ action="version",
28
+ version=f"dataeval-flow {__version__}",
29
+ help="Show the installed dataeval-flow version and exit.",
30
+ )
31
+
21
32
  # Headless execution flags (top-level, no subcommand needed)
22
33
  parser.add_argument(
23
34
  "-v",
@@ -60,9 +71,50 @@ def _build_parser() -> argparse.ArgumentParser:
60
71
  default=Path(_cache_default) if _cache_default else None,
61
72
  help="Directory for disk-backed computation cache (default: $DATAEVAL_CACHE or None).",
62
73
  )
74
+ parser.add_argument(
75
+ "-t",
76
+ "--task",
77
+ action="append",
78
+ default=None,
79
+ metavar="NAME",
80
+ help=(
81
+ "Run only this task, by name. Repeat to run several, in the order given. "
82
+ "Naming a task runs it whether or not the config marks it enabled. "
83
+ "Default: every enabled task."
84
+ ),
85
+ )
86
+ parser.add_argument(
87
+ "--fail-on-warning",
88
+ action="store_true",
89
+ help=(
90
+ "Exit non-zero when a task succeeds but reports findings that breached their "
91
+ "health thresholds. Off by default, so a warning stays a prompt to look."
92
+ ),
93
+ )
63
94
 
64
95
  subparsers = parser.add_subparsers(dest="command")
65
96
 
97
+ # --- workflows (discovery) ---
98
+ workflows_parser = subparsers.add_parser(
99
+ "workflows",
100
+ help="List available workflow types, or show one's parameter schema",
101
+ description=(
102
+ "List the workflow types this build provides. Naming one prints the JSON "
103
+ "Schema for its parameters — the fields a `workflows:` entry of that type accepts."
104
+ ),
105
+ )
106
+ workflows_parser.add_argument(
107
+ "name",
108
+ nargs="?",
109
+ default=None,
110
+ help="Workflow type to describe (e.g. data-cleaning). Omit to list them all.",
111
+ )
112
+ workflows_parser.add_argument(
113
+ "--json",
114
+ action="store_true",
115
+ help="Emit the listing as JSON rather than a table.",
116
+ )
117
+
66
118
  # --- app (interactive TUI) ---
67
119
  app_parser = subparsers.add_parser(
68
120
  "app",
@@ -134,6 +186,41 @@ def _build_parser() -> argparse.ArgumentParser:
134
186
  return parser
135
187
 
136
188
 
189
+ def _list_workflows(name: str | None, *, as_json: bool) -> int:
190
+ """Print the available workflow types, or one workflow's parameter schema.
191
+
192
+ Discovery without a TUI: the container image ships no browser and no Python REPL
193
+ worth the name, so the question "what can this build run, and what does it take?"
194
+ needs an answer from the command line.
195
+ """
196
+ import json
197
+
198
+ from dataeval_flow.workflow import get_workflow, list_workflows
199
+
200
+ if name is not None:
201
+ try:
202
+ workflow = get_workflow(name)
203
+ except ValueError as e:
204
+ print(f"ERROR: {e}", file=sys.stderr)
205
+ return 1
206
+ schema = workflow.params_schema
207
+ if schema is None:
208
+ print(f"{workflow.name} takes no parameters.")
209
+ return 0
210
+ print(json.dumps(schema.model_json_schema(), indent=2))
211
+ return 0
212
+
213
+ entries = sorted(list_workflows(), key=lambda w: w["name"])
214
+ if as_json:
215
+ print(json.dumps(entries, indent=2))
216
+ return 0
217
+
218
+ width = max(len(w["name"]) for w in entries)
219
+ for entry in entries:
220
+ print(f" {entry['name']:<{width}} {entry['description']}")
221
+ return 0
222
+
223
+
137
224
  def parse_args() -> argparse.Namespace:
138
225
  """Parse CLI arguments."""
139
226
  parser = _build_parser()
@@ -172,6 +259,9 @@ def main() -> NoReturn:
172
259
  setup_logging(verbosity=max(args.verbose, 2))
173
260
  sys.exit(write_encoding(args.result, args.output, args.task))
174
261
 
262
+ if args.command == "workflows":
263
+ sys.exit(_list_workflows(args.name, as_json=args.json))
264
+
175
265
  if args.command == "config":
176
266
  from dataeval_flow._app.cli import run_cli_builder
177
267
 
@@ -187,7 +277,17 @@ def main() -> NoReturn:
187
277
  try:
188
278
  from dataeval_flow.runner import run
189
279
 
190
- sys.exit(run(args.config, args.output, data_dir=args.data, verbosity=args.verbose, cache_dir=args.cache))
280
+ sys.exit(
281
+ run(
282
+ args.config,
283
+ args.output,
284
+ data_dir=args.data,
285
+ verbosity=args.verbose,
286
+ cache_dir=args.cache,
287
+ tasks=args.task,
288
+ fail_on_warning=args.fail_on_warning,
289
+ )
290
+ )
191
291
  except (FileNotFoundError, ValueError, ImportError) as e:
192
292
  _logger.error("%s", e)
193
293
  sys.exit(1)
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
18
18
  commit_id: str | None
19
19
  __commit_id__: str | None
20
20
 
21
- __version__ = version = '0.2.1'
22
- __version_tuple__ = version_tuple = (0, 2, 1)
21
+ __version__ = version = '0.2.2'
22
+ __version_tuple__ = version_tuple = (0, 2, 2)
23
23
 
24
24
  __commit_id__ = commit_id = None