Skip to content

feat(LAB-4585): designate workflow steps by id, or by name and group - #2095

Open
aurelienlombard wants to merge 6 commits into
mainfrom
feature/lab-4585-investigate-some-missing-checks-on-the-group-in-wv3
Open

aurelienlombard wants to merge 6 commits into
mainfrom
feature/lab-4585-investigate-some-missing-checks-on-the-group-in-wv3

Conversation

@aurelienlombard

@aurelienlombard aurelienlombard commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

Closes LAB-4585. Backend: kili!14636.

Step names are unique per group only. A step is now given by step_id, or by step_name with group_name when several groups use the name, never both; the SDK resolves names to ids before sending.

Changes (one commit each)

  1. Workflow methods designate a step by id, or by name and group: add/remove_reviewers_to_step, add/remove_labelers_to_step (and projects.workflow.*), update_labeling_step_properties, update_review_step_properties, rename_step. update_project_workflow resolves updates and deletes given by name (a delete can be {"name", "group_name"}); create_steps takes step_group_id; get_steps lists each step's group.
  2. add_review_step takes group_name: the step is added at the end of that group, and send_back_to_step is found within it.
  3. Labels on a step given by id, or by name and group: append_labels, its shapefile/GeoJSON variants and labels.create_*, sent as stepId. labels.create_default no longer forces the step named "Default".
  4. Filters by step id: step_id_in, step_id_not_in, step_id_and_status_in, step_id_and_status_not_in, and asset_step_id_in on labels. They are keyword-only and exclusive with the name filters. A name several groups use now matches each group's step (step_name_and_status_in kept only the last one); group_name_in narrows it.
  5. copy_workflow_from_project refuses a source with several groups instead of flattening them.
  6. Docs: a group's allowed jobs are enforced by the labeling app only, not on labels created through the SDK; consensus can only be set on the labeling step of the first group.

Compatibility

  • Existing calls keep working: step_name stays positional, and the arguments after it get a default with a required check.
  • Release after kili!14636 is deployed: creating labels on a step needs its stepId input.

🤖 Generated with Claude Code

@aurelienlombard

Copy link
Copy Markdown
Contributor Author

🧪 Local test — LAB-4585

Summary: the step designation (step_id, or step_name + group_name, never both) works on every method the matrix called, against the backend of kili!14636 running locally; the name filters now cover every group and group_name_in narrows them. CI's Pylint job is red on three messages this PR introduces.

✅ What works

