2929from os .path import join , dirname
3030from warnings import warn
3131
32- import sqlite3
33-
3432from .. import config , logging
3533from ..utils .filemanip import (
3634 copyfile , simplify_list , ensure_list ,
37- get_related_files , related_filetype_sets )
35+ get_related_files )
3836from ..utils .misc import human_order_sorted , str2bool
3937from .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
7142iflogger = 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