-
Notifications
You must be signed in to change notification settings - Fork 72
[SYNPY-1577] Submission View #1192
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
43 commits
Select commit
Hold shift + click to select a range
a084116
adds initial DatasetCollection implementation
BWMac 2d4b8e6
adds unit tests
BWMac 3d14cd7
pre-commit
BWMac cd9e910
updates docstrings
BWMac e1a1e8a
adds integration tests
BWMac 41eaf74
adds docs pages
BWMac 25f12ff
removes example script section from dataset documentation
BWMac 3a5b017
adds dataset collection tutorial
BWMac 2ffdeab
fixes tutorial script
BWMac c43a172
adds tutorial path to mkdocs.yml
BWMac 0b40a21
bullet points
BWMac 73baab0
fixes tutorial code lines
BWMac 9d2984e
fixes tutorial references
BWMac c4866f6
test doc format fix
BWMac 6c196a3
fixes dataset docs
BWMac daedf46
fixes sync integration tests
BWMac 84a73e3
fixes DatasetCollection docstrings
BWMac 60fa4f7
refactors entity factory
BWMac cd208d6
fixes argument error
BWMac 3a70496
updates test strings
BWMac b7e728e
Merge branch 'develop' into synpy-1578-oop-model-dataset-collection
BWMac 7512c0e
pre-commit
BWMac e0e82bd
Update docs/tutorials/python/dataset_collection.md
BWMac 27a7656
updates tutorials
BWMac cd775a5
removes elif block
BWMac 0b2603f
pre-commit
BWMac 66c562a
removes unused cleanup
BWMac 87950e9
updates version handling and tests
BWMac 1368c7a
fix async tests
BWMac 5d39a79
addresses comments
BWMac f279036
fixes docstrings
BWMac d63b212
adds retry logic for uncaught async jobs
BWMac 345a2ee
set max on timeout
BWMac 7a993ba
addresses comments
BWMac fe17606
updates unit test for version num
BWMac 80edc7e
fixes incorrect line number
BWMac 6bc4374
adds missing snapshot tests
BWMac f646dc1
corrects type hint
BWMac e16ab00
submission-view
BryanFauble 5a7b83f
Adds a new SubmissionView model class that represents Synapse Submiss…
BryanFauble d3e833a
Update ranking for sync apir reference on mkdocs
BryanFauble 8ce19b8
Update tutorial as first query won't have updated data
BryanFauble d04d603
removal of the redundant has_columns_changed property method from mul…
BryanFauble File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
# SubmissionView | ||
|
||
Contained within this file are experimental interfaces for working with the Synapse Python | ||
Client. Unless otherwise noted these interfaces are subject to change at any time. Use | ||
at your own risk. | ||
|
||
## API reference | ||
|
||
::: synapseclient.models.SubmissionView | ||
options: | ||
inherited_members: true | ||
members: | ||
- store_async | ||
- get_async | ||
- delete_async | ||
- query_async | ||
- query_part_mask_async | ||
- snapshot_async | ||
- add_column | ||
- reorder_column | ||
- delete_column | ||
- get_acl_async | ||
- get_permissions_async | ||
- set_permissions_async | ||
--- |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
# SubmissionView | ||
|
||
Contained within this file are experimental interfaces for working with the Synapse Python | ||
Client. Unless otherwise noted these interfaces are subject to change at any time. Use | ||
at your own risk. | ||
|
||
## API reference | ||
|
||
::: synapseclient.models.SubmissionView | ||
options: | ||
inherited_members: true | ||
members: | ||
- store | ||
- get | ||
- delete | ||
- query | ||
- query_part_mask | ||
- snapshot | ||
- add_column | ||
- reorder_column | ||
- delete_column | ||
- get_acl | ||
- get_permissions | ||
- set_permissions | ||
--- |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
# SubmissionView | ||
|
||
SubmissionViews in Synapse allow you to aggregate and query submissions from one or more | ||
evaluation queues in a tabular format. These views are useful for managing submissions in | ||
challenges, tracking scoring progress, and analyzing submission data across different | ||
evaluation queues. | ||
|
||
This tutorial will walk you through the basics of working with SubmissionViews | ||
using the Synapse Python client. | ||
|
||
## Tutorial Purpose | ||
In this tutorial, you will: | ||
|
||
1. Set up and create an evaluation queue | ||
2. Create a SubmissionView for the evaluation queue | ||
3. Create and submit a file to the evaluation queue | ||
4. Query and update the submission status | ||
5. Modify the SubmissionView scope | ||
6. Create a snapshot of the view | ||
7. Query the snapshot | ||
|
||
## Prerequisites | ||
* This tutorial assumes that you have a Synapse project. | ||
* Pandas must also be installed as shown in the [installation documentation](../installation.md). | ||
|
||
## 1. Set up and create an evaluation queue | ||
|
||
Before creating a SubmissionView, we need to log in to Synapse, retrieve your project, | ||
and create an evaluation queue that will be used in the view. | ||
|
||
You will want to replace `"My uniquely named project about Alzheimer's Disease"` with | ||
the name of your project. | ||
|
||
```python | ||
{!docs/tutorials/python/tutorial_scripts/submissionview.py!lines=13-44} | ||
``` | ||
|
||
## 2. Create a SubmissionView for the evaluation queue | ||
|
||
Next, we will create a SubmissionView that includes the evaluation queue we just created | ||
in its scope. We'll also add custom columns for metrics that will be used for scoring | ||
submissions. | ||
|
||
```python | ||
{!docs/tutorials/python/tutorial_scripts/submissionview.py!lines=46-82} | ||
``` | ||
|
||
## 3. Create and submit a file to the evaluation queue | ||
|
||
Now let's create a test file and submit it to our evaluation queue. For convenience, | ||
we'll use a temporary file that will be automatically cleaned up after execution. | ||
|
||
```python | ||
{!docs/tutorials/python/tutorial_scripts/submissionview.py!lines=84-105} | ||
``` | ||
|
||
## 4. Query and update the submission status | ||
|
||
After submitting a file, we can query the SubmissionView to see our submission and update | ||
its status with scoring metrics. | ||
|
||
Note: Due to Synapse's eventual consistency model, we need to wait briefly for the | ||
submission to appear in the view. | ||
|
||
```python | ||
{!docs/tutorials/python/tutorial_scripts/submissionview.py!lines=107-126} | ||
``` | ||
|
||
<details class="example"> | ||
<summary>The result of querying your SubmissionView should include your submission with its details:</summary> | ||
``` | ||
Query results: | ||
ROW_ID ROW_VERSION ROW_ETAG metric_A metric_B ... submitteralias entityid entityversion dockerrepositoryname dockerdigest | ||
0 9751779 0 e7c37ec7-e5e8-435d-b378-dc2d6bddad21 NaN NaN ... Participant 1 syn66272627 1 NaN NaN | ||
``` | ||
|
||
After updating the submission status: | ||
|
||
``` | ||
Submission status: SCORED | ||
``` | ||
</details> | ||
|
||
## 5. Modify the SubmissionView scope | ||
|
||
As your challenge evolves, you might need to add more evaluation queues to your SubmissionView. | ||
Here's how to create another evaluation queue and add it to your view's scope. | ||
|
||
```python | ||
{!docs/tutorials/python/tutorial_scripts/submissionview.py!lines=128-143} | ||
``` | ||
|
||
## 6. Create a snapshot of the view | ||
|
||
SubmissionViews support creating snapshots, which capture the state of all submissions at a | ||
specific point in time. This is useful for archiving or comparing submission states. | ||
|
||
```python | ||
{!docs/tutorials/python/tutorial_scripts/submissionview.py!lines=145-152} | ||
``` | ||
|
||
## 7. Query the snapshot | ||
|
||
After creating a snapshot, you can query it to retrieve the state of submissions at the | ||
time the snapshot was created. This is useful for historical analysis or auditing. | ||
|
||
```python | ||
{!docs/tutorials/python/tutorial_scripts/submissionview.py!lines=153-162} | ||
``` | ||
|
||
## Source Code for this Tutorial | ||
|
||
<details class="quote"> | ||
<summary>Click to show me</summary> | ||
|
||
```python | ||
{!docs/tutorials/python/tutorial_scripts/submissionview.py!} | ||
``` | ||
</details> | ||
|
||
## References | ||
- [SubmissionView][synapseclient.models.SubmissionView] | ||
- [Evaluation][synapseclient.evaluation] | ||
- [syn.submit][synapseclient.Synapse.submit] | ||
- [syn.getSubmissionStatus][synapseclient.Synapse.getSubmissionStatus] | ||
- [syn.getSubmission][synapseclient.Synapse.getSubmission] | ||
- [syn.getSubmissions][synapseclient.Synapse.getSubmissions] | ||
- [syn.getSubmissionBundles][synapseclient.Synapse.getSubmissionBundles] | ||
- [syn.store][synapseclient.Synapse.store] | ||
- [Column][synapseclient.models.Column] | ||
- [Project][synapseclient.models.Project] | ||
- [syn.login][synapseclient.Synapse.login] | ||
- [query examples](https://rest-docs.synapse.org/rest/org/sagebionetworks/repo/web/controller/TableExamples.html) |
162 changes: 162 additions & 0 deletions
162
docs/tutorials/python/tutorial_scripts/submissionview.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,162 @@ | ||
""" | ||
Here is where you'll find the code for the SubmissionView tutorial. | ||
|
||
A SubmissionView allows you to aggregate and query submissions from one or more | ||
evaluation queues in a tabular format, similar to other view types in Synapse. | ||
|
||
This tutorial also shows how to create an evaluation queue, submit a file to it, and | ||
update the submission status. The example uses a temporary file for the submission, | ||
which is automatically cleaned up after the script runs. You can modify the file | ||
path and name as needed. | ||
|
||
""" | ||
|
||
import tempfile | ||
|
||
import pandas as pd | ||
|
||
from synapseclient import Evaluation, Synapse | ||
from synapseclient.models import ( | ||
Activity, | ||
Column, | ||
ColumnType, | ||
File, | ||
Project, | ||
SubmissionView, | ||
UsedURL, | ||
) | ||
|
||
syn = Synapse() | ||
syn.login() | ||
|
||
# Retrieve the project ID | ||
my_project = Project(name="My uniquely named project about Alzheimer's Disease").get() | ||
project_id = my_project.id | ||
print(f"My project ID is: {project_id}") | ||
|
||
# Step 1: Set up and create an evaluation queue | ||
evaluation_name = "Test Evaluation Queue for Alzheimer conference" | ||
evaluation_description = "Evaluation queue for testing submission view" | ||
evaluation = Evaluation( | ||
name=evaluation_name, description=evaluation_description, contentSource=project_id | ||
) | ||
evaluation = syn.store(evaluation) | ||
print(f"Created evaluation queue with ID: {evaluation.id}") | ||
|
||
# Step 2: Create a SubmissionView for the evaluation queue | ||
view = SubmissionView( | ||
name="SubmissionView for Alzheimer conference", | ||
parent_id=project_id, | ||
scope_ids=[evaluation.id], | ||
include_default_columns=True, | ||
columns=[ | ||
Column( | ||
name="metric_A", | ||
column_type=ColumnType.DOUBLE, | ||
), | ||
Column( | ||
name="metric_B", | ||
column_type=ColumnType.DOUBLE, | ||
), | ||
], | ||
activity=Activity( | ||
name="Submission Review Analysis", | ||
description="Analysis of Q1 2025 challenge submissions", | ||
used=[ | ||
UsedURL( | ||
name="Challenge Homepage", | ||
url="https://sagebionetworks.org/community/challenges-portal", | ||
) | ||
], | ||
), | ||
).store() | ||
|
||
print(f"My SubmissionView ID is: {view.id}") | ||
|
||
# Reorder columns for better display | ||
view.reorder_column(name="name", index=2) | ||
view.reorder_column(name="status", index=3) | ||
view.reorder_column(name="evaluationid", index=4) | ||
view.store() | ||
|
||
print("Available columns in the view:", list(view.columns.keys())) | ||
|
||
# Step 3: Create and submit a file to the evaluation queue | ||
with tempfile.NamedTemporaryFile( | ||
mode="w", suffix=".txt", delete=True, delete_on_close=False | ||
) as temp_file: | ||
with open(temp_file.name, "w") as opened_temp_file: | ||
opened_temp_file.write("This is a test submission file.") | ||
temp_file_path = temp_file.name | ||
|
||
# Upload the temporary file to Synapse | ||
submission_file = File( | ||
path=temp_file_path, parent_id=project_id, name="Test Submission" | ||
).store() | ||
|
||
# Submit the file to the evaluation queue | ||
submission = syn.submit( | ||
evaluation=evaluation, | ||
entity=submission_file, | ||
name="Test Submission", | ||
submitterAlias="Participant 1", | ||
) | ||
|
||
print(f"Created submission with ID: {submission.id}") | ||
|
||
# Step 4: Query and update the submission status | ||
# Query the SubmissionView to see our submission | ||
query = f"SELECT * FROM {view.id} WHERE id = '{submission.id}'" | ||
results_as_dataframe: pd.DataFrame = view.query(query=query) | ||
# Due to the eventual consistency of the system, we need to perform 2 queries | ||
results_as_dataframe: pd.DataFrame = view.query(query=query) | ||
|
||
print("Query results:") | ||
print(results_as_dataframe) | ||
|
||
# Update the status to indicate it's been scored | ||
submission_status = syn.getSubmissionStatus(submission=submission.id) | ||
print(f"Submission status: {submission_status.status}") | ||
submission_status.status = "SCORED" | ||
submission_status.submissionAnnotations["metric_A"] = 90 | ||
submission_status.submissionAnnotations["metric_B"] = 80 | ||
submission_status.score = 0.7 | ||
submission_status = syn.store(submission_status) | ||
print(f"Updated submission status to: {submission_status.status}") | ||
|
||
# Step 5: Modify the SubmissionView scope | ||
# First let's make sure we have the latest view from Synapse: | ||
view.get() | ||
|
||
# Create another evaluation queue to demonstrate adding to the scope | ||
second_evaluation = Evaluation( | ||
name="Second Test Evaluation Queue for Alzheimer conference", | ||
description="Another evaluation queue for testing submission view", | ||
contentSource=project_id, | ||
) | ||
second_evaluation = syn.store(second_evaluation) | ||
print(f"Created second evaluation queue with ID: {second_evaluation.id}") | ||
|
||
# Add the new evaluation queue to the view's scope | ||
view.scope_ids.append(second_evaluation.id) | ||
view.store() # Store the updated view | ||
print("Updated SubmissionView scope. Current scope IDs:", view.scope_ids) | ||
|
||
# Step 6: Create a snapshot of the view | ||
snapshot_info = view.snapshot( | ||
comment="Initial submission review snapshot", | ||
) | ||
print("Created snapshot of the SubmissionView:") | ||
print(snapshot_info) | ||
snapshot_version = snapshot_info.snapshot_version_number | ||
print(f"Snapshot version number: {snapshot_version}") | ||
|
||
# Step 7: Query the snapshot we just created | ||
# You may also get the snapshot version from the view object directly by looking at the version number | ||
# (which is the latest version of the view) and subtracting 1. | ||
# snapshot_version = view.version_number - 1 | ||
|
||
snapshot_query = f"SELECT * FROM {view.id}.{snapshot_version}" | ||
snapshot_results = view.query(snapshot_query) | ||
print("Query results from the snapshot:") | ||
print(snapshot_results) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The use of both 'delete' and 'delete_on_close' parameters in NamedTemporaryFile is non-standard and may lead to unexpected behavior; consider using only one appropriate parameter based on your intended file deletion behavior.
Copilot uses AI. Check for mistakes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bad suggestion. Using both means the file is deleted when leaving the content managed "with" statement, but not deleted the moment we stop writing to the file through I/O