# IngestBuilder

## class nominal.experimental.ingest.IngestBuilder(client, dataset, *, tags=None)

Bases: [`object`](https://docs.python.org/3/builtins/functions.html#object "(in Python v3.15)")

Accumulate files and submit them as a single (MULTI) ingest job.

EXPERIMENTAL / UNSTABLE — see the module docstring. Targets an existing dataset; the v2
endpoint does not create datasets. Build with `add_*` (fluent), then [`submit()`](https://dev.nominal.io/python/ref/generated/nominal.experimental.ingest.IngestBuilder.md#nominal.experimental.ingest.IngestBuilder.submit "nominal.experimental.ingest.IngestBuilder.submit") exactly
once: a builder is single-use, and a second [`submit()`](https://dev.nominal.io/python/ref/generated/nominal.experimental.ingest.IngestBuilder.md#nominal.experimental.ingest.IngestBuilder.submit "nominal.experimental.ingest.IngestBuilder.submit") raises rather than re-uploading
and re-ingesting everything it holds.

Create a builder that targets an existing dataset.

Parameters:
:   - **client** ([*NominalClient*](https://dev.nominal.io/python/ref/generated/nominal.core.NominalClient.md#nominal.core.NominalClient "nominal.core.NominalClient"))

      Client used to upload files and trigger the ingest job.
    - **dataset** ([*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)") *|* [*Dataset*](https://dev.nominal.io/python/ref/generated/nominal.core.Dataset.md#nominal.core.Dataset "nominal.core.Dataset"))

      The dataset to ingest into, as a `Dataset` or its RID. It must already exist;
      the v2 ingest endpoint does not create datasets.
    - **tags** (*Mapping**[*[*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)")*,* [*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)")*]* *|* *None*)

      Request-level tags applied to every item in the job. Add more later with
      [`add_tags`](https://dev.nominal.io/python/ref/generated/nominal.experimental.ingest.IngestBuilder.md#nominal.experimental.ingest.IngestBuilder.add_tags "nominal.experimental.ingest.IngestBuilder.add_tags"), or set per-item tags on the individual `add_*` calls.

### add_ardupilot_dataflash(path, *, tags=None)

Register an ArduPilot Dataflash (.bin) file, mirroring `Dataset.add_ardupilot_dataflash`.

Parameters:
:   - **path** ([*Path*](https://docs.python.org/3/library/pathlib.html#pathlib.Path "(in Python v3.15)") *|* [*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)"))

      Path to the Dataflash file on disk.
    - **tags** ([*Mapping*](https://docs.python.org/3/library/typing.html#typing.Mapping "(in Python v3.15)")*[*[*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)")*,* [*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)")*]* *|* *None*)

      Key-value pairs applied as tags to all data from this file.

Returns:
:   This builder, for chaining.

Return type:
:   [*Self*](https://docs.python.org/3/library/typing.html#typing.Self "(in Python v3.15)")

### add_avro_stream(path, *, units=None, channel_prefix=None, timestamp_type=None, tags=None)

Register an Avro stream (.avro) file.

The file must conform to the canonical Avro stream schema (see `Dataset.add_avro_stream`
for the schema definition). The schema fixes which field holds the timestamps, so this takes
no timestamp column – only how to read the numbers in that field.

Parameters:
:   - **path** ([*Path*](https://docs.python.org/3/library/pathlib.html#pathlib.Path "(in Python v3.15)") *|* [*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)"))

      Path to the .avro file on disk.
    - **units** ([*Mapping*](https://docs.python.org/3/library/typing.html#typing.Mapping "(in Python v3.15)")*[*[*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)")*,* [*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)")*]* *|* *None*)

      Mapping of channel name to unit symbol.
    - **channel_prefix** ([*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)") *|* *None*)

      Prefix prepended to every channel name ingested from this file.
    - **timestamp_type** ([*Epoch*](https://dev.nominal.io/python/ref/generated/nominal.ts.Epoch.md#nominal.ts.Epoch "nominal.ts.Epoch") *|* [*Relative*](https://dev.nominal.io/python/ref/generated/nominal.ts.Relative.md#nominal.ts.Relative "nominal.ts.Relative") *|* [*Literal*](https://docs.python.org/3/library/typing.html#typing.Literal "(in Python v3.15)")*[**'epoch_picoseconds'**,* *'epoch_nanoseconds'**,* *'epoch_microseconds'**,* *'epoch_milliseconds'**,* *'epoch_seconds'**,* *'epoch_minutes'**,* *'epoch_hours'**,* *'epoch_days'**]* *|* *None*)

      How to read the file’s numeric timestamps – an absolute epoch
      (`ts.Epoch`, or its string literal) or an offset from a start (`ts.Relative`).
      Defaults to epoch nanoseconds, the canonical schema’s reading.
    - **tags** ([*Mapping*](https://docs.python.org/3/library/typing.html#typing.Mapping "(in Python v3.15)")*[*[*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)")*,* [*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)")*]* *|* *None*)

      Key-value pairs applied as tags to all data from this file. Tags in the records
      take precedence – these only fill keys a record does not already set.

Returns:
:   This builder, for chaining.

Return type:
:   [*Self*](https://docs.python.org/3/library/typing.html#typing.Self "(in Python v3.15)")

### add_containerized(extractor: str | ContainerizedExtractor, sources: Mapping[str, Path | str], *, arguments: Mapping[str, str] | None = None, tags: Mapping[str, str] | None = None) → Self

### add_containerized(extractor: str | ContainerizedExtractor, sources: Mapping[str, Path | str], *, arguments: Mapping[str, str] | None = None, timestamp_column: str, timestamp_type: Iso8601 | Epoch | Relative | Custom | Literal['iso_8601', 'epoch_picoseconds', 'epoch_nanoseconds', 'epoch_microseconds', 'epoch_milliseconds', 'epoch_seconds', 'epoch_minutes', 'epoch_hours', 'epoch_days'], tags: Mapping[str, str] | None = None) → Self

Register a containerized-extractor run over one or more named source files.

Pass both `timestamp_column` and `timestamp_type`, or neither; the overloads make passing
only one a type error, and the runtime guard below rejects it for callers without a type
checker.

Parameters:
:   - **extractor** ([*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)") *|* [*ContainerizedExtractor*](https://dev.nominal.io/python/ref/generated/nominal.core.ContainerizedExtractor.md#nominal.core.ContainerizedExtractor "nominal.core.containerized_extractor.ContainerizedExtractor"))

      The containerized extractor to run, as a `ContainerizedExtractor` or its RID.
    - **sources** ([*Mapping*](https://docs.python.org/3/library/typing.html#typing.Mapping "(in Python v3.15)")*[*[*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)")*,* [*Path*](https://docs.python.org/3/library/pathlib.html#pathlib.Path "(in Python v3.15)") *|* [*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)")*]*)

      Mapping of each registered extractor input name to a local file to upload.
      The names must match the extractor’s registered inputs exactly.
    - **arguments** ([*Mapping*](https://docs.python.org/3/library/typing.html#typing.Mapping "(in Python v3.15)")*[*[*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)")*,* [*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)")*]* *|* *None*)

      Key-value input arguments passed to the extractor.
    - **timestamp_column** ([*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)") *|* *None*)

      Column, applied uniformly to the extractor’s output files, holding
      each row’s timestamp.
    - **timestamp_type** ([*Iso8601*](https://dev.nominal.io/python/ref/generated/nominal.ts.Iso8601.md#nominal.ts.Iso8601 "nominal.ts.Iso8601") *|* [*Epoch*](https://dev.nominal.io/python/ref/generated/nominal.ts.Epoch.md#nominal.ts.Epoch "nominal.ts.Epoch") *|* [*Relative*](https://dev.nominal.io/python/ref/generated/nominal.ts.Relative.md#nominal.ts.Relative "nominal.ts.Relative") *|* [*Custom*](https://dev.nominal.io/python/ref/generated/nominal.ts.Custom.md#nominal.ts.Custom "nominal.ts.Custom") *|* [*Literal*](https://docs.python.org/3/library/typing.html#typing.Literal "(in Python v3.15)")*[**'iso_8601'**,* *'epoch_picoseconds'**,* *'epoch_nanoseconds'**,* *'epoch_microseconds'**,* *'epoch_milliseconds'**,* *'epoch_seconds'**,* *'epoch_minutes'**,* *'epoch_hours'**,* *'epoch_days'**]* *|* *None*)

      Type of the timestamp data in `timestamp_column`, e.g. ‘epoch_seconds’.
    - **tags** ([*Mapping*](https://docs.python.org/3/library/typing.html#typing.Mapping "(in Python v3.15)")*[*[*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)")*,* [*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)")*]* *|* *None*)

      Key-value pairs applied as tags to all data produced by this run.

Returns:
:   This builder, for chaining.

Raises:
:   [**ValueError**](https://docs.python.org/3/builtins/exceptions.html#ValueError "(in Python v3.15)") – if `sources` is empty, or if only one of `timestamp_column` /
    `timestamp_type` is given.

Return type:
:   [*Self*](https://docs.python.org/3/library/typing.html#typing.Self "(in Python v3.15)")

### add_csv(path, timestamp_column, timestamp_type, *, tag_columns=None, units=None, channel_prefix=None, channel_name_overrides=None, header_row=None, data_row=None, units_row=None, tags=None)

Register a CSV file (.csv or .csv.gz) with optional row selection.

All shared arguments follow [`add_tabular_data()`](https://dev.nominal.io/python/ref/generated/nominal.experimental.ingest.IngestBuilder.md#nominal.experimental.ingest.IngestBuilder.add_tabular_data "nominal.experimental.ingest.IngestBuilder.add_tabular_data"). Explicit `units` override
units read from `units_row` per channel; other channels retain their row units.
The backend validates row numbers and their ordering when the job is submitted.

Parameters:
:   - **path** ([*Path*](https://docs.python.org/3/library/pathlib.html#pathlib.Path "(in Python v3.15)") *|* [*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)"))

      Path to a .csv or .csv.gz file.
    - **timestamp_column** ([*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)"))

      Column containing timestamps; not ingested as a data channel.
    - **timestamp_type** ([*Iso8601*](https://dev.nominal.io/python/ref/generated/nominal.ts.Iso8601.md#nominal.ts.Iso8601 "nominal.ts.Iso8601") *|* [*Epoch*](https://dev.nominal.io/python/ref/generated/nominal.ts.Epoch.md#nominal.ts.Epoch "nominal.ts.Epoch") *|* [*Relative*](https://dev.nominal.io/python/ref/generated/nominal.ts.Relative.md#nominal.ts.Relative "nominal.ts.Relative") *|* [*Custom*](https://dev.nominal.io/python/ref/generated/nominal.ts.Custom.md#nominal.ts.Custom "nominal.ts.Custom") *|* [*Literal*](https://docs.python.org/3/library/typing.html#typing.Literal "(in Python v3.15)")*[**'iso_8601'**,* *'epoch_picoseconds'**,* *'epoch_nanoseconds'**,* *'epoch_microseconds'**,* *'epoch_milliseconds'**,* *'epoch_seconds'**,* *'epoch_minutes'**,* *'epoch_hours'**,* *'epoch_days'**]*)

      Type of the timestamp data, e.g. ‘epoch_seconds’.
    - **tag_columns** ([*Mapping*](https://docs.python.org/3/library/typing.html#typing.Mapping "(in Python v3.15)")*[*[*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)")*,* [*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)")*]* *|* *None*)

      Mapping of tag keys to columns supplying their values.
    - **units** ([*Mapping*](https://docs.python.org/3/library/typing.html#typing.Mapping "(in Python v3.15)")*[*[*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)")*,* [*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)")*]* *|* *None*)

      Mapping of channel names to unit symbols, overriding the units record per channel.
    - **channel_prefix** ([*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)") *|* *None*)

      Prefix prepended to every ingested channel name.
    - **channel_name_overrides** ([*Mapping*](https://docs.python.org/3/library/typing.html#typing.Mapping "(in Python v3.15)")*[*[*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)")*,* [*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)")*]* *|* *None*)

      Mapping of original channel names to their ingested names.
    - **tags** ([*Mapping*](https://docs.python.org/3/library/typing.html#typing.Mapping "(in Python v3.15)")*[*[*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)")*,* [*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)")*]* *|* *None*)

      Key-value pairs applied as tags to all data from this file.
    - **header_row** ([*int*](https://docs.python.org/3/builtins/functions.html#int "(in Python v3.15)") *|* *None*)

      Positive, one-based header record number, defaulting to 1.
      Blank lines are ignored; a multiline record counts as one record.
    - **data_row** ([*int*](https://docs.python.org/3/builtins/functions.html#int "(in Python v3.15)") *|* *None*)

      Positive, one-based first data record, defaulting to `header_row + 1`.
      Must follow the header; intervening records are skipped.
    - **units_row** ([*int*](https://docs.python.org/3/builtins/functions.html#int "(in Python v3.15)") *|* *None*)

      Positive, one-based units record, distinct from the header and before
      the first data record. Set `data_row` past it. Unit cells match columns
      by position, including a placeholder for the timestamp column. Empty
      cells have no unit. Omit to read no units row.

Returns:
:   This builder, for chaining.

Raises:
:   [**ValueError**](https://docs.python.org/3/builtins/exceptions.html#ValueError "(in Python v3.15)") – The path is not CSV.

Return type:
:   [*Self*](https://docs.python.org/3/library/typing.html#typing.Self "(in Python v3.15)")

### add_journal_json(path: Path | str, *, channel: str | None = None, tags: Mapping[str, str] | None = None) → Self

### add_journal_json(path: Path | str, *, channel: str | None = None, timestamp_column: str, timestamp_type: Epoch | Relative | Literal['epoch_picoseconds', 'epoch_nanoseconds', 'epoch_microseconds', 'epoch_milliseconds', 'epoch_seconds', 'epoch_minutes', 'epoch_hours', 'epoch_days'], tags: Mapping[str, str] | None = None) → Self

Register a journald-style .jsonl / .jsonl.gz log file.

Pass both `timestamp_column` and `timestamp_type`, or neither; the overloads make passing
only one a type error, and the runtime guard below rejects it for callers without a type
checker.

Parameters:
:   - **path** ([*Path*](https://docs.python.org/3/library/pathlib.html#pathlib.Path "(in Python v3.15)") *|* [*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)"))

      Path to the journal-json file on disk.
    - **channel** ([*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)") *|* *None*)

      Channel name to ingest the logs under. Defaults to ‘logs’ if omitted.
    - **timestamp_column** ([*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)") *|* *None*)

      Field holding each record’s timestamp. Omit to use the file’s
      default journald timestamp.
    - **timestamp_type** ([*Epoch*](https://dev.nominal.io/python/ref/generated/nominal.ts.Epoch.md#nominal.ts.Epoch "nominal.ts.Epoch") *|* [*Relative*](https://dev.nominal.io/python/ref/generated/nominal.ts.Relative.md#nominal.ts.Relative "nominal.ts.Relative") *|* [*Literal*](https://docs.python.org/3/library/typing.html#typing.Literal "(in Python v3.15)")*[**'epoch_picoseconds'**,* *'epoch_nanoseconds'**,* *'epoch_microseconds'**,* *'epoch_milliseconds'**,* *'epoch_seconds'**,* *'epoch_minutes'**,* *'epoch_hours'**,* *'epoch_days'**]* *|* *None*)

      How to read the numbers in `timestamp_column` – an absolute epoch
      (`ts.Epoch`, or its string literal, e.g. ‘epoch_microseconds’) or an offset from a
      start (`ts.Relative`). Log timestamps are read as numbers, so ISO 8601 and custom
      string formats cannot be used here.
    - **tags** ([*Mapping*](https://docs.python.org/3/library/typing.html#typing.Mapping "(in Python v3.15)")*[*[*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)")*,* [*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)")*]* *|* *None*)

      Key-value pairs applied as tags to all data from this file.

Returns:
:   This builder, for chaining.

Raises:
:   [**ValueError**](https://docs.python.org/3/builtins/exceptions.html#ValueError "(in Python v3.15)") – if only one of `timestamp_column` / `timestamp_type` is given, or if
    `timestamp_type` is not numeric.

Return type:
:   [*Self*](https://docs.python.org/3/library/typing.html#typing.Self "(in Python v3.15)")

### add_mcap(path: Path | str, *, include_topics: Sequence[str] | None = None, ignore_invalid_topics: bool | None = None, tags: Mapping[str, str] | None = None) → Self

### add_mcap(path: Path | str, *, exclude_topics: Sequence[str] | None = None, ignore_invalid_topics: bool | None = None, tags: Mapping[str, str] | None = None) → Self

Register an MCAP file.

Pass at most one of `include_topics` / `exclude_topics`; the overloads make passing both a
type error, and the runtime guard below rejects it for callers without a type checker.

Parameters:
:   - **path** ([*Path*](https://docs.python.org/3/library/pathlib.html#pathlib.Path "(in Python v3.15)") *|* [*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)"))

      Path to the MCAP file on disk.
    - **include_topics** ([*Sequence*](https://docs.python.org/3/library/typing.html#typing.Sequence "(in Python v3.15)")*[*[*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)")*]* *|* *None*)

      If given, restrict ingestion to these topics. Defaults to all
      protobuf-encoded topics present in the MCAP.
    - **exclude_topics** ([*Sequence*](https://docs.python.org/3/library/typing.html#typing.Sequence "(in Python v3.15)")*[*[*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)")*]* *|* *None*)

      If given, ingest every topic except these.
    - **ignore_invalid_topics** ([*bool*](https://docs.python.org/3/builtins/functions.html#bool "(in Python v3.15)") *|* *None*)

      If true, skip invalid MCAP topics and continue ingesting valid ones.
    - **tags** ([*Mapping*](https://docs.python.org/3/library/typing.html#typing.Mapping "(in Python v3.15)")*[*[*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)")*,* [*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)")*]* *|* *None*)

      Key-value pairs applied as tags to all data from this file.

Returns:
:   This builder, for chaining.

Raises:
:   [**ValueError**](https://docs.python.org/3/builtins/exceptions.html#ValueError "(in Python v3.15)") – if both `include_topics` and `exclude_topics` are given.

Return type:
:   [*Self*](https://docs.python.org/3/library/typing.html#typing.Self "(in Python v3.15)")

### add_parquet(path, timestamp_column, timestamp_type, *, tag_columns=None, units=None, channel_prefix=None, channel_name_overrides=None, tags=None)

Register a Parquet file or archive, inferring compression and archive format from its extension.

Supports .parquet, .parquet.gz, .parquet.tar, .parquet.tar.gz, and .parquet.zip.

Parameters:
:   - **path** ([*Path*](https://docs.python.org/3/library/pathlib.html#pathlib.Path "(in Python v3.15)") *|* [*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)"))

      Path to a Parquet file or archive.
    - **timestamp_column** ([*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)"))

      Column containing timestamps; not ingested as a data channel.
    - **timestamp_type** ([*Iso8601*](https://dev.nominal.io/python/ref/generated/nominal.ts.Iso8601.md#nominal.ts.Iso8601 "nominal.ts.Iso8601") *|* [*Epoch*](https://dev.nominal.io/python/ref/generated/nominal.ts.Epoch.md#nominal.ts.Epoch "nominal.ts.Epoch") *|* [*Relative*](https://dev.nominal.io/python/ref/generated/nominal.ts.Relative.md#nominal.ts.Relative "nominal.ts.Relative") *|* [*Custom*](https://dev.nominal.io/python/ref/generated/nominal.ts.Custom.md#nominal.ts.Custom "nominal.ts.Custom") *|* [*Literal*](https://docs.python.org/3/library/typing.html#typing.Literal "(in Python v3.15)")*[**'iso_8601'**,* *'epoch_picoseconds'**,* *'epoch_nanoseconds'**,* *'epoch_microseconds'**,* *'epoch_milliseconds'**,* *'epoch_seconds'**,* *'epoch_minutes'**,* *'epoch_hours'**,* *'epoch_days'**]*)

      Type of the timestamp data, e.g. ‘epoch_seconds’.
    - **tag_columns** ([*Mapping*](https://docs.python.org/3/library/typing.html#typing.Mapping "(in Python v3.15)")*[*[*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)")*,* [*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)")*]* *|* *None*)

      Mapping of tag keys to columns supplying their values.
    - **units** ([*Mapping*](https://docs.python.org/3/library/typing.html#typing.Mapping "(in Python v3.15)")*[*[*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)")*,* [*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)")*]* *|* *None*)

      Mapping of channel names to unit symbols.
    - **channel_prefix** ([*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)") *|* *None*)

      Prefix prepended to every ingested channel name.
    - **channel_name_overrides** ([*Mapping*](https://docs.python.org/3/library/typing.html#typing.Mapping "(in Python v3.15)")*[*[*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)")*,* [*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)")*]* *|* *None*)

      Mapping of original channel names to their ingested names.
    - **tags** ([*Mapping*](https://docs.python.org/3/library/typing.html#typing.Mapping "(in Python v3.15)")*[*[*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)")*,* [*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)")*]* *|* *None*)

      Key-value pairs applied as tags to all data from this file.

Returns:
:   This builder, for chaining.

Raises:
:   [**ValueError**](https://docs.python.org/3/builtins/exceptions.html#ValueError "(in Python v3.15)") – The path is not Parquet.

Return type:
:   [*Self*](https://docs.python.org/3/library/typing.html#typing.Self "(in Python v3.15)")

### add_tabular_data(path, timestamp_column, timestamp_type, *, tag_columns=None, units=None, channel_prefix=None, channel_name_overrides=None, tags=None)

Register a tabular file by forwarding to [`add_csv()`](https://dev.nominal.io/python/ref/generated/nominal.experimental.ingest.IngestBuilder.md#nominal.experimental.ingest.IngestBuilder.add_csv "nominal.experimental.ingest.IngestBuilder.add_csv") or [`add_parquet()`](https://dev.nominal.io/python/ref/generated/nominal.experimental.ingest.IngestBuilder.md#nominal.experimental.ingest.IngestBuilder.add_parquet "nominal.experimental.ingest.IngestBuilder.add_parquet").

Supported extensions: .csv / .csv.gz, .parquet / .parquet.gz, and the parquet-archive
formats (.parquet.tar / .parquet.tar.gz / .parquet.zip). The format is inferred from
the extension. Use [`add_csv()`](https://dev.nominal.io/python/ref/generated/nominal.experimental.ingest.IngestBuilder.md#nominal.experimental.ingest.IngestBuilder.add_csv "nominal.experimental.ingest.IngestBuilder.add_csv") for CSV-specific row options.

Parameters:
:   - **path** ([*Path*](https://docs.python.org/3/library/pathlib.html#pathlib.Path "(in Python v3.15)") *|* [*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)"))

      Path to the file on disk.
    - **timestamp_column** ([*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)"))

      Column containing the timestamp for each row. This column is not
      ingested as its own channel; it sets the timestamps for every other channel.
    - **timestamp_type** ([*Iso8601*](https://dev.nominal.io/python/ref/generated/nominal.ts.Iso8601.md#nominal.ts.Iso8601 "nominal.ts.Iso8601") *|* [*Epoch*](https://dev.nominal.io/python/ref/generated/nominal.ts.Epoch.md#nominal.ts.Epoch "nominal.ts.Epoch") *|* [*Relative*](https://dev.nominal.io/python/ref/generated/nominal.ts.Relative.md#nominal.ts.Relative "nominal.ts.Relative") *|* [*Custom*](https://dev.nominal.io/python/ref/generated/nominal.ts.Custom.md#nominal.ts.Custom "nominal.ts.Custom") *|* [*Literal*](https://docs.python.org/3/library/typing.html#typing.Literal "(in Python v3.15)")*[**'iso_8601'**,* *'epoch_picoseconds'**,* *'epoch_nanoseconds'**,* *'epoch_microseconds'**,* *'epoch_milliseconds'**,* *'epoch_seconds'**,* *'epoch_minutes'**,* *'epoch_hours'**,* *'epoch_days'**]*)

      Type of the timestamp data in `timestamp_column`, e.g. ‘epoch_seconds’.
    - **tag_columns** ([*Mapping*](https://docs.python.org/3/library/typing.html#typing.Mapping "(in Python v3.15)")*[*[*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)")*,* [*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)")*]* *|* *None*)

      Mapping of tag keys to the columns whose values supply each tag.
    - **units** ([*Mapping*](https://docs.python.org/3/library/typing.html#typing.Mapping "(in Python v3.15)")*[*[*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)")*,* [*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)")*]* *|* *None*)

      Mapping of channel name to unit symbol.
    - **channel_prefix** ([*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)") *|* *None*)

      Prefix prepended to every channel name ingested from this file.
    - **channel_name_overrides** ([*Mapping*](https://docs.python.org/3/library/typing.html#typing.Mapping "(in Python v3.15)")*[*[*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)")*,* [*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)")*]* *|* *None*)

      Mapping of original channel name to the name to ingest it under.
    - **tags** ([*Mapping*](https://docs.python.org/3/library/typing.html#typing.Mapping "(in Python v3.15)")*[*[*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)")*,* [*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)")*]* *|* *None*)

      Key-value pairs applied as tags to all data from this file.

Returns:
:   This builder, for chaining.

Raises:
:   [**ValueError**](https://docs.python.org/3/builtins/exceptions.html#ValueError "(in Python v3.15)") – The path is not a supported tabular format.

Return type:
:   [*Self*](https://docs.python.org/3/library/typing.html#typing.Self "(in Python v3.15)")

### add_tags(tags)

Add request-level tags applied to every item in the job.

Parameters:
:   **tags** ([*Mapping*](https://docs.python.org/3/library/typing.html#typing.Mapping "(in Python v3.15)")*[*[*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)")*,* [*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)")*]*)

    Key-value pairs to merge into the request-level tags.

Returns:
:   This builder, for chaining.

Return type:
:   [*Self*](https://docs.python.org/3/library/typing.html#typing.Self "(in Python v3.15)")

### add_video(path: Path | str, channel: str, *, start: datetime | int, tags: Mapping[str, str] | None = None) → Self

### add_video(path: Path | str, channel: str, *, frame_timestamps: Sequence[int], tags: Mapping[str, str] | None = None) → Self

Register a video file.

Pass exactly one of `start` / `frame_timestamps`; the overloads make anything else a
type error, and the runtime guard below rejects it for callers without a type checker.
With `start`, frames are timestamped from that instant at the video’s own frame rate.
With `frame_timestamps`, the per-frame timestamps are written to a manifest file that
is uploaded alongside the video.

Parameters:
:   - **path** ([*Path*](https://docs.python.org/3/library/pathlib.html#pathlib.Path "(in Python v3.15)") *|* [*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)"))

      Path to the video file on disk.
    - **channel** ([*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)"))

      Channel name to ingest the video under.
    - **start** ([*datetime*](https://docs.python.org/3/library/datetime.html#datetime.datetime "(in Python v3.15)") *|* [*int*](https://docs.python.org/3/builtins/functions.html#int "(in Python v3.15)") *|* *None*)

      Timestamp of the video’s first frame.
    - **frame_timestamps** ([*Sequence*](https://docs.python.org/3/library/typing.html#typing.Sequence "(in Python v3.15)")*[*[*int*](https://docs.python.org/3/builtins/functions.html#int "(in Python v3.15)")*]* *|* *None*)

      One epoch-nanosecond timestamp per video frame.
    - **tags** ([*Mapping*](https://docs.python.org/3/library/typing.html#typing.Mapping "(in Python v3.15)")*[*[*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)")*,* [*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)")*]* *|* *None*)

      Key-value pairs applied as tags to the video.

Returns:
:   This builder, for chaining.

Raises:
:   [**ValueError**](https://docs.python.org/3/builtins/exceptions.html#ValueError "(in Python v3.15)") – if `channel` is empty, the path is not a supported video container,
    `frame_timestamps` is empty, or both or neither of `start` /
    `frame_timestamps` are given.

Return type:
:   [*Self*](https://docs.python.org/3/library/typing.html#typing.Self "(in Python v3.15)")

### submit(*, allow_partial=False, runs_to_expand=None)

Upload all registered files and trigger one ingest job.

Uploads run in parallel, with transient failures (network weather, throttling) retried
by the uploader’s own per-file budget. By default the call is atomic and fail-fast: the
first file that fails permanently cancels the batch and raises, and no ingest is
triggered. With `allow_partial=True`, every file runs to settlement instead — items
whose files failed are logged and pruned, and one ingest job is triggered for the items
that uploaded cleanly.

Single-use: one [`submit()`](https://dev.nominal.io/python/ref/generated/nominal.experimental.ingest.IngestBuilder.md#nominal.experimental.ingest.IngestBuilder.submit "nominal.experimental.ingest.IngestBuilder.submit") consumes the builder, whether it succeeds or fails. A
failed trigger request can have been committed server-side (a timeout, say), so there
is no retry that cannot double-ingest — build a new builder instead.

Parameters:
:   - **allow_partial** ([*bool*](https://docs.python.org/3/builtins/functions.html#bool "(in Python v3.15)"))

      If true, items whose files failed to upload are dropped from the
      job (each failure logged as an error) instead of failing the whole batch.
      Deliberately reported through logs, not the return value — the job always
      covers exactly the items that uploaded.
    - **runs_to_expand** ([*Sequence*](https://docs.python.org/3/library/typing.html#typing.Sequence "(in Python v3.15)")*[*[*Run*](https://dev.nominal.io/python/ref/generated/nominal.core.Run.md#nominal.core.Run "nominal.core.run.Run") *|* [*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)")*]* *|* *None*)

      If provided, runs (or their rids) to expand upon successful ingest.
      This will only expand the bounds of the runs, not contract.

Returns:
:   The created ingest job. Track it by polling `job.refresh().status`, or block on its
    produced files with `list(job.as_files_ingested())`.

Raises:
:   - [**NominalIngestError**](https://dev.nominal.io/python/ref/generated/nominal.exceptions.NominalIngestError.md#nominal.exceptions.NominalIngestError "nominal.exceptions.NominalIngestError") – this builder was already submitted.
    - [**NominalIngestUploadFailed**](https://dev.nominal.io/python/ref/generated/nominal.exceptions.NominalIngestUploadFailed.md#nominal.exceptions.NominalIngestUploadFailed "nominal.exceptions.NominalIngestUploadFailed") – a file failed to upload — any file when
      `allow_partial` is false, or every file when it is true. Members carry
      per-file detail.
    - [**ValueError**](https://docs.python.org/3/builtins/exceptions.html#ValueError "(in Python v3.15)") – if no files have been added.

Return type:
:   [*IngestionJob*](https://dev.nominal.io/python/ref/generated/nominal.core.IngestionJob.md#nominal.core.IngestionJob "nominal.core.ingestion_job.IngestionJob")
