Form Responses
Form Responses are a part of Reader Tasks, which is a feature available with a Flywheel Clinical module.
A form response is the structured data submitted by a reader when completing a reader task. Responses are generated when the assignee fills in and submits the form defined by the task's protocol.
Responses can be saved multiple times as drafts before submission. Validation is only enforced at submission time. Once a response is submitted, it is locked: no further edits are possible.
Form response versions: Legacy vs Tasks Manager
Flywheel has two distinct form response systems, corresponding to the two reader task systems. They are not compatible with each other, and are accessed in different ways. If you are unsure which version your instance has, contact your Flywheel administrator or check your site settings with the SDK.
Legacy tasks are not managed through SDK methods, but can be managed through Low-Level API Access or the fw-client Python package for making API calls.
Form response fields
| Field | Description |
|---|---|
id | Unique identifier for the response |
task_id | ID of the task this response is linked to |
protocol_id | ID of the protocol whose form schema was used |
data | Dict containing the reader's submitted field values |
submitted | True if the response has been submitted and locked |
submitted_at | Timestamp of submission (only set if submitted is True) |
origin | The user who submitted the response |
parents | References to parent containers (subject, session, etc.) |
revision | Integer revision count (increments on each save) |
created | Creation timestamp |
modified | Last-modified timestamp |
The data field contains a dict whose keys match the key properties of the protocol's form fields, and whose values are the reader's input:
# For a protocol with fields keyed "finding" and "impression":
response.data == {
"finding": "abnormal",
"impression": "Patchy opacity noted in the right lower lobe."
}
List responses for a task
fw.list_task_responses(task_id) returns all form responses associated with a given task. A task typically has one response, but the endpoint supports pagination for edge cases.
result = fw.list_task_responses(task_id)
for response in result.results:
print(f"{response.id}: submitted={response.submitted}")
Get a response by ID
fw.get_response(response_id) retrieves a single response by its ID.
response = fw.get_response(response_id)
print(response.data)
print(response.submitted)
Access submitted field values
The data dict maps protocol field keys to the reader's input values. Access individual fields by key name.
response = fw.get_response(response_id)
finding = response.data.get("finding")
impression = response.data.get("impression")
print(f"Finding: {finding}")
print(f"Impression: {impression}")
Create or replace a response
fw.create_or_replace_task_response(task_id, body) creates a new response for a task, or replaces an existing unsubmitted response. If a submitted response already exists, the call returns a 409 conflict error. Only the task assignee can create or replace responses.
Responses can be saved multiple times as drafts (without validation) using this method. Validation is enforced only when submitting.
response = fw.create_or_replace_task_response(
task_id,
{
"task_id": task_id,
"data": {
"finding": "normal",
"impression": "No acute cardiopulmonary abnormality.",
},
},
)
Update an existing response
fw.update_response(response_id, body) performs a partial update on an unsubmitted response. This is useful for saving incremental draft changes. Submitted responses cannot be updated.
updated = fw.update_response(
response_id, {"data": {"finding": "abnormal", "impression": "Revised: Patchy opacity noted."}}
)
Submit a response
fw.submit_response(response_id) validates the response against the protocol's form schema and locks it. Once submitted:
submittedis set toTruesubmitted_atis recordedoriginis set to the submitting user- Further edits are disabled
submitted = fw.submit_response(response_id)
print(submitted.submitted) # True
print(submitted.submitted_at) # datetime of submission
Aggregate responses across tasks
A common use case is collecting form responses from multiple tasks for downstream analysis. Iterate through tasks and retrieve the submitted response for each.
import pandas as pd
result = fw.find_all_api_tasks_reader_get(filter=f"protocol_id={protocol_id},status=completed")
records = []
for task in result.results:
responses = fw.list_task_responses(task.id)
for response in responses.results:
if response.submitted:
record = {"task_id": task.id}
record.update(response.data or {})
records.append(record)
df = pd.DataFrame(records)
Related pages
- Protocol form technical reference — technical details of the current protocol form schema, including the
defaultsobject and how field keys map to response data