Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions docs/guides/extensions/curator/metadata_curation.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,32 @@ print(f"Created CurationTask: {task_id}")
- Automatic schema binding to the folder for validation
- Optional wiki attached to the folder

### Controlling who can access the grid session

Both `create_record_based_metadata_task` and `create_file_based_metadata_task` accept an optional `suggested_authorization_mode` that tells clients how to scope access when a grid session is created for the task:

- `SESSION_OWNER` (the server default applied when the mode is omitted) limits access to the session owner and their team. Use it when curation should be restricted to a specific user or team.
- `SOURCE_BENEFACTOR` extends access to anyone with `EDIT` rights on the source entity. Use it when curation should be open to all editors of the source.

```python
from synapseclient.models import AuthorizationMode

entity_view_id, task_id = create_file_based_metadata_task(
synapse_client=syn,
folder_id="syn987654321",
curation_task_name="FileMetadata_Curation",
instructions="Annotate each file with metadata according to the schema requirements.",
entity_view_name="Animal Study Files View",
schema_uri=schema_uri,
suggested_authorization_mode="SOURCE_BENEFACTOR",
)
```

When [CurationTask.create_grid_session][synapseclient.models.CurationTask.create_grid_session] is later called, it forwards this mode to the new grid session and the server uses it to determine access: `SESSION_OWNER` limits access to the session owner (the caller, or an explicit `owner_principal_id`) and their team, while `SOURCE_BENEFACTOR` lets the session inherit access from the source entity's benefactor.

!!! warning "Changing the mode invalidates the active session"
Updating `suggested_authorization_mode` on an existing task causes the server to automatically clear `activeSessionId` on the task status. The previously active grid session is no longer linked to the task, so you must create a new grid session before curation can continue.

## Complete example script

