Skip to content
Closed
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
5 changes: 5 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
62 changes: 62 additions & 0 deletions docs/news.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions synapseclient/models/mixins/table_components.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -201,6 +200,7 @@ def convert_dtypes_to_json_serializable(df) -> pd.DataFrame:
df = convert_dtypes_to_json_serializable(df)
print(df)
"""
import pandas as pd

def _serialize_json_value(x):
if isinstance(x, (list, dict)):
Expand Down
2 changes: 1 addition & 1 deletion synapseclient/synapsePythonClient
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"client": "synapsePythonClient",
"latestVersion": "4.12.0",
"latestVersion": "4.13.0",
"blacklist": [
"0.0.0",
"0.4.1",
Expand Down
Loading