Skip to content

feat(client)!: take an ordered list of sources - #661

Merged
karhu merged 5 commits into
tnet-157/12-client-readsfrom
tnet-157/13-sources-list
Nov 10, 2026
Merged

karhu merged 5 commits into
tnet-157/12-client-readsfrom
tnet-157/13-sources-list

Conversation

@karhu

@karhu karhu commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor

The Stack

This stack covers refactoring the internal logic of how releases are resolved during read, download & build, in particular also in the context of parent releases / parent datasets. On top of that it refactors the public TimeNet APIs and CLI interfaces around these actions, to streamline the behavior across them.

This PR

The client takes one ordered list of sources, TimeNet(sources=[...]), instead of a registry and the fetch_from= and auto_build= keywords.

Details

#660 reads through the read coordinator with a thin mapping of the old keywords onto a list. This PR makes the list the public interface and removes the mapping.

  • TimeNet(sources=[...]) takes registries, InstalledConnectors(), and strings or paths that open_registry() opens.
  • LocalRegistry takes read_only=True. Builds land in the first LocalRegistry of the list without it, the store. InstalledConnectors() needs such a registry.
  • open_registry() is the one parser of a registry value. A blank value, an unknown scheme, a file:// URI with a host and a timenet:// URI with a path raise TimeNetRegistryError. The message names the value by its label, for example sources[1]. local_registry_path() uses the same messages. open_writable_registry() goes away, because open_registry() returns a WritableRegistry.
  • timenet.client.default_sources() makes the list of TimeNet(): the store at <TIMENET_HOME>/registry, then timenet://, then InstalledConnectors(). A registry URL in TIMENET_REGISTRY takes the place of timenet://. A local path in TIMENET_REGISTRY is the store, and the list then has no other registry.
  • open(), load() and open_torch() pass the list and the store to read_release(). The hints depend on the list. For a release that no source provides, the hint asks for a registry that holds it. Only a list without InstalledConnectors() gets a hint that names it.
  • get(), list(), search() and download() still ask one registry: the first registry of the list that is not the store, else the store.
  • Each command of the consumer CLI builds its client from default_sources(), and --registry names the registry that the command reads.
  • timenet info and timenet download take org/name@version and no --version.
  • timenet_connectors.load() reads with TimeNet().load().
  • The examples show the list of sources.
  • Size: about 1060 changed lines.

Design decisions

  • The constructor checks the list. These raise TimeFValidationError: a bare string or path, an empty list, an item of another type, and InstalledConnectors() without a writable local registry. Each message shows the call that works, for example sources=['<path>'].
  • A string is a Sequence, so the client checks for a string or path before it treats the value as a list. Without that check, TimeNet(".timenet-registry") takes one source per character.
  • A list without InstalledConnectors() never builds, also for a newer version that a connector declares.
  • str() of a store stays "local registry ", so error messages do not change.

Breaking changes

  • TimeNet takes sources= instead of registry= and storage_path=.
  • open(), load() and open_torch() no longer take fetch_from= and auto_build=.
  • The default client also reads the local store and builds with the installed connectors.
  • timenet download no longer takes --storage.
  • open_registry() raises TimeNetRegistryError, not ValueError, and rejects a blank value.
  • open_writable_registry() is gone. Use open_registry().
  • timenet info and timenet download no longer take --version. Use org/name@version.

Stack

Changes later in the stack:

  • docs: update the docs for the build coordinator #683 holds the doc changes of this PR.
  • _catalog() for get(), list() and search(), the interim download(), the body of default_sources() and the --registry mapping are thin glue. The next PR moves download() into the store. The PRs on defaults and on inspection replace the rest.

Merge message

feat(client)!: take an ordered list of sources

TimeNet(sources=[...]) takes one ordered list of registries,
InstalledConnectors() and registry paths or URLs, in place of a
registry and the fetch_from and auto_build keywords.

- Builds land in the first LocalRegistry of the list without
  read_only=True. InstalledConnectors() needs such a registry.
- A list without InstalledConnectors() never builds.
- default_sources() makes the list of TimeNet(): the local registry,
  then timenet:// or the registry URL in TIMENET_REGISTRY, then
  InstalledConnectors().
- open_registry() is the one parser of a registry value.

BREAKING CHANGE: TimeNet takes sources= instead of registry= and
storage_path=. open(), load() and open_torch() lose fetch_from= and
auto_build=. The default client also reads the local registry and
builds with the installed connectors.

BREAKING CHANGE: open_registry() raises TimeNetRegistryError instead
of ValueError, and open_writable_registry() is gone.

BREAKING CHANGE: timenet info and timenet download take
org/name@version and lose --version. timenet download loses --storage.

@karhu
karhu added this pull request to stack #650 November 4, 2026 13:39
@karhu
karhu force-pushed the tnet-157/13-sources-list branch from 55121c9 to 3e39b6d Compare November 4, 2026 14:58
@karhu
karhu force-pushed the tnet-157/13-sources-list branch from 3e39b6d to 3e51550 Compare November 4, 2026 15:27
@karhu
karhu force-pushed the tnet-157/13-sources-list branch from 3e51550 to 580bfa5 Compare November 4, 2026 15:31
@karhu
karhu force-pushed the tnet-157/13-sources-list branch from 580bfa5 to 8ffd982 Compare November 4, 2026 20:02
@karhu
karhu force-pushed the tnet-157/13-sources-list branch from 4c08556 to 6795b03 Compare November 7, 2026 13:26

@TimoStoff TimoStoff left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

