Skip to content

Commit 2410411

Browse files
committed
Merge pull request #1020 from oesteban/enh/JSONFileInterface
ENH: IO interfaces to JSON files
2 parents 9b4e5d3 + 273fec0 commit 2410411

File tree

5 files changed

+168
-0
lines changed

5 files changed

+168
-0
lines changed

CHANGES

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
Next release
22
============
33

4+
* ENH: New io interfaces for JSON files reading/writing (https://github.com/nipy/nipype/pull/1020)
45
* ENH: Enhanced openfmri script to support freesurfer linkage (https://github.com/nipy/nipype/pull/1037)
56
* BUG: matplotlib is supposed to be optional (https://github.com/nipy/nipype/pull/1003)
67
* FIX: Fix split_filename behaviour when path has no file component (https://github.com/nipy/nipype/pull/1035)

nipype/interfaces/io.py

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1801,3 +1801,118 @@ def _get_ssh_client(self):
18011801
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
18021802
client.connect(host['hostname'], username=host['user'], sock=proxy)
18031803
return client
1804+
1805+
1806+
class JSONFileGrabberInputSpec(DynamicTraitedSpec, BaseInterfaceInputSpec):
1807+
in_file = File(exists=True, mandatory=True,
1808+
desc='JSON source file')
1809+
1810+
1811+
class JSONFileGrabber(IOBase):
1812+
1813+
"""
1814+
Datagrabber interface that loads a json file and generates an output for
1815+
every first-level object
1816+
1817+
Example
1818+
-------
1819+
1820+
>>> from nipype.interfaces.io import JSONFileGrabber
1821+
>>> jsonSource = JSONFileGrabber()
1822+
>>> jsonSource.inputs.in_file = 'jsongrabber.txt'
1823+
>>> res = jsonSource.run()
1824+
>>> print res.outputs.param1
1825+
exampleStr
1826+
>>> print res.outputs.param2
1827+
4
1828+
1829+
"""
1830+
input_spec = JSONFileGrabberInputSpec
1831+
output_spec = DynamicTraitedSpec
1832+
_always_run = True
1833+
1834+
def _list_outputs(self):
1835+
import json
1836+
1837+
with open(self.inputs.in_file, 'r') as f:
1838+
data = json.load(f)
1839+
1840+
if not isinstance(data, dict):
1841+
raise RuntimeError('JSON input has no dictionary structure')
1842+
1843+
outputs = {}
1844+
for key, value in data.iteritems():
1845+
outputs[key] = value
1846+
1847+
return outputs
1848+
1849+
1850+
class JSONFileSinkInputSpec(DynamicTraitedSpec, BaseInterfaceInputSpec):
1851+
out_file = File(desc='JSON sink file')
1852+
in_dict = traits.Dict(desc='input JSON dictionary')
1853+
1854+
1855+
class JSONFileSinkOutputSpec(TraitedSpec):
1856+
out_file = File(desc='JSON sink file')
1857+
1858+
1859+
class JSONFileSink(IOBase):
1860+
1861+
""" Very simple frontend for storing values into a JSON file.
1862+
1863+
.. warning::
1864+
1865+
This is not a thread-safe node because it can write to a common
1866+
shared location. It will not complain when it overwrites a file.
1867+
1868+
Examples
1869+
--------
1870+
1871+
>>> jsonsink = JSONFileSink(input_names=['subject_id',
1872+
... 'some_measurement'])
1873+
>>> jsonsink.inputs.subject_id = 's1'
1874+
>>> jsonsink.inputs.some_measurement = 11.4
1875+
>>> jsonsink.run() # doctest: +SKIP
1876+
1877+
Using a dictionary as input:
1878+
1879+
>>> dictsink = JSONFileSink()
1880+
>>> dictsink.inputs.in_dict = {'subject_id': 's1',
1881+
... 'some_measurement': 11.4}
1882+
>>> dictsink.run() # doctest: +SKIP
1883+
1884+
"""
1885+
input_spec = JSONFileSinkInputSpec
1886+
output_spec = JSONFileSinkOutputSpec
1887+
1888+
def __init__(self, input_names=[], **inputs):
1889+
super(JSONFileSink, self).__init__(**inputs)
1890+
self._input_names = filename_to_list(input_names)
1891+
add_traits(self.inputs, [name for name in self._input_names])
1892+
1893+
def _list_outputs(self):
1894+
import json
1895+
import os.path as op
1896+
if not isdefined(self.inputs.out_file):
1897+
out_file = op.abspath('datasink.json')
1898+
else:
1899+
out_file = self.inputs.out_file
1900+
1901+
out_dict = dict()
1902+
1903+
if isdefined(self.inputs.in_dict):
1904+
if isinstance(self.inputs.in_dict, dict):
1905+
out_dict = self.inputs.in_dict
1906+
else:
1907+
for name in self._input_names:
1908+
val = getattr(self.inputs, name)
1909+
val = val if isdefined(val) else 'undefined'
1910+
out_dict[name] = val
1911+
1912+
with open(out_file, 'w') as f:
1913+
json.dump(out_dict, f)
1914+
outputs = self.output_spec().get()
1915+
outputs['out_file'] = out_file
1916+
return outputs
1917+
1918+
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT
2+
from nipype.testing import assert_equal
3+
from nipype.interfaces.io import JSONFileGrabber
4+
5+
def test_JSONFileGrabber_inputs():
6+
input_map = dict(ignore_exception=dict(nohash=True,
7+
usedefault=True,
8+
),
9+
in_file=dict(mandatory=True,
10+
),
11+
)
12+
inputs = JSONFileGrabber.input_spec()
13+
14+
for key, metadata in input_map.items():
15+
for metakey, value in metadata.items():
16+
yield assert_equal, getattr(inputs.traits()[key], metakey), value
17+
18+
def test_JSONFileGrabber_outputs():
19+
output_map = dict()
20+
outputs = JSONFileGrabber.output_spec()
21+
22+
for key, metadata in output_map.items():
23+
for metakey, value in metadata.items():
24+
yield assert_equal, getattr(outputs.traits()[key], metakey), value
25+
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT
2+
from nipype.testing import assert_equal
3+
from nipype.interfaces.io import JSONFileSink
4+
5+
def test_JSONFileSink_inputs():
6+
input_map = dict(ignore_exception=dict(nohash=True,
7+
usedefault=True,
8+
),
9+
in_dict=dict(),
10+
out_file=dict(),
11+
)
12+
inputs = JSONFileSink.input_spec()
13+
14+
for key, metadata in input_map.items():
15+
for metakey, value in metadata.items():
16+
yield assert_equal, getattr(inputs.traits()[key], metakey), value
17+
18+
def test_JSONFileSink_outputs():
19+
output_map = dict(out_file=dict(),
20+
)
21+
outputs = JSONFileSink.output_spec()
22+
23+
for key, metadata in output_map.items():
24+
for metakey, value in metadata.items():
25+
yield assert_equal, getattr(outputs.traits()[key], metakey), value
26+

nipype/testing/data/jsongrabber.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"param2": 4, "param1": "exampleStr"}

0 commit comments

Comments
 (0)