# Timenet.types

## timenet.types

TimeF value types and type system: versions, units, enums, specs, annotations, tasks, metadata.

### EntityId `module-attribute`

```
EntityId: TypeAlias = int
```

The id of one TimeF entity, a positive int64.

### TASKS `module-attribute`

```
TASKS: dict[TaskType, type[Task]] = _build_task_registry()
```

Concrete task classes keyed by their stable storage tag.

### TargetItem `module-attribute`

```
TargetItem: TypeAlias = (
    TextHandle | int | float | bool | Record | Signal | Span
)
```

### US\_PER\_S `module-attribute`

```
US_PER_S = 1000000
```

### ureg `module-attribute`

```
ureg = pint.UnitRegistry()
```

### Access

Bases: `StrEnum`

How a user obtains the source data.

#### CREDENTIALED `class-attribute` `instance-attribute`

```
CREDENTIALED = 'credentialed'
```

A credentialed account and a signed agreement are needed, for example a PhysioNet DUA.

#### OPEN `class-attribute` `instance-attribute`

```
OPEN = 'open'
```

Anyone can fetch the data; no account or agreement is needed.

#### RESTRICTED `class-attribute` `instance-attribute`

```
RESTRICTED = 'restricted'
```

Access is granted case by case, for example an AWS-IAM grant or a direct request.

### Annotation `dataclass`

Contextual metadata attached to a record, optionally anchored to a region of its timeline.

An annotation carries a `value`, a `span`, or both. With a span, it says where on the
Record timeline it applies. Its owner determines which Signals it covers. Without a span, it is record-scoped
context that has no place in time, like a subject's age. The span's own shape says whether the
annotation marks a time offset or covers a stretch. One class covers every shape::

```
Annotation(key="age", value=64)
Annotation(key="stimulus", span=TimePoint.seconds(0.5))
Annotation(key="artifact", value="motion", span=TimeInterval.seconds(0.0, 0.25))
```

The class is final. Reuse content as a constant, or build content that varies with a function::

```
HEALTHY_ANNOTATION = Annotation(key="condition", value="healthy")


def quality_annotation(level: Literal["low", "medium", "high"]) -> Annotation:
    return Annotation(key="quality", value=level)
```

#### confidence `class-attribute` `instance-attribute`

```
confidence: float | None = field(
    default=None, compare=False
)
```

Optional confidence for this particular application.

#### description `class-attribute` `instance-attribute`

```
description: str | None = None
```

Optional human-readable description of the annotation.

#### key `instance-attribute`

```
key: str
```

Name identifying the annotation.

#### metadata `class-attribute` `instance-attribute`

```
metadata: JsonMapping = field(default_factory=dict)
```

Optional metadata that is part of the reusable content.

#### name `property`

```
name: str
```

The annotation's public name.

#### occurrence\_metadata `class-attribute` `instance-attribute`

```
occurrence_metadata: JsonMapping = field(
    default_factory=dict, compare=False
)
```

Optional metadata for this particular application.

#### source `class-attribute` `instance-attribute`

```
source: str | None = None
```

Optional per-instance provenance (the rater, method, or model behind this value). Unlike
`description`, which the descriptor holds once per key, `source` can differ between
annotations that share a key.

#### span `class-attribute` `instance-attribute`

```
span: TimePoint | TimeInterval | None = None
```

Where on the Record timeline this annotation applies. Its owner determines its scope.
`None` means it is record-scoped context with no place in time.

#### unit `class-attribute` `instance-attribute`

```
unit: str | Unit | None = None
```

Optional physical unit of `value`. Give a unit string (for example `"years"`) or a
:class:`pint.Unit`. Construction validates the unit against the shared registry. An unrecognized
string raises `ValueError`. Construction stores a `pint.Unit` as its canonical name.

#### value `class-attribute` `instance-attribute`

```
value: ValueField[Any, AnnotationValue] = field(
    default=ValueField(_annotation_value, None)
)
```

A native scalar or a text handle. Call `read()` for string and string-list values.

`None` makes it a pure marker, which needs a `span` to mark something.

### AnnotationDescriptor

Bases: `TimeFModel`

Type-level projection of an annotation key, stored in the schema and manifest.

#### annotation\_type `instance-attribute`

```
annotation_type: AnnotationType
```

Which of the three annotation shapes this key uses.

#### description `class-attribute` `instance-attribute`

```
description: StrictStr | None = None
```

Optional human-readable description of the annotation.

#### key `instance-attribute`

```
key: StrictStr
```

Name of the annotation this descriptor projects.

#### model\_config `class-attribute` `instance-attribute`

```
model_config = ConfigDict(
    extra="forbid",
    frozen=True,
    revalidate_instances="always",
    serialize_by_alias=True,
    validate_by_name=True,
    validate_default=True,
)
```

#### unit `class-attribute` `instance-attribute`

```
unit: Annotated[
    StrictStr | None, BeforeValidator(normalize_unit)
] = None
```

Optional physical unit of the value.

#### value\_type `class-attribute` `instance-attribute`

```
value_type: ValueType | None = None
```

Manifest value-type tag (bool, int, float, str, list, or map).

### AnnotationType

Bases: `StrEnum`

Name the shape an annotation key takes across the dataset. It is a schema-level projection in the manifest.

#### INTERVAL `class-attribute` `instance-attribute`

```
INTERVAL = 'interval'
```

#### POINT `class-attribute` `instance-attribute`

```
POINT = 'point'
```

#### STATIC `class-attribute` `instance-attribute`

```
STATIC = 'static'
```

### AnswerTask `dataclass`

Bases: `Task`

Answer a question or caption the inputs.

#### annotations `class-attribute` `instance-attribute`

```
annotations: tuple[Annotation, ...] = ()
```

Annotations describing this task itself.

#### from\_tasks `class-attribute` `instance-attribute`

```
from_tasks: tuple[Task, ...] = field(
    default=(), compare=False
)
```

Tasks from which this task was derived.

#### id `property`

```
id: EntityId
```

The task's id, unique among the tasks of its dataset.

:meth:`~timenet.dataset.TimeFDataset.add_task` sets it. The reader sets it when it reads the task back.

Raises:

| Type | Description |
| --- | --- |
| `TimeFValidationError` | If the task is not in a dataset yet. |

#### input\_annotations `class-attribute` `instance-attribute`

```
input_annotations: tuple[Annotation, ...] = field(
    default=(), compare=False
)
```

Existing annotation occurrences supplied to the model as context.

#### input\_modalities `class-attribute` `instance-attribute`

```
input_modalities: frozenset[InputModality] | None = None
```

Optional override. None infers the input kinds when resolved or written.

#### inputs `class-attribute` `instance-attribute`

```
inputs: tuple[Record, ...] = field(
    default=(), compare=False
)
```

Records supplied to the model, in semantic order.

#### metadata `class-attribute` `instance-attribute`

```
metadata: JsonMapping = field(default_factory=dict)
```

Optional JSON-compatible task metadata.

#### prompt `class-attribute` `instance-attribute`

```
prompt: ValueField[
    str | TextHandle | None, TextHandle | None
] = field(default=ValueField(optional_text, None))
```

Call `read()` for the prompt; `None` identifies an unprompted task.

#### rationale `class-attribute` `instance-attribute`

```
rationale: ValueField[
    str | TextHandle | None, TextHandle | None
] = field(default=ValueField(optional_text, None))
```

Call `read()` for the explanation; `None` means no rationale is present.

#### resolved\_input\_modalities `property`

```
resolved_input_modalities: frozenset[InputModality]
```

The validated override, or kinds inferred from the current inputs.

Inference reads Signal specs within the scope, the prompt, and text input annotations.
It does not load values or inspect targets. NO\_INPUT means there are no input Records.
The result is not cached: connectors can assign inputs after construction.

#### scope `class-attribute` `instance-attribute`

```
scope: Span | None = None
```

Optional region of the inputs to which the task applies.

#### split `class-attribute` `instance-attribute`

```
split: Split | None = None
```

The partition the task belongs to: train, validation, or test. None when the dataset does not
partition its tasks.

#### target\_annotations `class-attribute` `instance-attribute`

```
target_annotations: tuple[Annotation, ...] = field(
    default=(), compare=False
)
```

Existing annotation occurrences that form the expected output.

#### targets `class-attribute` `instance-attribute`

```
targets: ValueField[
    Iterable[TargetInput] | None,
    tuple[TargetItem, ...] | None,
] = field(
    default=ValueField(_target_values, None), compare=False
)
```

Ordered native values and stored objects that form the expected output.

#### task\_type `class-attribute`

```
task_type: TaskType = TaskType.ANSWER
```

#### annotate

```
annotate(annotation: Annotation) -> Annotation
```

Attach one annotation occurrence and return it.

Returns:

| Type | Description |
| --- | --- |
| `Annotation` | The attached occurrence. |

#### check\_against\_scope

```
check_against_scope() -> None
```

Validate configuration that depends on the finalized scope.

#### check\_targets

```
check_targets() -> None
```

Make sure that the final targets follow the rules of this task class.

#### named\_records

```
named_records() -> tuple[Record, ...]
```

Return the Records that the task names, each once: its inputs, then its Record targets.

A task class with candidate Records returns them too, after the inputs.

#### referenced\_signals

```
referenced_signals() -> tuple[Signal, ...]
```

Return the Signals that the task references, each once.

They are its Signal targets, then the Signals that its scope and its span targets name, in the
order of :meth:`spans`.

#### register\_label\_set

```
register_label_set(label_sets: LabelSetRegistry) -> None
```

Add the label set of the task to the dataset's label sets.

Only a classification task has a label set.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `label_sets` | `LabelSetRegistry` | The label sets of the dataset so far. | *required* |

#### spans

```
spans() -> tuple[Span, ...]
```

Return the task scope followed by every span-valued target.

#### with\_references

```
with_references(
    records: Mapping[EntityId, Record],
    signals: Mapping[EntityId, Signal],
) -> Self
```

Return a copy of the task that references the given Records and Signals, by ID.

The copy has the class of the task. Each input, candidate Record, Record target, and Signal
target of the copy is the object of the same ID in `records` or `signals`. The scope and
the span targets of the copy name the Signals of the same IDs in `signals`. Each span keeps
its class. The copy has no ID.

Every other field keeps its value: the annotations of the task, the annotations that it
references, `from_tasks`, the text, and the metadata. A caller that needs other values for
them sets them on the copy.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `records` | `Mapping[EntityId, Record]` | The Records for the copy, by ID. | *required* |
| `signals` | `Mapping[EntityId, Signal]` | The Signals for the copy, by ID. | *required* |

Returns:

| Type | Description |
| --- | --- |
| `Self` | The copy. |

Raises:

| Type | Description |
| --- | --- |
| `TimeFValidationError` | If a Record or Signal that the task references has no ID, or if `records` or `signals` has no object for its ID. |

### ArrayHandle

Bases: `ValueHandle[Array]`

Refer to one array with one value per step, as Arrow, as NumPy, or as a range of steps.

A handle returns the values as it holds or stores them, nulls included, and checks them against
no spec.

#### is\_loaded `abstractmethod` `property`

```
is_loaded: bool
```

Whether the value is held in memory, so `read()` needs no storage access.

#### read `abstractmethod`

```
read() -> _Value_co
```

Return the value, from memory or read through from storage.

#### read\_numpy

```
read_numpy() -> ndarray
```

Return the values as a read-only NumPy array, shaped `(n_steps, *value_shape)`.

The default converts :meth:`read`. A handle whose data is NumPy already returns it without
building Arrow.

Returns:

| Type | Description |
| --- | --- |
| `ndarray` | The values, in the NumPy dtype of their Arrow type. |

Raises:

| Type | Description |
| --- | --- |
| `TimeFNullValuesError` | If the values contain nulls, which NumPy cannot hold. Read them with :meth:`read` instead. |

#### read\_steps

```
read_steps(start: int, stop: int) -> Array
```

Return the half-open step range `[start, stop)`.

The default slices :meth:`read`, so a `stop` past the end reads to the end. A stored
handle reads only the chunks that cover the range.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `start` | `int` | First step, inclusive, and not negative. | *required* |
| `stop` | `int` | Last step, exclusive, and not before `start`. | *required* |

Returns:

| Type | Description |
| --- | --- |
| `Array` | The steps' values, in the form :meth:`read` returns. |

### ClassificationTask `dataclass`

Bases: `Task`

Classify the inputs using a required set of allowed labels.

#### annotations `class-attribute` `instance-attribute`

```
annotations: tuple[Annotation, ...] = ()
```

Annotations describing this task itself.

#### from\_tasks `class-attribute` `instance-attribute`

```
from_tasks: tuple[Task, ...] = field(
    default=(), compare=False
)
```

Tasks from which this task was derived.

#### id `property`

```
id: EntityId
```