Here's the full script that demonstrates both workflow types:
Expand Down
6 changes: 6 additions & 0 deletions docs/reference/experimental/async/curator.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,12 @@ at your own risk.
inherited_members: true
members:
---
[](){ #AuthorizationMode-reference-async }
::: synapseclient.models.AuthorizationMode
options:
inherited_members: true
members:
---
[](){ #grid-reference-async }
::: synapseclient.models.Grid
options:
Expand Down
6 changes: 6 additions & 0 deletions docs/reference/experimental/sync/curator.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,12 @@ at your own risk.
inherited_members: true
members:
---
[](){ #AuthorizationMode-reference }
::: synapseclient.models.AuthorizationMode
options:
inherited_members: true
members:
---
[](){ #grid-reference }
::: synapseclient.models.Grid
options:
Expand Down
23 changes: 20 additions & 3 deletions synapseclient/extensions/curator/file_based_metadata_task.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from synapseclient.core.exceptions import SynapseHTTPError # type: ignore
from synapseclient.extensions.curator.utils import project_id_from_entity_id
from synapseclient.models import ( # type: ignore
AuthorizationMode,
Column,
ColumnType,
EntityView,
Expand Down Expand Up @@ -325,6 +326,7 @@ def create_file_based_metadata_task(
enable_derived_annotations: bool = False,
assignee_principal_id: Optional[Union[str, int]] = None,
view_type_mask: Union[int, ViewTypeMask] = ViewTypeMask.FILE,
suggested_authorization_mode: Optional[Union[AuthorizationMode, str]] = None,
*,
synapse_client: Optional[Synapse] = None,
) -> Tuple[str, str]:
Expand All @@ -338,7 +340,7 @@ def create_file_based_metadata_task(
```python
import synapseclient
from synapseclient.extensions.curator import create_file_based_metadata_task
from synapseclient.models import ViewTypeMask
from synapseclient.models import AuthorizationMode, ViewTypeMask

syn = synapseclient.Synapse()
syn.login()
Expand All @@ -351,8 +353,9 @@ def create_file_based_metadata_task(
attach_wiki=False,
entity_view_name="Biospecimen Metadata View",
schema_uri="sage.schemas.v2571-amp.Biospecimen.schema-0.0.1",
assignee_principal_id=123456, # Optional: Assign to a user or team (can be str or int)
view_type_mask=ViewTypeMask.FILE | ViewTypeMask.DOCKER, # Optional: include additional entity types in the view
assignee_principal_id=123456, # Optional: Assign to a user or team (can be str or int)
view_type_mask=ViewTypeMask.FILE | ViewTypeMask.DOCKER, # Optional: include additional entity types in the view
suggested_authorization_mode=AuthorizationMode.SOURCE_BENEFACTOR,
)
```

Expand All @@ -377,6 +380,19 @@ def create_file_based_metadata_task(
ViewTypeMask.FILE. Additional types can be added using bitwise OR
(e.g., ViewTypeMask.FILE | ViewTypeMask.DOCKER). Accepts either a
ViewTypeMask enum member or its raw integer value.
suggested_authorization_mode: Recommends who is allowed to access the curation
grid session that a client opens for this task. The value is stored on the
task as a suggestion; the client applies it when it creates a new session.
Choose from:
- SESSION_OWNER: only the person or team who owns the session can access it.
- SOURCE_BENEFACTOR: anyone with EDIT permission on the
data being curated can access the session. This lets editors collaborate
in the same session without being added to a shared ownership team.
When omitted (None, the default), no recommendation is stored and clients
fall back to their usual behavior of finding or creating a private session
for the current user. Changing this value after the task already exists
resets the task's active session, so a new grid session must be opened
before curation can continue.
synapse_client: If not passed in and caching was not disabled by
`Synapse.allow_client_caching(False)` this will use the last created
instance from the Synapse class constructor.
Expand Down Expand Up @@ -481,6 +497,7 @@ def create_file_based_metadata_task(
task_properties=FileBasedMetadataTaskProperties(
upload_folder_id=folder_id,
file_view_id=entity_view_id,
suggested_authorization_mode=suggested_authorization_mode,
),
).store(synapse_client=synapse_client)
except Exception as e:
Expand Down
21 changes: 19 additions & 2 deletions synapseclient/extensions/curator/record_based_metadata_task.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from synapseclient.core.utils import test_import_pandas
from synapseclient.extensions.curator.utils import project_id_from_entity_id
from synapseclient.models import (
AuthorizationMode,
CurationTask,
Grid,
JSONSchema,
Expand Down Expand Up @@ -111,6 +112,7 @@ def create_record_based_metadata_task(
bind_schema_to_record_set: bool = True,
enable_derived_annotations: bool = False,
assignee_principal_id: Optional[Union[str, int]] = None,
suggested_authorization_mode: Optional[Union[AuthorizationMode, str]] = None,
*,
synapse_client: Optional[Synapse] = None,
project_id: Optional[str] = None, # Deprecated, will be removed in v5.0.0
Expand All @@ -136,13 +138,13 @@ def create_record_based_metadata_task(
Example: Creating a record-based metadata curation task with a schema URI
In this example, we create a RecordSet and CurationTask for biospecimen metadata
curation using a schema URI. By default this will also bind the schema to the
RecordSet, however the `bind_schema_to_record_set` parameter can be set to
RecordSet, however the bind_schema_to_record_set parameter can be set to
False to skip that step.


```python
import synapseclient
from synapseclient.extensions.curator import create_record_based_metadata_task
from synapseclient.models import AuthorizationMode

syn = synapseclient.Synapse()
syn.login()
Expand All @@ -157,6 +159,7 @@ def create_record_based_metadata_task(
instructions="Please curate this metadata according to the schema requirements",
schema_uri="schema-org-schema.name.schema-v1.0.0",
assignee_principal_id=123456, # Optional: Assign to a user or team (can be str or int)
suggested_authorization_mode=AuthorizationMode.SOURCE_BENEFACTOR,
create_grid=False, # Opt out of deprecated Grid creation
)
```
Expand All @@ -182,6 +185,19 @@ def create_record_based_metadata_task(
(default), the task will be unassigned. For metadata tasks, this determines
the owner of the grid session. Team members can all join grid sessions owned
by their team, while user-owned grid sessions are restricted to that user only.
suggested_authorization_mode: Recommends who is allowed to access the curation
grid session that a client opens for this task. The value is stored on the
task as a suggestion; the client applies it when it creates a new session.
Choose from:
- SESSION_OWNER: only the person or team who owns the session can access it.
- SOURCE_BENEFACTOR: anyone with EDIT permission on the
data being curated can access the session. This lets editors collaborate
in the same session without being added to a shared ownership team.
When omitted (None, the default), no recommendation is stored and clients
fall back to their usual behavior of finding or creating a private session
for the current user. Changing this value after the task already exists
resets the task's active session, so a new grid session must be opened
before curation can continue.
synapse_client: If not passed in and caching was not disabled by
`Synapse.allow_client_caching(False)` this will use the last created
instance from the Synapse class constructor.
Expand Down Expand Up @@ -286,6 +302,7 @@ def create_record_based_metadata_task(
),
task_properties=RecordBasedMetadataTaskProperties(
record_set_id=record_set_id,
suggested_authorization_mode=suggested_authorization_mode,
),
).store(synapse_client=synapse_client)
synapse_client.logger.info(
Expand Down
2 changes: 2 additions & 0 deletions synapseclient/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
)
from synapseclient.models.annotations import Annotations
from synapseclient.models.curation import (
AuthorizationMode,
CurationTask,
CurationTaskStatus,
FileBasedMetadataTaskProperties,
Expand Down Expand Up @@ -97,6 +98,7 @@
"Team",
"TeamMember",
"TeamMembershipStatus",
"AuthorizationMode",
"CurationTask",
"CurationTaskStatus",
"FileBasedMetadataTaskProperties",
Expand Down
Loading
Loading