Skip to content
This repository was archived by the owner on Sep 8, 2025. It is now read-only.

Commit b3a8091

Browse files
author
Jen Reiter
authored
Merge pull request #1 from flywheel-apps/v0.1.0
V0.1.0
2 parents 94bfb3a + 46600d5 commit b3a8091

File tree

4 files changed

+177
-0
lines changed

4 files changed

+177
-0
lines changed

Dockerfile

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#flywheel/csv-import
2+
3+
# Start with python 2.7
4+
FROM python:2.7
5+
MAINTAINER Flywheel <[email protected]>
6+
7+
# Install Python SDK
8+
RUN pip install https://github.com/flywheel-io/sdk/releases/download/0.2.0/flywheel-0.2.0-py2-none-linux_x86_64.whl
9+
10+
# Make directory for flywheel spec (v0)
11+
ENV FLYWHEEL /flywheel/v0
12+
RUN mkdir -p ${FLYWHEEL}
13+
COPY run ${FLYWHEEL}/run
14+
COPY script.py ${FLYWHEEL}/script.py
15+
COPY manifest.json ${FLYWHEEL}/manifest.json
16+
17+
# ENV preservation for Flywheel Engine
18+
RUN env -u HOSTNAME -u PWD | \
19+
awk -F = '{ print "export " $1 "=\"" $2 "\"" }' > ${FLYWHEEL}/docker-env.sh
20+
21+
# Set the entrypoint
22+
ENTRYPOINT ["/flywheel/v0/run"]

manifest.json

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
{
2+
"name": "csv-import",
3+
"label": "CSV Import",
4+
"description": "Import a CSV of subject metadata into Flywheel. Import a CSV of subject metadata into Flywheel. Each row is a subject, each column is a value. First row must contain header. Subject Code matching input column name, or default to Subject ID",
5+
"version": "0.1.0",
6+
"flywheel": "0",
7+
"inputs": {
8+
"file": {
9+
"base": "file",
10+
"description": "Subject Metadata CSV file."
11+
},
12+
"api_key": {
13+
"base": "api-key"
14+
}
15+
},
16+
"config": {
17+
"Group_Tags_By": {
18+
"default": "",
19+
"description": "Enter value to group imported tags by, or leave blank to import to subject.info",
20+
"type": "string"
21+
},
22+
"Match_Column": {
23+
"default": "Subject ID",
24+
"description": "Column header for column containing Subject Code.",
25+
"type": "string"
26+
}
27+
},
28+
"author": "Imad Nijim",
29+
"maintainer": "Flywheel <[email protected]>",
30+
"license": "Other",
31+
"source": "https://github.com/flywheel-apps/csv-import",
32+
"url": "www.flywheel.io",
33+
"custom": {
34+
"docker-image": "flywheel/csv-import:v0.1.0"
35+
}
36+
}

run

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#!/usr/bin/env bash
2+
3+
export PATH=/opt/conda/bin:$PATH
4+
5+
python /flywheel/v0/script.py

