Skip to content

Commit 99ebbb4

Browse files
committed
RF: Several IO interfaces to LibraryBaseInterface
1 parent b10bd89 commit 99ebbb4

File tree

1 file changed

+35
-60
lines changed

1 file changed

+35
-60
lines changed

nipype/interfaces/io.py

Lines changed: 35 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -29,44 +29,15 @@
2929
from os.path import join, dirname
3030
from warnings import warn
3131

32-
import sqlite3
33-
3432
from .. import config, logging
3533
from ..utils.filemanip import (
3634
copyfile, simplify_list, ensure_list,
37-
get_related_files, related_filetype_sets)
35+
get_related_files)
3836
from ..utils.misc import human_order_sorted, str2bool
3937
from .base import (
4038
TraitedSpec, traits, Str, File, Directory, BaseInterface, InputMultiPath,
41-
isdefined, OutputMultiPath, DynamicTraitedSpec, Undefined, BaseInterfaceInputSpec)
42-
43-
have_pybids = True
44-
try:
45-
import bids
46-
except ImportError:
47-
have_pybids = False
48-
49-
if have_pybids:
50-
try:
51-
from bids import layout as bidslayout
52-
except ImportError:
53-
from bids import grabbids as bidslayout
54-
55-
try:
56-
import pyxnat
57-
except:
58-
pass
59-
60-
try:
61-
import paramiko
62-
except:
63-
pass
64-
65-
try:
66-
import boto
67-
from boto.s3.connection import S3Connection, OrdinaryCallingFormat
68-
except:
69-
pass
39+
isdefined, OutputMultiPath, DynamicTraitedSpec, Undefined, BaseInterfaceInputSpec,
40+
LibraryBaseInterface)
7041

7142
iflogger = logging.getLogger('nipype.interface')
7243