The task's id, unique among the tasks of its dataset.

:meth:`~timenet.dataset.TimeFDataset.add_task` sets it. The reader sets it when it reads the task back.

Raises:

| Type | Description |
| --- | --- |
| `TimeFValidationError` | If the task is not in a dataset yet. |

#### input\_annotations `class-attribute` `instance-attribute`

```
input_annotations: tuple[Annotation, ...] = field(
    default=(), compare=False
)
```

Existing annotation occurrences supplied to the model as context.

#### input\_modalities `class-attribute` `instance-attribute`

```
input_modalities: frozenset[InputModality] | None = None
```

Optional override. None infers the input kinds when resolved or written.

#### inputs `class-attribute` `instance-attribute`

```
inputs: tuple[Record, ...] = field(
    default=(), compare=False
)
```

Records supplied to the model, in semantic order.

#### label\_set `instance-attribute`

```
label_set: LabelSet
```

The allowed labels and whether a target can contain more than one label.

#### metadata `class-attribute` `instance-attribute`

```
metadata: JsonMapping = field(default_factory=dict)
```

Optional JSON-compatible task metadata.

#### prompt `class-attribute` `instance-attribute`

```
prompt: ValueField[
    str | TextHandle | None, TextHandle | None
] = field(default=ValueField(optional_text, None))
```

Call `read()` for the prompt; `None` identifies an unprompted task.

#### rationale `class-attribute` `instance-attribute`

```
rationale: ValueField[
    str | TextHandle | None, TextHandle | None
] = field(default=ValueField(optional_text, None))
```

Call `read()` for the explanation; `None` means no rationale is present.

#### resolved\_input\_modalities `property`

```
resolved_input_modalities: frozenset[InputModality]
```

The validated override, or kinds inferred from the current inputs.

Inference reads Signal specs within the scope, the prompt, and text input annotations.
It does not load values or inspect targets. NO\_INPUT means there are no input Records.
The result is not cached: connectors can assign inputs after construction.

#### scope `class-attribute` `instance-attribute`

```
scope: Span | None = None
```

Optional region of the inputs to which the task applies.

#### split `class-attribute` `instance-attribute`

```
split: Split | None = None
```

The partition the task belongs to: train, validation, or test. None when the dataset does not
partition its tasks.

#### target\_annotations `class-attribute` `instance-attribute`

```
target_annotations: tuple[Annotation, ...] = field(
    default=(), compare=False
)
```

Existing annotation occurrences that form the expected output.

#### targets `class-attribute` `instance-attribute`

```
targets: ValueField[
    Iterable[TargetInput] | None,
    tuple[TargetItem, ...] | None,
] = field(
    default=ValueField(_target_values, None), compare=False
)
```

Ordered native values and stored objects that form the expected output.

#### task\_type `class-attribute`

```
task_type: TaskType = TaskType.CLASSIFICATION
```

#### annotate

```
annotate(annotation: Annotation) -> Annotation
```

Attach one annotation occurrence and return it.

Returns:

| Type | Description |
| --- | --- |
| `Annotation` | The attached occurrence. |

#### check\_against\_scope

```
check_against_scope() -> None
```

Validate configuration that depends on the finalized scope.

#### check\_targets

```
check_targets() -> None
```

Make sure that the target labels follow the rules of the label set.

The labels come from the targets stored directly on the task or from its target annotations.
Each label must be text.

After the targets are final, the dataset calls this method when it adds or streams the task.

Raises:

| Type | Description |
| --- | --- |
| `TimeFValidationError` | If a label is not text or the labels break a rule of the label set. |

#### named\_records

```
named_records() -> tuple[Record, ...]
```

Return the Records that the task names, each once: its inputs, then its Record targets.

A task class with candidate Records returns them too, after the inputs.

#### referenced\_signals

```
referenced_signals() -> tuple[Signal, ...]
```

Return the Signals that the task references, each once.

They are its Signal targets, then the Signals that its scope and its span targets name, in the
order of :meth:`spans`.

#### register\_label\_set

```
register_label_set(label_sets: LabelSetRegistry) -> None
```

Add the label set of the task to the dataset's label sets.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `label_sets` | `LabelSetRegistry` | The label sets of the dataset so far. | *required* |

Raises:

| Type | Description |
| --- | --- |
| `TimeFValidationError` | If a different set already has the same name. |

#### spans

```
spans() -> tuple[Span, ...]
```

Return the task scope followed by every span-valued target.

#### with\_references

```
with_references(
    records: Mapping[EntityId, Record],
    signals: Mapping[EntityId, Signal],
) -> Self
```

Return a copy of the task that references the given Records and Signals, by ID.

The copy has the class of the task. Each input, candidate Record, Record target, and Signal
target of the copy is the object of the same ID in `records` or `signals`. The scope and
the span targets of the copy name the Signals of the same IDs in `signals`. Each span keeps
its class. The copy has no ID.

Every other field keeps its value: the annotations of the task, the annotations that it
references, `from_tasks`, the text, and the metadata. A caller that needs other values for
them sets them on the copy.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `records` | `Mapping[EntityId, Record]` | The Records for the copy, by ID. | *required* |
| `signals` | `Mapping[EntityId, Signal]` | The Signals for the copy, by ID. | *required* |

Returns:

| Type | Description |
| --- | --- |
| `Self` | The copy. |

Raises:

| Type | Description |
| --- | --- |
| `TimeFValidationError` | If a Record or Signal that the task references has no ID, or if `records` or `signals` has no object for its ID. |

### DatasetFilter `dataclass`

The filters of a dataset search. Filters combine with AND, and an empty filter matches every dataset.

#### dataset\_id `class-attribute` `instance-attribute`

```
dataset_id: tuple[str, ...] = ()
```

IDs of which the dataset must have any.

#### domain `class-attribute` `instance-attribute`

```
domain: tuple[Domain, ...] = ()
```

Domains of which the dataset must have any.

#### license `class-attribute` `instance-attribute`

```
license: tuple[License, ...] = ()
```

Licenses of which the dataset must have any.

#### limit `class-attribute` `instance-attribute`

```
limit: int = 100
```

The maximum number of results.

#### needs\_schema `property`

```
needs_schema: bool
```

Whether a `task` or `time_series_spec` filter is set. Both read the schema of a manifest.

#### query `class-attribute` `instance-attribute`

```
query: tuple[str, ...] = ()
```

Terms of which any must appear in the name, description, or tags, ignoring case.

#### tag `class-attribute` `instance-attribute`

```
tag: tuple[str, ...] = ()
```

Tags that the dataset must declare all of.

#### task `class-attribute` `instance-attribute`

```
task: tuple[type[Task], ...] = ()
```

Task classes of which the schema must declare any.

#### time\_series\_spec `class-attribute` `instance-attribute`

```
time_series_spec: tuple[str, ...] = ()
```

`spec_type` values that the schema must declare all of.

#### matches\_card

```
matches_card(card: DatasetMetadata) -> bool
```

Return whether a card matches the `query`, `domain`, `license`, `dataset_id` and `tag` filters.

#### matches\_schema

```
matches_schema(schema: DatasetSchema) -> bool
```

Return whether a schema matches the `task` and `time_series_spec` filters.

#### of `classmethod`

```
of(
    *,
    query: str | list[str] | None = None,
    domain: Domain | list[Domain] | None = None,
    task: type[Task] | list[type[Task]] | None = None,
    license: License | list[License] | None = None,
    time_series_spec: str | list[str] | None = None,
    dataset_id: str | list[str] | None = None,
    tag: str | list[str] | None = None,
    limit: int = 100,
) -> Self
```

Build a filter from one value, a list, or None for each filter.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `query` | `str | list[str] | None` | Match any term in the name, description, or tags, ignoring case. | `None` |
| `domain` | `Domain | list[Domain] | None` | Match any of these domains. | `None` |
| `task` | `type[Task] | list[type[Task]] | None` | Match any of these task classes in the schema. | `None` |
| `license` | `License | list[License] | None` | Match any of these licenses. | `None` |
| `time_series_spec` | `str | list[str] | None` | Match all of these `spec_type` values. | `None` |
| `dataset_id` | `str | list[str] | None` | Match any of these IDs. | `None` |
| `tag` | `str | list[str] | None` | Match all of these tags. | `None` |
| `limit` | `int` | The maximum number of results. | `100` |

Returns:

| Type | Description |
| --- | --- |
| `Self` | The filter. `None` or an empty list sets no restriction. |

Raises:

| Type | Description |
| --- | --- |
| `TimeFValidationError` | If `limit` is negative. |

#### select

```
select(
    listed: Iterable[ListedRelease],
) -> list[DatasetMetadata]
```

Return the cards of the listed releases that match, in order, with at most `limit` entries.

A `task` or `time_series_spec` filter reads the schema of a release only if its card matches. A release
without a registry has no schema, so it never matches these filters.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `listed` | `Iterable[ListedRelease]` | The releases to filter. | *required* |

Returns:

| Type | Description |
| --- | --- |
| `list[DatasetMetadata]` | The matching cards. |

### DatasetMetadata

Bases: `TimeFModel`

Dataset identity, release version, source information, and access requirements.

The dataset card defines these fields. `dataset_version` identifies the TimeNet release.
`source_revision` identifies the original source release, tag, or commit.
`yaml_schema_version` identifies the card schema. `dataset_id` is a case-sensitive
`org/name` pair with exactly one slash. Casing-only differences can cause conflicts on
case-insensitive filesystems.

#### access `class-attribute` `instance-attribute`

```
access: Access = Access.OPEN
```

How a user obtains the data (see :class:`Access`). `OPEN` needs nothing.

An import into a child dataset does not change it. The level that applies to a release with
parents is :func:`~timenet.types.access.effective_access`.

#### access\_url `class-attribute` `instance-attribute`

```
access_url: StrictStr | None = None
```

Where to obtain access (the DUA or credentialing page). Required when `access` is not `OPEN`.

#### citation `class-attribute` `instance-attribute`

```
citation: StrictStr | None = None
```

How to cite the dataset, when the source asks for attribution.

#### dataset\_id `instance-attribute`

```
dataset_id: DatasetId
```

HuggingFace-style `org/name` pair, case-sensitive, exactly one slash.

#### dataset\_version `instance-attribute`

```
dataset_version: SemanticVersion
```

Semantic version of the compiled TimeNet release.

#### description `instance-attribute`

```
description: NonEmptyText
```

Free-text description of the dataset.

#### domains `class-attribute` `instance-attribute`

```
domains: tuple[Domain, ...] = ()
```

Kinds of data the dataset contains.

#### license `instance-attribute`

```
license: License
```

Legal license of the source data, as an SPDX-style identifier.

#### license\_url `class-attribute` `instance-attribute`

```
license_url: StrictStr | None = None
```

Where to read the full license text. Required and nonblank when `license` is :attr:`License.OTHER`.

#### model\_config `class-attribute` `instance-attribute`

```
model_config = ConfigDict(
    extra="forbid",
    frozen=True,
    revalidate_instances="always",
    serialize_by_alias=True,
    validate_by_name=True,
    validate_default=True,
)
```

#### name `instance-attribute`

```
name: NonEmptyText
```

Human-readable display name.

#### parents `class-attribute` `instance-attribute`

```
parents: dict[ParentAlias, DatasetRef] = Field(
    default_factory=dict
)
```

Exact parent releases indexed by connector-local aliases.

#### source\_revision `class-attribute` `instance-attribute`

```
source_revision: StrictStr | None = None
```

Upstream release, tag, or commit, separate from the compiled dataset version.

#### source\_url `class-attribute` `instance-attribute`

```
source_url: StrictStr | None = None
```

Link to the dataset's origin, if any.

#### tags `class-attribute` `instance-attribute`

```
tags: tuple[StrictStr, ...] = ()
```

Free-form tags for search and grouping.

#### yaml\_schema\_version `class-attribute` `instance-attribute`

```
yaml_schema_version: Annotated[
    int, Field(strict=True, ge=1, le=1)
] = 1
```

Version of the card's own field schema.

#### from\_yaml `classmethod`

```
from_yaml(path: str | Path) -> DatasetMetadata
```

Load and validate a dataset card YAML into metadata.

Authoring mistakes surface as clear, aggregated messages instead of a stack trace from deep
inside coercion. PyYAML is optional and imported lazily. Install the `timenet[build]` extra
to use this method.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `path` | `str | Path` | Path to the card YAML file. | *required* |

Returns:

| Type | Description |
| --- | --- |
| `DatasetMetadata` | The constructed :class:`DatasetMetadata`. |

Raises:

| Type | Description |
| --- | --- |
| `TimeNetInvalidCardError` | If the build extra is missing, or the card is unreadable or is not a mapping. |

### DatasetSchema

Bases: `TimeFModel`

A dataset's type declaration, derived from its data (never hand-authored).

