Reader
timenet.reader ¶source
Deserialization of a TimeF version directory into a :class:~timenet.dataset.TimeFDataset.
RECORD_BATCH_SIZE
module-attribute
¶source
The most Records one batch of a Record stream holds, unless the stream sets another batch size.
TASK_BATCH_SIZE
module-attribute
¶source
The most tasks one batch of a task read or stream holds, unless a stream sets another batch size.
LoadPlan
dataclass
¶source
Specify, for each kind of stored value, whether a read loads it or leaves it lazy.
A read applies its plan to the objects it builds: a dataset's records, tasks, and annotations; a
record's signals, time offsets, and annotations; a task's text, annotations, and the records,
signals, and annotations it references. It loads nothing on objects passed to it, such as the
records given to read_tasks, and nothing on tasks it builds only as another task's
from_tasks. A plan never widens what a read reaches.
ALL_EAGER
class-attribute
¶source
ALL_EAGER: LoadPlan
Load every kind, so the objects a read builds need no storage afterwards.
Loading ¶source
Bases: StrEnum
How a read delivers one kind of stored value on the objects it builds.
TimeFReader ¶source
Read a committed TimeF dataset through its DuckDB control plane.
get ¶source
get(
kind: type[E],
id: EntityId,
*,
parent: ParentAlias | DatasetRef | None = None,
load: LoadPlan = ALL_LAZY,
) -> E
Read one object by its ID, from this dataset or imported from a parent.
An ID is an opaque handle. It stays the same across edits of one dataset, and it means
something only together with that dataset's reference: an object imported from a parent is
found by the parent's ID, with parent naming the parent. An ID is not a lookup key for
content; to find an object by what it is, read objects with :meth:iter_records or
:meth:read_tasks and check their metadata.
get(Task, 7) reads the task with ID 7; get(AnswerTask, 7) also checks that it is an
answer task. With parent, id is the ID the parent dataset gives the object, and the
read returns this dataset's imported copy.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
kind
|
type[E]
|
|
required |
id
|
EntityId
|
The object's ID, a positive int64. |
required |
parent
|
ParentAlias | DatasetRef | None
|
The parent the object was imported from: the |
None
|
load
|
LoadPlan
|
Which kinds of stored values to load into the object and what it references. The default loads none. |
ALL_LAZY
|
Returns:
| Type | Description |
|---|---|
E
|
The object. A Signal is part of its Record, which the read builds too. |
Raises:
| Type | Description |
|---|---|
TimeFNotFoundError
|
If the ID or |
TimeFValidationError
|
If |
TimeFFormatError
|
If the catalog names no parent release or another one for the alias than the manifest does, or lists the alias or a parent ID more than once. |
get_many ¶source
get_many(
kind: type[E],
ids: Iterable[EntityId],
*,
parent: ParentAlias | DatasetRef | None = None,
load: LoadPlan = ALL_LAZY,
) -> tuple[E, ...]
Read objects of one kind by their IDs, in one batch.
IDs are opaque handles, as :meth:get describes: stable across edits of this dataset,
meaningful only with its reference, and no key for content. The objects form one graph: a
Record that two of them reference is one object, and the Signals on one irregular axis
share one time-offsets handle. load loads their values in one batch.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
kind
|
type[E]
|
|
required |
ids
|
Iterable[EntityId]
|
The objects' IDs, positive int64s in a list, tuple, or other iterable. With
|
required |
parent
|
ParentAlias | DatasetRef | None
|
The parent the objects were imported from: the |
None
|
load
|
LoadPlan
|
Which kinds of stored values to load into the objects and what they reference. The default loads none. |
ALL_LAZY
|
Returns:
| Type | Description |
|---|---|
tuple[E, ...]
|
One object per ID, in the order of |
Raises:
| Type | Description |
|---|---|
TimeFNotFoundError
|
If an ID or |
TimeFValidationError
|
If |
TimeFFormatError
|
If the catalog names no parent release or another one for the alias than the manifest does, or lists the alias or a parent ID more than once. |
iter_records ¶source
iter_records(
record_ids: Iterable[EntityId] | None = None,
*,
with_annotations: bool = True,
load: LoadPlan = ALL_LAZY,
batch_size: int = RECORD_BATCH_SIZE,
) -> Iterator[Record]
Yield complete records a bounded batch at a time, in a requested ID order or in record order.
The stream builds and loads each batch on its own, before it yields the batch. The records of a batch share the objects that the batch builds. So the signals on one irregular axis share one handle to the time offsets of that axis.
Batches share nothing. So after the stream yields the objects of a batch, it keeps none of them. It holds one batch of objects at a time. If two batches request one record ID, each batch builds that record as a separate object. The stream checks every requested ID before it builds the first batch.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
record_ids
|
Iterable[EntityId] | None
|
IDs to read in result order, or |
None
|
with_annotations
|
bool
|
Whether to build annotations on the records and descendants. |
True
|
load
|
LoadPlan
|
The kinds of stored values to load into the records that each batch builds. The default loads none. |
ALL_LAZY
|
batch_size
|
int
|
The most records that a batch holds. By default, a batch holds up to 1,000
records ( |
RECORD_BATCH_SIZE
|
Yields:
| Type | Description |
|---|---|
Record
|
Records with loaded values for each kind of value that the plan names. Other stored |
Record
|
values stay behind their value handles. |
iter_tasks ¶source
iter_tasks(
*,
inputs: Iterable[Record] | None = None,
split: Split | str | None = None,
required_modalities: Iterable[InputModality]
| None = None,
supported_modalities: Iterable[InputModality]
| None = None,
load: LoadPlan = ALL_LAZY,
batch_size: int = TASK_BATCH_SIZE,
) -> Iterator[Task]
Yield the tasks :meth:read_tasks reads, a bounded batch at a time.
Each batch is built and loaded on its own. Its tasks share the objects it builds: a record
that two of them use is one object, and the signals on one irregular axis share one
time-offsets handle. Batches share nothing but inputs, so the stream keeps none of a
batch's objects once it has yielded them: it holds one batch of objects and that batch's
task IDs at a time, and selects the next batch's IDs after the last one, while the reader
keeps compact chunk locators for the signals it has resolved until it closes. A record or
parent task that tasks of several batches use is built once per batch, as separate objects
with the same ID, each loaded as far as its own batch's plan reaches it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
inputs
|
Iterable[Record] | None
|
Keep only tasks that use one of these Records as input, or |
None
|
split
|
Split | str | None
|
Keep only tasks of this split, or |
None
|
required_modalities
|
Iterable[InputModality] | None
|
Keep only tasks that declare every one of these input modalities. |
None
|
supported_modalities
|
Iterable[InputModality] | None
|
Keep only tasks whose declared input modalities are all among these. |
None
|
load
|
LoadPlan
|
Which kinds of stored values to load into the objects each batch builds. The
default loads none. A batch builds but does not load what it reaches only through
its tasks' |
ALL_LAZY
|
batch_size
|
int
|
The most tasks a batch holds. By default, a batch holds up to 5,000 tasks
( |
TASK_BATCH_SIZE
|
Yields:
| Type | Description |
|---|---|
Task
|
Concrete tasks in stable ID order. |
open
classmethod
¶source
open(
path: str | Path,
*,
sources_root: str | Path | None = None,
) -> TimeFReader
Open a local version directory for reading.
Opening reads only metadata, as :func:~timenet.registry.dependencies.open_local_version
does. The reader opens the catalog on its first read. Close the reader after use, or use it
as a context manager.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str | Path
|
The version directory, which holds |
required |
sources_root
|
str | Path | None
|
The registry root to find payload sources under. By default this is the
root that holds |
None
|
Returns:
| Type | Description |
|---|---|
TimeFReader
|
A reader for the version. |
Raises:
| Type | Description |
|---|---|
FileNotFoundError
|
If |
TimeFValidationError
|
If the version has payload sources, is not stored as
|
TimeNetMissingParentError
|
If a payload source is not under the sources root. |
read ¶source
read(*, load: LoadPlan = ALL_LAZY) -> TimeFDataset
Read the whole dataset, loading the kinds of stored values that load names.
Every call builds new objects. With the default, every stored value stays behind its value
handle and reads through to storage on access. With LoadPlan.ALL_EAGER, the dataset
needs no storage after the reader closes.
The dataset gets the parent cards and the lineage of the manifest, and the import map of the catalog, so a later import into it reuses the copies it holds instead of copying them again.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
load
|
LoadPlan
|
Which kinds of stored values to load into the objects the read builds. |
ALL_LAZY
|
Returns:
| Type | Description |
|---|---|
TimeFDataset
|
The dataset. |
Raises:
| Type | Description |
|---|---|
TimeFFormatError
|
If the catalog's parent aliases or their parent releases differ from the manifest's parent cards, or the catalog lists an alias or a parent ID more than once. |
read_annotation_table ¶source
read_annotation_table(
object_type: ObjectKind | None = None,
) -> Table
Return every annotation occurrence with its content as an Arrow table.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
object_type
|
ObjectKind | None
|
Keep occurrences on this object kind, such as |
None
|
Returns:
| Type | Description |
|---|---|
Table
|
One row per occurrence. |
read_target_table ¶source
read_target_table(
record_ids: Iterable[EntityId] | None = None,
*,
required_modalities: Iterable[InputModality]
| None = None,
supported_modalities: Iterable[InputModality]
| None = None,
split: Split | str | None = None,
) -> Table
Return every inline task target as one typed Arrow row.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
record_ids
|
Iterable[EntityId] | None
|
Keep only targets of tasks whose inputs include one of these Records. |
None
|
split
|
Split | str | None
|
Keep only targets of tasks of this split, or |
None
|
Returns:
| Type | Description |
|---|---|
Table
|
Targets in task ID and position order. |
read_task_table ¶source
read_task_table(
record_ids: Iterable[EntityId] | None = None,
*,
required_modalities: Iterable[InputModality]
| None = None,
supported_modalities: Iterable[InputModality]
| None = None,
split: Split | str | None = None,
) -> Table
Return the tasks as an Arrow table without building Task objects.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
record_ids
|
Iterable[EntityId] | None
|
Keep only tasks whose inputs include one of these Records, or |
None
|
split
|
Split | str | None
|
Keep only tasks of this split, or |
None
|
Returns:
| Type | Description |
|---|---|
Table
|
One row per task with public IDs in place of object references. Targets are in |
Table
|
meth: |
read_tasks ¶source
read_tasks(
*,
inputs: Iterable[Record] | None = None,
split: Split | str | None = None,
required_modalities: Iterable[InputModality]
| None = None,
supported_modalities: Iterable[InputModality]
| None = None,
load: LoadPlan = ALL_LAZY,
) -> tuple[Task, ...]
Read the tasks that match every filter given, in one pass; no filter reads every task.
Every call builds new tasks. A record a task uses that is not among inputs is read once
and shared by every task of the call.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
inputs
|
Iterable[Record] | None
|
Keep only tasks that use one of these Records as input, or |
None
|
split
|
Split | str | None
|
Keep only tasks of this split, or |
None
|
required_modalities
|
Iterable[InputModality] | None
|
Keep only tasks that declare every one of these input modalities. |
None
|
supported_modalities
|
Iterable[InputModality] | None
|
Keep only tasks whose declared input modalities are all among these. |
None
|
load
|
LoadPlan
|
Which kinds of stored values to load into the objects the read builds. The default loads none. |
ALL_LAZY
|
Returns:
| Type | Description |
|---|---|
tuple[Task, ...]
|
Concrete tasks in stable ID order. |
record_ids ¶source
Return the ID of every Record, without building the Records.
The IDs come in the release's record order, which iter_records() and read() also use.
Every reader of a release returns the same order. In a release with imported Records, the
order follows where the values are stored, so that a walk over the records reads the stored
values in sequence. In any other release, the order is by ID.
Returns:
| Type | Description |
|---|---|
tuple[EntityId, ...]
|
The IDs in the order :meth: |
verify ¶source
Verify the size and checksum of every file the release reads.
These are the artifacts its manifest lists, and the files it pins on each payload source.
Raises:
| Type | Description |
|---|---|
TimeNetFileError
|
If a file is missing, or its size or checksum differs from the manifest record that describes it: its own record, or the pin of a payload source file. |