Title: Flywheel SDK Example

Date: April 24th 2020

Description: This notebook is used to showcase a live version of commands used in the Flywheel SDK Documentation Examples section.

Install and Import Dependencies¶

In [ ]:
# Install specific packages required for this notebook
!pip install flywheel-sdk
In [ ]:
# Import packages
from getpass import getpass
from pathlib import Path
import os
import logging

import pandas as pd
import flywheel
from permission import check_user_permission
In [ ]:
# Instantiate a logger
logging.basicConfig(level=logging.INFO, format='%(asctime)s %(levelname)s %(message)s')
log = logging.getLogger('root')

Flywheel API Key and Client¶

Get a API_KEY. More on this at in the Flywheel SDK doc here.

In [ ]:
API_KEY = getpass('Enter API_KEY here: ')

Instantiate the Flywheel API client

In [ ]:
fw = flywheel.Client(API_KEY if 'API_KEY' in locals() else os.environ.get('FW_KEY'))

Show Flywheel logging information

In [ ]:
log.info('You are now logged in as %s to %s', fw.get_current_user()['email'], fw.get_config()['site']['api_url'])

Group¶

To learn more about different roles and respective permissions, please see Permissions.

<b>Notes:</b> Be sure you have the right permission to run the cells below.

Add a New Group¶

Create a new group, with an id of new_group and a label of New Group:

In [ ]:
group_id = fw.add_group(flywheel.Group('new_group', 'New Group'))

List Groups¶

List all Groups that you have access to:

In [ ]:
for group in fw.groups():
    print(f'Group Name/Label: {group.label}; Group ID: {group.id} ')

Modify Group Tags¶

In this example, you will be adding tags named Control and Study to a Group

In [ ]:
for group in fw.groups():
    if group.label == 'new_group':
        # Get the group ID for `my_test_group` group label
        group_id = group.id

# Get the group container by using the group ID
group = fw.get(group_id)

# Add tag to the selected group 
group.add_tag('Control')
group.add_tag('Study')

# Reload is nessecary to load the entire container
group = group.reload()

# Printing all the tags available in the selected group
print(', '.join(group.tags))
Tip: To learn more about different types of Containers and managing tags, files, notes or info, see Containers.

List Projects in Group¶

List all of the projects belonging to a Group.

In [ ]:
for project in group.projects():
    print(f'Project Label: {project.label}; Project ID: {project.id}')

Projects¶

How to Create a New Project¶

In this use case, you will be creating a new Project that belongs to the Group Label named my_group with a label of new_project_label.

In [19]:
# Grab the group container
my_group = fw.lookup('new_group')

# Define the project label
my_project_label = 'new_project_label'

Then, you can use add_project method to create a new Project with the label you have pre-defined earlier.

In [20]:
new_project = my_group.add_project(label = my_project_label)

List All Projects that You Have Access to¶

  1. Access your Project via the Project Label, which is new_project_label.
In [38]:
# Replace this with the project label you want to access.
my_project_label = 'new_project_label'
new_project = fw.projects.find_first(f'label={my_project_label}')
  1. Access your Project via Flywheel path (Group/ProjectLabel)

