Architecture¶
How TimeNet's packages, registries, and curation fit together. This page is the map; follow the links for per-component detail.
The big picture¶
TimeNet splits into three parts. A connector curates a raw source into a manifest plus parquet artifacts; the client/SDK reads the manifest from a registry and loads the data. The client never runs connector code.
| What it is | Ships | Used by | |
|---|---|---|---|
timenet |
Python package | TimeF format, reader/writer, registry client, engine, BaseConnector, SDK, CLI |
everyone (install coming soon) |
| registry | a served location | compiled manifests + parquet | the SDK reads it; curation publishes to it |
timenet-connectors |
a repo | connector recipes + cards + the timenet-curate CLI |
connector authors (clone it) |
There can be several registries: one public, private internal ones, or a local directory.
The two flows¶
PRODUCE dataset.yaml + connector ─► engine (download -> convert -> derive_schema -> store) ─► publish ─┐
▼
registry
CONSUME SDK ─► get_manifest ─► fetch parquet ─► TimeFReader ─► Arrow ◄──────────────────────────────┘
The compiled manifest.json (the card's human-authored metadata plus the schema derived from the data)
is the single source of truth the SDK reads. Because the SDK never imports connector code, everything a
consumer needs to interpret the parquet lives in the manifest.
Curation roles: connector, engine, curator¶
Three producer-side pieces, each with one job:
| Role | What it is | Job |
|---|---|---|
| Connector | one BaseConnector subclass per dataset (connectors) |
the dataset-specific recipe: download() fetches raw files, convert() builds a TimeFDataset. Knows nothing about the engine or registry. |
| Engine | run_pipeline (curate & publish) |
drives any connector through the fixed pipeline and owns caching, idempotency, and force / clean_cache. Knows no dataset specifics. |
| Curator | the timenet-curate CLI (curation) |
the entry point: resolves the id to its connector and runs the engine into a registry. |
timenet-curate build org/name curator
└─ discovery.resolve("org/name") -> Connector class (datasets/<org>/<name>/ exposes CONNECTOR)
└─ run_pipeline(connector, <registry>) engine
metadata -> download -> convert -> derive_schema -> store -> <registry>/org/name/<version>/
metadata() reads the dataset.yaml card and store() streams through
TimeFWriter. The output directory is itself a valid local registry, so the consume
flow reads it straight back.
Where each component lives¶
| Component | Package | Side |
|---|---|---|
TimeF format, types, TimeFDataset, manifest |
timenet |
shared |
CLI, SDK, registry client, TimeFReader |
timenet |
consumer |
Engine, TimeFWriter, BaseConnector |
timenet |
producer |
Connector recipes + cards, timenet-curate |
timenet-connectors |
producer |
Design principles¶
- The manifest is self-describing. The SDK reads schema, counts, and file pointers from
manifest.json. It never runs connector code or globs the directory. - Types are plain frozen dataclasses. Specs, data sources, and annotations are frozen
descriptors, so they pickle and round-trip through the reader with no runtime class
synthesis. That keeps multiprocessing
DataLoaderworkers safe. - Values are Arrow in, Arrow out. A
TimeSeriesexposesto_arrow()andto_numpy()over a private lazy loader. The writer storesfloat32values as Parquet withBYTE_STREAM_SPLITand zstd. - Units go through pint. One shared registry owns every definition and conversion.
- Commits are atomic. The writer stages a version into a temp directory and publishes it with a
single atomic rename. Once
manifest.jsonis present, the version is committed. - Versions are immutable; edits are copy-on-write. Removing a row writes a new version through the
same atomic path (
edit_version); stable never-reused ids keep references valid, and content-defined chunking keeps the rewrite cheap on a deduplicating backend.
Lifecycle of a dataset¶
- Author a connector at
datasets/<org>/<name>/(its__init__.pyexposesCONNECTOR) with itsdataset.yamlcard beside it, intimenet-connectors. - Curate:
timenet-curate build <org>/<name>runs the engine, compiles the manifest, and writes parquet. - Verify locally by pointing the SDK at the output directory (itself a valid local registry).
- Publish the manifest + parquet to a registry.
- Consume:
timenet download <id>reads the manifest and fetches the parquet.