Skip to content

Data Views

A data view is a structured query that collects fields from across the Flywheel container hierarchy and returns the result as tabular data. Instead of writing nested loops to gather subject demographics, session timestamps, and acquisition labels into a single table, you define a view once and execute it against a project or container. The result comes back as JSON, a pandas DataFrame, or a local CSV/TSV file.

When to Use Data Views

Direct hierarchy traversal works fine for small-scale inspection or when you need to act on containers rather than read from them. Data views are the better choice when:

  • You need structured tabular output for downstream analysis or export.
  • You are collecting fields from multiple hierarchy levels (project, subject, session, acquisition) in one operation.
  • You want to pull columns out of CSV or JSON output files produced by analysis gears.
  • You plan to reuse the same query across different projects.

See Core Concepts: Hierarchy for a description of the container levels data views operate across.

Discovering Available Columns

Before building a view, check which columns and column groups are available:

Print available view columns
fw.print_view_columns()

This prints a list like:

project (group): All column aliases belonging to project
project.id (string): The project id
project.label (string): The project label
subject (group): All column aliases belonging to subject
subject.id (string): The subject id
subject.label (string): The subject label or code
subject.firstname (string): The subject first name
subject.lastname (string): The subject last name
subject.age (int): The subject age, in seconds
subject.sex (string): The subject sex
...

You can filter the output by passing a string: fw.print_view_columns(filter="subject").

Building a View

fw.View() — simple shorthand

fw.View() is a shorthand for flywheel.ViewBuilder(**kwargs).build(). Use it when you do not need file extraction or complex analysis filtering:

Build a view with fw.View() and read as a DataFrame
# Collect all built-in subject columns across a project
view = fw.View(columns=["subject"])
data = fw.read_view_dataframe(view, project.id)

ViewBuilder — full control

ViewBuilder is the underlying class. Use it when you need file extraction, analysis filtering, or any option not exposed by fw.View().

Build a view with ViewBuilder
builder = flywheel.ViewBuilder(
    label="Session Summary",
    columns=["subject.label", "session.label", "session.timestamp"],
)
view = builder.build()
data = fw.read_view_dataframe(view, project.id)

Key ViewBuilder constructor parameters:

Parameter Type Description
label str Optional label, used when saving the view.
columns list Column names or group names to include.
container str Container level where files are matched (project, subject, session, acquisition). Required when extracting file data.
filename str Filename pattern to match. Supports * and ? wildcards.
analysis_gear_name str Restrict file matching to analyses run by this gear. Supports wildcards.
analysis_label str Restrict file matching to analyses with this label. Supports wildcards.
analysis_gear_version str Restrict file matching to this gear version. Supports wildcards.
match str File match strategy when multiple files are found (see below).
filter str Default filter expression to embed in the saved view definition.
include_ids bool Include container ID columns (default True).
include_labels bool Include container label columns (default True).

Column Types

Individual columns

Columns follow the format <container>.<field>, for example subject.label, session.timestamp, acquisition.label. You can add them as a list in the constructor or call builder.column() individually:

Add columns with builder.column()
builder = flywheel.ViewBuilder()
builder.column("subject.label")
builder.column("session.label")
builder.column("acquisition.label")
view = builder.build()

builder.column() accepts optional parameters:

  • dst — rename the column in the output.
  • type — coerce values to int, float, string, or bool.

Column groups

Passing a container name as a column adds all pre-defined fields for that level:

Add all subject fields to a View
# Adds all subject fields: id, label, firstname, lastname, age, sex, etc.
view = fw.View(columns=["subject", "session.label"])

Info columns

The info field on a container holds unstructured key-value metadata. To pull a specific key, use <container>.info.<key>:

Access info field columns
builder = flywheel.ViewBuilder(columns=["subject.label"])
builder.column("subject.info.diagnosis")
builder.column("subject.info.IQ")
view = builder.build()

Avoid adding subject.info as a bare column in CSV or TSV output. The view engine extracts columns from the first row it encounters, which produces inconsistent results when info fields differ across subjects. Always name the specific key you want. See Core Concepts: Metadata for more on the info field.

Executing a View

All execution methods accept a DataView object or a saved view ID string as the first argument.

Load as JSON

Load view data as JSON
import json