It holds flat descriptor instances for specs and annotations. It also holds the real built-in
:class:`~timenet.types.tasks.Task` subclasses, resolved against the registry instead of reconstructed.

#### annotations `class-attribute` `instance-attribute`

```
annotations: tuple[AnnotationDescriptor, ...] = ()
```

Type-level descriptors for the dataset's annotation keys.

#### model\_config `class-attribute` `instance-attribute`

```
model_config = ConfigDict(
    extra="forbid",
    frozen=True,
    revalidate_instances="always",
    serialize_by_alias=True,
    validate_by_name=True,
    validate_default=True,
)
```

#### tasks `class-attribute` `instance-attribute`

```
tasks: tuple[TaskDeclaration, ...] = ()
```

Built-in `Task` subclasses the dataset declares, resolved from the registry.

#### time\_series\_specs `class-attribute` `instance-attribute`

```
time_series_specs: tuple[TimeSeriesSpec, ...] = ()
```

Descriptors for the dataset's measurement modalities.

### Domain

Bases: `StrEnum`

Describes what kind of data a dataset contains. A dataset may declare more than one.

#### ACTIVITY `class-attribute` `instance-attribute`

```
ACTIVITY = 'activity'
```

What people are doing: labeled human activities and daily behavior, usually from wearables.

Declare `motion` as well when the signals record the movement itself.

#### AUDIO `class-attribute` `instance-attribute`

```
AUDIO = 'audio'
```

Recorded sound: speech, cough, and environmental audio.

#### CARDIOLOGY `class-attribute` `instance-attribute`

```
CARDIOLOGY = 'cardiology'
```

The heart: ECG, heart rate, and heart sounds.

#### ECONOMICS `class-attribute` `instance-attribute`

```
ECONOMICS = 'economics'
```

Economic activity: macroeconomic indicators, prices, sales, and demand.

#### ENERGY `class-attribute` `instance-attribute`

```
ENERGY = 'energy'
```

Energy systems: electricity load, generation, power grids, and transformers.

#### ENVIRONMENT `class-attribute` `instance-attribute`

```
ENVIRONMENT = 'environment'
```

The natural world: weather, climate, air quality, and hydrology.

#### FINANCE `class-attribute` `instance-attribute`

```
FINANCE = 'finance'
```

Financial markets: asset prices, returns, trading volumes, and exchange rates.

#### GENERAL `class-attribute` `instance-attribute`

```
GENERAL = 'general'
```

No particular field: synthetic or demo data, or generic series without a stated origin.

A corpus that mixes such data with field-specific components declares those domains too.

#### HEALTH `class-attribute` `instance-attribute`

```
HEALTH = 'health'
```

Human physiology and clinical care: biosignals, vital signs, clinical records, glucose.

The umbrella for `cardiology`, `respiratory`, and `sleep`. Declare it alongside them.

#### INDUSTRIAL `class-attribute` `instance-attribute`

```
INDUSTRIAL = 'industrial'
```

Machines and industrial processes: engines, turbines, bearings, and production equipment.

Covers condition monitoring, degradation, fault diagnosis, and remaining useful life, including
simulated run-to-failure data.

#### MOTION `class-attribute` `instance-attribute`

```
MOTION = 'motion'
```

Movement of a body or an object: accelerometer, gyroscope, magnetometer, and motion capture.

#### OBSERVABILITY `class-attribute` `instance-attribute`

```
OBSERVABILITY = 'observability'
```

Software and IT infrastructure: service metrics and cloud monitoring.

#### RESPIRATORY `class-attribute` `instance-attribute`

```
RESPIRATORY = 'respiratory'
```

Breathing and the lungs: respiration, airflow, oxygen saturation, and cough.

#### SLEEP `class-attribute` `instance-attribute`

```
SLEEP = 'sleep'
```

Sleep studies: polysomnography and sleep staging.

#### TRANSPORT `class-attribute` `instance-attribute`

```
TRANSPORT = 'transport'
```

Movement of people and goods through transport networks: road traffic, congestion, and ridership.

Telemetry from a vehicle's own machinery, such as engine health, belongs to `industrial`.

### ForecastingTask `dataclass`

Bases: `Task`

Predict future values from the supplied inputs.

#### annotations `class-attribute` `instance-attribute`

```
annotations: tuple[Annotation, ...] = ()
```

Annotations describing this task itself.

#### from\_tasks `class-attribute` `instance-attribute`

```
from_tasks: tuple[Task, ...] = field(
    default=(), compare=False
)
```

Tasks from which this task was derived.

#### id `property`

```
id: EntityId
```

The task's id, unique among the tasks of its dataset.

:meth:`~timenet.dataset.TimeFDataset.add_task` sets it. The reader sets it when it reads the task back.

Raises:

| Type | Description |
| --- | --- |
| `TimeFValidationError` | If the task is not in a dataset yet. |

#### input\_annotations `class-attribute` `instance-attribute`

```
input_annotations: tuple[Annotation, ...] = field(
    default=(), compare=False
)
```

Existing annotation occurrences supplied to the model as context.

#### input\_modalities `class-attribute` `instance-attribute`

```
input_modalities: frozenset[InputModality] | None = None
```

Optional override. None infers the input kinds when resolved or written.

#### inputs `class-attribute` `instance-attribute`

```
inputs: tuple[Record, ...] = field(
    default=(), compare=False
)
```

Records supplied to the model, in semantic order.

#### metadata `class-attribute` `instance-attribute`

```
metadata: JsonMapping = field(default_factory=dict)
```

Optional JSON-compatible task metadata.

#### prompt `class-attribute` `instance-attribute`

```
prompt: ValueField[
    str | TextHandle | None, TextHandle | None
] = field(default=ValueField(optional_text, None))
```

Call `read()` for the prompt; `None` identifies an unprompted task.

#### rationale `class-attribute` `instance-attribute`

```
rationale: ValueField[
    str | TextHandle | None, TextHandle | None
] = field(default=ValueField(optional_text, None))
```

Call `read()` for the explanation; `None` means no rationale is present.

#### resolved\_input\_modalities `property`

```
resolved_input_modalities: frozenset[InputModality]
```

The validated override, or kinds inferred from the current inputs.

Inference reads Signal specs within the scope, the prompt, and text input annotations.
It does not load values or inspect targets. NO\_INPUT means there are no input Records.
The result is not cached: connectors can assign inputs after construction.

#### scope `class-attribute` `instance-attribute`

```
scope: Span | None = None
```

Optional region of the inputs to which the task applies.

#### split `class-attribute` `instance-attribute`

```
split: Split | None = None
```

The partition the task belongs to: train, validation, or test. None when the dataset does not
partition its tasks.

#### target\_annotations `class-attribute` `instance-attribute`

```
target_annotations: tuple[Annotation, ...] = field(
    default=(), compare=False
)
```

Existing annotation occurrences that form the expected output.

#### targets `class-attribute` `instance-attribute`

```
targets: ValueField[
    Iterable[TargetInput] | None,
    tuple[TargetItem, ...] | None,
] = field(
    default=ValueField(_target_values, None), compare=False
)
```

Ordered native values and stored objects that form the expected output.

#### task\_type `class-attribute`

```
task_type: TaskType = TaskType.FORECASTING
```

#### annotate

```
annotate(annotation: Annotation) -> Annotation
```

Attach one annotation occurrence and return it.

Returns:

| Type | Description |
| --- | --- |
| `Annotation` | The attached occurrence. |

#### check\_against\_scope

```
check_against_scope() -> None
```

Validate configuration that depends on the finalized scope.

#### check\_targets

```
check_targets() -> None
```

Make sure that the final targets follow the rules of this task class.

#### named\_records

```
named_records() -> tuple[Record, ...]
```

Return the Records that the task names, each once: its inputs, then its Record targets.

A task class with candidate Records returns them too, after the inputs.

#### referenced\_signals

```
referenced_signals() -> tuple[Signal, ...]
```

Return the Signals that the task references, each once.

They are its Signal targets, then the Signals that its scope and its span targets name, in the
order of :meth:`spans`.

#### register\_label\_set

```
register_label_set(label_sets: LabelSetRegistry) -> None
```

Add the label set of the task to the dataset's label sets.

Only a classification task has a label set.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `label_sets` | `LabelSetRegistry` | The label sets of the dataset so far. | *required* |

#### spans

```
spans() -> tuple[Span, ...]
```

Return the task scope followed by every span-valued target.

#### with\_references

```
with_references(
    records: Mapping[EntityId, Record],
    signals: Mapping[EntityId, Signal],
) -> Self
```

Return a copy of the task that references the given Records and Signals, by ID.

The copy has the class of the task. Each input, candidate Record, Record target, and Signal
target of the copy is the object of the same ID in `records` or `signals`. The scope and
the span targets of the copy name the Signals of the same IDs in `signals`. Each span keeps
its class. The copy has no ID.

Every other field keeps its value: the annotations of the task, the annotations that it
references, `from_tasks`, the text, and the metadata. A caller that needs other values for
them sets them on the copy.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `records` | `Mapping[EntityId, Record]` | The Records for the copy, by ID. | *required* |
| `signals` | `Mapping[EntityId, Signal]` | The Signals for the copy, by ID. | *required* |

Returns:

| Type | Description |
| --- | --- |
| `Self` | The copy. |

Raises:

| Type | Description |
| --- | --- |
| `TimeFValidationError` | If a Record or Signal that the task references has no ID, or if `records` or `signals` has no object for its ID. |

### InputModality

Bases: `StrEnum`

A kind of input supplied to a task.

#### AUDIO `class-attribute` `instance-attribute`

```
AUDIO = 'audio'
```

#### IMAGE `class-attribute` `instance-attribute`

```
IMAGE = 'image'
```

#### NO\_INPUT `class-attribute` `instance-attribute`

```
NO_INPUT = 'no_input'
```

#### TEXT `class-attribute` `instance-attribute`

```
TEXT = 'text'
```

#### TIME\_SERIES `class-attribute` `instance-attribute`

```
TIME_SERIES = 'time_series'
```

### Label

Bases: `TimeFModel`

One label in a label set, such as `awake` in a sleep-stage task.

#### description `class-attribute` `instance-attribute`

```
description: NonEmptyString | None = None
```

What the label means, such as `The subject is awake.`.

#### model\_config `class-attribute` `instance-attribute`

```
model_config = ConfigDict(
    extra="forbid",
    frozen=True,
    revalidate_instances="always",
    serialize_by_alias=True,
    validate_by_name=True,
    validate_default=True,
)
```

#### name `instance-attribute`

```
name: NonEmptyString
```

The text that a target holds for this label.

### LabelSet

Bases: `TimeFModel`

The allowed labels for a classification target.

A target must contain one label unless `multi_label=True`.

Tasks that ask the same kind of question share one label set::

```
SLEEP_STAGE = LabelSet(
    name="sleep_stage",
    labels=(
        Label(name="awake", description="The subject is awake."),
        Label(name="non_rem_sleep"),
        Label(name="rem_sleep"),
    ),
)
ClassificationTask(inputs=(record,), targets=("awake",), label_set=SLEEP_STAGE)
```

Each name identifies one label set in a dataset.

#### labels `instance-attribute`

```
labels: tuple[Label, ...]
```

The allowed labels in a fixed order.

#### model\_config `class-attribute` `instance-attribute`

```
model_config = ConfigDict(
    extra="forbid",
    frozen=True,
    revalidate_instances="always",
    serialize_by_alias=True,
    validate_by_name=True,
    validate_default=True,
)
```

#### multi\_label `class-attribute` `instance-attribute`

```
multi_label: StrictBool = False
```

If `False`, a target holds exactly one label from the set.

If `True`, a target holds all labels from the set that apply.
An empty target means that no label applies.

#### name `instance-attribute`

```
name: NonEmptyString
```

The name of the set within a dataset, such as `sleep_stage`.

#### names `property`

```
names: tuple[str, ...]
```

The name of each label, in label order.

#### check\_targets

```
check_targets(targets: Sequence[str]) -> None
```

Make sure that the target labels follow the rules of this set.

For a set with the labels `W`, `N1` and `R`, the rules are:

* Each label must be in the set. `("X",)` fails.
* If `multi_label` is `False`, the target holds exactly one label. `("W",)` passes.
  `()` and `("W", "R")` fail.
* No label can repeat. `("W", "W")` fails, also when `multi_label` is `True`.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `targets` | `Sequence[str]` | The target labels, in the order that the task stores them. | *required* |

Raises:

| Type | Description |
| --- | --- |
| `TimeFValidationError` | If a label is not in the set or a label repeats. Also if a single-label target does not hold exactly one label. |

### LabelSetRegistry

The label sets of a dataset, with one set per name.

The sets stay in the order in which tasks first added them.

#### copy

```
copy() -> LabelSetRegistry
```

