From 37c85b2b9f24ef6031881d89e3770e999b96c746 Mon Sep 17 00:00:00 2001 From: John Wilkie Date: Wed, 21 Aug 2024 12:24:02 +0100 Subject: [PATCH 1/4] Test commit --- darwin/dataset/remote_dataset_v2.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/darwin/dataset/remote_dataset_v2.py b/darwin/dataset/remote_dataset_v2.py index 59f87b320..e21a554ae 100644 --- a/darwin/dataset/remote_dataset_v2.py +++ b/darwin/dataset/remote_dataset_v2.py @@ -842,3 +842,6 @@ def register_multi_slotted( print(f" - {item}") print(f"Reistration complete. Check your items in the dataset: {self.slug}") return results + + +# Test comment From bf2a03344003491cd1b55aa7567d19d5470bbb7a Mon Sep 17 00:00:00 2001 From: John Wilkie Date: Wed, 21 Aug 2024 19:02:03 +0100 Subject: [PATCH 2/4] Don't download single-slotted items as multi-slotted items when force_slots=False --- darwin/dataset/download_manager.py | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/darwin/dataset/download_manager.py b/darwin/dataset/download_manager.py index 4eede09eb..3ddd232f4 100644 --- a/darwin/dataset/download_manager.py +++ b/darwin/dataset/download_manager.py @@ -90,7 +90,7 @@ def download_all_images_from_annotations( if is_file_extension_allowed(image.name) } - annotations_to_download_path = [] + annotations_to_download_path: List = [] for annotation_path in annotations_path.glob(f"*.{annotation_format}"): annotation = parse_darwin_json(annotation_path, count=0) if annotation is None: @@ -108,13 +108,18 @@ def download_all_images_from_annotations( ): continue - annotations_to_download_path.append(annotation_path) - if len(annotation.slots) > 1: - force_slots = True + if not force_slots: + force_slots_for_item = False + if len(annotation.slots) > 1: + force_slots_for_item = True - for slot in annotation.slots: - if len(slot.source_files) > 1: - force_slots = True + for slot in annotation.slots: + if len(slot.source_files) > 1: + force_slots_for_item = True + else: + force_slots_for_item = True + + annotations_to_download_path.append((annotation_path, force_slots_for_item)) if remove_extra: annotations = ( @@ -138,7 +143,7 @@ def download_all_images_from_annotations( # Create the generator with the partial functions download_functions: List = [] - for annotation_path in annotations_to_download_path: + for annotation_path, force_slots in annotations_to_download_path: file_download_functions = lazy_download_image_from_annotation( api_key, annotation_path, From 20cfc5215bec9f21e0201bb54cf52610b1008f57 Mon Sep 17 00:00:00 2001 From: John Wilkie Date: Wed, 21 Aug 2024 23:08:29 +0100 Subject: [PATCH 3/4] Unit tests + simpler approach --- darwin/dataset/download_manager.py | 17 ++--- darwin/dataset/remote_dataset_v2.py | 3 - tests/darwin/dataset/remote_dataset_test.py | 79 +++++++++++++++++++- tests/data.zip | Bin 296066 -> 300936 bytes 4 files changed, 85 insertions(+), 14 deletions(-) diff --git a/darwin/dataset/download_manager.py b/darwin/dataset/download_manager.py index 3ddd232f4..752f37579 100644 --- a/darwin/dataset/download_manager.py +++ b/darwin/dataset/download_manager.py @@ -64,8 +64,9 @@ def download_all_images_from_annotations( Recreate folders video_frames : bool, default: False Pulls video frames images instead of video files - force_slots: bool + force_slots: bool, default: False Pulls all slots of items into deeper file structure ({prefix}/{item_name}/{slot_name}/{file_name}) + If False, all multi-slotted items and items with slots containing multiple source files will be downloaded as the deeper file structure Returns ------- @@ -108,16 +109,12 @@ def download_all_images_from_annotations( ): continue - if not force_slots: - force_slots_for_item = False - if len(annotation.slots) > 1: - force_slots_for_item = True - - for slot in annotation.slots: - if len(slot.source_files) > 1: - force_slots_for_item = True - else: + if force_slots: force_slots_for_item = True + else: + force_slots_for_item = len(annotation.slots) > 1 or any( + len(slot.source_files) > 1 for slot in annotation.slots + ) annotations_to_download_path.append((annotation_path, force_slots_for_item)) diff --git a/darwin/dataset/remote_dataset_v2.py b/darwin/dataset/remote_dataset_v2.py index e21a554ae..59f87b320 100644 --- a/darwin/dataset/remote_dataset_v2.py +++ b/darwin/dataset/remote_dataset_v2.py @@ -842,6 +842,3 @@ def register_multi_slotted( print(f" - {item}") print(f"Reistration complete. Check your items in the dataset: {self.slug}") return results - - -# Test comment diff --git a/tests/darwin/dataset/remote_dataset_test.py b/tests/darwin/dataset/remote_dataset_test.py index fb2790bf9..c974ace0e 100644 --- a/tests/darwin/dataset/remote_dataset_test.py +++ b/tests/darwin/dataset/remote_dataset_test.py @@ -15,7 +15,10 @@ from darwin.client import Client from darwin.config import Config from darwin.dataset import RemoteDataset -from darwin.dataset.download_manager import _download_image_from_json_annotation +from darwin.dataset.download_manager import ( + _download_image_from_json_annotation, + download_all_images_from_annotations, +) from darwin.dataset.release import Release, ReleaseStatus from darwin.dataset.remote_dataset_v2 import RemoteDatasetV2 from darwin.dataset.upload_manager import LocalFile, UploadHandlerV2 @@ -25,6 +28,12 @@ from tests.fixtures import * +@pytest.fixture +def mock_is_file_extension_allowed(): + with patch("darwin.dataset.download_manager.is_file_extension_allowed") as mock: + yield mock + + @pytest.fixture def annotation_name() -> str: return "test_video.json" @@ -1373,3 +1382,71 @@ def test_omits_unavailable_releases_when_retry_is_false( releases = remote_dataset.get_releases(include_unavailable=False) assert len(releases) == 1 assert isinstance(releases[0], Release) + + +def test_force_slots_true(mock_is_file_extension_allowed): + mock_is_file_extension_allowed.return_value = True + with tempfile.TemporaryDirectory() as tmp_dir: + with zipfile.ZipFile("tests/data.zip") as zfile: + zfile.extractall(tmp_dir) + annotations_path = Path(tmp_dir) / "v7-darwin-json-v2/force_slots" + images_path = Path("images") + generator, count = download_all_images_from_annotations( + api_key="api_key", + annotations_path=annotations_path, + images_path=images_path, + force_slots=True, + force_replace=True, + ) + + download_funcs = list(generator()) + planned_paths = [download_funcs[i].args[2] for i in range(count)] + expected_paths = [ + Path("images/dir1/single_slotted_video_flat/0/mini_uct.mp4"), + Path("images/dir1/multiple_slots_multiple_source_files/0.1/slice_1.dcm"), + Path("images/dir1/multiple_slots_multiple_source_files/0.1/slice_2.dcm"), + Path("images/dir1/multiple_slots_multiple_source_files/1.1/slice_1.dcm"), + Path("images/dir1/multiple_slots_multiple_source_files/1.1/slice_2.dcm"), + Path("images/dir1/multiple_slots_multiple_source_files/1.1/slice_3.dcm"), + Path("images/dir1/single_slotted_image_flat/0/001.png"), + Path("images/dir1/multi_slotted_item_flat/0/000000580654.jpg"), + Path("images/dir1/multi_slotted_item_flat/1/000000580676.jpg"), + Path("images/dir1/multi_slotted_item_flat/2/000000580703.jpg"), + ] + assert count == 10 + for expected_path in expected_paths: + assert expected_path in planned_paths + + +def test_force_slots_false(mock_is_file_extension_allowed): + mock_is_file_extension_allowed.return_value = True + with tempfile.TemporaryDirectory() as tmp_dir: + with zipfile.ZipFile("tests/data.zip") as zfile: + zfile.extractall(tmp_dir) + annotations_path = Path(tmp_dir) / "v7-darwin-json-v2/force_slots" + images_path = Path("images") + generator, count = download_all_images_from_annotations( + api_key="api_key", + annotations_path=annotations_path, + images_path=images_path, + force_slots=False, + force_replace=True, + ) + + download_funcs = list(generator()) + planned_paths = [download_funcs[i].args[2] for i in range(count)] + expected_paths = [ + Path("images/dir1/single_slotted_video_flat.mp4"), + Path("images/dir1/multiple_slots_multiple_source_files/0.1/slice_1.dcm"), + Path("images/dir1/multiple_slots_multiple_source_files/0.1/slice_2.dcm"), + Path("images/dir1/multiple_slots_multiple_source_files/1.1/slice_1.dcm"), + Path("images/dir1/multiple_slots_multiple_source_files/1.1/slice_2.dcm"), + Path("images/dir1/multiple_slots_multiple_source_files/1.1/slice_3.dcm"), + Path("images/dir1/single_slotted_image_flat.png"), + Path("images/dir1/multi_slotted_item_flat/0/000000580654.jpg"), + Path("images/dir1/multi_slotted_item_flat/1/000000580676.jpg"), + Path("images/dir1/multi_slotted_item_flat/2/000000580703.jpg"), + ] + assert count == 10 + for expected_path in expected_paths: + assert expected_path in planned_paths diff --git a/tests/data.zip b/tests/data.zip index 0a675941aaac136184dac516c93b0082167bcbeb..fda8c0e0b496591404c7c8bfe3dc0afa266d8ad3 100644 GIT binary patch delta 15692 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 delta 16168 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 ro9S0HUHAdv{@`UUHrTM4)c&8b)UM_h Date: Thu, 22 Aug 2024 10:53:49 +0100 Subject: [PATCH 4/4] GHA permissions --- .github/workflows/EVENT_merge_to_master.yml | 4 ++++ .github/workflows/EVENT_tag.yml | 2 +- .github/workflows/JOB_typecheck.yml | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/EVENT_merge_to_master.yml b/.github/workflows/EVENT_merge_to_master.yml index d49415792..bb97e1134 100644 --- a/.github/workflows/EVENT_merge_to_master.yml +++ b/.github/workflows/EVENT_merge_to_master.yml @@ -9,6 +9,7 @@ on: permissions: contents: read + id-token: write # Necessary for the generate documentation job concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -24,6 +25,9 @@ jobs: name: Documentation uses: ./.github/workflows/JOB_generate_documentation.yml secrets: inherit + permissions: + id-token: write + contents: read warn_on_fail: needs: [run_tests, documentation] diff --git a/.github/workflows/EVENT_tag.yml b/.github/workflows/EVENT_tag.yml index e0ac39292..bd4c16c0a 100644 --- a/.github/workflows/EVENT_tag.yml +++ b/.github/workflows/EVENT_tag.yml @@ -15,7 +15,7 @@ env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} permissions: - contents: write + contents: read jobs: create_release: diff --git a/.github/workflows/JOB_typecheck.yml b/.github/workflows/JOB_typecheck.yml index 1ca9d2348..11a5c77b6 100644 --- a/.github/workflows/JOB_typecheck.yml +++ b/.github/workflows/JOB_typecheck.yml @@ -36,5 +36,5 @@ jobs: - name: MyPy typecheck shell: bash run: | - pip install pydantic==2.8.2 + pip install pydantic bash ${{ github.workspace }}/deploy/format_lint.sh typecheck ${{ inputs.files }}