lacing.store.base#

IntervalAnnotationStore — the headline Pythonic API.

A MutableMapping[TimeInterval, list[Annotation]] facade with methods named after Allen’s relations. See ANN-DOC §C (“a natural design target”) and BACK-DOC §4.1.

The facade hides the index. Phase 0 ships MemoryStore over intervaltree. Phase 1 adds SQLite + R*Tree (.annot) and PostgreSQL

  • tstzrange GiST. The mapping interface is the same in all three.

Classes

IntervalAnnotationStore(*args, **kwargs)

Protocol for any interval-keyed annotation store.

class lacing.store.base.IntervalAnnotationStore(*args, **kwargs)[source]#

Bases: Protocol

Protocol for any interval-keyed annotation store.

Conceptually a MutableMapping[TimeInterval, list[Annotation]]: keys are TimeInterval; values are lists because multiple annotations can share an interval (different tiers, multiple annotators, soft labels).

We use Protocol rather than inheriting from MutableMapping so backends (in-memory, SQLite, Postgres) can structurally conform without forcing a single class hierarchy. The mapping methods below match the MutableMapping ABC; concrete backends like MemoryStore implement the full interface.

add(annotation)[source]#

Append annotation to the list at its reference interval.

Return type:

None

all()[source]#

Iterate every annotation in the store, order unspecified.

Return type:

Iterator[Annotation]

at_tier(tier_name, query)[source]#

Annotations on tier_name that intersect query.

Return type:

Iterator[Annotation]

by_tier(tier_name)[source]#

All annotations on tier_name, regardless of interval.

Return type:

Iterator[Annotation]

contains(query)[source]#

Annotations whose interval strictly contains query (Allen di).

Return type:

Iterator[Annotation]

during(query)[source]#

Annotations whose interval is strictly inside query (Allen d).

Return type:

Iterator[Annotation]

equals(query)[source]#

Allen =: identical interval.

Return type:

Iterator[Annotation]

extend(annotations)[source]#

Add many; equivalent to repeated .add but adapters can optimize.

Return type:

None

finishes(query)[source]#

Allen f: later start, same end.

Return type:

Iterator[Annotation]

intersects(query)[source]#

Annotations whose interval shares any time with query.

Return type:

Iterator[Annotation]

lock(key)[source]#

Exclusive lock named key, held for the with block.

Scoped to this store’s data (for PostgresStore, its owner and project): holders of the same key exclude each other, different keys do not. The reach of the exclusion is the backend’s: MemoryStore excludes threads of this process, SqliteStore also other processes on the host, PostgresStore every client of the database, on any host. A holder that dies releases the lock. Not re-entrant.

Return type:

AbstractContextManager[None]

meets(query)[source]#

Allen m: a.end == q.start.

Return type:

Iterator[Annotation]

overlaps(query)[source]#

Strict Allen o: a.start < q.start < a.end < q.end.

Return type:

Iterator[Annotation]

relate(query, relations)[source]#

Annotations whose interval has any of the named relations to query.

Generic dispatch — useful when relations are computed at runtime.

Return type:

Iterator[Annotation]

remove(annotation_id)[source]#

Remove and return the annotation with this id, or None if absent.

Return type:

Annotation | None

starts(query)[source]#

Allen s: same start, earlier end.

Return type:

Iterator[Annotation]

tiers()[source]#

Registered tiers. Annotations may reference tiers not yet registered; callers decide whether that’s an error.

Return type:

Iterator[Tier]

update(annotation)[source]#

Replace the stored annotation that has annotation.id, atomically.

One commit: a concurrent reader sees the old annotation or the new one, never neither (remove(id) then add(...) leaves a gap in between). The replacement may move to a different interval or tier. Raises KeyError when no annotation has that id — use add() for a new one.

Return type:

None