Return a separate registry with the same label sets.

The dataset uses the copy to check a batch before adding its tasks.
If a task fails, the dataset discards the copy and keeps its original registry.

Returns:

| Type | Description |
| --- | --- |
| `LabelSetRegistry` | The copy. |

#### register\_or\_reuse\_matching\_label\_set

```
register_or_reuse_matching_label_set(
    label_set: LabelSet,
) -> LabelSet
```

Store a label set by name.

If the registry already holds an equal set with this name, return that set.

Returns:

| Type | Description |
| --- | --- |
| `LabelSet` | The set that the registry holds under the name. |

Raises:

| Type | Description |
| --- | --- |
| `TimeFValidationError` | If a different set already has the same name. |

### LazyText

Bases: `_LazyTextBehaviour[str]`, `TextHandle`

Read one string through the supplied function on each request.

A connector can use this handle to load text from a source file.
The writer stores the text in a separate payload file so readers can load it on request.

#### function `instance-attribute`

```
function: Callable[[], _Lazy]
```

A function that returns the text.

#### is\_loaded `property`

```
is_loaded: bool
```

Always False.

#### length `property`

```
length: int
```

The number of characters or list items.

If the caller omits `length`, the first access reads the text to calculate it.

#### read

```
read() -> _Lazy
```

Return the text from the supplied function.

Raises:

| Type | Description |
| --- | --- |
| `TimeFValidationError` | If the result has the wrong type or its length differs from the known length. |

### LazyTextList

Bases: `_LazyTextBehaviour[list[str]]`, `TextListHandle`

Read a list of strings through the supplied function on each request.

A connector can use this handle to load strings from a source file.
The writer stores the list in a separate payload file so readers can load it on request.

#### function `instance-attribute`

```
function: Callable[[], _Lazy]
```

A function that returns the text.

#### is\_loaded `property`

```
is_loaded: bool
```

Always False.

#### length `property`

```
length: int
```

The number of characters or list items.

If the caller omits `length`, the first access reads the text to calculate it.

#### read

```
read() -> _Lazy
```

Return the text from the supplied function.

Raises:

| Type | Description |
| --- | --- |
| `TimeFValidationError` | If the result has the wrong type or its length differs from the known length. |

### License

Bases: `StrEnum`

The legal license of the source data. Values are SPDX-style identifiers.

#### APACHE\_2\_0 `class-attribute` `instance-attribute`

```
APACHE_2_0 = 'Apache-2.0'
```

#### BSD\_2\_CLAUSE `class-attribute` `instance-attribute`

```
BSD_2_CLAUSE = 'BSD-2-Clause'
```

#### BSD\_3\_CLAUSE `class-attribute` `instance-attribute`

```
BSD_3_CLAUSE = 'BSD-3-Clause'
```

#### CC0\_1\_0 `class-attribute` `instance-attribute`

```
CC0_1_0 = 'CC0-1.0'
```

#### CC\_BY\_4\_0 `class-attribute` `instance-attribute`

```
CC_BY_4_0 = 'CC-BY-4.0'
```

#### CC\_BY\_NC\_4\_0 `class-attribute` `instance-attribute`

```
CC_BY_NC_4_0 = 'CC-BY-NC-4.0'
```

#### CC\_BY\_SA\_4\_0 `class-attribute` `instance-attribute`

```
CC_BY_SA_4_0 = 'CC-BY-SA-4.0'
```

#### GPL\_3\_0 `class-attribute` `instance-attribute`

```
GPL_3_0 = 'GPL-3.0'
```

#### LGPL\_3\_0 `class-attribute` `instance-attribute`

```
LGPL_3_0 = 'LGPL-3.0'
```

#### MIT `class-attribute` `instance-attribute`

```
MIT = 'MIT'
```

#### MPL\_2\_0 `class-attribute` `instance-attribute`

```
MPL_2_0 = 'MPL-2.0'
```

#### NONE `class-attribute` `instance-attribute`

```
NONE = 'NONE'
```

SPDX's value for a source that states no license; its terms are unknown, not unrestricted.

#### ODBL\_1\_0 `class-attribute` `instance-attribute`

```
ODBL_1_0 = 'ODbL-1.0'
```

#### ODC\_BY\_1\_0 `class-attribute` `instance-attribute`

```
ODC_BY_1_0 = 'ODC-By-1.0'
```

#### OTHER `class-attribute` `instance-attribute`

```
OTHER = 'OTHER'
```

Escape hatch for a license outside this list; requires a `license_url` on the card.

### ListedRelease `dataclass`

A card of a dataset listing, with the registry that lists it.

#### card `instance-attribute`

```
card: DatasetMetadata
```

The card of the release.

#### registry `instance-attribute`

```
registry: BaseRegistry | None
```

The registry that holds the manifest of the release, or `None` for the card of an installed connector.

### LocalizationMode

Bases: `StrEnum`

Whether a localization target is sparse or exhaustive.

#### EXHAUSTIVE `class-attribute` `instance-attribute`

```
EXHAUSTIVE = 'exhaustive'
```

#### SPARSE `class-attribute` `instance-attribute`

```
SPARSE = 'sparse'
```

### MissingReason

Bases: `StrEnum`

Reasons why a series can have missing timesteps.

#### ALIGNMENT\_PADDING `class-attribute` `instance-attribute`

```
ALIGNMENT_PADDING = 'alignment_padding'
```

The series covers only part of a shared time grid. Values outside that part are missing.

#### NOT\_APPLICABLE `class-attribute` `instance-attribute`

```
NOT_APPLICABLE = 'not_applicable'
```

The measurement does not apply at this timestep, for example before a sensor is ready.

#### NOT\_RECORDED `class-attribute` `instance-attribute`

```
NOT_RECORDED = 'not_recorded'
```

The recording continued, but the source reported no value for this timestep.

#### REDACTED `class-attribute` `instance-attribute`

```
REDACTED = 'redacted'
```

The source deliberately removed the value, for example to protect a person's privacy.

#### SENSOR\_GAP `class-attribute` `instance-attribute`

```
SENSOR_GAP = 'sensor_gap'
```

The device stopped recording, for example because it lost contact with the body.

### MissingValues

Bases: `TimeFModel`

The reason for missing timesteps in a series.

A time-series specification without this record allows no missing timesteps.
An Arrow null represents a missing timestep.

#### description `class-attribute` `instance-attribute`

```
description: NonEmptyString | None = None
```

An explanation of missing timesteps in the source, or `None`.

#### model\_config `class-attribute` `instance-attribute`

```
model_config = ConfigDict(
    extra="forbid",
    frozen=True,
    revalidate_instances="always",
    serialize_by_alias=True,
    validate_by_name=True,
    validate_default=True,
)
```

#### reason `instance-attribute`

```
reason: MissingReason
```

Why timesteps are missing.

### ObjectKind

Bases: `StrEnum`

Catalog of tags for TimeF objects.

#### ANNOTATION `class-attribute` `instance-attribute`

```
ANNOTATION = 'Annotation'
```

#### ANNOTATION\_CONTENT `class-attribute` `instance-attribute`

```
ANNOTATION_CONTENT = 'Content'
```

#### AXIS `class-attribute` `instance-attribute`

```
AXIS = 'Axis'
```

#### DATASET `class-attribute` `instance-attribute`

```
DATASET = 'Dataset'
```

#### RECORD `class-attribute` `instance-attribute`

```
RECORD = 'Record'
```

#### SIGNAL `class-attribute` `instance-attribute`

```
SIGNAL = 'Signal'
```

#### SOURCE `class-attribute` `instance-attribute`

```
SOURCE = 'Source'
```

#### TASK `class-attribute` `instance-attribute`

```
TASK = 'Task'
```

### ScalarPredictionTask `dataclass`

Bases: `Task`

Predict one or more quantities described by the task configuration.

#### annotations `class-attribute` `instance-attribute`

```
annotations: tuple[Annotation, ...] = ()
```

Annotations describing this task itself.

#### from\_tasks `class-attribute` `instance-attribute`

```
from_tasks: tuple[Task, ...] = field(
    default=(), compare=False
)
```

Tasks from which this task was derived.

#### id `property`

```
id: EntityId
```

The task's id, unique among the tasks of its dataset.

:meth:`~timenet.dataset.TimeFDataset.add_task` sets it. The reader sets it when it reads the task back.

Raises:

| Type | Description |
| --- | --- |
| `TimeFValidationError` | If the task is not in a dataset yet. |

#### input\_annotations `class-attribute` `instance-attribute`

```
input_annotations: tuple[Annotation, ...] = field(
    default=(), compare=False
)
```

Existing annotation occurrences supplied to the model as context.

#### input\_modalities `class-attribute` `instance-attribute`

```
input_modalities: frozenset[InputModality] | None = None
```

Optional override. None infers the input kinds when resolved or written.

#### inputs `class-attribute` `instance-attribute`

```
inputs: tuple[Record, ...] = field(
    default=(), compare=False
)
```

Records supplied to the model, in semantic order.

#### metadata `class-attribute` `instance-attribute`

```
metadata: JsonMapping = field(default_factory=dict)
```

Optional JSON-compatible task metadata.

#### prompt `class-attribute` `instance-attribute`

```
prompt: ValueField[
    str | TextHandle | None, TextHandle | None
] = field(default=ValueField(optional_text, None))
```

Call `read()` for the prompt; `None` identifies an unprompted task.

#### rationale `class-attribute` `instance-attribute`

```
rationale: ValueField[
    str | TextHandle | None, TextHandle | None
] = field(default=ValueField(optional_text, None))
```

Call `read()` for the explanation; `None` means no rationale is present.

#### resolved\_input\_modalities `property`

```
resolved_input_modalities: frozenset[InputModality]
```

The validated override, or kinds inferred from the current inputs.

Inference reads Signal specs within the scope, the prompt, and text input annotations.
It does not load values or inspect targets. NO\_INPUT means there are no input Records.
The result is not cached: connectors can assign inputs after construction.

#### scope `class-attribute` `instance-attribute`

```
scope: Span | None = None
```

Optional region of the inputs to which the task applies.

#### split `class-attribute` `instance-attribute`

```
split: Split | None = None
```

The partition the task belongs to: train, validation, or test. None when the dataset does not
partition its tasks.

#### target\_annotations `class-attribute` `instance-attribute`

```
target_annotations: tuple[Annotation, ...] = field(
    default=(), compare=False
)
```

Existing annotation occurrences that form the expected output.

#### target\_name `class-attribute` `instance-attribute`

```
target_name: str | None = None
```

Optional name of the predicted quantity.

#### targets `class-attribute` `instance-attribute`

```
targets: ValueField[
    Iterable[TargetInput] | None,
    tuple[TargetItem, ...] | None,
] = field(
    default=ValueField(_target_values, None), compare=False
)
```

Ordered native values and stored objects that form the expected output.

#### task\_type `class-attribute`

```
task_type: TaskType = TaskType.SCALAR_PREDICTION
```

#### unit `class-attribute` `instance-attribute`

```
unit: str | Unit | None = None
```

Optional physical unit shared by numerical target items.

#### annotate

```
annotate(annotation: Annotation) -> Annotation
```

Attach one annotation occurrence and return it.

Returns:

| Type | Description |
| --- | --- |
| `Annotation` | The attached occurrence. |

#### check\_against\_scope

```
check_against_scope() -> None
```

Validate configuration that depends on the finalized scope.

#### check\_targets

```
check_targets() -> None
```

Make sure that the final targets follow the rules of this task class.

#### named\_records

```
named_records() -> tuple[Record, ...]
```

Return the Records that the task names, each once: its inputs, then its Record targets.

A task class with candidate Records returns them too, after the inputs.

#### referenced\_signals

```
referenced_signals() -> tuple[Signal, ...]
```

Return the Signals that the task references, each once.

They are its Signal targets, then the Signals that its scope and its span targets name, in the
order of :meth:`spans`.

#### register\_label\_set

```
register_label_set(label_sets: LabelSetRegistry) -> None
```

Add the label set of the task to the dataset's label sets.

Only a classification task has a label set.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `label_sets` | `LabelSetRegistry` | The label sets of the dataset so far. | *required* |

#### spans

```
spans() -> tuple[Span, ...]
```

Return the task scope followed by every span-valued target.

#### with\_references

```
with_references(
    records: Mapping[EntityId, Record],
    signals: Mapping[EntityId, Signal],
) -> Self
```

Return a copy of the task that references the given Records and Signals, by ID.

The copy has the class of the task. Each input, candidate Record, Record target, and Signal
target of the copy is the object of the same ID in `records` or `signals`. The scope and
the span targets of the copy name the Signals of the same IDs in `signals`. Each span keeps
its class. The copy has no ID.