@@ -536,8 +507,6 @@ def _fetch_bucket(self, bucket_name):
536507
'''
537508

538509
# Import packages
539-
import logging
540-
541510
try:
542511
import boto3
543512
import botocore
@@ -607,7 +576,6 @@ def _upload_to_s3(self, bucket, src, dst):
607576

608577
# Import packages
609578
import hashlib
610-
import logging
611579
import os
612580

613581
from botocore.exceptions import ClientError
@@ -849,7 +817,7 @@ class S3DataGrabberInputSpec(DynamicTraitedSpec, BaseInterfaceInputSpec):
849817
desc='Information to plug into template')
850818

851819

852-
class S3DataGrabber(IOBase):
820+
class S3DataGrabber(LibraryBaseInterface, IOBase):
853821
""" Generic datagrabber module that wraps around glob in an
854822
intelligent way for neuroimaging tasks to grab files from
855823
Amazon S3
@@ -865,6 +833,8 @@ class S3DataGrabber(IOBase):
865833
input_spec = S3DataGrabberInputSpec
866834
output_spec = DynamicTraitedSpec
867835
_always_run = True
836+
_pkg = 'boto'
837+
imports = ('botocore',)
868838

869839
def __init__(self, infields=None, outfields=None, **kwargs):
870840
"""
@@ -919,6 +889,7 @@ def _add_output_traits(self, base):
919889
def _list_outputs(self):
920890
# infields are mandatory, however I could not figure out how to set 'mandatory' flag dynamically
921891
# hence manual check
892+
import boto
922893
if self._infields:
923894
for key in self._infields:
924895
value = getattr(self.inputs, key)
@@ -1035,6 +1006,7 @@ def _list_outputs(self):
10351006
# Takes an s3 address and downloads the file to a local
10361007
# directory, returning the local path.
10371008
def s3tolocal(self, s3path, bkt):
1009+
import boto
10381010
# path formatting
10391011
if not os.path.split(self.inputs.local_directory)[1] == '':
10401012
self.inputs.local_directory += '/'
@@ -1817,7 +1789,7 @@ class XNATSourceInputSpec(DynamicTraitedSpec, BaseInterfaceInputSpec):
18171789
cache_dir = Directory(desc='Cache directory')
18181790

18191791

1820-
class XNATSource(IOBase):
1792+
class XNATSource(LibraryBaseInterface, IOBase):
18211793
""" Generic XNATSource module that wraps around the pyxnat module in
18221794
an intelligent way for neuroimaging tasks to grab files and data
18231795
from an XNAT server.
@@ -1852,6 +1824,7 @@ class XNATSource(IOBase):
18521824
"""
18531825
input_spec = XNATSourceInputSpec
18541826
output_spec = DynamicTraitedSpec
1827+
_pkg = 'pyxnat'
18551828

18561829
def __init__(self, infields=None, outfields=None, **kwargs):
18571830
"""
@@ -1901,6 +1874,7 @@ def _add_output_traits(self, base):
19011874
def _list_outputs(self):
19021875
# infields are mandatory, however I could not figure out
19031876
# how to set 'mandatory' flag dynamically, hence manual check
1877+
import pyxnat
19041878

19051879
cache_dir = self.inputs.cache_dir or tempfile.gettempdir()
19061880

@@ -2034,16 +2008,18 @@ def __setattr__(self, key, value):
20342008
super(XNATSinkInputSpec, self).__setattr__(key, value)
20352009

20362010

2037-
class XNATSink(IOBase):
2011+
class XNATSink(LibraryBaseInterface, IOBase):
20382012
""" Generic datasink module that takes a directory containing a
20392013
list of nifti files and provides a set of structured output
20402014
fields.
20412015
"""
20422016
input_spec = XNATSinkInputSpec
2017+
_pkg = 'xnat'
20432018

20442019
def _list_outputs(self):
20452020
"""Execute this module.
20462021
"""
2022+
import pyxnat
20472023

20482024
# setup XNAT connection
20492025
cache_dir = self.inputs.cache_dir or tempfile.gettempdir()
@@ -2202,7 +2178,7 @@ class SQLiteSinkInputSpec(DynamicTraitedSpec, BaseInterfaceInputSpec):
22022178
table_name = Str(mandatory=True)
22032179

22042180

2205-
class SQLiteSink(IOBase):
2181+
class SQLiteSink(LibraryBaseInterface, IOBase):
22062182
""" Very simple frontend for storing values into SQLite database.
22072183
22082184
.. warning::
@@ -2222,6 +2198,7 @@ class SQLiteSink(IOBase):
22222198
22232199
"""
22242200
input_spec = SQLiteSinkInputSpec
2201+
_pkg = 'sqlite3'
22252202

22262203
def __init__(self, input_names, **inputs):
22272204

@@ -2233,6 +2210,7 @@ def __init__(self, input_names, **inputs):
22332210
def _list_outputs(self):
22342211
"""Execute this module.
22352212
"""
2213+
import sqlite3
22362214
conn = sqlite3.connect(
22372215
self.inputs.database_file, check_same_thread=False)
22382216
c = conn.cursor()
@@ -2333,7 +2311,7 @@ class SSHDataGrabberInputSpec(DataGrabberInputSpec):
23332311
desc='If set SSH commands will be logged to the given file')
23342312

23352313

2336-
class SSHDataGrabber(DataGrabber):
2314+
class SSHDataGrabber(LibraryBaseInterface, DataGrabber):
23372315
""" Extension of DataGrabber module that downloads the file list and
23382316
optionally the files from a SSH server. The SSH operation must
23392317
not need user and password so an SSH agent must be active in
@@ -2397,6 +2375,7 @@ class SSHDataGrabber(DataGrabber):
23972375
input_spec = SSHDataGrabberInputSpec
23982376
output_spec = DynamicTraitedSpec
23992377
_always_run = False
2378+
_pkg = 'paramiko'
24002379

24012380
def __init__(self, infields=None, outfields=None, **kwargs):
24022381
"""
@@ -2411,11 +2390,6 @@ def __init__(self, infields=None, outfields=None, **kwargs):
24112390
See class examples for usage
24122391
24132392
"""
2414-
try:
2415-
paramiko
2416-
except NameError:
2417-
warn("The library paramiko needs to be installed"
2418-
" for this module to run.")
24192393
if not outfields:
24202394
outfields = ['outfiles']
24212395
kwargs = kwargs.copy()
@@ -2490,11 +2464,7 @@ def _get_files_over_ssh(self, template):
24902464
return outfiles
24912465

24922466
def _list_outputs(self):
2493-
try:
2494-
paramiko
2495-
except NameError:
2496-
raise ImportError("The library paramiko needs to be installed"
2497-
" for this module to run.")
2467+
import paramiko
24982468

24992469
if len(self.inputs.ssh_log_to_file) > 0:
25002470
paramiko.util.log_to_file(self.inputs.ssh_log_to_file)
@@ -2574,6 +2544,7 @@ def _list_outputs(self):
25742544
return outputs
25752545

25762546
def _get_ssh_client(self):
2547+
import paramiko
25772548
config = paramiko.SSHConfig()
25782549
config.parse(open(os.path.expanduser('~/.ssh/config')))
25792550
host = config.lookup(self.inputs.hostname)
@@ -2765,7 +2736,7 @@ class BIDSDataGrabberInputSpec(DynamicTraitedSpec):
27652736
'ignore derivatives/, sourcedata/, etc.)')
27662737

27672738

2768-
class BIDSDataGrabber(IOBase):
2739+
class BIDSDataGrabber(LibraryBaseInterface, IOBase):
27692740

27702741
""" BIDS datagrabber module that wraps around pybids to allow arbitrary
27712742
querying of BIDS datasets.
@@ -2798,6 +2769,7 @@ class BIDSDataGrabber(IOBase):
27982769
input_spec = BIDSDataGrabberInputSpec
27992770
output_spec = DynamicTraitedSpec
28002771
_always_run = True
2772+
_pkg = 'bids'
28012773

28022774
def __init__(self, infields=None, **kwargs):
28032775
"""
@@ -2815,7 +2787,12 @@ def __init__(self, infields=None, **kwargs):
28152787
}
28162788

28172789
# If infields is empty, use all BIDS entities
2818-
if infields is None and have_pybids:
2790+
if infields is None:
2791+
# Version resilience
2792+
try:
2793+
from bids import layout as bidslayout
2794+
except ImportError:
2795+
from bids import grabbids as bidslayout
28192796
bids_config = join(dirname(bidslayout.__file__), 'config', 'bids.json')
28202797
bids_config = json.load(open(bids_config, 'r'))
28212798
infields = [i['name'] for i in bids_config['entities']]
@@ -2830,18 +2807,16 @@ def __init__(self, infields=None, **kwargs):
28302807

28312808
self.inputs.trait_set(trait_change_notify=False, **undefined_traits)
28322809

2833-
def _run_interface(self, runtime):
2834-
if not have_pybids:
2835-
raise ImportError(
2836-
"The BIDSEventsGrabber interface requires pybids."
2837-
" Please make sure it is installed.")
2838-
return runtime
2839-
28402810
def _list_outputs(self):
2811+
# Version resilience
2812+
try:
2813+
from bids import BIDSLayout
2814+
except ImportError:
2815+
from bids.grabbids import BIDSLayout
28412816
exclude = None
28422817
if self.inputs.strict:
28432818
exclude = ['derivatives/', 'code/', 'sourcedata/']
2844-
layout = bidslayout.BIDSLayout(self.inputs.base_dir, exclude=exclude)
2819+
layout = BIDSLayout(self.inputs.base_dir, exclude=exclude)
28452820

28462821
# If infield is not given nm input value, silently ignore
28472822
filters = {}

0 commit comments

Comments
 (0)