Skip to content

Commit afb6330

Browse files
committed
updated plugin to use auth token
1 parent 51a90c8 commit afb6330

5 files changed

Lines changed: 72 additions & 58 deletions

File tree

base_client.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
from abc import ABC, abstractmethod
22

33
class BaseClient(ABC):
4-
@abstractmethod
5-
def create_con(self, params: dict):
6-
pass
74

85
@abstractmethod
96
def pacs_pull(self):

chrisClient.py

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
### Python Chris Client Implementation ###
22

33
from base_client import BaseClient
4-
from chrisclient import client
5-
from chris_pacs_service import PACSClient
64
import json
7-
import time
5+
import requests
86
from loguru import logger
97
import sys
108
from pipeline import Pipeline
@@ -22,23 +20,29 @@
2220
logger.add(sys.stderr, format=logger_format)
2321

2422
class ChrisClient(BaseClient):
25-
def __init__(self, url: str, username: str, password: str):
26-
self.cl = client.Client(url, username, password)
27-
self.cl.pacs_series_url = f"{url}/pacs/series/"
28-
self.req = PACSClient(self.cl.pacs_series_url,username,password)
29-
30-
def create_con(self,params:dict):
31-
return self.cl
23+
def __init__(self, url: str, token: str):
24+
self.api_base = url.rstrip('/')
25+
self.auth = token
26+
self.headers = {"Content-Type": "application/json", "Authorization": f"Token {token}"}
27+
self.pacs_series_url = f"{url}/pacs/series/"
3228

3329
def health_check(self):
34-
return self.cl.get_chris_instance()
30+
endpoint = f"{self.api_base}/"
31+
response = requests.request("GET", endpoint, headers=self.headers, timeout=30)
32+
33+
response.raise_for_status()
34+
35+
try:
36+
return response.json()
37+
except ValueError:
38+
return response.text
3539