Unit tests: 842 passed, 1 skipped (pytest tests --ignore tests/e2e, PR worktree on the repo's venv — no conda on this machine for the sandbox env); pyright 0 errors. CI: tests, pyright, pre-commit, build and docs green; Pylint red (below); markdown-link-check red on main too.

Test data: a workflow V3 project with two groups Team 1 / Team 2, both named Label / Review, on the backend of kili!14636; one asset per case, walked through the interface's requests.

Call Expected Observed
add_reviewers_to_step(step_id=<Team 2/Review>) on Team 2/Review only ✅
add_labelers_to_step("Label", …, group_name="Team 2") on Team 2/Label only ✅
add_labelers_to_step("Label", …) refused, asks for the group ✅
step_id and step_name together refused ✅
update_project_workflow(update_steps=[{name, group_name, step_coverage}]) that group's step only ✅
append_labels(step_name="Label", group_name="Team 1"), no project_id label added, asset moves to Team 1/Review ✅
assets(step_name_and_status_in=[("Label","TO_DO")]) the Team 1 and the Team 2 asset ✅
same + group_name_in=["Team 2"] / step_id_in=[<Team 2/Label>] the Team 2 asset ✅ / ✅
step_id_in + step_name_in refused ✅
copy_workflow_from_project from two groups refused ✅

Released 26.2.0 against the new backend: a step name two groups share is refused with "give its id" (append_labels, update_project_workflow); a single-group project works as before.

🐛 Bug: Pylint fails in CI

R0916 too-many-boolean-expressions at presentation/client/label.py:153 and :531 (the asset_step_id_in added to the condition makes 6/5), R0912 too-many-branches at use_cases/project_workflow/__init__.py:178 (the multi-group refusal makes 13/12). Pylint is green on main's latest run.

Not tested

  • copy_project(copy_labels=True) on two groups fails on the backend side (copyLabels): reported on kili!14636.
  • Screenshots: on kili!14636 (UI only there).

tested at e64be2f · backend kili!14636 @ daf03becd4

@aurelienlombard aurelienlombard left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Review Summary

Verdict: Needs changes

Severity Count
Required 1
Suggestion 1

Tested locally: 842 passed · 10-call matrix against kili!14636, 10/10 as expected · released SDK 3/3 — report

The designation by id, or by name and group, behaves as specified on every call the matrix made; CI's Pylint is red on three messages this PR adds.

reviewing-feature · e64be2f

Comment thread src/kili/presentation/client/label.py Outdated
if (
asset_status_in is not None
or asset_step_name_in is not None
or asset_step_id_in is not None

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

[REQUIRED] CI's Pylint fails here: R0916 too-many-boolean-expressions (6/5), same at line 533, and R0912 too-many-branches (13/12) on copy_workflow_from_project (use_cases/project_workflow/__init__.py:178, from the multi-group refusal). Green on main.

Suggested fix: collect the workflow filters in a tuple and test any(f is not None for f in (...)), and move the group check of copy_workflow_from_project into a small _validate_source_has_one_group(source_steps) next to _validate_destination_is_workflow_v2.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

✔ addressed in aaa8f65 — asset_step_id_in no longer joins the condition that fetches the project steps (it does not need them, its exclusivity check sits before), and the single-group check is _validate_source_has_one_group. Pylint green in CI on 3.10, 3.12 and 3.13.

Comment thread src/kili/presentation/client/asset.py Outdated
step_name_and_status_not_in: Optional[list[tuple[str, StatusInStep]]] = None,
step_name_in: Optional[list[str]] = None,
step_name_not_in: Optional[list[str]] = None,
step_id_in: Optional[list[str]] = None,

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

[SUGGESTION] step_id_* are inserted before step_status_in, which shifts the position of every later parameter of a public legacy method (also lines 241, 318, 716, and asset_step_id_in in label.py 79, 235, 278 and the forwarding methods). append_labels and the GeoJSON / shapefile methods append theirs at the end; doing the same here keeps any positional call working.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

✔ addressed in aaa8f65 — the step id filters are the last parameters, keyword-only after the * of every assets / count_assets / labels / count_labels / predictions / inferences signature: no existing positional slot moves.

@aurelienlombard

Copy link
Copy Markdown
Contributor Author

🧪 Local test — LAB-4585 (re-review)

  • ✔ fixed in aaa8f65 — Pylint: green in CI (3.10, 3.12, 3.13); locally 10.00/10 on the changed files.
  • ✔ fixed in aaa8f65 — the step id filters are keyword-only, after every existing parameter.

Regression: 842 passed, 1 skipped; pyright 0 errors. CI: tests, pyright, Pylint, pre-commit, build and docs green; markdown-link-check red as on main. The SDK's copy_project(copy_labels=True) on two groups — the bug reported on kili!14636 — now copies labels and positions faithfully against kili!14636 @ 18741d92b1.

tested at aaa8f65 · backend kili!14636 @ 18741d92b1

@aurelienlombard aurelienlombard left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Review Summary

Verdict: Ready to merge

Tested locally: 842 passed · both findings re-checked, Pylint green in CI — report

Both findings of the first pass are addressed; release after kili!14636 is deployed.

reviewing-feature · aaa8f65

@aurelienlombard

Copy link
Copy Markdown
Contributor Author

🧪 Local test — LAB-4585 (third pass)

  • add_review_step takes group_name (the group to add the step to, at its end) and resolves send_back_to_step within it; the step property methods keep step_id / step_name + group_name, and now work on workflow V3 against kili!14636. Checked on a two-group project: each call acts on Team 2's step only.
  • A step given twice to update_project_workflow(delete_steps=…) is deleted once; the step_id_* filters follow the rules of the name ones; get_steps lists each step's group; every name filter documents that a name several groups use matches each of them.
  • 848 passed, 1 skipped; pyright 0 errors; Pylint (CI config) 10.00/10.

Release notes: release after kili!14636 is deployed (label creation on a step sends stepId). labels.create_default no longer sends a step named "Default".

tested at df0afca · backend kili!14636 @ a51ed19237

@aurelienlombard
aurelienlombard force-pushed the feature/lab-4585-investigate-some-missing-checks-on-the-group-in-wv3 branch from 5487dc2 to 4af9105 Compare October 6, 2026 10:01
@aurelienlombard
aurelienlombard marked this pull request as ready for review October 6, 2026 13:51
Aurélien Lombard and others added 6 commits October 6, 2026 15:53
Step names are unique per group only. The workflow methods take step_id,
or step_name with group_name when several groups use it, never both; the
SDK resolves names to ids, also for update_project_workflow's updates and
deletes. create_steps takes step_group_id.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
add_review_step takes group_name, sent as the group's id, and finds
send_back_to_step within that group.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
append_labels and labels.create_* take step_id, or step_name with
group_name, resolved to the id the request sends (appendManyLabels
stepId). labels.create_default no longer forces the step named Default.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
step_id_in, step_id_not_in, step_id_and_status_in(_not_in) and
asset_step_id_in, keyword-only and exclusive with their name filters. A
step name several groups use matches each of them; group_name_in narrows.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
copy_workflow_from_project writes a single-group workflow, so a source
with several groups would lose which step belongs to which.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
On workflow V3, a group's allowed jobs are enforced by the labeling app
only, not on labels created through the SDK. Consensus can only be set on
the labeling step of the first group.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@aurelienlombard
aurelienlombard force-pushed the feature/lab-4585-investigate-some-missing-checks-on-the-group-in-wv3 branch from 4af9105 to 1f10444 Compare October 6, 2026 13:54

This branch has not been deployed

No deployments
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.

3 participants