Every other field keeps its value: the annotations of the task, the annotations that it
references, `from_tasks`, the text, and the metadata. A caller that needs other values for
them sets them on the copy.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `records` | `Mapping[EntityId, Record]` | The Records for the copy, by ID. | *required* |
| `signals` | `Mapping[EntityId, Signal]` | The Signals for the copy, by ID. | *required* |

Returns:

| Type | Description |
| --- | --- |
| `Self` | The copy. |

Raises:

| Type | Description |
| --- | --- |
| `TimeFValidationError` | If a Record or Signal that the task references has no ID, or if `records` or `signals` has no object for its ID. |

### Span `dataclass`

Abstract base for every localized region. Not constructible. Build a concrete leaf type.

The concrete spans are :class:`TimePoint`, :class:`TimeInterval`, :class:`StepPoint`, and
:class:`StepInterval`. Annotate with `Span` where any of them fits, and shared code reads them
through this base.

#### exclusive\_end `property`

```
exclusive_end: int
```

The exclusive upper bound of the span, in its own frame.

The region is half-open, so a point ends one unit past its position and an interval ends at
its stored end. Each concrete leaf supplies this.

#### is\_point `class-attribute`

```
is_point: bool = False
```

Whether this span marks a single position rather than a bounded interval.

### Split

Bases: `StrEnum`

Which partition of a dataset a task belongs to.

#### TEST `class-attribute` `instance-attribute`

```
TEST = 'test'
```

#### TRAIN `class-attribute` `instance-attribute`

```
TRAIN = 'train'
```

#### VALIDATION `class-attribute` `instance-attribute`

```
VALIDATION = 'validation'
```

### StepInterval `dataclass`

Bases: `StepSpan`

The half-open range `[start, stop)` of step ordinals on the named series.

#### exclusive\_end `property`

```
exclusive_end: int
```

The range's own exclusive end, `stop`.

#### frame `class-attribute`

```
frame: str = 'steps'
```

The frame its bounds read in, as stored on disk.

#### is\_point `class-attribute`

```
is_point: bool = False
```

Whether this span marks a single position rather than a bounded interval.

#### n\_steps `property`

```
n_steps: int
```

How many steps the interval covers, the horizon `h` step-based forecasting libraries speak in.

#### start `instance-attribute`

```
start: int
```

The position, or the start of the interval, as a step ordinal from the series' first stored step.

#### stop `instance-attribute`

```
stop: int
```

Last step ordinal, exclusive.

#### time\_series `instance-attribute`

```
time_series: Signal
```

The single series whose steps the span counts.

### StepPoint `dataclass`

Bases: `StepSpan`

One step ordinal on the named series.

#### exclusive\_end `property`

```
exclusive_end: int
```

One step past the ordinal, so the half-open range covering it is `[start, +1)`.

#### frame `class-attribute`

```
frame: str = 'steps'
```

The frame its bounds read in, as stored on disk.

#### is\_point `class-attribute`

```
is_point: bool = True
```

#### start `instance-attribute`

```
start: int
```

The position, or the start of the interval, as a step ordinal from the series' first stored step.

#### time\_series `instance-attribute`

```
time_series: Signal
```

The single series whose steps the span counts.

### StepSpan `dataclass`

Bases: `Span`

Abstract base for a region counted in the step ordinals of one series.

A step index means nothing without a series to count on, so a step span names exactly one
series in `time_series`. Valid only on a series whose axis is ordinal (no timeline).

#### exclusive\_end `property`

```
exclusive_end: int
```

The exclusive upper bound of the span, in its own frame.

The region is half-open, so a point ends one unit past its position and an interval ends at
its stored end. Each concrete leaf supplies this.

#### frame `class-attribute`

```
frame: str = 'steps'
```

The frame its bounds read in, as stored on disk.

#### is\_point `class-attribute`

```
is_point: bool = False
```

Whether this span marks a single position rather than a bounded interval.

#### start `instance-attribute`

```
start: int
```

The position, or the start of the interval, as a step ordinal from the series' first stored step.

#### time\_series `instance-attribute`

```
time_series: Signal
```

The single series whose steps the span counts.

### SupportsAnnotate

Bases: `Protocol`

Anything an annotation occurrence can be attached to.

`annotate` binds a fresh occurrence of `annotation` to this object and returns it; the
returned occurrence is what a Task names in `input_annotations` or `target_annotations`.
`annotations` lists every occurrence attached so far. Records, Sources, Signals, Tasks, and
the dataset itself implement it. A :class:`~timenet.dataset.SignalSelection` does not: it fans
one annotation out over several Signals and returns every occurrence it created. The contract is
checked statically; there is no runtime `isinstance` support because `annotations` is a
property.

#### annotations `property`

```
annotations: tuple[Annotation, ...]
```

The occurrences attached to this object.

#### annotate

```
annotate(annotation: Annotation) -> Annotation
```

Attach one occurrence of `annotation` and return it.

### TSCorrespondenceTask `dataclass`

Bases: `Task`

Relate input recordings to an optional candidate pool.

#### annotations `class-attribute` `instance-attribute`

```
annotations: tuple[Annotation, ...] = ()
```

Annotations describing this task itself.

#### candidate\_records `class-attribute` `instance-attribute`

```
candidate_records: tuple[Record, ...] = field(
    default=(), compare=False
)
```

Optional candidate pool. An empty tuple means the dataset-wide pool.

#### from\_tasks `class-attribute` `instance-attribute`

```
from_tasks: tuple[Task, ...] = field(
    default=(), compare=False
)
```

Tasks from which this task was derived.

#### id `property`

```
id: EntityId
```

The task's id, unique among the tasks of its dataset.

:meth:`~timenet.dataset.TimeFDataset.add_task` sets it. The reader sets it when it reads the task back.

Raises:

| Type | Description |
| --- | --- |
| `TimeFValidationError` | If the task is not in a dataset yet. |

#### input\_annotations `class-attribute` `instance-attribute`

```
input_annotations: tuple[Annotation, ...] = field(
    default=(), compare=False
)
```

Existing annotation occurrences supplied to the model as context.

#### input\_modalities `class-attribute` `instance-attribute`

```
input_modalities: frozenset[InputModality] | None = None
```

Optional override. None infers the input kinds when resolved or written.

#### inputs `class-attribute` `instance-attribute`

```
inputs: tuple[Record, ...] = field(
    default=(), compare=False
)
```

Records supplied to the model, in semantic order.

#### metadata `class-attribute` `instance-attribute`

```
metadata: JsonMapping = field(default_factory=dict)
```

Optional JSON-compatible task metadata.

#### prompt `class-attribute` `instance-attribute`

```
prompt: ValueField[
    str | TextHandle | None, TextHandle | None
] = field(default=ValueField(optional_text, None))
```

Call `read()` for the prompt; `None` identifies an unprompted task.

#### rationale `class-attribute` `instance-attribute`

```
rationale: ValueField[
    str | TextHandle | None, TextHandle | None
] = field(default=ValueField(optional_text, None))
```

Call `read()` for the explanation; `None` means no rationale is present.

#### resolved\_input\_modalities `property`

```
resolved_input_modalities: frozenset[InputModality]
```

The validated override, or kinds inferred from the current inputs.

Inference reads Signal specs within the scope, the prompt, and text input annotations.
It does not load values or inspect targets. NO\_INPUT means there are no input Records.
The result is not cached: connectors can assign inputs after construction.

#### scope `class-attribute` `instance-attribute`

```
scope: Span | None = None
```

Optional region of the inputs to which the task applies.

#### split `class-attribute` `instance-attribute`

```
split: Split | None = None
```

The partition the task belongs to: train, validation, or test. None when the dataset does not
partition its tasks.

#### target\_annotations `class-attribute` `instance-attribute`

```
target_annotations: tuple[Annotation, ...] = field(
    default=(), compare=False
)
```

Existing annotation occurrences that form the expected output.

#### targets `class-attribute` `instance-attribute`

```
targets: ValueField[
    Iterable[TargetInput] | None,
    tuple[TargetItem, ...] | None,
] = field(
    default=ValueField(_target_values, None), compare=False
)
```

Ordered native values and stored objects that form the expected output.

#### task\_type `class-attribute`

```
task_type: TaskType = TaskType.TS_CORRESPONDENCE
```

#### annotate

```
annotate(annotation: Annotation) -> Annotation
```

Attach one annotation occurrence and return it.

Returns:

| Type | Description |
| --- | --- |
| `Annotation` | The attached occurrence. |

#### check\_against\_scope

```
check_against_scope() -> None
```

Validate configuration that depends on the finalized scope.

#### check\_targets

```
check_targets() -> None
```

Make sure that the final targets follow the rules of this task class.

#### named\_records

```
named_records() -> tuple[Record, ...]
```

Return the Records that the task names, each once.

They are its inputs, its candidate Records, then its Record targets.

#### referenced\_signals

```
referenced_signals() -> tuple[Signal, ...]
```

Return the Signals that the task references, each once.

They are its Signal targets, then the Signals that its scope and its span targets name, in the
order of :meth:`spans`.

#### register\_label\_set

```
register_label_set(label_sets: LabelSetRegistry) -> None
```

Add the label set of the task to the dataset's label sets.

Only a classification task has a label set.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `label_sets` | `LabelSetRegistry` | The label sets of the dataset so far. | *required* |

#### spans

```
spans() -> tuple[Span, ...]
```

Return the task scope followed by every span-valued target.

#### with\_references

```
with_references(
    records: Mapping[EntityId, Record],
    signals: Mapping[EntityId, Signal],
) -> Self
```

Return a copy of the task that references the given Records and Signals, by ID.

The copy has the class of the task. Each input, candidate Record, Record target, and Signal
target of the copy is the object of the same ID in `records` or `signals`. The scope and
the span targets of the copy name the Signals of the same IDs in `signals`. Each span keeps
its class. The copy has no ID.

Every other field keeps its value: the annotations of the task, the annotations that it
references, `from_tasks`, the text, and the metadata. A caller that needs other values for
them sets them on the copy.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `records` | `Mapping[EntityId, Record]` | The Records for the copy, by ID. | *required* |
| `signals` | `Mapping[EntityId, Signal]` | The Signals for the copy, by ID. | *required* |

Returns:

| Type | Description |
| --- | --- |
| `Self` | The copy. |

Raises:

| Type | Description |
| --- | --- |
| `TimeFValidationError` | If a Record or Signal that the task references has no ID, or if `records` or `signals` has no object for its ID. |

### TSEditingTask `dataclass`

Bases: `Task`

Transform the input recording into the output described by targets.

#### annotations `class-attribute` `instance-attribute`

```
annotations: tuple[Annotation, ...] = ()
```

Annotations describing this task itself.

#### from\_tasks `class-attribute` `instance-attribute`

```
from_tasks: tuple[Task, ...] = field(
    default=(), compare=False
)
```

Tasks from which this task was derived.

#### id `property`

```
id: EntityId
```

The task's id, unique among the tasks of its dataset.

:meth:`~timenet.dataset.TimeFDataset.add_task` sets it. The reader sets it when it reads the task back.

Raises:

| Type | Description |
| --- | --- |
| `TimeFValidationError` | If the task is not in a dataset yet. |

#### input\_annotations `class-attribute` `instance-attribute`

```
input_annotations: tuple[Annotation, ...] = field(
    default=(), compare=False
)
```

Existing annotation occurrences supplied to the model as context.

#### input\_modalities `class-attribute` `instance-attribute`

```
input_modalities: frozenset[InputModality] | None = None
```

Optional override. None infers the input kinds when resolved or written.

#### inputs `class-attribute` `instance-attribute`

```
inputs: tuple[Record, ...] = field(
    default=(), compare=False
)
```

Records supplied to the model, in semantic order.

#### metadata `class-attribute` `instance-attribute`

```
metadata: JsonMapping = field(default_factory=dict)
```

Optional JSON-compatible task metadata.

#### prompt `class-attribute` `instance-attribute`

```
prompt: ValueField[
    str | TextHandle | None, TextHandle | None
] = field(default=ValueField(optional_text, None))
```

Call `read()` for the prompt; `None` identifies an unprompted task.

#### rationale `class-attribute` `instance-attribute`

```
rationale: ValueField[
    str | TextHandle | None, TextHandle | None
] = field(default=ValueField(optional_text, None))
```

Call `read()` for the explanation; `None` means no rationale is present.

#### resolved\_input\_modalities `property`

```
resolved_input_modalities: frozenset[InputModality]
```

The validated override, or kinds inferred from the current inputs.

Inference reads Signal specs within the scope, the prompt, and text input annotations.
It does not load values or inspect targets. NO\_INPUT means there are no input Records.
The result is not cached: connectors can assign inputs after construction.

#### scope `class-attribute` `instance-attribute`

```
scope: Span | None = None
```

Optional region of the inputs to which the task applies.

#### split `class-attribute` `instance-attribute`

```
split: Split | None = None
```

