|
6 | 6 | TEST_BOX_ANNOTATIONS,
|
7 | 7 | TEST_POLYGON_ANNOTATIONS,
|
8 | 8 | TEST_CATEGORY_ANNOTATIONS,
|
| 9 | + TEST_MULTICATEGORY_ANNOTATIONS, |
9 | 10 | TEST_SEGMENTATION_ANNOTATIONS,
|
10 | 11 | reference_id_from_url,
|
11 | 12 | assert_box_annotation_matches_dict,
|
12 | 13 | assert_polygon_annotation_matches_dict,
|
13 | 14 | assert_category_annotation_matches_dict,
|
| 15 | + assert_multicategory_annotation_matches_dict, |
14 | 16 | assert_segmentation_annotation_matches_dict,
|
15 | 17 | )
|
16 | 18 |
|
17 | 19 | from nucleus import (
|
18 | 20 | BoxAnnotation,
|
19 | 21 | PolygonAnnotation,
|
20 | 22 | CategoryAnnotation,
|
| 23 | + MultiCategoryAnnotation, |
21 | 24 | SegmentationAnnotation,
|
22 | 25 | DatasetItem,
|
23 | 26 | Segment,
|
@@ -64,6 +67,14 @@ def dataset(CLIENT):
|
64 | 67 | "category",
|
65 | 68 | [f"[Pytest] Category Label ${i}" for i in range((len(TEST_IMG_URLS)))],
|
66 | 69 | )
|
| 70 | + response = ds.add_taxonomy( |
| 71 | + "[Pytest] MultiCategory Taxonomy 1", |
| 72 | + "multicategory", |
| 73 | + [ |
| 74 | + f"[Pytest] MultiCategory Label ${i}" |
| 75 | + for i in range((len(TEST_IMG_URLS) + 1)) |
| 76 | + ], |
| 77 | + ) |
67 | 78 | yield ds
|
68 | 79 |
|
69 | 80 | response = CLIENT.delete_dataset(ds.id)
|
@@ -127,6 +138,27 @@ def test_category_gt_upload(dataset):
|
127 | 138 | )
|
128 | 139 |
|
129 | 140 |
|
| 141 | +def test_multicategory_gt_upload(dataset): |
| 142 | + annotation = MultiCategoryAnnotation.from_json( |
| 143 | + TEST_MULTICATEGORY_ANNOTATIONS[0] |
| 144 | + ) |
| 145 | + response = dataset.annotate(annotations=[annotation]) |
| 146 | + |
| 147 | + assert response["dataset_id"] == dataset.id |
| 148 | + assert response["annotations_processed"] == 1 |
| 149 | + assert response["annotations_ignored"] == 0 |
| 150 | + |
| 151 | + response = dataset.refloc(annotation.reference_id)["annotations"][ |
| 152 | + "multicategory" |
| 153 | + ] |
| 154 | + |
| 155 | + assert len(response) == 1 |
| 156 | + response_annotation = response[0] |
| 157 | + assert_multicategory_annotation_matches_dict( |
| 158 | + response_annotation, TEST_MULTICATEGORY_ANNOTATIONS[0] |
| 159 | + ) |
| 160 | + |
| 161 | + |
130 | 162 | def test_single_semseg_gt_upload(dataset):
|
131 | 163 | annotation = SegmentationAnnotation.from_json(
|
132 | 164 | TEST_SEGMENTATION_ANNOTATIONS[0]
|
@@ -206,6 +238,7 @@ def test_mixed_annotation_upload(dataset):
|
206 | 238 | response_annotations = dataset.refloc(bbox_annotations[0].reference_id)[
|
207 | 239 | "annotations"
|
208 | 240 | ]
|
| 241 | + |
209 | 242 | assert len(response_annotations) == 2
|
210 | 243 | assert len(response_annotations["box"]) == 1
|
211 | 244 | assert "segmentation" in response_annotations
|
@@ -392,34 +425,120 @@ def test_category_gt_upload_ignore(dataset):
|
392 | 425 | response_annotation, TEST_CATEGORY_ANNOTATIONS[0]
|
393 | 426 | )
|
394 | 427 |
|
395 |
| - @pytest.mark.integration |
396 |
| - def test_box_gt_deletion(dataset): |
397 |
| - annotation = BoxAnnotation(**TEST_BOX_ANNOTATIONS[0]) |
398 | 428 |
|
399 |
| - print(annotation) |
| 429 | +def test_multicategory_gt_upload_update(dataset): |
| 430 | + annotation = MultiCategoryAnnotation.from_json( |
| 431 | + TEST_MULTICATEGORY_ANNOTATIONS[0] |
| 432 | + ) |
| 433 | + response = dataset.annotate(annotations=[annotation]) |
| 434 | + |
| 435 | + assert response["annotations_processed"] == 1 |
| 436 | + |
| 437 | + # Copy so we don't modify the original. |
| 438 | + annotation_update_params = dict(TEST_MULTICATEGORY_ANNOTATIONS[1]) |
| 439 | + annotation_update_params["reference_id"] = TEST_MULTICATEGORY_ANNOTATIONS[ |
| 440 | + 0 |
| 441 | + ]["reference_id"] |
| 442 | + |
| 443 | + annotation_update = MultiCategoryAnnotation.from_json( |
| 444 | + annotation_update_params |
| 445 | + ) |
| 446 | + response = dataset.annotate(annotations=[annotation_update], update=True) |
| 447 | + |
| 448 | + assert response["annotations_processed"] == 1 |
| 449 | + assert response["annotations_ignored"] == 0 |
| 450 | + |
| 451 | + response = dataset.refloc(annotation.reference_id)["annotations"][ |
| 452 | + "multicategory" |
| 453 | + ] |
| 454 | + assert len(response) == 1 |
| 455 | + response_annotation = response[0] |
| 456 | + assert_multicategory_annotation_matches_dict( |
| 457 | + response_annotation, annotation_update_params |
| 458 | + ) |
| 459 | + |
| 460 | + |
| 461 | +def test_multicategory_gt_upload_ignore(dataset): |
| 462 | + annotation = MultiCategoryAnnotation.from_json( |
| 463 | + TEST_MULTICATEGORY_ANNOTATIONS[0] |
| 464 | + ) |
| 465 | + response = dataset.annotate(annotations=[annotation]) |
| 466 | + |
| 467 | + assert response["annotations_processed"] == 1 |
| 468 | + |
| 469 | + # Copy so we don't modify the original. |
| 470 | + annotation_update_params = dict(TEST_MULTICATEGORY_ANNOTATIONS[1]) |
| 471 | + annotation_update_params["reference_id"] = TEST_MULTICATEGORY_ANNOTATIONS[ |
| 472 | + 0 |
| 473 | + ]["reference_id"] |
| 474 | + |
| 475 | + annotation_update = MultiCategoryAnnotation.from_json( |
| 476 | + annotation_update_params |
| 477 | + ) |
| 478 | + # Default behavior is ignore. |
| 479 | + response = dataset.annotate(annotations=[annotation_update]) |
| 480 | + |
| 481 | + assert response["annotations_processed"] == 0 |
| 482 | + assert response["annotations_ignored"] == 1 |
| 483 | + |
| 484 | + response = dataset.refloc(annotation.reference_id)["annotations"][ |
| 485 | + "multicategory" |
| 486 | + ] |
| 487 | + assert len(response) == 1 |
| 488 | + response_annotation = response[0] |
| 489 | + assert_multicategory_annotation_matches_dict( |
| 490 | + response_annotation, TEST_MULTICATEGORY_ANNOTATIONS[0] |
| 491 | + ) |
| 492 | + |
| 493 | + |
| 494 | +@pytest.mark.integration |
| 495 | +def test_box_gt_deletion(dataset): |
| 496 | + annotation = BoxAnnotation(**TEST_BOX_ANNOTATIONS[0]) |
| 497 | + |
| 498 | + print(annotation) |
| 499 | + |
| 500 | + response = dataset.annotate(annotations=[annotation]) |
| 501 | + |
| 502 | + assert response["annotations_processed"] == 1 |
| 503 | + |
| 504 | + job = dataset.delete_annotations() |
| 505 | + job.sleep_until_complete() |
| 506 | + job_status = job.status() |
| 507 | + assert job_status["status"] == "Completed" |
| 508 | + assert job_status["job_id"] == job.job_id |
| 509 | + |
| 510 | + |
| 511 | +@pytest.mark.integration |
| 512 | +def test_category_gt_deletion(dataset): |
| 513 | + annotation = CategoryAnnotation.from_json(TEST_CATEGORY_ANNOTATIONS[0]) |
| 514 | + |
| 515 | + print(annotation) |
| 516 | + |
| 517 | + response = dataset.annotate(annotations=[annotation]) |
400 | 518 |
|
401 |
| - response = dataset.annotate(annotations=[annotation]) |
| 519 | + assert response["annotations_processed"] == 1 |
402 | 520 |
|
403 |
| - assert response["annotations_processed"] == 1 |
| 521 | + job = dataset.delete_annotations() |
| 522 | + job.sleep_until_complete() |
| 523 | + job_status = job.status() |
| 524 | + assert job_status["status"] == "Completed" |
| 525 | + assert job_status["job_id"] == job.job_id |
404 | 526 |
|
405 |
| - job = dataset.delete_annotations() |
406 |
| - job.sleep_until_complete() |
407 |
| - job_status = job.status() |
408 |
| - assert job_status["status"] == "Completed" |
409 |
| - assert job_status["job_id"] == job.id |
410 | 527 |
|
411 |
| - @pytest.mark.integration |
412 |
| - def test_category_gt_deletion(dataset): |
413 |
| - annotation = CategoryAnnotation.from_json(TEST_CATEGORY_ANNOTATIONS[0]) |
| 528 | +@pytest.mark.integration |
| 529 | +def test_multicategory_gt_deletion(dataset): |
| 530 | + annotation = MultiCategoryAnnotation.from_json( |
| 531 | + TEST_MULTICATEGORY_ANNOTATIONS[0] |
| 532 | + ) |
414 | 533 |
|
415 |
| - print(annotation) |
| 534 | + print(annotation) |
416 | 535 |
|
417 |
| - response = dataset.annotate(annotations=[annotation]) |
| 536 | + response = dataset.annotate(annotations=[annotation]) |
418 | 537 |
|
419 |
| - assert response["annotations_processed"] == 1 |
| 538 | + assert response["annotations_processed"] == 1 |
420 | 539 |
|
421 |
| - job = dataset.delete_annotations() |
422 |
| - job.sleep_until_complete() |
423 |
| - job_status = job.status() |
424 |
| - assert job_status["status"] == "Completed" |
425 |
| - assert job_status["job_id"] == job.id |
| 540 | + job = dataset.delete_annotations() |
| 541 | + job.sleep_until_complete() |
| 542 | + job_status = job.status() |
| 543 | + assert job_status["status"] == "Completed" |
| 544 | + assert job_status["job_id"] == job.job_id |
0 commit comments