Skip to content

Implement timelapse containers with nested member scans - #114

Merged
jlegrand62 merged 17 commits into
devfrom
feature/timelapse
Sep 4, 2026
Merged

jlegrand62 merged 17 commits into
devfrom
feature/timelapse

Conversation

@ArthurLuciani2

@ArthurLuciani2 ArthurLuciani2 commented Sep 4, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Adds end-to-end support for timelapses — named containers holding a set of member scans with a shared owner and chronological index — spanning the database layer, the REST API, the Python client, and the CLI.
The implementation enables users to group temporally-related scans into logical containers while maintaining compatibility with existing workflows.

A timelapse is a directory in the FSDB root identified by a timelapse.json marker. Each member scan carries a metadata.timelapse.id (and index) reference. The marker is maintained append/remove-only (never rebuilt on load) and records the container's owner, the ordered list of member scans, and a last_modified timestamp.

Highlights

  • fsdb: create_timelapse / get_timelapse / delete_timelapse + TimeLapse container class; dedicated TimeLapseNotFoundError / TimeLapseExistsError; member scans are registered/unregistered in the marker on create/delete; owner is set on first registration and kept on conflict; last_modified refreshed on each mutation.
  • server: new /api/v1/timelapses REST endpoints (list, CRUD, member scans) with auth/rate-limit integration; API handlers map the dedicated timelapse errors to the correct HTTP statuses.
  • client: timelapse support in the SDK and in filesystem sync (client → server pull/push of timelapse containers).
  • cli: healthcheck validates member scans inside timelapse containers.
  • validation: unify scan/fileset/file/timelapse identifier validation into a single tightened _is_valid_id (128-char cap, no dots, no leading separator, precompiled regex), removing the timelapse-specific validator.
  • build: enable namespace package discovery in all three packages (client, commons, server).

Tests

Backend (test_fsdb.py, test_file_ops.py, test_validation.py), REST API (test_timelapse_api.py), and client sync tests were added/updated. The romi import test now sources from the shared dummy dataset instead of hand-committed fixtures (those legacy fixtures are removed and testdata/ is ignored except romidb).

Breaking / notes

  • _is_valid_id now rejects dots and caps length at 128 chars (previously allowed dots and up to 255).

see also https://codimd.math.cnrs.fr/J0ZAYUJMTRqHXNKQ9SqzNw#Timelapse-Detailed-Implementation-Plan-ltdbgttl_idscan_id

Define the abstract timelapse contract before any backend implements it:
a TimeLapse groups temporal member scans plus shared metadata. Adds the
TimeLapse base class, the Series alias, abstract DB timelapse methods
(create/get/list/delete), and Scan.get_timelapse/get_series navigation.
Exclude the .junie plan/draft directory and the large real_plant dataset
downloaded via test_database.py (150MB of image fixtures) from version control.
Store a timelapse as a top-level directory holding a timelapse.json marker
and its scans nested under <db>/{tl_id}/{scan_id}/. Standalone scans stay
at the root, and new plantdb still opens old flat databases.

Adds TimeLapse and Series FSDB implementations (create/get/list/delete,
member scan management, metadata, dict-style access), timelapse path and
marker helpers, ID validation, dual-read scan loading (_load_scan_at plus
nested discovery in _load_scans/_load_scan), nested scan directory creation,
_timelapse delete with a non-recursive guard, chronological scan sorting by
timelapse.scheduled with index tie-break, and immutable timelapse.id in
metadata updates. Scan/timelapse creation reject cross-namespace collisions.
…hcheck

The healthcheck previously treated each root directory as a scan. It now
descends into timelapse containers (marked by timelapse.json) and validates
their child scans, and reports the correct total scan count.
Adds /timelapses, /timelapses/{id} and /timelapses/{id}/scans resources with
URL builders in api_endpoints, plus timelapse_id and sort filtering on the
existing scan list and table endpoints.
Adds create/get/list/delete_timelapse methods to PlantDBClient and
timelapse_id/sort filter parameters on scan listing. Filesystem sync now
detects timelapse membership from scan metadata and preserves the nested
<db>/{tl_id}/{scan_id}/ layout across local, HTTP and SFTP transfers.
Tests the abstract and FSDB TimeLapse lifecycle (CRUD, sorting, immutable
timelapse.id, collision guards), timelapse path/id validation and nested scan
loading, the timelapse REST endpoints, the PlantDBClient SDK methods, and
nested-layout preservation during local sync.
- Extend `create_timelapse`, `get_timelapse`, `list_timelapses`, and `delete_timelapse` docstrings with concrete doctest-style examples.
…se docstrings

- Delete the `Series` alias for `TimeLapse` in `db.py`.
- Remove the `Scan.get_series` method and its documentation.
- Refine the `TimeLapse` class docstring to reference only a timelapse object.
- Update `Scan.get_timelapse` docstring to reflect the parent timelapse instance.
@ArthurLuciani2 ArthurLuciani2 changed the title Implement timelapse containers with nested member scans - #113 Implement timelapse containers with nested member scans Sep 4, 2026
…fixtures

Rewrite the romi import test to source data from the shared dummy dataset instead of the hand-committed testscan fixtures, then retire those fixtures and ignore the rest of testdata so large datasets are not tracked.
…pse_id

Collapse the timelapse-specific validator into a single tightened _is_valid_id used by scans, filesets, files and timelapses: 128-char cap, no dots, no leading separator, precompiled regex.
Add dedicated TimeLapseNotFound/Exists errors, persist owner and scans index in timelapse markers, register/unregister member scans on create/delete, refresh last_modified, and expose owner/scans via to_dict and item access.
Switch timelapse handlers from scan errors to the dedicated timelapse errors so missing/existing timelapses return the right status, and assert owner and scans in API responses.
@jlegrand62
jlegrand62 self-requested a review September 4, 2026 14:19
@jlegrand62
jlegrand62 merged commit c034400 into dev Sep 4, 2026
2 checks passed
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