The partition the task belongs to: train, validation, or test. None when the dataset does not
partition its tasks.

#### target\_annotations `class-attribute` `instance-attribute`

```
target_annotations: tuple[Annotation, ...] = field(
    default=(), compare=False
)
```

Existing annotation occurrences that form the expected output.

#### targets `class-attribute` `instance-attribute`

```
targets: ValueField[
    Iterable[TargetInput] | None,
    tuple[TargetItem, ...] | None,
] = field(
    default=ValueField(_target_values, None), compare=False
)
```

Ordered native values and stored objects that form the expected output.

#### task\_type `class-attribute`

```
task_type: TaskType = TaskType.TS_EDITING
```

#### annotate

```
annotate(annotation: Annotation) -> Annotation
```

Attach one annotation occurrence and return it.

Returns:

| Type | Description |
| --- | --- |
| `Annotation` | The attached occurrence. |

#### check\_against\_scope

```
check_against_scope() -> None
```

Validate configuration that depends on the finalized scope.

#### check\_targets

```
check_targets() -> None
```

Make sure that the final targets follow the rules of this task class.

#### named\_records

```
named_records() -> tuple[Record, ...]
```

Return the Records that the task names, each once: its inputs, then its Record targets.

A task class with candidate Records returns them too, after the inputs.

#### referenced\_signals

```
referenced_signals() -> tuple[Signal, ...]
```

Return the Signals that the task references, each once.

They are its Signal targets, then the Signals that its scope and its span targets name, in the
order of :meth:`spans`.

#### register\_label\_set

```
register_label_set(label_sets: LabelSetRegistry) -> None
```

Add the label set of the task to the dataset's label sets.

Only a classification task has a label set.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `label_sets` | `LabelSetRegistry` | The label sets of the dataset so far. | *required* |

#### spans

```
spans() -> tuple[Span, ...]
```

Return the task scope followed by every span-valued target.

#### with\_references

```
with_references(
    records: Mapping[EntityId, Record],
    signals: Mapping[EntityId, Signal],
) -> Self
```

Return a copy of the task that references the given Records and Signals, by ID.

The copy has the class of the task. Each input, candidate Record, Record target, and Signal
target of the copy is the object of the same ID in `records` or `signals`. The scope and
the span targets of the copy name the Signals of the same IDs in `signals`. Each span keeps
its class. The copy has no ID.

Every other field keeps its value: the annotations of the task, the annotations that it
references, `from_tasks`, the text, and the metadata. A caller that needs other values for
them sets them on the copy.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `records` | `Mapping[EntityId, Record]` | The Records for the copy, by ID. | *required* |
| `signals` | `Mapping[EntityId, Signal]` | The Signals for the copy, by ID. | *required* |

Returns:

| Type | Description |
| --- | --- |
| `Self` | The copy. |

Raises:

| Type | Description |
| --- | --- |
| `TimeFValidationError` | If a Record or Signal that the task references has no ID, or if `records` or `signals` has no object for its ID. |

### TSGenerationTask `dataclass`

Bases: `Task`

Generate output described by the prompt, optionally without record inputs.

#### annotations `class-attribute` `instance-attribute`

```
annotations: tuple[Annotation, ...] = ()
```

Annotations describing this task itself.

#### from\_tasks `class-attribute` `instance-attribute`

```
from_tasks: tuple[Task, ...] = field(
    default=(), compare=False
)
```

Tasks from which this task was derived.

#### id `property`

```
id: EntityId
```

The task's id, unique among the tasks of its dataset.

:meth:`~timenet.dataset.TimeFDataset.add_task` sets it. The reader sets it when it reads the task back.

Raises:

| Type | Description |
| --- | --- |
| `TimeFValidationError` | If the task is not in a dataset yet. |

#### input\_annotations `class-attribute` `instance-attribute`

```
input_annotations: tuple[Annotation, ...] = field(
    default=(), compare=False
)
```

Existing annotation occurrences supplied to the model as context.

#### input\_modalities `class-attribute` `instance-attribute`

```
input_modalities: frozenset[InputModality] | None = None
```

Optional override. None infers the input kinds when resolved or written.

#### inputs `class-attribute` `instance-attribute`

```
inputs: tuple[Record, ...] = field(
    default=(), compare=False
)
```

Records supplied to the model, in semantic order.

#### metadata `class-attribute` `instance-attribute`

```
metadata: JsonMapping = field(default_factory=dict)
```

Optional JSON-compatible task metadata.

#### prompt `class-attribute` `instance-attribute`

```
prompt: ValueField[
    str | TextHandle | None, TextHandle | None
] = field(default=ValueField(optional_text, None))
```

Call `read()` for the prompt; `None` identifies an unprompted task.

#### rationale `class-attribute` `instance-attribute`

```
rationale: ValueField[
    str | TextHandle | None, TextHandle | None
] = field(default=ValueField(optional_text, None))
```

Call `read()` for the explanation; `None` means no rationale is present.

#### resolved\_input\_modalities `property`

```
resolved_input_modalities: frozenset[InputModality]
```

The validated override, or kinds inferred from the current inputs.

Inference reads Signal specs within the scope, the prompt, and text input annotations.
It does not load values or inspect targets. NO\_INPUT means there are no input Records.
The result is not cached: connectors can assign inputs after construction.

#### scope `class-attribute` `instance-attribute`

```
scope: Span | None = None
```

Optional region of the inputs to which the task applies.

#### split `class-attribute` `instance-attribute`

```
split: Split | None = None
```

The partition the task belongs to: train, validation, or test. None when the dataset does not
partition its tasks.

#### target\_annotations `class-attribute` `instance-attribute`

```
target_annotations: tuple[Annotation, ...] = field(
    default=(), compare=False
)
```

Existing annotation occurrences that form the expected output.

#### targets `class-attribute` `instance-attribute`

```
targets: ValueField[
    Iterable[TargetInput] | None,
    tuple[TargetItem, ...] | None,
] = field(
    default=ValueField(_target_values, None), compare=False
)
```

Ordered native values and stored objects that form the expected output.

#### task\_type `class-attribute`

```
task_type: TaskType = TaskType.TS_GENERATION
```

#### annotate

```
annotate(annotation: Annotation) -> Annotation
```

Attach one annotation occurrence and return it.

Returns:

| Type | Description |
| --- | --- |
| `Annotation` | The attached occurrence. |

#### check\_against\_scope

```
check_against_scope() -> None
```

Validate configuration that depends on the finalized scope.

#### check\_targets

```
check_targets() -> None
```

Make sure that the final targets follow the rules of this task class.

#### named\_records

```
named_records() -> tuple[Record, ...]
```

Return the Records that the task names, each once: its inputs, then its Record targets.

A task class with candidate Records returns them too, after the inputs.

#### referenced\_signals

```
referenced_signals() -> tuple[Signal, ...]
```

Return the Signals that the task references, each once.

They are its Signal targets, then the Signals that its scope and its span targets name, in the
order of :meth:`spans`.

#### register\_label\_set

```
register_label_set(label_sets: LabelSetRegistry) -> None
```

Add the label set of the task to the dataset's label sets.

Only a classification task has a label set.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `label_sets` | `LabelSetRegistry` | The label sets of the dataset so far. | *required* |

#### spans

```
spans() -> tuple[Span, ...]
```

Return the task scope followed by every span-valued target.

#### with\_references

```
with_references(
    records: Mapping[EntityId, Record],
    signals: Mapping[EntityId, Signal],
) -> Self
```

Return a copy of the task that references the given Records and Signals, by ID.

The copy has the class of the task. Each input, candidate Record, Record target, and Signal
target of the copy is the object of the same ID in `records` or `signals`. The scope and
the span targets of the copy name the Signals of the same IDs in `signals`. Each span keeps
its class. The copy has no ID.

Every other field keeps its value: the annotations of the task, the annotations that it
references, `from_tasks`, the text, and the metadata. A caller that needs other values for
them sets them on the copy.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `records` | `Mapping[EntityId, Record]` | The Records for the copy, by ID. | *required* |
| `signals` | `Mapping[EntityId, Signal]` | The Signals for the copy, by ID. | *required* |

Returns:

| Type | Description |
| --- | --- |
| `Self` | The copy. |

Raises:

| Type | Description |
| --- | --- |
| `TimeFValidationError` | If a Record or Signal that the task references has no ID, or if `records` or `signals` has no object for its ID. |

### Task `dataclass`

Bases: `SupportsAnnotate`

One modelling problem with ordered inputs and ordered output items.

Targets deliberately accept a mixture of supported values. Concrete task classes describe the
modelling operation, but they do not impose a second hierarchy of target wrapper classes. None
means that the answer is supplied through target annotations. An empty tuple is an explicit
empty answer.

Only a concrete task class, one that sets `task_type`, can be built; `Task` itself cannot.

The task classes form a closed set. TimeF stores a task's `task_type` tag, and the reader maps
it back to a built-in class, so only this module defines subclasses, and each concrete class is
final. To reuse a prompt, write a function that builds a built-in task::

```
def age_question(record: Record, age: int) -> AnswerTask:
    return AnswerTask(inputs=(record,), prompt="How old is the subject?", targets=(str(age),))
```

#### annotations `class-attribute` `instance-attribute`

```
annotations: tuple[Annotation, ...] = ()
```

Annotations describing this task itself.

#### from\_tasks `class-attribute` `instance-attribute`

```
from_tasks: tuple[Task, ...] = field(
    default=(), compare=False
)
```

Tasks from which this task was derived.

#### id `property`

```
id: EntityId
```

The task's id, unique among the tasks of its dataset.

:meth:`~timenet.dataset.TimeFDataset.add_task` sets it. The reader sets it when it reads the task back.

Raises:

| Type | Description |
| --- | --- |
| `TimeFValidationError` | If the task is not in a dataset yet. |

#### input\_annotations `class-attribute` `instance-attribute`

```
input_annotations: tuple[Annotation, ...] = field(
    default=(), compare=False
)
```

Existing annotation occurrences supplied to the model as context.

#### input\_modalities `class-attribute` `instance-attribute`

```
input_modalities: frozenset[InputModality] | None = None
```

Optional override. None infers the input kinds when resolved or written.

#### inputs `class-attribute` `instance-attribute`

```
inputs: tuple[Record, ...] = field(
    default=(), compare=False
)
```

Records supplied to the model, in semantic order.

#### metadata `class-attribute` `instance-attribute`

```
metadata: JsonMapping = field(default_factory=dict)
```

Optional JSON-compatible task metadata.

#### prompt `class-attribute` `instance-attribute`

```
prompt: ValueField[
    str | TextHandle | None, TextHandle | None
] = field(default=ValueField(optional_text, None))
```

Call `read()` for the prompt; `None` identifies an unprompted task.

#### rationale `class-attribute` `instance-attribute`

```
rationale: ValueField[
    str | TextHandle | None, TextHandle | None
] = field(default=ValueField(optional_text, None))
```

Call `read()` for the explanation; `None` means no rationale is present.

#### resolved\_input\_modalities `property`

```
resolved_input_modalities: frozenset[InputModality]
```

The validated override, or kinds inferred from the current inputs.

Inference reads Signal specs within the scope, the prompt, and text input annotations.
It does not load values or inspect targets. NO\_INPUT means there are no input Records.
The result is not cached: connectors can assign inputs after construction.

#### scope `class-attribute` `instance-attribute`

```
scope: Span | None = None
```

Optional region of the inputs to which the task applies.

#### split `class-attribute` `instance-attribute`

```
split: Split | None = None
```

The partition the task belongs to: train, validation, or test. None when the dataset does not
partition its tasks.

#### target\_annotations `class-attribute` `instance-attribute`

```
target_annotations: tuple[Annotation, ...] = field(
    default=(), compare=False
)
```

Existing annotation occurrences that form the expected output.

#### targets `class-attribute` `instance-attribute`

```
targets: ValueField[
    Iterable[TargetInput] | None,
    tuple[TargetItem, ...] | None,
] = field(
    default=ValueField(_target_values, None), compare=False
)
```

Ordered native values and stored objects that form the expected output.

#### task\_type `class-attribute`

```
task_type: TaskType
```

The concrete task class's stable storage tag.

#### annotate

```
annotate(annotation: Annotation) -> Annotation
```

Attach one annotation occurrence and return it.

Returns:

| Type | Description |
| --- | --- |
| `Annotation` | The attached occurrence. |

#### check\_against\_scope

```
check_against_scope() -> None
```

Validate configuration that depends on the finalized scope.

#### check\_targets

```
check_targets() -> None
```

Make sure that the final targets follow the rules of this task class.

#### named\_records

```
named_records() -> tuple[Record, ...]
```

Return the Records that the task names, each once: its inputs, then its Record targets.

A task class with candidate Records returns them too, after the inputs.

#### referenced\_signals