Comment thread packages/timenet/src/timenet/client.py Resolved
Comment thread packages/timenet/src/timenet/client.py Resolved
Comment thread packages/timenet/src/timenet/client.py Resolved
Comment thread packages/timenet/src/timenet/client.py Resolved
Comment thread packages/timenet/src/timenet/client.py Resolved
Comment thread packages/timenet/src/timenet/client.py Resolved
Comment thread packages/timenet/src/timenet/client.py Resolved
Comment thread packages/timenet/tests/test_client.py Resolved
@karhu
karhu force-pushed the tnet-157/13-sources-list branch from 6795b03 to 83a1832 Compare November 7, 2026 15:20
@karhu
karhu force-pushed the tnet-157/13-sources-list branch from 83a1832 to a8841fd Compare November 7, 2026 16:27
@karhu
karhu force-pushed the tnet-157/13-sources-list branch from a8841fd to 40c59e1 Compare November 7, 2026 17:40
@karhu
karhu force-pushed the tnet-157/13-sources-list branch 2 times, most recently from 369567b to b75d11d Compare November 9, 2026 13:56
@karhu
karhu force-pushed the tnet-157/13-sources-list branch from b75d11d to c49ced9 Compare November 10, 2026 14:39

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code review completed

Nothing new to post: everything this review found is already covered by existing comments on this pull request or didn't merit a separate one.

@karhu
karhu force-pushed the tnet-157/13-sources-list branch from c49ced9 to bbe936d Compare November 10, 2026 15:50
@karhu
karhu removed this pull request from stack #699 November 10, 2026 15:58
Comment thread packages/timenet/src/timenet/client.py Resolved
Comment thread packages/timenet/src/timenet/client.py Resolved
@karhu
karhu force-pushed the tnet-157/13-sources-list branch from bbe936d to e60394d Compare November 10, 2026 16:24
@karhu
karhu added this pull request to stack #772 November 10, 2026 16:24

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Code review skipped: your organization has reached its API usage limit, so Code Review can't run right now.

An organization admin can review the limit in your organization's usage and billing settings.

Once the limit resets or is raised, someone with write access to this repository can comment @claude review on this pull request to trigger a review.

A client now takes one ordered list of sources as
TimeNet(sources=[...]). An item is a registry, InstalledConnectors(),
or a string or Path that open_registry() opens. A bare string or Path,
an empty list and an item of another type raise TimeFValidationError.
A string that names no registry raises TimeNetRegistryError, which
names the item, such as sources[0].

Every registry takes read_only=False, and the property read_only reads
the flag. A read-only registry refuses each write with
TimeNetRegistryError: put_dataset(), put_release(), a copy into it, and
a run of a plan that copies or builds into it. Builds land in the first
LocalRegistry of the list that is not read-only. A string or Path in
the list opens a writable LocalRegistry. The client only reads a later
writable local registry. A list with InstalledConnectors() needs a
writable local registry, else TimeNet() raises TimeFValidationError.

default_sources() makes the list of TimeNet(): the local registry at
<TIMENET_HOME>/registry, then timenet://, then InstalledConnectors(). A
registry URL in TIMENET_REGISTRY takes the place of timenet://. A local
path in TIMENET_REGISTRY is the local registry, and the list then has no
other registry. The remote_registry argument puts a registry after the
local registry.

open(), load() and open_torch() pass the list and that local registry
to read_release(). The fetch_from= and auto_build= keywords go away, and so
do _read_sources() and _missing_hint(). If no source provides a release,
the hint asks for a registry that holds it. If the list has no
InstalledConnectors(), the hint also names it. An access error names
InstalledConnectors() and timenet-build build as the ways to build the
release locally.

get(), list(), search() and download() still ask one registry.
_catalog() picks the first registry of the list that is not that local
registry, else that local registry. download() still copies into
TIMENET_STORAGE. Each command of the consumer CLI builds its client from
default_sources(), and --registry becomes the remote_registry argument.
timenet_connectors.load() reads with TimeNet().load(), because its build
already put each parent and payload source into the local registry of
the default list.

open_registry() is now the one parser of a registry value. It raises
TimeNetRegistryError, not ValueError, and it rejects a blank value
instead of opening the current directory. Its label argument names the
value in the error. open_writable_registry() goes away, because every
registry is writable. timenet info and timenet download drop
--version, because org/name@version names a version.

The examples show the list of sources.

BREAKING CHANGE: TimeNet takes sources= instead of registry= and
storage_path=. open(), load() and open_torch() no longer take
fetch_from= and auto_build=. The default client also reads the local
registry and builds with installed connectors. timenet download no
longer takes --storage. open_registry() raises TimeNetRegistryError, not
ValueError, and rejects a blank value. open_writable_registry() is gone.
timenet info and timenet download no longer take --version: use
org/name@version.

Part of TNET-157.
The glue comments of this change now start with TODO(adrian), so a search finds each one that
is left.

Part of TNET-157.
Say only what a caller of TimeNet(sources=...) and its store needs to know.

Part of TNET-157.
Shorter docstrings for the code that this change adds or changes.

Part of TNET-157.
Drop tests that cannot fail or repeat other tests, and sharpen the rest.

Part of TNET-157.
@karhu
karhu force-pushed the tnet-157/13-sources-list branch from e60394d to 5e0655a Compare November 10, 2026 17:41
@karhu
karhu merged commit 0949ba2 into main Nov 10, 2026
4 of 8 checks passed
@karhu
karhu deleted the tnet-157/13-sources-list branch November 10, 2026 18:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants