Skip to content

Commit 26e6d13

Browse files
authored
Merge pull request #101 from DanielaSchacherer/main
fetch_index implemented
2 parents ab19b89 + aa021d5 commit 26e6d13

2 files changed

Lines changed: 61 additions & 7 deletions

File tree

idc_index/index.py

Lines changed: 50 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
aws_endpoint_url = "https://s3.amazonaws.com"
2323
gcp_endpoint_url = "https://storage.googleapis.com"
24+
asset_endpoint_url = f"https://github.com/ImagingDataCommons/idc-index-data/releases/download/{idc_index_data.__version__}"
2425

2526
logging.basicConfig(format="%(asctime)s - %(message)s", level=logging.INFO)
2627
logger = logging.getLogger(__name__)
@@ -58,9 +59,8 @@ def client(cls) -> IDCClient:
5859
return cls._client
5960

6061
def __init__(self):
62+
# Read main index file
6163
file_path = idc_index_data.IDC_INDEX_PARQUET_FILEPATH
62-
63-
# Read index file
6464
logger.debug(f"Reading index file v{idc_index_data.__version__}")
6565
self.index = pd.read_parquet(file_path)
6666
# self.index = self.index.astype(str).replace("nan", "")
@@ -69,9 +69,26 @@ def __init__(self):
6969
{"Modality": pd.Series.unique, "series_size_MB": "sum"}
7070
)
7171

72+
self.indices_overview = {
73+
"index": {
74+
"description": "Main index containing one row per DICOM series.",
75+
"installed": True,
76+
"url": None,
77+
},
78+
"sm_index": {
79+
"description": "DICOM Slide Microscopy series-level index.",
80+
"installed": False,
81+
"url": f"{asset_endpoint_url}/sm_index.parquet",
82+
},
83+
"sm_instance_index": {
84+
"description": "DICOM Slide Microscopy instance-level index.",
85+
"installed": False,
86+
"url": f"{asset_endpoint_url}/sm_instance_index.parquet",
87+
},
88+
}
89+
7290
# Lookup s5cmd
7391
self.s5cmdPath = shutil.which("s5cmd")
74-
7592
if self.s5cmdPath is None:
7693
# Workaround to support environment without a properly setup PATH
7794
# See https://github.com/Slicer/Slicer/pull/7587
@@ -80,16 +97,12 @@ def __init__(self):
8097
if str(script).startswith("s5cmd/bin/s5cmd"):
8198
self.s5cmdPath = script.locate().resolve(strict=True)
8299
break
83-
84100
if self.s5cmdPath is None:
85101
raise FileNotFoundError(
86102
"s5cmd executable not found. Please install s5cmd from https://github.com/peak/s5cmd#installation"
87103
)
88-
89104
self.s5cmdPath = str(self.s5cmdPath)
90-
91105
logger.debug(f"Found s5cmd executable: {self.s5cmdPath}")
92-
93106
# ... and check it can be executed
94107
subprocess.check_call([self.s5cmdPath, "--help"], stdout=subprocess.DEVNULL)
95108

@@ -177,6 +190,36 @@ def get_idc_version():
177190
idc_version = Version(idc_index_data.__version__).major
178191
return f"v{idc_version}"
179192

193+
def fetch_index(self, index) -> None:
194+
"""
195+
Downloads requested index.
196+
197+
Args:
198+
index (str): Name of the index to be downloaded.
199+
"""
200+
201+
if index not in self.indices_overview:
202+
logger.error(f"Index {index} is not available and can not be fetched.")
203+
elif self.indices_overview[index]["installed"]:
204+
logger.warning(
205+
f"Index {index} already installed and will not be fetched again."
206+
)
207+
else:
208+
response = requests.get(self.indices_overview[index]["url"], timeout=30)
209+
if response.status_code == 200:
210+
filepath = os.path.join(
211+
idc_index_data.IDC_INDEX_PARQUET_FILEPATH.parents[0],
212+
f"{index}.parquet",
213+
)
214+
with open(filepath, mode="wb") as file:
215+
file.write(response.content)
216+
setattr(self.__class__, index, pd.read_parquet(filepath))
217+
self.indices_overview[index]["installed"] = True
218+
else:
219+
logger.error(
220+
f"Failed to fetch index from URL {self.indices_overview[index]['url']}: {response.status_code}"
221+
)
222+
180223
def get_collections(self):
181224
"""
182225
Returns the collections present in IDC

tests/idcindex.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -483,6 +483,17 @@ def test_prior_version_manifest(self):
483483
with open(temp_manifest_file) as file:
484484
assert len(file.readlines()) == 0
485485

486+
def test_list_indices(self):
487+
i = IDCClient()
488+
assert i.indices_overview # assert that dict was created
489+
490+
def test_fetch_index(self):
491+
i = IDCClient()
492+
assert i.indices_overview["sm_index"]["installed"] is False
493+
i.fetch_index("sm_index")
494+
assert i.indices_overview["sm_index"]["installed"] is True
495+
assert hasattr(i, "sm_index")
496+
486497

487498
if __name__ == "__main__":
488499
unittest.main()

0 commit comments

Comments
 (0)