```
referenced_signals() -> tuple[Signal, ...]
```

Return the Signals that the task references, each once.

They are its Signal targets, then the Signals that its scope and its span targets name, in the
order of :meth:`spans`.

#### register\_label\_set

```
register_label_set(label_sets: LabelSetRegistry) -> None
```

Add the label set of the task to the dataset's label sets.

Only a classification task has a label set.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `label_sets` | `LabelSetRegistry` | The label sets of the dataset so far. | *required* |

#### spans

```
spans() -> tuple[Span, ...]
```

Return the task scope followed by every span-valued target.

#### with\_references

```
with_references(
    records: Mapping[EntityId, Record],
    signals: Mapping[EntityId, Signal],
) -> Self
```

Return a copy of the task that references the given Records and Signals, by ID.

The copy has the class of the task. Each input, candidate Record, Record target, and Signal
target of the copy is the object of the same ID in `records` or `signals`. The scope and
the span targets of the copy name the Signals of the same IDs in `signals`. Each span keeps
its class. The copy has no ID.

Every other field keeps its value: the annotations of the task, the annotations that it
references, `from_tasks`, the text, and the metadata. A caller that needs other values for
them sets them on the copy.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `records` | `Mapping[EntityId, Record]` | The Records for the copy, by ID. | *required* |
| `signals` | `Mapping[EntityId, Signal]` | The Signals for the copy, by ID. | *required* |

Returns:

| Type | Description |
| --- | --- |
| `Self` | The copy. |

Raises:

| Type | Description |
| --- | --- |
| `TimeFValidationError` | If a Record or Signal that the task references has no ID, or if `records` or `signals` has no object for its ID. |

### TaskType

Bases: `StrEnum`

Stable storage tags for the built-in task classes.

#### ANSWER `class-attribute` `instance-attribute`

```
ANSWER = 'answer'
```

#### CLASSIFICATION `class-attribute` `instance-attribute`

```
CLASSIFICATION = 'classification'
```

#### FORECASTING `class-attribute` `instance-attribute`

```
FORECASTING = 'forecasting'
```

#### SCALAR\_PREDICTION `class-attribute` `instance-attribute`

```
SCALAR_PREDICTION = 'scalar_prediction'
```

#### TEMPORAL\_LOCALIZATION `class-attribute` `instance-attribute`

```
TEMPORAL_LOCALIZATION = 'temporal_localization'
```

#### TS\_CORRESPONDENCE `class-attribute` `instance-attribute`

```
TS_CORRESPONDENCE = 'ts_correspondence'
```

#### TS\_EDITING `class-attribute` `instance-attribute`

```
TS_EDITING = 'ts_editing'
```

#### TS\_GENERATION `class-attribute` `instance-attribute`

```
TS_GENERATION = 'ts_generation'
```

### TemporalLocalizationTask `dataclass`

Bases: `Task`

Locate events or regions in the inputs.

#### annotations `class-attribute` `instance-attribute`

```
annotations: tuple[Annotation, ...] = ()
```

Annotations describing this task itself.

#### from\_tasks `class-attribute` `instance-attribute`

```
from_tasks: tuple[Task, ...] = field(
    default=(), compare=False
)
```

Tasks from which this task was derived.

#### id `property`

```
id: EntityId
```

The task's id, unique among the tasks of its dataset.

:meth:`~timenet.dataset.TimeFDataset.add_task` sets it. The reader sets it when it reads the task back.

Raises:

| Type | Description |
| --- | --- |
| `TimeFValidationError` | If the task is not in a dataset yet. |

#### input\_annotations `class-attribute` `instance-attribute`

```
input_annotations: tuple[Annotation, ...] = field(
    default=(), compare=False
)
```

Existing annotation occurrences supplied to the model as context.

#### input\_modalities `class-attribute` `instance-attribute`

```
input_modalities: frozenset[InputModality] | None = None
```

Optional override. None infers the input kinds when resolved or written.

#### inputs `class-attribute` `instance-attribute`

```
inputs: tuple[Record, ...] = field(
    default=(), compare=False
)
```

Records supplied to the model, in semantic order.

#### metadata `class-attribute` `instance-attribute`

```
metadata: JsonMapping = field(default_factory=dict)
```

Optional JSON-compatible task metadata.

#### mode `class-attribute` `instance-attribute`

```
mode: LocalizationMode = LocalizationMode.SPARSE
```

Whether the localization is sparse or exhaustive.

#### prompt `class-attribute` `instance-attribute`

```
prompt: ValueField[
    str | TextHandle | None, TextHandle | None
] = field(default=ValueField(optional_text, None))
```

Call `read()` for the prompt; `None` identifies an unprompted task.

#### rationale `class-attribute` `instance-attribute`

```
rationale: ValueField[
    str | TextHandle | None, TextHandle | None
] = field(default=ValueField(optional_text, None))
```

Call `read()` for the explanation; `None` means no rationale is present.

#### resolved\_input\_modalities `property`

```
resolved_input_modalities: frozenset[InputModality]
```

The validated override, or kinds inferred from the current inputs.

Inference reads Signal specs within the scope, the prompt, and text input annotations.
It does not load values or inspect targets. NO\_INPUT means there are no input Records.
The result is not cached: connectors can assign inputs after construction.

#### scope `class-attribute` `instance-attribute`

```
scope: Span | None = None
```

Optional region of the inputs to which the task applies.

#### split `class-attribute` `instance-attribute`

```
split: Split | None = None
```

The partition the task belongs to: train, validation, or test. None when the dataset does not
partition its tasks.

#### target\_annotations `class-attribute` `instance-attribute`

```
target_annotations: tuple[Annotation, ...] = field(
    default=(), compare=False
)
```

Existing annotation occurrences that form the expected output.

#### targets `class-attribute` `instance-attribute`

```
targets: ValueField[
    Iterable[TargetInput] | None,
    tuple[TargetItem, ...] | None,
] = field(
    default=ValueField(_target_values, None), compare=False
)
```

Ordered native values and stored objects that form the expected output.

#### task\_type `class-attribute`

```
task_type: TaskType = TaskType.TEMPORAL_LOCALIZATION
```

#### annotate

```
annotate(annotation: Annotation) -> Annotation
```

Attach one annotation occurrence and return it.

Returns:

| Type | Description |
| --- | --- |
| `Annotation` | The attached occurrence. |

#### check\_against\_scope

```
check_against_scope() -> None
```

Validate configuration that depends on the finalized scope.

#### check\_targets

```
check_targets() -> None
```

Make sure that the final targets follow the rules of this task class.

#### named\_records

```
named_records() -> tuple[Record, ...]
```

Return the Records that the task names, each once: its inputs, then its Record targets.

A task class with candidate Records returns them too, after the inputs.

#### referenced\_signals

```
referenced_signals() -> tuple[Signal, ...]
```

Return the Signals that the task references, each once.

They are its Signal targets, then the Signals that its scope and its span targets name, in the
order of :meth:`spans`.

#### register\_label\_set

```
register_label_set(label_sets: LabelSetRegistry) -> None
```

Add the label set of the task to the dataset's label sets.

Only a classification task has a label set.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `label_sets` | `LabelSetRegistry` | The label sets of the dataset so far. | *required* |

#### spans

```
spans() -> tuple[Span, ...]
```

Return the task scope followed by every span-valued target.

#### with\_references

```
with_references(
    records: Mapping[EntityId, Record],
    signals: Mapping[EntityId, Signal],
) -> Self
```

Return a copy of the task that references the given Records and Signals, by ID.

The copy has the class of the task. Each input, candidate Record, Record target, and Signal
target of the copy is the object of the same ID in `records` or `signals`. The scope and
the span targets of the copy name the Signals of the same IDs in `signals`. Each span keeps
its class. The copy has no ID.

Every other field keeps its value: the annotations of the task, the annotations that it
references, `from_tasks`, the text, and the metadata. A caller that needs other values for
them sets them on the copy.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `records` | `Mapping[EntityId, Record]` | The Records for the copy, by ID. | *required* |
| `signals` | `Mapping[EntityId, Signal]` | The Signals for the copy, by ID. | *required* |

Returns:

| Type | Description |
| --- | --- |
| `Self` | The copy. |

Raises:

| Type | Description |
| --- | --- |
| `TimeFValidationError` | If a Record or Signal that the task references has no ID, or if `records` or `signals` has no object for its ID. |

### TextHandle

Bases: `_TextBehaviour`, `ValueHandle[str]`

Refer to one string: a task prompt, rationale, or text target, or an annotation value.

#### is\_loaded `abstractmethod` `property`

```
is_loaded: bool
```

Whether the value is held in memory, so `read()` needs no storage access.

#### length `abstractmethod` `property`

```
length: int
```

The value of `len(read())`, known without reading the text.

That is the string's number of code points, or the list's number of items. `__eq__` skips
the read when lengths differ, so a stored handle must report its length the same way.

#### read `abstractmethod`

```
read() -> str
```

Return the string, from memory or read through from storage.

### TextListHandle

Bases: `_TextBehaviour`, `ValueHandle[list[str]]`

Refer to a list of strings, such as a recording's labels in one annotation value.

#### is\_loaded `abstractmethod` `property`

```
is_loaded: bool
```

Whether the value is held in memory, so `read()` needs no storage access.

#### length `abstractmethod` `property`

```
length: int
```

The value of `len(read())`, known without reading the text.

That is the string's number of code points, or the list's number of items. `__eq__` skips
the read when lengths differ, so a stored handle must report its length the same way.

#### read `abstractmethod`

```
read() -> list[str]
```

Return the list of strings, from memory or read through from storage.

### TimeInterval `dataclass`

Bases: `TimeSpan`

The half-open range `[start_us, end_us)` on the recording timeline.

#### end\_us `instance-attribute`

```
end_us: int
```

End of the interval, exclusive, in microseconds.

#### exclusive\_end `property`

```
exclusive_end: int
```

The interval's own exclusive end, `end_us`.

#### frame `class-attribute`

```
frame: str = 'seconds'
```

The frame its bounds read in, as stored on disk.

#### is\_point `class-attribute`

```
is_point: bool = False
```

Whether this span marks a single position rather than a bounded interval.

#### start\_us `instance-attribute`

```
start_us: int
```

The position, or the start of the interval, in microseconds on the source recording timeline.

#### time\_series `class-attribute` `instance-attribute`

```
time_series: tuple[Signal, ...] | None = None
```

Series the span is scoped to. `None` covers every series in the record.

#### micros `classmethod`

```
micros(
    start: int,
    end: int,
    *,
    time_series: tuple[Signal, ...] | None = None,
) -> TimeInterval
```

Construct an interval from whole microseconds, for a source that already has them.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `start` | `int` | Start of the interval, in microseconds. | *required* |
| `end` | `int` | End of the interval, exclusive, in microseconds. | *required* |
| `time_series` | `tuple[Signal, ...] | None` | Series the interval is scoped to. `None` covers every series. | `None` |

Returns:

| Type | Description |
| --- | --- |
| `TimeInterval` | The interval. |

#### seconds `classmethod`

```
seconds(
    start: float,
    end: float,
    *,
    time_series: tuple[Signal, ...] | None = None,
) -> TimeInterval
```

Construct an interval from recording seconds, each bound rounded to the nearest microsecond.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `start` | `float` | Start of the interval, in recording seconds. | *required* |
| `end` | `float` | End of the interval, exclusive, in recording seconds. | *required* |
| `time_series` | `tuple[Signal, ...] | None` | Series the interval is scoped to. `None` covers every series. | `None` |

Returns:

| Type | Description |
| --- | --- |
| `TimeInterval` | The interval. |

### TimeOrigin `dataclass`

One Record origin, shared explicitly when Records use the same relative zero.

Equal timestamps do not make two origins interchangeable. `None` means that
the clock has no known absolute timestamp.

#### timestamp `class-attribute` `instance-attribute`

```
timestamp: datetime | int | None = None
```

### TimePoint `dataclass`

Bases: `TimeSpan`

One point on the recording timeline.

#### exclusive\_end `property`

```
exclusive_end: int
```

One microsecond past the point, so the half-open window covering it is `[start_us, +1)`.

#### frame `class-attribute`

```
frame: str = 'seconds'
```

The frame its bounds read in, as stored on disk.

#### is\_point `class-attribute`

```
is_point: bool = True
```

#### start\_us `instance-attribute`

```
start_us: int
```

The position, or the start of the interval, in microseconds on the source recording timeline.

#### time\_series `class-attribute` `instance-attribute`

```
time_series: tuple[Signal, ...] | None = None
```

Series the span is scoped to. `None` covers every series in the record.

#### micros `classmethod`

```
micros(
    at: int,
    *,
    time_series: tuple[Signal, ...] | None = None,
) -> TimePoint
```