3640
def pacs_pull(self):
3741
pass
3842
def pacs_push(self):
3943
pass
4044
def anonymize(self, params: dict, pv_id: int):
41-
pipe = Pipeline(self.cl)
45+
pipe = Pipeline(self.api_base, self.auth)
4246
plugin_params = {
4347
'PACS-query': {
4448
"PACSurl": params["pull"]["url"],
@@ -52,9 +56,7 @@ def anonymize(self, params: dict, pv_id: int):
5256
"copyInputFile": True
5357
},
5458
'verify-registration': {
55-
"CUBEurl": self.cl.url,
56-
"CUBEuser": self.cl.username,
57-
"CUBEpassword": self.cl.password,
59+
"CUBEurl": self.api_base,
5860
"inputJSONfile": "search_results.json",
5961
"folderName": params["push"]["Folder name"],
6062
"neuroDicomLocation": params["push"]["Dicom path"],

chris_pacs_service.py

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
from chrisclient import request
33
from loguru import logger
44
import sys
5+
from requests.exceptions import RequestException, Timeout, HTTPError
6+
from tenacity import retry, wait_exponential, stop_after_attempt, retry_if_exception_type
7+
from urllib.parse import urlencode
58

69
LOG = logger.debug
710

@@ -18,19 +21,44 @@
1821

1922

2023
class PACSClient(object):
21-
def __init__(self, url: str, username: str, password: str):
22-
self.cl = request.Request(username, password)
24+
def __init__(self, url: str, token: str):
25+
self.api_base = url.rstrip('/')
26+
self.auth = token
27+
self.headers = {"Content-Type": "application/json"}
2328
self.pacs_series_search_url = f"{url}search/"
2429

30+
# --------------------------
31+
# Retryable request handler
32+
# --------------------------
33+
@retry(
34+
retry=retry_if_exception_type((RequestException, Timeout, HTTPError)),
35+
wait=wait_exponential(multiplier=1, min=2, max=10),
36+
stop=stop_after_attempt(5),
37+
reraise=True
38+
)
39+
def make_request(self, method, endpoint, **kwargs):
40+
response = requests.request(method, endpoint, headers=self.headers, auth=self.auth, timeout=30, **kwargs)
41+
response.raise_for_status()
42+
43+
try:
44+
return response.json()
45+
except ValueError:
46+
return response.text
47+
2548

2649
def get_pacs_files(self, params: dict):
50+
"""
51+
Get PACS folder path
52+
"""
2753
l_dir_path = set()
28-
resp = self.cl.get(self.pacs_series_search_url,params)
29-
LOG(resp)
30-
for item in resp.items:
31-
for link in item.links:
32-
folder = self.cl.get(link.href)
33-
for item_folder in folder.items:
34-
path = item_folder.data.path.value
35-
l_dir_path.add(path)
54+
query_string = urlencode(params)
55+
response = self.make_request("GET", f"{self.pacs_series_search_url}?{query_string}")
56+
for item in response.get("collection", {}).get("items", []):
57+
for link in item.get("links", []):
58+
folder = self.make_request("GET",link.get("href"))
59+
for item_folder in folder.get("collection", {}).get("items", []):
60+
for field in item_folder.get("data", []):
61+
if field.get("name") == "path":
62+
l_dir_path.add(field.get("value"))
63+
3664
return ','.join(l_dir_path)

dypxFlow.py

Lines changed: 12 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,10 @@
66
from loguru import logger
77
from chris_plugin import chris_plugin, PathMapper
88
import pandas as pd
9-
import json
10-
import itertools
119
from collections import ChainMap
1210
from chrisClient import ChrisClient
1311
import pfdcm
1412
import sys
15-
import time
1613
import os
1714
import concurrent.futures
1815

@@ -29,7 +26,7 @@
2926
logger.remove()
3027
logger.add(sys.stderr, format=logger_format)
3128

32-
__version__ = '1.0.7'
29+
__version__ = '1.0.8'
3330

3431
DISPLAY_TITLE = r"""
3532
_ _ ______ _
@@ -68,20 +65,15 @@
6865
help="CUBE URL. Please include api version in the url endpoint."
6966
)
7067
parser.add_argument(
71-
"--CUBEuser",
72-
default="chris",
73-
help="CUBE/ChRIS username"
68+
"--CUBEtoken",
69+
default="",
70+
help="CUBE/ChRIS user token"
7471
)
7572
parser.add_argument(
7673
"--maxThreads",
7774
default=4,
7875
help="max number of parallel threads"
7976
)
80-
parser.add_argument(
81-
"--CUBEpassword",
82-
default="chris1234",
83-
help="CUBE/ChRIS password"
84-
)
8577
parser.add_argument(
8678
"--thread",
8779
help="use threading to branch in parallel",
@@ -97,7 +89,7 @@
9789
default=False,
9890
)
9991
parser.add_argument(
100-
'--PACSurl',
92+
'--PFDCMurl',
10193
default='',
10294
type=str,
10395
help='endpoint URL of pfdcm. Please include api version in the url endpoint.'
@@ -108,11 +100,6 @@
108100
type=str,
109101
help='name of the PACS'
110102
)
111-
parser.add_argument(
112-
"--pftelDB",
113-
help="an optional pftel telemetry logger, of form '<pftelURL>/api/v1/<object>/<collection>/<event>'",
114-
default="",
115-
)
116103

117104
def skip_condition(row):
118105
# Skip rows where starting column says 'no'
@@ -172,7 +159,7 @@ def main(options: Namespace, inputdir: Path, outputdir: Path):
172159
results: Iterator = executor.map(lambda t: register_and_anonymize(options, t, options.wait), l_job)
173160

174161
# Wait for all tasks to complete
175-
# executor.shutdown(wait=True)
162+
executor.shutdown(wait=True)
176163
else:
177164
for d_job in l_job:
178165
response = register_and_anonymize(options, d_job)
@@ -200,12 +187,12 @@ def register_and_anonymize(options: Namespace, d_job: dict, wait: bool = False):
200187
"""
201188
resp = {}
202189
d_job["pull"] = {
203-
"url": options.PACSurl,
190+
"url": options.PFDCMurl,
204191
"pacs": options.PACSname
205192
}
206193
LOG(d_job)
207194
if not d_job["push"]["status"]:
208-
cube_con = ChrisClient(options.CUBEurl, options.CUBEuser, options.CUBEpassword)
195+
cube_con = ChrisClient(options.CUBEurl, options.CUBEtoken)
209196
d_ret = cube_con.anonymize(d_job, options.pluginInstanceID)
210197
else:
211198
d_ret = d_job["push"]
@@ -226,14 +213,16 @@ def health_check(options) -> bool:
226213
return False
227214
try:
228215
# create connection object
229-
cube_con = ChrisClient(options.CUBEurl, options.CUBEuser, options.CUBEpassword)
216+
if not options.CUBEtoken:
217+
options.CUBEtoken = os.environ['CHRIS_USER_TOKEN']
218+
cube_con = ChrisClient(options.CUBEurl, options.CUBEtoken)
230219
cube_con.health_check()
231220
except Exception as ex:
232221
LOG(ex)
233222
return False
234223
try:
235224
# pfdcm health check
236-
pfdcm.health_check(options.PACSurl)
225+
pfdcm.health_check(options.PFDCMurl)
237226
except Exception as ex:
238227
LOG(ex)
239228
return False

pipeline.py

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -61,11 +61,9 @@ def compute_workflow_nodes_info(pipeline_default_parameters: list[dict], include
6161

6262

6363
class Pipeline:
64-
def __init__(self, client):
65-
self.cl = client
66-
self.api_base = self.cl.url.rstrip('/')
67-
self.auth = HTTPBasicAuth(self.cl.username, self.cl.password)
68-
self.headers = {"Content-Type": "application/json"}
64+
def __init__(self, url: str, token: str):
65+
self.api_base = url.rstrip('/')
66+
self.headers = {"Content-Type": "application/json", "Authorization": f"Token {token}"}
6967

7068
# --------------------------
7169
# Retryable request handler
@@ -78,7 +76,7 @@ def __init__(self, client):
7876
)
7977
def make_request(self, method: str, endpoint: str, **kwargs):
8078
url = f"{self.api_base}{endpoint}"
81-
response = requests.request(method, url, headers=self.headers, auth=self.auth, timeout=30, **kwargs)
79+
response = requests.request(method, url, headers=self.headers, timeout=30, **kwargs)
8280
response.raise_for_status()
8381

8482
try:
@@ -88,7 +86,7 @@ def make_request(self, method: str, endpoint: str, **kwargs):
8886

8987
def post_request(self, endpoint: str, **kwargs):
9088
url = f"{self.api_base}{endpoint}"
91-
response = requests.request("POST", url, headers=self.headers, auth=self.auth, timeout=30, **kwargs)
89+
response = requests.request("POST", url, headers=self.headers, timeout=30, **kwargs)
9290
response.raise_for_status()
9391

9492
try:

0 commit comments

Comments
 (0)