From 99bbdba3e00d27f88365c0ead70714e9ef270c00 Mon Sep 17 00:00:00 2001 From: Andrew Lamb Date: Fri, 5 Jun 2026 08:26:57 -0700 Subject: [PATCH 1/5] update version v4.13.0 --- synapseclient/synapsePythonClient | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/synapseclient/synapsePythonClient b/synapseclient/synapsePythonClient index 5131531b8..3209defcf 100644 --- a/synapseclient/synapsePythonClient +++ b/synapseclient/synapsePythonClient @@ -1,6 +1,6 @@ { "client": "synapsePythonClient", - "latestVersion": "4.12.0", + "latestVersion": "4.13.0", "blacklist": [ "0.0.0", "0.4.1", From 60c1eedf2504b08de802e54dfa89ca988b0944ae Mon Sep 17 00:00:00 2001 From: Andrew Lamb Date: Fri, 5 Jun 2026 08:29:55 -0700 Subject: [PATCH 2/5] update release notes v4.13.0 --- docs/news.md | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/docs/news.md b/docs/news.md index 5d099b638..c8a273b8e 100644 --- a/docs/news.md +++ b/docs/news.md @@ -9,6 +9,68 @@ detailing some of the changes. the 4.x.x versions hidden behind optional feature flags or different import paths. Any breaking changes will not be included until v5.0. +## 4.13.0 + +## Highlights + +- New object-oriented `DownloadList` model and `sync_to_synapse` / `sync_from_synapse` workflows with manifest generation, modernizing bulk upload/download. +- Curator extensions gain Grid synchronization: CSV import/export to Grid sessions, Grid-to-CurationTask linking, and configurable view types for metadata tasks. +- Storage locations and migration are now supported in the new OOP models. +- Several bug fixes for table queries, RecordSet versioning, async messaging, and special-character handling in row stores. +- Extensive documentation refresh: new tutorials, migrated reference style, and improved configuration docs. + +## Features + +- [SYNPY-1802] Add DownloadList OOP model and deprecate legacy methods by @andrewelamb in #1347 +- [SYNPY-1800] Add new sync_to_synapse method on StorableContainer by @andrewelamb in #1353 +- [SYNPY-1799, SYNPY-1804] Add manifest generation to sync_from_synapse by @danlu1 in #1354 +- [SYNPY-1809] Add generate_sync_manifest method by @andrewelamb in #1373 +- [DPE-1577] Support storage locations and migration in OOP models by @BryanFauble in #1315 +- [SYNPY-1781] Implement CSV import to Grid session by @linglp in #1360 +- [SYNPY-1782] Implement CSV download from Grid session by @linglp in #1366 +- [SYNPY-1783] Implement Grid synchronization by @linglp in #1368 +- [SYNPY-1760] Add ability to link Grid to CurationTask by @andrewelamb in #1383 +- [SYNPY-1841] Add fields for CurationTask search/filtering by @andrewelamb in #1384 +- [SYNPY-1836] Support configurable view_type_mask in file-based metadata task by @BryanFauble in #1374 + +## Bug Fixes + +- [SYNPY-1835] Fix query() failure when a list column is all-NA by @BryanFauble in #1390 +- [SYNPY-1832] Fix bug causing RecordSet to be updated to v2 by @andrewelamb in #1378 +- [SYNPY-1838] Prevent create_record_based_metadata_task from creating a Grid entity by @andrewelamb in #1380 +- [SYNPY-1824] Fix syn.sendMessage in async context by @linglp in #1370 +- [SYNPY-1749] Allow quote, apostrophe and ellipsis in store_row_async by @danlu1 in #1316 + +## Tech Debt + +- [SYNPY-1764] Add Trivy container vulnerability scanning by @BryanFauble in #1346, #1355, #1357 +- [SYNPY-1798] Update black to 26.3.1 and rerun pre-commit by @linglp in #1341 +- Add validate-release workflow by @xschildw in #1361 +- Fix circular dependencies by @andrewelamb in #1365 +- Fix flaky integration test test_wikiAttachment by @linglp in #1363 +- Fix flaky test test_get_docker_repo_by_id by @linglp in #1381 +- Remove explicit default columns when creating EntityView in curation tests by @linglp in #1377 +- Set higher requests version minimum by @andrewelamb in #1385 + +## Documentation + +- [SYNPY-1810] Migrate all docs to new reference style by @thomasyu888 in #1386 +- [SYNPY-1508] Add tutorial for downloading files by Synapse ID concurrently by @thomasyu888 in #1337 +- [SYNPY-1375] Add Activity/Provenance tutorial by @thomasyu888 in #1351 +- [SYNPY-1402] Update reticulate tutorial for new OOP models/operations API by @thomasyu888 in #1352 +- [SYNPY-1480] Improve documentation around configuration file by @thomasyu888 in #1350 +- [SYNPY-1638] Clarify that the config file is not generated upon installation by @thomasyu888 in #1387 +- Promote the usage of MCP by @thomasyu888 in #1349 +- Curator documentation: add viewtype mask by @thomasyu888 in #1382 +- Add missing MY_PROXY_SECRET_KEY variable in tutorials by @rxu17 in #1375 +- Update project name in activity.py by @thomasyu888 in #1367 + +## Other + +- Add initial CLAUDE.md for AI-assisted development by @BryanFauble in #1342 + +Full Changelog: https://github.com/Sage-Bionetworks/synapsePythonClient/compare/v4.12.0...v4.13.0 + ## 4.12.0 ## Highlights From a1f03d39288aca4d73b00b88259c3b9a9d25d02b Mon Sep 17 00:00:00 2001 From: andrewelamb Date: Fri, 5 Jun 2026 11:08:41 -0700 Subject: [PATCH 3/5] Fix bad import of pandas (#1395) * fix bad import of pandas * add calling of test_import_pandas --- CLAUDE.md | 5 +++++ synapseclient/models/mixins/table_components.py | 5 +++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 0a47bd9a6..16766b4ec 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -102,6 +102,11 @@ synapseutils/ # Legacy bulk utilities (copy, sync, migrate, walk) — s Data flow: User → `operations/` factory → model async methods → `api/` service functions → `client.py` REST calls → Synapse API. Responses deserialized via `fill_from_dict()` on model instances. +### Optional dependency imports +pandas, boto3, pysftp, and other optional extras must never be imported at the top level of any module. Always import them lazily inside the functions/methods that need them. A top-level import of an optional dependency will crash the CLI and any code path that imports the module — even for unrelated operations like `synapse --version`. + +For type annotations referencing pandas types, use `DATA_FRAME_TYPE` and `SERIES_TYPE` from `core/typing_utils.py` rather than `pd.DataFrame` or `pd.Series`. These aliases resolve correctly at type-check time without requiring pandas at runtime. + ## Constraints - Do not use Pydantic for models — the codebase uses stdlib dataclasses with custom serialization. Mixing would break the `@async_to_sync` decorator and `fill_from_dict()` pattern. diff --git a/synapseclient/models/mixins/table_components.py b/synapseclient/models/mixins/table_components.py index f37a1dfaf..3d25c0898 100644 --- a/synapseclient/models/mixins/table_components.py +++ b/synapseclient/models/mixins/table_components.py @@ -13,7 +13,6 @@ from io import BytesIO from typing import Any, Dict, List, Optional, Protocol, Tuple, Union -import pandas as pd from tqdm import tqdm from tqdm.contrib.logging import logging_redirect_tqdm from typing_extensions import Self @@ -139,7 +138,7 @@ def row_labels_from_rows(rows: List[Row]) -> List[Row]: ) -def convert_dtypes_to_json_serializable(df) -> pd.DataFrame: +def convert_dtypes_to_json_serializable(df) -> "DATA_FRAME_TYPE": """ Prepare a DataFrame for JSON/CSV serialization by cleaning special values and normalizing dtypes. Mutates the passed-in DataFrame in place (and also @@ -201,6 +200,8 @@ def convert_dtypes_to_json_serializable(df) -> pd.DataFrame: df = convert_dtypes_to_json_serializable(df) print(df) """ + test_import_pandas() + import pandas as pd def _serialize_json_value(x): if isinstance(x, (list, dict)): From cd2cc866b34a2283ac2fd22af8ff419ef78bf79c Mon Sep 17 00:00:00 2001 From: Andrew Lamb Date: Mon, 8 Jun 2026 11:18:50 -0700 Subject: [PATCH 4/5] Linglings suggestions --- docs/guides/extensions/curator/metadata_contribution.md | 2 +- docs/guides/extensions/curator/metadata_curation.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/guides/extensions/curator/metadata_contribution.md b/docs/guides/extensions/curator/metadata_contribution.md index 67d933a94..40b07d05e 100644 --- a/docs/guides/extensions/curator/metadata_contribution.md +++ b/docs/guides/extensions/curator/metadata_contribution.md @@ -126,7 +126,7 @@ import numpy as np df = pd.read_csv(csv_path) print(df) -# Smoke-test stand-in: fills 4 rows with random integers regardless of column type. +# Example only: fills 4 rows with random integers regardless of column type. # Replace this with real edits that match your task's schema before importing — # schema validation runs in Step 6 and will reject values that don't fit. df = pd.DataFrame( diff --git a/docs/guides/extensions/curator/metadata_curation.md b/docs/guides/extensions/curator/metadata_curation.md index 321b9411a..2cb023df4 100644 --- a/docs/guides/extensions/curator/metadata_curation.md +++ b/docs/guides/extensions/curator/metadata_curation.md @@ -115,7 +115,7 @@ entity_view_id, task_id = create_file_based_metadata_task( attach_wiki=False, # Creates a wiki in the folder with the entity view (Defaults to False) entity_view_name="Animal Study Files View", schema_uri=schema_uri, # Schema found in Step 2 - assignee_principal_id=123456 # Optional: Assign to a user or team + assignee_principal_id=123456, # Optional: Assign to a user or team view_type_mask=ViewTypeMask.FILE # Optional: include additional entity types in the view (ViewTypeMask.FILE | ViewTypeMask.DOCKER). (Defaults to ViewTypeMask.FILE) ) @@ -184,7 +184,7 @@ entity_view_id, task_id = create_file_based_metadata_task( attach_wiki=True, entity_view_name="Animal Study Files View", schema_uri=schema_uri, - assignee_principal_id=123456 # Optional: Assign to a user or team + assignee_principal_id=123456, # Optional: Assign to a user or team view_type_mask=ViewTypeMask.FILE # Optional: include additional entity types in the view (ViewTypeMask.FILE | ViewTypeMask.DOCKER). (Defaults to ViewTypeMask.FILE) ) From c7db1185285372decb17b7c9289fd4ccbe63e9eb Mon Sep 17 00:00:00 2001 From: Andrew Lamb Date: Mon, 8 Jun 2026 12:37:08 -0700 Subject: [PATCH 5/5] Toms suggestions --- docs/news.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/docs/news.md b/docs/news.md index c8a273b8e..f5c13a536 100644 --- a/docs/news.md +++ b/docs/news.md @@ -13,11 +13,10 @@ breaking changes will not be included until v5.0. ## Highlights -- New object-oriented `DownloadList` model and `sync_to_synapse` / `sync_from_synapse` workflows with manifest generation, modernizing bulk upload/download. -- Curator extensions gain Grid synchronization: CSV import/export to Grid sessions, Grid-to-CurationTask linking, and configurable view types for metadata tasks. -- Storage locations and migration are now supported in the new OOP models. -- Several bug fixes for table queries, RecordSet versioning, async messaging, and special-character handling in row stores. -- Extensive documentation refresh: new tutorials, migrated reference style, and improved configuration docs. +- `sync_to_synapse` / `sync_from_synapse` to enable bulk upload/download operations on OOP `Project` and `Folder` models. +- Enabling programmatic Grid collaboration through CSV import/export to Grid sessions, and Grid session to CurationTask linking for Curator. +- Object-oriented `DownloadList`, storage locations and migration are now supported. +- Bug fixes for table queries, Recordset versioning, async messaging, and special-character handling in row stores. ## Features