Skip to content

feat(api): the workflows as Python callables - #94

Merged
vboussot merged 0 commit into
feat/impact-reg-cases-and-fieldsfrom
feat/konfai-python-api
Aug 6, 2026
Merged

feat(api): the workflows as Python callables#94
vboussot merged 0 commit into
feat/impact-reg-cases-and-fieldsfrom
feat/konfai-python-api

Conversation

@vboussot

@vboussot vboussot commented Aug 6, 2026

Copy link
Copy Markdown
Member

The workflows become Python callables: konfai.transform / plan_transform / evaluate / predict / train accept live stage objects or a config tree as a dict, build the same tree the YAML file would hold, and hand it to the same binder. Refusals raise KonfAIError; results come back structured; the resolved YAML is still written to the workspace.

Supporting pieces in the same line:

  • 3ac59c3 feat(data): a reference that follows the case — reference: "{case}" resolves per case
  • 5df9455 feat(data): Std reduction and Magnitude transform — the streamed-uncertainty vocabulary
  • c6ca8e4 feat(api): the workflows as Python callables
  • 79ef557 feat(impact-reg): every derivation through konfai's own engine — the orchestrator's moved/mean/uncertainty/warp all run as TRANSFORM chains, fully out of core
  • a7b429f docs(mcp): plan_transform's verdict list gains LOAD

Stacked on feat/impact-reg-cases-and-fields.

