Skip to content

Conversation

@jaymedina
Copy link
Contributor

@jaymedina jaymedina commented Sep 10, 2025

Problem:

This work is part of the ongoing effort to refactor the Synapse Python Client using object-oriented principles, following the pattern established in https://sagebionetworks.jira.com/browse/SYNPY-1418.

We currently to not have an OOP model for communications to the Evaluation API services provided by the Synapse platform.

Solution:

The work has been separated into 3 feature branches, with the *main branch being intended for merge into develop and the other 2 branches merging into *main when ready.

The acceptance criteria has been split up into these 3 branches in the following way.


Branch: synpy-1589-evaluation-model-main

  • async integration tests are introduced

Branch: synpy-1589-evaluation-model-functionality (merges into *main)

  • A new DataClass is introduced following the official attributes of an Evaluation entity on Synapse, via models/evaluation.py.
  • Communications to the following services are exposed via api/evaluation_services.py:

Create evaluation: https://rest-docs.synapse.org/rest/POST/evaluation.html
Get evaluation by ID: https://rest-docs.synapse.org/rest/GET/evaluation/evalId.html
Get evaluations by entity: https://rest-docs.synapse.org/rest/GET/entity/id/evaluation.html
Get all evaluations: https://rest-docs.synapse.org/rest/GET/evaluation.html
Get available evaluations: https://rest-docs.synapse.org/rest/GET/evaluation/available.html
Find evaluation by name: https://rest-docs.synapse.org/rest/GET/evaluation/name/name.html
Update evaluation: https://rest-docs.synapse.org/rest/PUT/evaluation/evalId.html
Delete evaluation: https://rest-docs.synapse.org/rest/DELETE/evaluation/evalId.html
Get ACL: https://rest-docs.synapse.org/rest/GET/evaluation/evalId/acl.html
Update ACL: https://rest-docs.synapse.org/rest/PUT/evaluation/acl.html
Get permissions: https://rest-docs.synapse.org/rest/GET/evaluation/evalId/permissions.html

  • async/sync methods are introduced to the DataClass that wrap around the evaluation services
  • async/sync methods' docstrings are updated with example use-cases
  • async/sync Integration tests are patched/introduced

Branch: synpy-1589-evaluation-model-docs (merges into *main)

  • The old Evaluation model is deprecated
  • Our Synapse Python Client documentation (using mkdocs) is updated for this model
  • A tutorial is made for popular use-cases of this model

Testing:

  • Passing unit tests
  • Passing integration tests
  • Passing documentation build
  • Running through the tutorial presents no issues

jaymedina and others added 2 commits October 17, 2025 18:44
)

* Initialize protocol class + Evaluation dataclass

* exposing Evaluation API services. dataclass updates. syntax updates.

* dataclass methods are added which wrap API service functions

* fixed missing imports and syntax failures

* Evaluations can be imported like from synapseclient.models import Evaluation

* correct ACL inputs and output types. first pass at fixing async integration tests.

* fix import issues

* fix type errors. api module and its functions can now be imported individually. test improvements.

* add etag to prevent issues from OCC when updating an evaluation

* some formatting

* refactor: update and create will rely on the attributes changing in the class object itself rather than feeding it into the method. new to_synapse_request

* remove principal_id param. cannot be used. adding examples to docstrings

* patch all async tests

* style

* remove unnecessary imports

* complete refactor of store/update. store is now used for updating too

* add example to Evaluation dataclass

* new evaluation protocol class. moved out to protocols subfolder

* add synchronous integration tests

* new unit tests. updated integration tests. content_source is an immutable field. style

* show available access types

* remove todo

* get logger instance

* no need for request_type param in store_evaluation_async. removing CASE 2 for handling ID of new evals. remove integration test

* docstring example formatting

Co-authored-by: BryanFauble <[email protected]>

* update examples in docstrings

* the logger called in merge_dataclass_entities is now retrieved from active client

* remove _async suffix from evaluation_services functions

* style

* updated docstrings

* store -> create_or_update, updated tests

* style

* refactor update_acl dataclass method for user qol

* give users option to remove principals from ACL

* convert sync test methods to async so it calls schedule_for_cleanup fixture properly

* style

* if/elif -> if/else

* iteratively grab the attributes instead

* request_type is now a CREATE/UPDATE enum

* feed query params directly into client httpx response call so it can parse params with urlencode

* style

* grab the logger outside of the for-loop

---------

Co-authored-by: BryanFauble <[email protected]>
@jaymedina jaymedina force-pushed the synpy-1589-evaluation-model-main branch from eb6e692 to fc79d2e Compare October 17, 2025 22:44
jaymedina and others added 2 commits October 22, 2025 16:42
* first draft of docs

* style

* update tutorial to reflect new code in tutorial script. update formatting of model examples.

* add more examples to API reference docs

* update tutorial source code

* enforce principal_id is not none

* move PRINCIPAL_ID assert. update tutorial .md

* Update docs/tutorials/python/evaluation.md

Co-authored-by: BryanFauble <[email protected]>

* force uppercase

* fix uppercase force

* additional prereq

* fix indentation. fix example

* change eval names

---------

Co-authored-by: BryanFauble <[email protected]>
@jaymedina jaymedina marked this pull request as ready for review October 23, 2025 16:55
@jaymedina jaymedina requested a review from a team as a code owner October 23, 2025 16:55
Copy link
Member

@BryanFauble BryanFauble left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lgtm! There are a few formatting pieces to patch, but otherwise looks great.

@jaymedina
Copy link
Contributor Author

Thanks @BryanFauble 🙏

Copy link
Contributor

@linglp linglp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Thanks for the PR! Just two small comments.

active_evaluations = await Evaluation.get_all_evaluations_async(synapse_client=self.syn, active_only=True)

# THEN the active evaluations should be retrieved
assert active_evaluations is not None
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am a bit worried that the test here is not sufficient. If active_evaluations returns an empty list, this will also pass the test. Is there a way to make sure all the statuses of evaluations are "active" in active_evaluations?

evaluations_list = Evaluation.get_evaluations_by_project(project_id)

# Let's delete the evaluation we created for this tutorial, and any other evaluations in this project (uncomment below to enable deletion)
# for evaluation_to_delete in evaluations_list:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Intead of having the user going through a loop to delete evaluation, I am thinking if it is possible to just do evaluation.delete() since the evaluation object was created in previous step.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants