Skip to content

fix(files)!: follow the api's verbatim file external ids and deletedAt trash - #164

Merged
olavgg merged 2 commits into
mainfrom
fix/files-verbatim-external-ids
Sep 30, 2026
Merged

olavgg merged 2 commits into
mainfrom
fix/files-verbatim-external-ids

Conversation

@JosteinGj

@JosteinGj JosteinGj commented Sep 28, 2026 •

Copy link
Copy Markdown
Contributor

Follows datahub-platform 829a6079 (fix(files): verbatim external ids and column-based soft delete). The SDK still assumed the old model: slug-lowercased file external ids, and a trash that rewrote the external id to DELETED_<checksum>_<id>_<epochMillis>. Against the current api, file_lifecycle_get_search_update_download_trash_restore failed.

Changes

  • INode.deleted_at (Rust and Python, plus the .pyi stub). It is set on files listed by list_trash.

  • FileUpload::new defaults the external id to the file name verbatim (sola.jpg, not sola_jpg). This matches the server's own default and the Java SDK. A file name outside [A-Za-z0-9._:+=-] now needs an explicit external id; otherwise the upload is a 400 naming externalId.

  • Restoring by external id works. The restore/list_trash docs (Rust and Python) no longer steer callers to numeric ids. By external id, the most recently deleted copy is restored.

  • Tests:

    • The lifecycle tests (Rust and Python) assert that the trashed file keeps its external id and has deleted_at set, restore by external id, and check deleted_at is cleared afterwards.
    • The Rust lifecycle test also round-trips a mixed-case id (Lifecycle-Sola.JPG) and looks it up case-insensitively.
    • New tests: default_external_id_is_the_file_name and upload_with_an_external_id_outside_the_charset_is_a_400.
  • Python tests (python_tests/test_files.py):

    • The default external id is the file name.
    • An id is stored verbatim and found under any casing.
    • A charset violation is a 400 naming externalId.
    • Restoring by external id returns the most recently deleted of two copies.
    • The async client's trash/restore round-trips with deleted_at.

Breaking

  • INode has a new public field, so code that builds it literally must add deleted_at.
  • Uploads that relied on the default external id get name.ext instead of name_ext.

Docs

The Files page on datahub-sdk-docs needs updating: the default upload external id, trash entries keeping their external id plus deletedAt, and restore by external id.

Testing

  • cargo test (full suite): 286 passed, 34 ignored
  • ./run_python_tests.sh (full suite, before the new Python tests): 651 passed, 9 skipped
  • ./run_python_tests.sh -k test_files: 16 passed

🤖 Generated with Claude Code

JosteinGj and others added 2 commits September 28, 2026 15:24
…t trash

The api now stores a file's external id as sent (charset-checked, looked
up case-insensitively) and soft-deletes by stamping deletedAt instead of
rewriting the external id to a DELETED_ tombstone.

- INode gains deleted_at (Python: INode.deleted_at).
- FileUpload::new defaults the external id to the file name verbatim,
  the server's own default, rather than a snake-lowercased slug. A name
  outside [A-Za-z0-9._:+=-] needs an explicit external id or is a 400.
- restore by external id works; the docs no longer steer callers to ids.
- The lifecycle tests assert the preserved external id, deletedAt and a
  restore by external id; new tests pin the default id and the 400.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Signed-off-by: jgjesdal <jostein@intellistream.ai>
Default external id is the file name; ids are stored verbatim and looked
up case-insensitively; a charset violation is a 400 naming externalId;
restore by external id takes the most recently deleted copy; and the
async client's trash and restore round-trip with deleted_at.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Signed-off-by: jgjesdal <jostein@intellistream.ai>
@olavgg
olavgg merged commit 1f267e7 into main Sep 30, 2026
18 checks passed
@olavgg
olavgg deleted the fix/files-verbatim-external-ids branch September 30, 2026 11:03
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.

2 participants