script.py

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
# Import a CSV of subject metadata into Flywheel.
2+
# Each row is a subject, each column is a value. Expecting one subject in each file (i.e. no checking for duplicates).
3+
# First row must contain header.
4+
# Subject Code matching input column name, or default to "Subject ID"
5+
# To do:
6+
# get user contenxt and remove Imad's API key
7+
# Add field type (string, int, etc) to make search facet useful (probably expected in the second row).
8+
# Need to implement subject code not in first colum
9+
10+
import os
11+
import sys
12+
import time
13+
import csv
14+
import json
15+
import re
16+
17+
# Gear basics
18+
print 'Setup'
19+
flywheel_base = '/flywheel/v0'
20+
input_folder = os.path.join(flywheel_base, 'input/file')
21+
output_folder = os.path.join(flywheel_base, 'output')
22+
config_file = os.path.join(flywheel_base, 'config.json')
23+
24+
# Grab the input file path
25+
input_filename = os.listdir(input_folder)[0]
26+
input_filepath = os.path.join(input_folder, input_filename)
27+
28+
# Grab config from config.json
29+
print 'Reading config'
30+
with open(config_file) as fp:
31+
config = json.load(fp)
32+
33+
# Get config parameters
34+
if 'Match_Column' in config['config']:
35+
MatchColumn = config['config']['Match_Column'].strip()
36+
else:
37+
MatchColumn = 'Subject ID'
38+
39+
if 'Group_Tags_By' in config['config']:
40+
GroupTagsBy = config['config']['Group_Tags_By'].strip()
41+
if GroupTagsBy != "":
42+
if not re.match('^[a-zA-Z0-9][a-zA-Z0-9_-]+$', GroupTagsBy):
43+
print 'Group By Tags is invalid.'
44+
print 'Valid values are: blank, alphanumeric including dashes and underscores'
45+
sys.exit(1)
46+
else:
47+
GroupTagsBy = ""
48+
49+
50+
51+
# Load Flywheel Python SDK
52+
print 'Loading Python SDK'
53+
from flywheel import Flywheel
54+
55+
# Get temporary API key
56+
api_key = str(config['inputs']['api_key']['key'])
57+
fw = Flywheel(api_key)
58+
59+
# Get fileid
60+
fileid = config['inputs']['file']['hierarchy']['id']
61+
# get project information from file
62+
acquisition = fw.get_acquisition(fileid)
63+
session = fw.get_session(acquisition['session'])
64+
project = fw.get_project(session['project'])
65+
projectid = project['_id']
66+
projectname = project['label']
67+
68+
# read CSV into list
69+
print 'Reading in CSV'
70+
with open(input_filepath, 'rbU') as f:
71+
reader = csv.reader(f)
72+
rows = list(reader)
73+
74+
# Check if matching column exists
75+
if MatchColumn not in rows[0]:
76+
print("Match Column not found in CSV")
77+
sys.exit(1)
78+
79+
# make list into json
80+
headers = rows[0]
81+
csv_subjects = []
82+
for row in rows[1:]:
83+
newdict = {}
84+
for i in range(0, len(headers)):
85+
newdict[headers[i]] = row[i]
86+
csv_subjects.append(newdict)
87+
88+
# Build the string and update session
89+
print 'Updating sessions'
90+
sessions = fw.get_project_sessions(projectid)
91+
92+
for row in csv_subjects:
93+
subjectfound = 0
94+
for session in sessions:
95+
if session['subject']['code'] == row[MatchColumn]:
96+
subjectfound += 1
97+
val = row.copy()
98+
del val[MatchColumn]
99+
if GroupTagsBy == "":
100+
myobject = {'subject': {'info': val}}
101+
else:
102+
myobject = {'subject': {'info': {GroupTagsBy: val}}}
103+
fw.modify_session(session['_id'], myobject)
104+
if not subjectfound:
105+
#print "Subject Code %s in %s does not match a subject in the %s project." % (row[MatchColumn], input_filename, projectname)
106+
print 'Subject Code ' + row[MatchColumn] + ' in ' + input_filename + ' does not match a subject in the ' + projectname + ' project' + '.'
107+
108+
# Add record keeping note to project notes
109+
if not GroupTagsBy:
110+
fw.add_project_note(projectid, 'Imported %d fields from %s' % ((len(headers) - 1), input_filename) )
111+
#fw.add_project_note(projectid, 'Imported ' + str(len(headers) - 1) + ' fields from ' + input_filename)
112+
else:
113+
fw.add_project_note(projectid, 'Imported %d fields from %s, grouped by %s' % ((len(headers) - 1), input_filename, GroupTagsBy))
114+
#fw.add_project_note(projectid, 'Imported ' + str(len(headers) - 1) + ' fields from ' + input_filename + ', grouped by ' + GroupTagsBy)

0 commit comments

Comments
 (0)