Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1 @@
"""The ``timenet-build`` producer CLI."""

from timenet_connectors.builder.cli import app, main


__all__ = ["app", "main"]
"""Build datasets with connectors and the ``timenet-build`` CLI."""
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"""The build backend the SDK reaches through the ``timenet.builders`` entry point."""
"""Read connector cards and build dataset releases."""

from collections.abc import Mapping
from dataclasses import dataclass
Expand All @@ -10,18 +10,17 @@
from timenet.errors import TimeNetDatasetNotFoundError, TimeNetVersionUnavailableError
from timenet.manifest import PayloadSource
from timenet.progress import BytesMoved, ProgressCallback, ShardWritten
from timenet.registry import BaseRegistry, LocalRegistry
from timenet.registry import LocalRegistry
from timenet.types import DatasetMetadata
from timenet.types.references import DatasetRef
from timenet.writer.progress import ProgressStage, WriteProgressEvent
from timenet_connectors.builder.cli import build_one
from timenet_connectors.builder.env import run_isolated_build
from timenet_connectors.discovery import connector_dir, has_connector, known_ids, resolve
from timenet_connectors.discovery import connector_dir, known_ids, resolve
from timenet_connectors.download import DownloadProgress, progress_sink


class ConnectorBuilder:
"""Build a dataset with its connector, in an environment built from the connector's requirements."""
"""Build dataset releases with their connectors."""

def dataset_ids(self) -> list[str]: # ruff: ignore[no-self-use] (BuilderBackend protocol method)
"""List this package's dataset IDs without importing connectors.
Expand All @@ -31,87 +30,27 @@ def dataset_ids(self) -> list[str]: # ruff: ignore[no-self-use] (BuilderBackend
"""
return known_ids()

def knows(self, dataset_id: str) -> bool: # ruff: ignore[no-self-use] (BuilderBackend protocol method)
"""Report whether a connector package exists for the id, without importing it.

Args:
dataset_id: The dataset id.

Returns:
Whether a connector exists.
"""
return has_connector(dataset_id)

def declared_version(self, dataset_id: str) -> str | None:
"""Read the version the connector's card declares, without importing or building it.

Args:
dataset_id: The dataset id.

Returns:
The declared version string, or ``None`` if no connector exists for the dataset.

Raises:
TimeNetInvalidCardError: If the card of the connector cannot be read or is not a mapping.
""" # ruff: ignore[docstring-extraneous-exception] - raised by card()
card = self.card(dataset_id)
return None if card is None else str(card.dataset_version)

def card(self, dataset_id: str) -> DatasetMetadata | None: # ruff: ignore[no-self-use] (protocol)
"""Read the connector's ``dataset.yaml`` card, without importing or building the connector.
"""Read a connector's dataset card without importing the connector.

Args:
dataset_id: The dataset id.
dataset_id: The exact dataset ID declared in the card.

Returns:
The validated card, or ``None`` if no connector exists for the dataset.
The validated card, or ``None`` if no connector card declares this ID.

Raises:
TimeNetInvalidCardError: If the card cannot be read or is not a mapping.
TimeNetInvalidCardError: If reading the card fails or the card is not a mapping.
""" # ruff: ignore[docstring-extraneous-exception] - raised by DatasetMetadata.from_yaml
try:
directory = connector_dir(dataset_id)
except LookupError:
return None
return DatasetMetadata.from_yaml(directory / "dataset.yaml")

def build( # ruff: ignore[too-many-arguments, no-self-use] (protocol)
self,
dataset_id: str,
root: Path,
*,
force: bool = False,
build_parents: bool = False,
fetch_from: str | BaseRegistry | None = None,
pinned_by: Mapping[DatasetRef, PayloadSource] | None = None,
) -> Path:
"""Build a dataset in an isolated environment.

Set ``TIMENET_ISOLATION=off`` to run in the current interpreter.

Args:
dataset_id: The dataset id.
root: The output registry directory.
force: Rebuild an existing version.
build_parents: Build missing parent releases from their installed connectors.
fetch_from: The registry, or its URI, to copy missing parent releases from.
pinned_by: Releases that read this dataset's files, with file pins the build must match.

Returns:
The committed version directory.
"""
return Path(
build_one(
dataset_id,
root,
fetch_from=fetch_from,
build_parents=build_parents,
force=force,
pinned_by=pinned_by,
)
)
card = DatasetMetadata.from_yaml(directory / "dataset.yaml")
# The module path of a connector also accepts other spellings, such as "_" for "-".
return card if card.dataset_id == dataset_id else None

def build_prepared(
def build(
self,
release: DatasetRef,
store: LocalRegistry,
Expand Down
Loading
Loading