Skip to content

Commit 9d85950

Browse files
author
Jermiah
committed
lint nbia class and add baseURL to nbiaEndpoints
1 parent a229025 commit 9d85950

File tree

2 files changed

+66
-86
lines changed

2 files changed

+66
-86
lines changed

src/nbiatoolkit/nbia.py

Lines changed: 64 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -6,74 +6,63 @@
66

77
import requests
88
from requests.exceptions import JSONDecodeError as JSONDecodeError
9-
import io, zipfile, os
9+
import io
10+
import zipfile
1011

1112

1213
class NBIAClient:
1314
"""
1415
TODO:: Add docstring
15-
FIXME:: logger prints duplicate logs if you instantiate the class more than once
16+
FIXME:: logger prints duplicate logs if you instantiate the class more
17+
than once
1618
"""
17-
18-
def __init__(self,
19-
username: str = "nbia_guest",
19+
20+
def __init__(self,
21+
username: str = "nbia_guest",
2022
password: str = "",
2123
log_level: str = "INFO"
2224
) -> None:
23-
25+
2426
# Setup logger
2527
self.logger = setup_logger(
26-
name = "NBIAClient",
27-
console_logging=True,
28-
log_level=log_level,
29-
log_file = None)
30-
28+
name="NBIAClient", console_logging=True,
29+
log_level=log_level, log_file=None)
30+
3131
# Setup OAuth2 client
32-
self.logger.debug("Setting up OAuth2 client... with username %s", username)
32+
self.logger.debug(
33+
"Setting up OAuth2 client... with username %s", username)
34+
3335
self._oauth2_client = OAuth2(username=username, password=password)
3436
self.api_headers = self._oauth2_client.getToken()
35-
37+
3638
def query_api(self, endpoint: NBIA_ENDPOINTS, params: dict = {}) -> dict:
37-
base_url = "https://services.cancerimagingarchive.net/nbia-api/services/"
38-
query_url = base_url + endpoint.value
39-
39+
40+
query_url = NBIA_ENDPOINTS.BASE_URL.value + endpoint.value
41+
4042
self.logger.debug("Querying API endpoint: %s", query_url)
41-
# self.logger.debug("API headers: %s", (self._createDebugURL(endpoint, params)))
42-
4343
try:
4444
response = requests.get(
45-
url=query_url,
45+
url=query_url,
4646
headers=self.api_headers,
4747
params=params
4848
)
49-
# Check if response is likely to be JSON
5049
if response.headers.get('Content-Type') == 'application/json':
5150
response_data = response.json()
5251
else:
5352
# If response is binary data, return raw response
5453
response_data = response.content
5554
except JSONDecodeError as j:
56-
if (response.text==""):
55+
if (response.text == ""):
5756
self.logger.error("Response text is empty.")
5857
return response
5958
self.logger.error("Error parsing response as JSON: %s", j)
6059
self.logger.debug("Response: %s", response.text)
6160
except Exception as e:
6261
self.logger.error("Error querying API: %s", e)
6362
raise e
64-
63+
6564
return response_data
66-
67-
def _createDebugURL(self, endpoint, params):
68-
auth = "'Authorization:" + self.api_headers["Authorization"] + "' -k "
69-
base_url = "'https://services.cancerimagingarchive.net/nbia-api/services/"
70-
query_url = auth + base_url + endpoint.value
71-
debug_url = query_url + "?"
72-
for key, value in params.items():
73-
debug_url += f"{key}={value}&"
74-
debug_url = debug_url[:-1] + "'"
75-
return debug_url
76-
65+
7766
def getCollections(self) -> list:
7867
response = self.query_api(NBIA_ENDPOINTS.GET_COLLECTIONS)
7968
collections = []
@@ -86,41 +75,44 @@ def getCollectionPatientCount(self) -> list:
8675
patientCount = []
8776
for collection in response:
8877
patientCount.append({
89-
"Collection": collection["criteria"],
78+
"Collection": collection["criteria"],
9079
"PatientCount": collection["count"]})
91-
80+
9281
return patientCount
93-
94-
def getBodyPartCounts(self, collection: str = "", modality: str = "") -> list:
82+
83+
def getBodyPartCounts(
84+
self, collection: str = "", modality: str = "") -> list:
85+
9586
PARAMS = {}
9687
if collection:
9788
PARAMS["Collection"] = collection
9889
if modality:
9990
PARAMS["Modality"] = modality
100-
response = self.query_api(
101-
endpoint = NBIA_ENDPOINTS.GET_BODY_PART_PATIENT_COUNT,
102-
params = PARAMS)
103-
91+
response = self.query_api(
92+
endpoint=NBIA_ENDPOINTS.GET_BODY_PART_PATIENT_COUNT,
93+
params=PARAMS)
94+
10495
bodyparts=[]
10596
for bodypart in response:
10697
bodyparts.append({
107-
"BodyPartExamined": bodypart["criteria"],
98+
"BodyPartExamined": bodypart["criteria"],
10899
"Count": bodypart["count"]})
109100
return bodyparts
110101

