Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CLI-COMMANDS.md
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,8 @@ roboflow annotation job admin-list -p my-project --limit 50
roboflow annotation job admin-get <job-id> -p my-project
roboflow annotation job admin-create -p my-project --batch <batch-id> \
--labeler a@co.com --reviewer b@co.com --name "Label round 1"
roboflow annotation job reassign-images -p my-project --image-id <image-id> \
--labeler a@co.com --yes
roboflow annotation job create -p my-project --name "Label round 1" \
--batch <batch-id> --num-images 100 --labeler a@co.com --reviewer b@co.com
roboflow annotation job images <job-id> -p my-project
Expand Down
2 changes: 1 addition & 1 deletion roboflow/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
CLIPModel = None # type: ignore[assignment,misc]
GazeModel = None # type: ignore[assignment,misc]

__version__ = "1.4.0"
__version__ = "1.4.1"


def check_key(api_key, model, notebook, num_retries=0):
Expand Down
23 changes: 13 additions & 10 deletions roboflow/cli/handlers/annotation.py
Original file line number Diff line number Diff line change
Expand Up @@ -268,18 +268,21 @@ def job_reassign_images(
reviewer: Annotated[Optional[str], typer.Option(help="Reviewer email")] = None,
instructions: Annotated[Optional[str], typer.Option(help="Labeling instructions")] = None,
name: Annotated[Optional[str], typer.Option(help="Optional job name")] = None,
yes: Annotated[bool, typer.Option("-y", "--yes", help="Confirm reassignment of the images")] = False,
) -> None:
"""Create a job by explicitly reassigning images."""
_simple_command(
ctx_to_args(ctx, project=project),
"reassign_annotation_job_images",
image_ids=image_ids,
labeler_email=labeler,
reviewer_email=reviewer,
instructions=instructions,
name=name,
success="Reassigned images to a new annotation job.",
)
args = ctx_to_args(ctx, project=project, yes=yes)
if _confirm(args, "Remove these images from their current assignments and reassign them to a new job?"):
_simple_command(
args,
"reassign_annotation_job_images",
image_ids=image_ids,
labeler_email=labeler,
reviewer_email=reviewer,
instructions=instructions,
name=name,
success="Reassigned images to a new annotation job.",
)


@job_app.command("add-images")
Expand Down
32 changes: 32 additions & 0 deletions tests/cli/test_annotation_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,38 @@ def test_job_add_images_requires_yes_non_interactively(self, _resolve, mock_api)
self.assertEqual(result.exit_code, 0, result.output)
mock_api.assert_called_once_with("key", "ws", "proj", "job-1", image_ids=["image-1"])

@patch("roboflow.adapters.rfapi.reassign_annotation_job_images")
@patch(_RESOLVE, return_value=("key", "ws", "proj"))
def test_job_reassign_images_requires_yes_non_interactively(self, _resolve, mock_api):
command = [
"annotation",
"job",
"reassign-images",
"-p",
"ws/proj",
"--image-id",
"image-1",
"--labeler",
"labeler@example.com",
]
result = runner.invoke(app, command)
self.assertEqual(result.exit_code, 1)
mock_api.assert_not_called()

mock_api.return_value = {"jobId": "job-1"}
result = runner.invoke(app, [*command, "--yes"])
self.assertEqual(result.exit_code, 0, result.output)
mock_api.assert_called_once_with(
"key",
"ws",
"proj",
image_ids=["image-1"],
labeler_email="labeler@example.com",
reviewer_email=None,
instructions=None,
name=None,
)

@patch("roboflow.adapters.rfapi.accept_annotation_job_images")
@patch(_RESOLVE, return_value=("key", "ws", "proj"))
def test_job_accept_maps_lists_and_split_counts(self, _resolve, mock_api):
Expand Down
Loading