You can find the path in the Project Homepage

  • EX: (fw://new_group/new_project_label)
In [64]:
new_project = fw.lookup('new_group/new_project_label')
  1. Access Project container with Project ID
    • You can get your Project ID on the URL path OR via the Project container
In [48]:
# Access project ID in the project container
project_id = new_project.id
get_project = fw.get_project(project_id)

Project Container Property and Info Attributes¶

Discover the Property in the Project container.¶

Tip: For more information about each property, visit the SDK Documentations.

You will be working with the new_project in this section.

Please make sure you have followed the steps above before moving forward.

In [158]:
# This will shows all the property available in the project
new_project.keys()
Out[158]:
dict_keys(['label', 'info', 'description', 'group', 'providers', 'editions', '_id', 'parents', 'info_exists', 'created', 'modified', 'revision', 'templates', 'permissions', 'files', 'notes', 'tags', 'analyses'])

Modify/Update Information in Property¶

In this section, you are going to add new information to the info property.

In [ ]:
new_info_label = input('Enter a descriptive name for your info label: ')
new_info = input('Enter a short description you want to be added to the info property: ')

Based on your inputs above, they will be stored in dictionary format.

In [ ]:
tmp_info = {new_info_label : new_info}

We are going to use update_info() to update the Project Info with the tmp_info we define above.

This is a more "user-friendly" way to add the metadata (or overwrite if the key already exists) to the Project container.

In [ ]:
new_project.update_info(tmp_info)

Check if it has been successfully modified

In [ ]:
# Reload is nessecary to load the entire container
new_project = new_project.reload()

# View all keys that are stored in the `info` attribute
new_project['info'].keys()
In [ ]:
# Print the content in the `info` attribute 
new_project['info']

Replace Metadata¶

You can also removes all information on the Project and only adds back what's in tmp_info.

In [ ]:
# Re-define the tmp_info with the key and value you have entered earlier
tmp_info = {new_info_label : new_info}

new_project.replace_info(tmp_info)
Tip: Useful command to learn more about the Project object.
In [ ]:
help(new_project)

IMPORTANT : For the following sections, you will need a testing project that you own and contains some dummy data which you can tinker with in this notebook.
If you don't have one already, please visit this repo before proceeding. Otherwise, please specify below the Group and Project labels.

Constants¶

In [ ]:
YOUR_GROUP = input('Enter the group label here: ')

YOUR_PROJECT = input('Enter the project label here: ')
# Hit 'Enter' after you have entered the value.

Search the Project Container¶

This project variable will be used throughout the next few sections.

In [32]:
FW_PROJ = fw.lookup(f'{YOUR_GROUP}/{YOUR_PROJECT}')

Subjects¶

List Subjects¶

  1. List all Subjects that belong to the Project.
In [ ]:
for subject in FW_PROJ.subjects():
    print('%s: %s' % (subject.id, subject.label))
  1. List all of the Subjects that you have access to.
In [ ]:
for subject in fw.subjects():
    print('%s: %s' % (subject.id, subject.label))
  1. List all of the Sessions belonging to Subject.
In [ ]:
for subject in fw.subjects():
    # Loop through all sessions in the subject container. 
    for session in subject.sessions():
            print('%s: %s' % (session.id, session.label))

Add Subject¶

Create a new Subject with a desired label to the FW_PROJ.

Notes: The subject.label should be unique for the Project

In [ ]:
new_subj_label = input('Enter an unique label for the new subject: ')
In [34]:
new_subj = FW_PROJ.add_subject(label= new_subj_label)

Modify/Edit Subject metadata¶

Update the details for the new_subj.

In [ ]:
new_subj.update(
        firstname='John',
        lastname='Doe',
        cohort='Study',
        type='human',
        sex='male',
        race='Unknown or Not Reported'
)

Check whether the update went through.

In [ ]:
# Reload is nessecary to load the entire container.
new_subj = new_subj.reload()

# Display the specific subject container
print(new_subj)

Sessions¶

Add Session¶

Here, you will be attaching a new Session container with label Session 01 to a Subject container. You will add this Session to the Subject you created earlier.

In [40]:
new_session = new_subj.add_session(label='Session 01')

List Sessions¶

  1. List all of the Sessions that you have access to.
In [ ]:
for session in fw.sessions():
    print('%s: %s' % (session.id, session.label))
  1. List all of the Sessions belonging to the FW_PROJ.
In [ ]:
for session in anxiety_project.sessions():
        print('%s: %s' % (session.id, session.label))
  1. List all of the Sessions belonging to Subject.
In [ ]:
for subject in anxiety_project.subjects():
    for session in subject.sessions():
        print('%s: %s' % (session.id, session.label))
  1. List all of the Acquisitions belonging to Session.
In [ ]:
for session in anxiety_project.sessions.iter():
    print('This is the session label: %s' % ( session.label))
    for acquisition in session.acquisitions.iter():
        acquisition = acquisition.reload()
        print('%s: %s' % (acquisition.id, acquisition.label))
        for file in acquisition.files:
            print(file.name)

Acquisitions¶

Add Acquisition¶

Create a new Acquisition with a label of Localizer, and upload a file.

Notes: You will be using the new_session that you created earlier.

In [41]:
new_acquisition = new_session.add_acquisition(label='Localizer')

List Acquisitions¶

List all of the Acqusitions that you have access to.

Notes:This will take a long time to run if you have accessed to a significant number of Acquisitions. Therefore, in this example, you will only get the first 10 Acquisitions.
In [ ]:
for i, acquisition in enumerate(fw.acquisitions.iter()):
    print('%s: %s' % (acquisition.id, acquisition.label))
    if i > 9:
        break

List all of the files on an acquisition¶

In [ ]:
for acquisition in fw.acquisitions.iter():
    for file in acquisition.files:
        # printing all the file that is stored under each acquisition containter.
        print(file.name)
Tip: Click here to learn more about different property in the file module.

Analyses¶

List Analyses¶

List all of the Analyses which belong to the Project container

In [ ]:
anxiety_project = anxiety_project.reload()
for analysis in anxiety_project.analyses:
    print('%s: %s' % (analysis.id, analysis.label))

List all of the Analyses belong to the Session container

In [66]:
for session in anxiety_project.sessions.iter():
    session = session.reload()
    for analysis in session.analyses:
        print('Session name: %s' % (session.label))
        analysis = analysis.reload()
        print('%s: %s' % (analysis.id, analysis.label))
Session name: anx_s5_anx_ses2_protB
5e9609675201f11a1244d87b: Test Analysis
Session name: anx_s5_anx_ses2_protB
5e960f905201f11a1744d8a2: fsl-fast 04/14/2020 14:31:20

Use get_analyses function to get the nested analyses for a container

In [ ]:
fw.get_analyses("projects", anxiety_project.id, "sessions")

Jobs and Analyses¶

Get the details about a specific Gear in Flywheel

You can list of Gear that is available from this link https://flywheel.io/gear-exchange/

In [ ]:
# Get the latest version of the example gear
gear = fw.lookup('gears/afq')

# Get a specific version of the example gear
gear = fw.lookup('gears/afq/0.0.2')

# Print details about the gear
gear.print_details()
In [ ]:
destination_file = PATH_TO_PROJECT /'download_files'
analysis = fw.lookup('group-id/project-label/subject-label/session-label/analyses/analysis-label')
analysis.download_tar('destination_file')

Utility Job Example¶

In [ ]:
# Get the Flywheel Example Utility gear
gear = fw.lookup('gears/flywheel-example-gear')

# Find the input files, the acquisition will be the destination container
# You will need the group label, project label and specific session label to get the acquisition container
acquisition = fw.lookup('my_group/anxiety-study-101/anx_s1_anx_ses1_protA /3Plane Loc SSFSE')

# Here we get the DICOM input 
inputs = {
        
    'dicom': acquisition.get_file('4784_1_1_loc.dcm.zip')
}

# Override some configuration values, the rest will use defaults
config = {
        'number': 42,
        'string': 'Hello World!'
}

# Schedule the job, adding the "my-job" tag
job_id = gear.run(config=config, inputs=inputs, destination=acquisition, tags=['my-job'])