111102
def getPatients(self, collection: str, modality: str) -> list:
112103
assert collection is not None
113104
assert modality is not None
114-
115-
PARAMS = {"Collection": collection,"Modality": modality}
105+
106+
PARAMS = {"Collection": collection, "Modality": modality}
116107
response = self.query_api(
117-
endpoint = NBIA_ENDPOINTS.GET_PATIENT_BY_COLLECTION_AND_MODALITY,
118-
params = PARAMS)
108+
endpoint=NBIA_ENDPOINTS.GET_PATIENT_BY_COLLECTION_AND_MODALITY,
109+
params=PARAMS)
110+
119111
patientList = [_["PatientId"] for _ in response]
120112
return patientList
121113

122114
def getSeries(self,
123-
Collection: str = "",
115+
Collection: str = "",
124116
PatientID: str = "",
125117
StudyInstanceUID: str = "",
126118
Modality: str = "",
@@ -129,75 +121,63 @@ def getSeries(self,
129121
ManufacturerModelName: str = "",
130122
Manufacturer: str = "",
131123
) -> list:
132-
124+
133125
params = dict()
134-
126+
135127
for key, value in locals().items():
136128
if (value != "") and (key != "self"):
137129
params[key] = value
138-
139-
130+
131+
140132
response = self.query_api(
141133
endpoint = NBIA_ENDPOINTS.GET_SERIES,
142134
params = params)
143-
135+
144136
return response
145-
146-
137+
138+
147139
def downloadSeries(
148-
self, SeriesInstanceUID: str, downloadDir: str,
140+
self, SeriesInstanceUID: str, downloadDir: str,
149141
filePattern: str = '%PatientName/%StudyDescription-%StudyDate/%SeriesNumber-%SeriesDescription-%SeriesInstanceUID/%InstanceNumber.dcm',
150142
overwrite: bool = False
151143
) -> bool:
152-
144+
153145
# create temporary directory
154146
from tempfile import TemporaryDirectory
155-
147+
156148
params = dict()
157149
params["SeriesInstanceUID"] = SeriesInstanceUID
158-
150+
159151
response = self.query_api(
160-
endpoint = NBIA_ENDPOINTS.DOWNLOAD_SERIES,
161-
params = params)
162-
152+
endpoint=NBIA_ENDPOINTS.DOWNLOAD_SERIES,
153+
params=params)
154+
163155
if not isinstance(response, bytes):
164156
# Handle the case where the expected binary data is not received
165157
# Log error or raise an exception
166158
return False
167-
159+
168160
file = zipfile.ZipFile(io.BytesIO(response))
169-
161+
170162
with TemporaryDirectory() as tempDir:
171163
file.extractall(path=tempDir)
172-
assert validateMD5(seriesDir=tempDir) == True
164+
if not validateMD5(seriesDir=tempDir) and not overwrite:
165+
self.logger.error("MD5 validation failed. Exiting...")
166+
return False
173167

174168
# Create an instance of DICOMSorter with the desired target pattern
175169
sorter = DICOMSorter(
176-
sourceDir = tempDir,
170+
sourceDir=tempDir,
177171
destinationDir=downloadDir,
178172
targetPattern=filePattern,
179173
truncateUID=True,
180174
sanitizeFilename=True
181175
)
182-
176+
183177
sorter.sortDICOMFiles(option="move", overwrite=overwrite)
184178

185-
186-
187-
# if isinstance(response, bytes):
188-
# file = zipfile.ZipFile(io.BytesIO(response))
189-
# seriesDir = os.path.join(downloadDir, SeriesInstanceUID)
190-
# file.extractall(path=seriesDir)
191-
192-
# validateMD5(seriesDir=seriesDir)
193-
# else:
194-
# # Handle the case where the expected binary data is not received
195-
# # Log error or raise an exception
196-
# pass
197-
198179
return True
199-
200-
201-
202-
203-
180+
181+
182+
183+

src/nbiatoolkit/utils/nbia_endpoints.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
from enum import Enum, auto
2-
31
from enum import Enum
42

53
class NBIA_ENDPOINTS(Enum):
64
"""
75
This enum class defines the NBIA endpoints used in the NBIA toolkit.
86
"""
7+
BASE_URL = 'https://services.cancerimagingarchive.net/nbia-api/services/'
8+
99
GET_COLLECTION_PATIENT_COUNT = 'getCollectionValuesAndCounts'
1010
GET_COLLECTIONS = 'v2/getCollectionValues'
1111
GET_BODY_PART_PATIENT_COUNT = 'getBodyPartValuesAndCounts'

0 commit comments

Comments
 (0)