Construct a point from whole microseconds, for a source that already has them.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `at` | `int` | The position, in microseconds. | *required* |
| `time_series` | `tuple[Signal, ...] | None` | Series the point is scoped to. `None` covers every series. | `None` |

Returns:

| Type | Description |
| --- | --- |
| `TimePoint` | The point. |

#### seconds `classmethod`

```
seconds(
    at: float,
    *,
    time_series: tuple[Signal, ...] | None = None,
) -> TimePoint
```

Construct a point from recording seconds, rounded to the nearest microsecond.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `at` | `float` | The position, in recording seconds. | *required* |
| `time_series` | `tuple[Signal, ...] | None` | Series the point is scoped to. `None` covers every series. | `None` |

Returns:

| Type | Description |
| --- | --- |
| `TimePoint` | The point. |

### TimeSeriesSpec

Bases: `TimeFModel`

Define the contract for a measurement modality: identity, value unit, dtype, and per-timestep shape.

The spec carries no unit for time or for a sampling rate. Time offsets are integer microseconds and
a cadence is a Fraction of them, so those units can only be `second` and `hertz`.

#### categories `class-attribute` `instance-attribute`

```
categories: tuple[NonEmptyString, ...] = ()
```

Ordered codebook for `dtype="enum"`. Empty for every other dtype.

#### dimension\_names `class-attribute` `instance-attribute`

```
dimension_names: tuple[NonEmptyString, ...] = ()
```

Optional names for the dimensions in :attr:`value_shape`.

#### dtype `class-attribute` `instance-attribute`

```
dtype: ValueDtype = 'float32'
```

Value dtype: a NumPy scalar dtype, `"str"` for text, or `"enum"` for a categorical value.

#### missing `class-attribute` `instance-attribute`

```
missing: MissingValues | None = None
```

Why timesteps can be missing, or `None` if none are allowed.

#### modality `class-attribute` `instance-attribute`

```
modality: InputModality = InputModality.TIME_SERIES
```

Semantic input kind. Set IMAGE, AUDIO, or TEXT for Signals that carry those kinds of data.

#### model\_config `class-attribute` `instance-attribute`

```
model_config = ConfigDict(
    extra="forbid",
    frozen=True,
    revalidate_instances="always",
    serialize_by_alias=True,
    validate_by_name=True,
    validate_default=True,
)
```

#### name `instance-attribute`

```
name: StrictStr
```

Human-readable display name of the modality.

#### nullable `property`

```
nullable: bool
```

Whether the specification allows missing timesteps. True when :attr:`missing` is set.

#### spec\_type `instance-attribute`

```
spec_type: NonEmptyString
```

Type tag identifying the modality. Callers use it to filter datasets by spec type.

#### unit\_value `instance-attribute`

```
unit_value: UnitValue
```

Unit of the measured values. `None` means unknown, not dimensionless.

#### value\_shape `class-attribute` `instance-attribute`

```
value_shape: tuple[StrictPositiveInt, ...] = ()
```

Shape of one timestep, excluding the leading time axis. An empty shape means scalar values.

#### check\_nulls\_allowed

```
check_nulls_allowed(
    null_count: int, *, series: str
) -> None
```

Check that the specification allows missing timesteps.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `null_count` | `int` | The number of missing timesteps in the series. | *required* |
| `series` | `str` | The series name to use in an error message. | *required* |

Raises:

| Type | Description |
| --- | --- |
| `TimeFValidationError` | If the series has missing timesteps but the spec has no :attr:`missing` record. |

### TimeSpan `dataclass`

Bases: `Span`

Abstract base for a region on the recording timeline. Bounds are microseconds.

Covers the whole record when `time_series` is `None`, or a subset of series when it holds
them. Valid only on a series whose axis is a timeline (regular or irregular).

#### exclusive\_end `property`

```
exclusive_end: int
```

The exclusive upper bound of the span, in its own frame.

The region is half-open, so a point ends one unit past its position and an interval ends at
its stored end. Each concrete leaf supplies this.

#### frame `class-attribute`

```
frame: str = 'seconds'
```

The frame its bounds read in, as stored on disk.

#### is\_point `class-attribute`

```
is_point: bool = False
```

Whether this span marks a single position rather than a bounded interval.

#### start\_us `instance-attribute`

```
start_us: int
```

The position, or the start of the interval, in microseconds on the source recording timeline.

#### time\_series `class-attribute` `instance-attribute`

```
time_series: tuple[Signal, ...] | None = None
```

Series the span is scoped to. `None` covers every series in the record.

### ValueHandle

Bases: `ABC`, `Generic[_Value_co]`

Refer to one value and read it only on request.

A handle built in memory holds its value. A stored handle can read through to storage on each
`read()`.

#### is\_loaded `abstractmethod` `property`

```
is_loaded: bool
```

Whether the value is held in memory, so `read()` needs no storage access.

#### read `abstractmethod`

```
read() -> _Value_co
```

Return the value, from memory or read through from storage.

### Version `dataclass`

A `major.minor.patch` semantic version with non-negative integer components.

Frozen and ordered, so versions compare with the usual precedence
(`Version(1, 2, 0) > Version(1, 1, 9)`).

#### major `instance-attribute`

```
major: int
```

Major version. Increments on breaking changes.

#### minor `instance-attribute`

```
minor: int
```

Minor version. Increments on backwards-compatible additions.

#### patch `instance-attribute`

```
patch: int
```

Patch version. Increments on backwards-compatible fixes.

#### parse `classmethod`

```
parse(text: str) -> Version
```

Parse a `major.minor.patch` string.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `text` | `str` | The version string to parse. | *required* |

Returns:

| Type | Description |
| --- | --- |
| `Version` | The parsed :class:`Version`. |

Raises:

| Type | Description |
| --- | --- |
| `TimeFValidationError` | If `text` is not exactly three integer components. |

### annotation\_type\_of

```
annotation_type_of(
    annotation: Annotation,
) -> AnnotationType
```

Return the :class:`AnnotationType` shape of an annotation instance.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `annotation` | `Annotation` | The annotation to classify. | *required* |

Returns:

| Type | Description |
| --- | --- |
| `AnnotationType` | The matching :class:`AnnotationType`, derived from the span rather than from a class. |

### check\_id

```
check_id(value: object, what: str) -> EntityId
```

Return `value` as an int if it is a valid entity id.

The function accepts any integral value, including NumPy integers read back from Arrow or pandas.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `value` | `object` | The candidate id. | *required* |
| `what` | `str` | The name of the id, used in the error message. | *required* |

Returns:

| Type | Description |
| --- | --- |
| `EntityId` | `value` as a Python int. |

Raises:

| Type | Description |
| --- | --- |
| `TimeFValidationError` | If `value` is not an integral number (bool excluded) in `0 < value < 2**63`. |

### normalize\_unit

```
normalize_unit(unit: str | Unit | None) -> str | None
```

Validate a unit against the shared registry, rejecting an unrecognized unit string.

A :class:`pint.Unit` becomes its canonical name. The function keeps a unit string as written but
validates it, and raises on an unknown one. `None` passes through. The result is always a
string or `None`, so serialization is unchanged. Every type that carries a unit uses this
function, so annotation values and scalar task targets accept and store units the same way.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `unit` | `str | Unit | None` | A :class:`pint.Unit`, a unit string (for example `"years"`), or `None`. | *required* |

Returns:

| Type | Description |
| --- | --- |
| `str | None` | The unit as a string, or `None`. |

Raises:

| Type | Description |
| --- | --- |
| `TimeFValidationError` | If `unit` is a string the shared registry does not recognize. |

### offset\_us

```
offset_us(
    moment: datetime, start_time: datetime | int | None
) -> int
```

Convert a wall-clock moment to an offset from the Record origin.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `moment` | `datetime` | The wall-clock moment, timezone-aware. | *required* |
| `start_time` | `datetime | int | None` | The Record's absolute origin. | *required* |

Returns:

| Type | Description |
| --- | --- |
| `int` | Microseconds from the Record's relative zero. |

Raises:

| Type | Description |
| --- | --- |
| `TimeFValidationError` | If the Record has no known absolute origin. |

### parse\_split

```
parse_split(value: Split | str) -> Split
```

Coerce a split name to :class:`Split`.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `value` | `Split | str` | The member itself, or its value such as `"train"`. | *required* |

Returns:

| Type | Description |
| --- | --- |
| `Split` | The matching member. |

Raises:

| Type | Description |
| --- | --- |
| `TimeFValidationError` | If `value` names no split. |

### read\_value

```
read_value(value: TextHandle) -> str
```

```
read_value(value: TextListHandle) -> list[str]
```

```
read_value(value: TextHandle | None) -> str | None
```

```
read_value(
    value: TextHandle | TextListHandle,
) -> str | list[str]
```

```
read_value(value: TargetItem) -> TargetValue
```

```
read_value(
    value: TextHandle | TextListHandle | _Other,
) -> str | list[str] | _Other
```

```
read_value(value: object) -> object
```

Read a text handle and return any other value unchanged, `None` included.

Returns:

| Type | Description |
| --- | --- |
| `object` | The handle's string or list of strings, or the value itself when it is not text. |

### read\_values

```
read_values(values: None) -> None
```

```
read_values(
    values: Iterable[TextHandle],
) -> tuple[str, ...]
```

```
read_values(
    values: Iterable[TextListHandle],
) -> tuple[list[str], ...]
```

```
read_values(
    values: Iterable[TargetItem],
) -> tuple[TargetValue, ...]
```

```
read_values(
    values: Iterable[TextHandle | TextListHandle | _Other],
) -> tuple[str | list[str] | _Other, ...]
```

```
read_values(
    values: Iterable[object] | None,
) -> tuple[object, ...] | None
```

Read every text handle among `values` and return every other item unchanged.

Each item is read as :func:`read_value` reads it.

Returns:

| Type | Description |
| --- | --- |
| `tuple[object, ...] | None` | The items in order, or `None` when `values` is `None`. |

Raises:

| Type | Description |
| --- | --- |
| `TimeFValidationError` | If `values` is a bare string, which would split into characters. |

### seconds\_to\_us

```
seconds_to_us(seconds: float) -> int
```

Round seconds onto the microsecond timeline.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `seconds` | `float` | A time offset or duration in seconds. | *required* |

Returns:

| Type | Description |
| --- | --- |
| `int` | The nearest whole microsecond. |

### unix\_us

```
unix_us(moment: datetime | int) -> int
```

Normalize a wall-clock timestamp to Unix microseconds.

This accepts two forms. A timezone-aware :class:`~datetime.datetime` already resolves to
microseconds, so this changes the origin without rounding. An `int` passes through, for a source
that gives microseconds directly.

This refuses a float. The value `1700000000.5` can mean seconds or microseconds, and the wrong
reading is off by a factor of a million. If the source gives seconds, wrap it in
:func:`seconds_to_us` so the unit is visible at the call site.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `moment` | `datetime | int` | A timezone-aware datetime, or whole Unix microseconds. | *required* |

Returns:

| Type | Description |
| --- | --- |
| `int` | Unix microseconds. |

Raises:

| Type | Description |
| --- | --- |
| `TimeFValidationError` | If `moment` is a float, any other type, or a naive datetime. A naive datetime reads in the local zone of the building machine. That anchors the same recording differently for each builder. |

### us\_to\_seconds

```
us_to_seconds(microseconds: int) -> float
```

Render microseconds back as seconds.

This is exact for everything TimeF can store. A value written in seconds reads back equal to
itself, unless it was finer than a microsecond.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `microseconds` | `int` | A time offset or duration in microseconds. | *required* |

Returns:

| Type | Description |
| --- | --- |
| `float` | The same quantity in seconds. |

### use\_as\_application\_registry

```
use_as_application_registry() -> None
```

Make TimeNet's registry pint's process-wide application registry.

Opt in for two cases. First, when you pickle bare :class:`pint.Unit` or :class:`pint.Quantity`
objects built from :data:`ureg`, because custom units such as `bpm` otherwise fail to unpickle.
Second, when you want units from :data:`ureg` to compare and convert against units another
library built.

Importing this module does not call this function. It replaces the process-wide registry, so a host
with its own registry can break. Call it once from application startup, where the decision is yours.

This is a global assignment, not a merge. The last call wins, and any custom units that a
previously installed registry defined stop resolving.

### value\_type\_of

```
value_type_of(value: Any) -> ValueType | None
```

Return the manifest `value_type` tag for an annotation value.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `value` | `Any` | The annotation's value. | *required* |

Returns:

| Type | Description |
| --- | --- |
| `ValueType | None` | One of `"bool" | "int" | "float" | "str" | "list"`, or `None` for a marker with no value. |
| `ValueType | None` | A list holds only strings, such as the names of activities in a recording. |

Raises:

| Type | Description |
| --- | --- |
| `TimeFValidationError` | If `value` is a non-null value of an unsupported type. |