@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown
🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 46.08% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ⚠️ Warning The description explains the main change and supporting work, but omits the template's testing, checklist, type, and migration sections. Add the required template sections, record testing results, mark applicable checklist items, and state whether related issues or breaking changes apply.
✅ Passed checks (3 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly and concisely identifies the primary change: exposing workflows as Python callables.

Comment @coderabbitai help to get the list of available commands.

@vboussot

vboussot commented Aug 6, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown
⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@vboussot
vboussot force-pushed the feat/konfai-python-api branch from ba53ab5 to a8bbe32 Compare August 6, 2026 11:29
@vboussot
vboussot force-pushed the feat/konfai-python-api branch from a8bbe32 to b822331 Compare August 6, 2026 12:03

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 8

🧹 Nitpick comments (6)
konfai/data/reduction.py (1)

165-166: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Declare working_multiple = 2.0 for Std. Std retains _mean and _m2 in addition to the incoming region. The planner therefore needs four regions, including the output, instead of two.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@konfai/data/reduction.py` around lines 165 - 166, Declare working_multiple =
2.0 alongside voxel_local and incremental for the Std reduction configuration,
so the planner allocates four regions including the output.
tests/unit/test_api.py (3)

40-53: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add the recording tests to tests/unit/test_config.py as well.

record_given_arguments is new in konfai/utils/config.py and changes how constructor arguments bind to the config tree. The behaviour is pinned here only. The guideline requires configuration-binding changes to update tests/unit/test_config.py.

Cases worth pinning there directly: a **kwargs constructor (flattened into the record), a *args constructor (records None), and a subclass that defines no __init__ (inherits the parent's recording wrapper and records under the parent's signature).

As per coding guidelines: "For configuration-binding changes, update tests/unit/test_config.py".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/unit/test_api.py` around lines 40 - 53, Add equivalent recording
coverage to tests/unit/test_config.py for record_given_arguments: verify
**kwargs are flattened into _konfai_given, *args records None, and a subclass
without its own __init__ uses the inherited parent signature while recording.
Keep the existing test_api.py coverage unchanged.

Source: Coding guidelines


56-58: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add coverage for a chain that repeats one stage name.

_chain_tree has three branches for a repeated name: bare, module-qualified, and refusal. None is tested. The mapping form of the second branch is broken (see the comment on konfai/api.py lines 144-155), and a test would have caught it.

🧪 Suggested tests
def test_a_repeated_stage_is_written_module_qualified() -> None:
    tree = api._chain_tree(
        [Clip(min_value=0.0), Clip(max_value=1.0)], api._STAGE_MODULES, "chains.CT.CT"
    )
    assert list(tree) == ["Clip", "konfai.data.transform:Clip"]


def test_a_thrice_repeated_stage_is_refused() -> None:
    with pytest.raises(ConfigError, match="three stages"):
        api._chain_tree(
            [Clip(min_value=0.0), Clip(max_value=1.0), Clip(min_value=2.0)],
            api._STAGE_MODULES,
            "chains.CT.CT",
        )


def test_a_repeated_mapping_stage_is_refused_by_name() -> None:
    with pytest.raises(ConfigError, match="Clip"):
        api._chain_tree(
            [{"Clip": {"min_value": 0.0}}, {"Clip": {"max_value": 1.0}}],
            api._STAGE_MODULES,
            "chains.CT.CT",
        )
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/unit/test_api.py` around lines 56 - 58, Add coverage in the test suite
for _chain_tree’s repeated-stage branches: verify a twice-repeated Clip is
emitted once bare and once module-qualified, verify a thrice-repeated stage
raises ConfigError mentioning three stages, and verify repeated mapping-form
Clip stages are refused with an error naming Clip.

128-139: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Also pin the environment restore on the failure path.

This test covers the success path. _one_workflow_at_a_time restores the environment in a finally block, and a designed refusal (as in test_a_designed_refusal_raises_instead_of_exiting) is the path most likely to regress. Assert that the KONFAI_* keys and the lock are both released after the raise.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/unit/test_api.py` around lines 128 - 139, Extend
test_the_environment_is_left_as_found to exercise a designed refusal that
raises, then assert all KONFAI_* environment keys are absent and the workflow
lock is released afterward. Reuse the refusal setup and lock symbol from
test_a_designed_refusal_raises_instead_of_exiting, while preserving the existing
success-path assertions.
konfai/trainer.py (1)

1096-1096: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Three build functions widened the config parameter to Path | str | dict without updating their numpydoc blocks. build_transform documents the dict form; build_train, build_predict and build_evaluate do not, so the rendered API reference still says the parameter is a path.

  • konfai/trainer.py#L1096-L1096: update the config description at lines 1110-1111 to Path | str | dict and state that a dict is the config tree itself.
  • konfai/predictor.py#L2254-L2254: update the prediction_file description at lines 2264-2265 the same way.
  • konfai/evaluator.py#L651-L651: update the evaluations_file description at lines 659-660 the same way.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@konfai/trainer.py` at line 1096, Update the numpydoc parameter descriptions
for build_train’s config, predictor.py’s prediction_file, and evaluator.py’s
evaluations_file to document the type as Path | str | dict and state that a dict
is the configuration tree itself; update all three listed sites consistently.
konfai/data/transform.py (1)

286-299: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Document the write_stream_cache_attribute API change.

All in-repository overrides accept name. External Transform subclasses with the previous two-argument signature will raise TypeError when callers pass name positionally. Add a release note for this extension-point change.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@konfai/data/transform.py` around lines 286 - 299, Add a release note
documenting that the Transform.write_stream_cache_attribute extension point now
accepts the case name parameter, name. State that external Transform subclasses
retaining the previous two-argument signature must update their override to
accept name because callers may pass it positionally.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/impact_reg/impact_reg_konfai/impact_reg.py`:
- Around line 690-703: Before writing the `Uncertainty` dataset in the
`impact_reg_uncertainty` transform, call `_output_path` to remove any stale
output with the same stem in the alternate format. Match the cleanup behavior
used by `_ensemble_mean` and `_derive_moved`, while preserving the existing
format selection and `Write` configuration.
- Around line 496-515: Update _derive_moved so mixed DVF suffixes cannot cause
one case’s Write format to be applied to every case: validate that all cases in
cases share the same suffix/form before _run_transform proceeds, and fail
clearly when they differ. Preserve each case’s existing _output_path cleanup and
use the validated common form for the Write dataset format.

In `@konfai/api.py`:
- Around line 259-271: Add a return annotation of
konfai.transformer.TransformPlan to the public plan_transform function,
importing TransformPlan under TYPE_CHECKING so runtime imports remain
lightweight.
- Around line 144-155: Update the duplicate-name handling in the stage-tree
construction loop to derive the module-qualified name from the resolved stage
entry returned by _stage_entry, rather than from the runtime type of the stage
container. Preserve the existing three-spellings ConfigError behavior and ensure
repeated one-entry mappings qualify using their entry name.
- Around line 317-323: Update the group derivation before the groups_src
construction to expand each target key by splitting it on “;” and include every
component in groups, while retaining metric source groups. Ensure composite
targets such as Seg;Mask produce separate Seg and Mask entries for Evaluator
validation.

In `@konfai/metric/measure.py`:
- Around line 78-83: Update record_given_arguments and the __init_subclass__
path for Metric subclasses so classes inheriting Criterion.__init__, such as
Accuracy, receive a wrapped constructor and populate _konfai_given when
instantiated. Preserve existing behavior for classes with local constructors,
and add a regression test verifying that an inherited-constructor metric can be
serialized in a live workflow.

In `@konfai/utils/runtime.py`:
- Around line 184-204: Update _materialized_config to retain the scratch
directory path and register it for process-exit cleanup, using the appropriate
tempfile cleanup mechanism. Keep the directory available through workflow
execution so resolved defaults can still be written, while ensuring each
generated scratch directory is removed after the process exits.

In `@tests/unit/test_api.py`:
- Around line 211-217: Update test_a_config_tree_must_hold_the_workflow_root to
verify that the temporary directory created by _materialized_config is cleaned
up after materialization, replacing the current path.is_file-only assertion as
needed. Preserve the existing ConfigError validation and successful Transformer
configuration coverage, and align the assertion with the cleanup behavior
implemented by _materialized_config.

---

Nitpick comments:
In `@konfai/data/reduction.py`:
- Around line 165-166: Declare working_multiple = 2.0 alongside voxel_local and
incremental for the Std reduction configuration, so the planner allocates four
regions including the output.

In `@konfai/data/transform.py`:
- Around line 286-299: Add a release note documenting that the
Transform.write_stream_cache_attribute extension point now accepts the case name
parameter, name. State that external Transform subclasses retaining the previous
two-argument signature must update their override to accept name because callers
may pass it positionally.

In `@konfai/trainer.py`:
- Line 1096: Update the numpydoc parameter descriptions for build_train’s
config, predictor.py’s prediction_file, and evaluator.py’s evaluations_file to
document the type as Path | str | dict and state that a dict is the
configuration tree itself; update all three listed sites consistently.

In `@tests/unit/test_api.py`:
- Around line 40-53: Add equivalent recording coverage to
tests/unit/test_config.py for record_given_arguments: verify **kwargs are
flattened into _konfai_given, *args records None, and a subclass without its own
__init__ uses the inherited parent signature while recording. Keep the existing
test_api.py coverage unchanged.
- Around line 56-58: Add coverage in the test suite for _chain_tree’s
repeated-stage branches: verify a twice-repeated Clip is emitted once bare and
once module-qualified, verify a thrice-repeated stage raises ConfigError
mentioning three stages, and verify repeated mapping-form Clip stages are
refused with an error naming Clip.
- Around line 128-139: Extend test_the_environment_is_left_as_found to exercise
a designed refusal that raises, then assert all KONFAI_* environment keys are
absent and the workflow lock is released afterward. Reuse the refusal setup and
lock symbol from test_a_designed_refusal_raises_instead_of_exiting, while
preserving the existing success-path assertions.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: e735a4bd-4150-4da1-bade-875aed937e78

📥 Commits

Reviewing files that changed from the base of the PR and between 2e72275 and b822331.

📒 Files selected for processing (21)
  • .claude/skills/konfai-experiments/references/tool-reference.md
  • apps/impact_reg/impact_reg_konfai/cli.py
  • apps/impact_reg/impact_reg_konfai/impact_reg.py
  • apps/impact_reg/tests/unit/test_displacement_field_io.py
  • apps/impact_reg/tests/unit/test_orchestration.py
  • apps/impact_reg/tests/unit/test_tmp_dir_forwarding.py
  • konfai-mcp/konfai_mcp/guide.py
  • konfai/__init__.py
  • konfai/api.py
  • konfai/data/augmentation.py
  • konfai/data/patching.py
  • konfai/data/reduction.py
  • konfai/data/transform.py
  • konfai/evaluator.py
  • konfai/metric/measure.py
  • konfai/predictor.py
  • konfai/trainer.py
  • konfai/transformer.py
  • konfai/utils/config.py
  • konfai/utils/runtime.py
  • tests/unit/test_api.py

Comment thread apps/impact_reg/impact_reg_konfai/impact_reg.py Outdated
Comment thread apps/impact_reg/impact_reg_konfai/impact_reg.py Outdated
Comment thread konfai/api.py
Comment thread konfai/api.py Outdated
Comment thread konfai/api.py Outdated
Comment thread konfai/metric/measure.py
Comment thread konfai/utils/runtime.py
Comment thread tests/unit/test_api.py
@vboussot
vboussot force-pushed the feat/konfai-python-api branch from b822331 to 5b8c6ea Compare August 6, 2026 13:31
@vboussot
vboussot merged commit 4337e9c into main Aug 6, 2026
@vboussot
vboussot deleted the feat/konfai-python-api branch August 6, 2026 13:48
@vboussot
vboussot force-pushed the feat/konfai-python-api branch from 5b8c6ea to 4337e9c Compare August 6, 2026 13:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant