Skip to content

Commit 8bdeed1

Browse files
committed
changing the way how the zenodo file is downloaded
1 parent 2a2c3d8 commit 8bdeed1

File tree

2 files changed

+43
-33
lines changed

2 files changed

+43
-33
lines changed

pydra/engine/boutiques.py

Lines changed: 39 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import typing as ty
22
import json
33
import attr
4+
from urllib.request import urlretrieve
45
import subprocess as sp
56
import os
67
from pathlib import Path
@@ -25,7 +26,7 @@ class BoshTask(ShellCommandTask):
2526

2627
def __init__(
2728
self,
28-
zenodo=None,
29+
zenodo_id=None,
2930
bosh_file=None,
3031
audit_flags: AuditFlag = AuditFlag.NONE,
3132
cache_dir=None,
@@ -43,7 +44,7 @@ def __init__(
4344
4445
Parameters
4546
----------
46-
zenodo: :obj: str
47+
zenodo_id: :obj: str
4748
Zenodo ID
4849
bosh_file : : str
4950
json file with the boutiques descriptors
@@ -65,16 +66,19 @@ def __init__(
6566
TODO
6667
6768
"""
68-
if (bosh_file and zenodo) or not (bosh_file or zenodo):
69-
raise Exception("either bosh or zenodo has to be specified")
70-
elif zenodo:
71-
bosh_file = self._download_spec(zenodo)
69+
self.cache_dir = cache_dir
70+
if (bosh_file and zenodo_id) or not (bosh_file or zenodo_id):
71+
raise Exception("either bosh or zenodo_id has to be specified")
72+
elif zenodo_id:
73+
self.bosh_file = self._download_spec(zenodo_id)
74+
else:
75+
self.bosh_file = bosh_file
7276

7377
# retry logic - an error on travis is raised randomly, not able to reproduce
7478
tries, tries_max = 0, 7
7579
while tries < tries_max:
7680
try:
77-
with bosh_file.open() as f:
81+
with self.bosh_file.open() as f:
7882
self.bosh_spec = json.load(f)
7983
break
8084
except json.decoder.JSONDecodeError:
@@ -88,37 +92,42 @@ def __init__(
8892
if output_spec is None:
8993
output_spec = self._prepare_output_spec()
9094
self.output_spec = output_spec
91-
self.bindings = []
95+
self.bindings = ["-v", f"{self.bosh_file.parent}:{self.bosh_file.parent}:ro"]
9296

9397
super(BoshTask, self).__init__(
9498
name=name,
9599
input_spec=input_spec,
96100
output_spec=output_spec,
97-
executable=["bosh", "exec", "launch", str(bosh_file)],
101+
executable=["bosh", "exec", "launch"],
98102
args=["-s"],
99103
audit_flags=audit_flags,
100104
messengers=messengers,
101105
messenger_args=messenger_args,
102-
cache_dir=cache_dir,
106+
cache_dir=self.cache_dir,
103107
strip=strip,
104108
rerun=rerun,
105109
**kwargs,
106110
)
107111
self.strip = strip
108112

109-
def _download_spec(self, zenodo):
110-
""" usind bosh pull to download the zenodo file"""
111-
spec_file = (
112-
Path(os.environ["HOME"])
113-
/ ".cache/boutiques/production"
114-
/ (zenodo.replace(".", "-") + ".json")
115-
)
116-
for i in range(3):
117-
if not spec_file.exists():
118-
sp.run(["bosh", "pull", zenodo])
119-
if not spec_file.exists():
120-
raise Exception(f"can't pull zenodo file {zenodo}")
121-
return spec_file
113+
def _download_spec(self, zenodo_id):
114+
"""
115+
usind boutiques Searcher to find url of zenodo file for a specific id,
116+
and download the file to self.cache_dir
117+
"""
118+
from boutiques.searcher import Searcher
119+
120+
searcher = Searcher(zenodo_id, exact_match=True)
121+
hits = searcher.zenodo_search().json()["hits"]["hits"]
122+
if len(hits) == 0:
123+
raise Exception(f"can't find zenodo spec for {zenodo_id}")
124+
elif len(hits) > 1:
125+
raise Exception(f"too many hits for {zenodo_id}")
126+
else:
127+
zenodo_url = hits[0]["files"][0]["links"]["self"]
128+
zenodo_file = self.cache_dir / f"zenodo.{zenodo_id}.json"
129+
urlretrieve(zenodo_url, zenodo_file)
130+
return zenodo_file
122131

123132
def _prepare_input_spec(self):
124133
""" creating input spec from the zenodo file"""
@@ -175,13 +184,17 @@ def _prepare_output_spec(self):
175184

176185
def _command_args_single(self, state_ind, ind=None):
177186
"""Get command line arguments for a single state"""
178-
input_filepath = self._input_file(state_ind=state_ind, ind=ind)
187+
input_filepath = self._bosh_invocation_file(state_ind=state_ind, ind=ind)
179188
cmd_list = (
180-
self.inputs.executable + [input_filepath] + self.inputs.args + self.bindings
189+
self.inputs.executable
190+
+ [str(self.bosh_file), input_filepath]
191+
+ self.inputs.args
192+
+ self.bindings
181193
)
182194
return cmd_list
183195

184-
def _input_file(self, state_ind, ind=None):
196+
def _bosh_invocation_file(self, state_ind, ind=None):
197+
"""creating bosh invocation file - json file with inputs values"""
185198
input_json = {}
186199
for f in attr_fields(self.inputs):
187200
if f.name in ["executable", "args"]:

pydra/engine/tests/test_boutiques.py

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
@pytest.mark.parametrize("plugin", Plugins)
3333
def test_boutiques_1(maskfile, plugin, results_function):
3434
""" simple task to run fsl.bet using BoshTask"""
35-
btask = BoshTask(name="NA", zenodo="zenodo.1482743")
35+
btask = BoshTask(name="NA", zenodo_id="1482743")
3636
btask.inputs.infile = Infile
3737
btask.inputs.maskfile = maskfile
3838
res = results_function(btask, plugin)
@@ -62,7 +62,7 @@ def test_boutiques_wf_1(maskfile, plugin):
6262
wf.add(
6363
BoshTask(
6464
name="bet",
65-
zenodo="zenodo.1482743",
65+
zenodo_id="1482743",
6666
infile=wf.lzin.infile,
6767
maskfile=wf.lzin.maskfile,
6868
)
@@ -93,17 +93,14 @@ def test_boutiques_wf_2(maskfile, plugin):
9393
wf.add(
9494
BoshTask(
9595
name="bet",
96-
zenodo="zenodo.1482743",
96+
zenodo_id="1482743",
9797
infile=wf.lzin.infile,
9898
maskfile=wf.lzin.maskfile,
9999
)
100100
)
101101
wf.add(
102102
BoshTask(
103-
name="stat",
104-
zenodo="zenodo.3240521",
105-
input_file=wf.bet.lzout.outfile,
106-
v=True,
103+
name="stat", zenodo_id="3240521", input_file=wf.bet.lzout.outfile, v=True
107104
)
108105
)
109106
wf.add(ShellCommandTask(name="cat", executable="cat", args=wf.stat.lzout.output))

0 commit comments

Comments
 (0)