response = fw.read_view_data(view, project.id)
rows = json.load(response)

To change the output format, pass format:

Load view data as CSV
response = fw.read_view_data(view, project.id, format="csv")

Supported formats: json (default), json-row-column, json-flat, csv, tsv.

Load as a DataFrame

Requires the pandas package:

Load view data as a DataFrame
df = fw.read_view_dataframe(view, project.id)
print(df.head())

Save to a local file

Save view data to a local file
fw.save_view_data(view, project.id, output_path, format="csv")

Filter at execution time

Pass a filter keyword to any execution method to restrict which rows are returned without changing the view definition:

Filter rows at execution time
# Only rows where subject sex is male
df = fw.read_view_dataframe(view, project.id, filter="subject.sex=male")

You can also paginate large results with skip and limit:

Paginate Dataframe results
df = fw.read_view_dataframe(view, project.id, skip=0, limit=100)

Extracting File Data

Data views can read rows directly from CSV, TSV, or JSON files attached to containers or produced by analysis gears. Set container and filename to match the target files, then use file_column() to specify which columns to extract.

file_match — handling multiple matches

If more than one file matches the pattern on a given container, file_match controls which one is used:

Value Behavior
first Use the first file returned.
last Use the last file returned.
newest Use the file with the most recent creation timestamp.
oldest Use the file with the oldest creation timestamp.
all Use all matching files, producing a row per file per data row.

file_column — extract specific columns

file_column(src, dst=None, type=None) adds a single column from the matched file:

  • src — the column name in the CSV/TSV/JSON file.
  • dst — rename the column in the output (defaults to src).
  • type — coerce the value: float, int, string, bool.

Full example: AFQ tract metrics

This example reads diffusion metrics from the newest Mean_Diffusivity.csv output file produced by the afq gear, combined with subject and session labels from the hierarchy:

AFQ tract metrics example
builder = flywheel.ViewBuilder(
    label="AFQ Tract Metrics",
    columns=["subject.label", "session.label"],
    container="session",
    filename="Mean_Diffusivity.csv",
    analysis_gear_name="afq",
)
builder.file_match("newest")
builder.file_column("Left_Thalamic_Radiation", type="float")
builder.file_column("Right_Thalamic_Radiation", type="float")
view = builder.build()

df = fw.read_view_dataframe(view, project.id)

The result is a DataFrame where each row corresponds to one session, with columns for subject.label, session.label, Left_Thalamic_Radiation, and Right_Thalamic_Radiation.

Matching files without analysis filters

To read from files attached directly to containers (not analysis output), omit the analysis_* parameters:

Read columns from files
# Read all columns from files named behavioral_results_*.csv on each session
view = fw.View(container="session", filename="behavioral_results*.csv")
df = fw.read_view_dataframe(view, project.id)

Saving and Reusing Views

Saving a view stores its definition on your user account or on a project, so you can run it again without rebuilding it.

Save a view

fw.add_view(owner_id, view) saves the view definition and returns a view ID string:

Save a view to your user account
me = fw.get_current_user().id
subjects_view = fw.View(label="Subject Demographics", columns=["subject"])
view_id = fw.add_view(me, subjects_view)
print(view_id)  # e.g. "000123456789abcdefABCDEF"

To save to a project instead of your user account, pass the project ID:

Save a view to a project
view_id = fw.add_view(project.id, subjects_view)

Execute a saved view

Pass the view ID string in place of a DataView object:

Execute a saved view by ID
df = fw.read_view_dataframe(view_id, project.id)

You can execute a saved view against any container you have access to, not just the one it was saved on.

List saved views

fw.get_views(container_id) returns all views saved on a container (user account or project):

List views saved on a container
views = fw.get_views(project.id)
for v in views:
    print(v.id, v.label)

Load a view by ID

Load a view by ID
view = fw.get_view(view_id)

Ad-hoc vs. Saved Views

Ad-hoc view Saved view
Definition DataView object built in code Stored on server, referenced by ID
Reusable No — must rebuild each time Yes — execute by ID from anywhere
Appears in UI No Yes
When to use One-off queries, exploration Recurring reports, shared across sessions

For one-off analysis during development, build views ad-hoc with ViewBuilder. When the query is stable and you need to run it repeatedly — or share it with other users via the Flywheel UI — save it.