embedl_hub.tracking package#

Public API for the Embedl Hub tracking package.

Top-level re-exports#

  • ApiError — Raised when the Hub answers a request with an error.

  • Artifact — A file logged to a run.

  • ArtifactUploadError — Raised when the file upload for an artifact fails.

  • Client — Tracking client for projects and runs.

  • Context — The Hub, project, run and batch resolved from arguments, the environment, the workspace and the global config.

  • DomainError — Base class of the errors the Hub reports about what a request asked for.

  • ExternalLink — A link logged to a run.

  • FileTooLargeError — Raised when the file for an artifact is too large to upload.

  • InvalidRunLineageError — Raised when the Hub rejects a parent run link.

  • NetworkRequestError — Raised when a request never reaches the Hub or gets no answer.

  • Parameter — A parameter logged to a run.

  • Project — A project on the Hub.

  • Run — A run on the Hub.

  • RunDashboard — A dashboard logged to a run.

  • RunListPage — One page of a run listing.

  • RunStatus — The states a run moves through, for filtering listings.

  • RunType — Built-in run-type categories.

  • Setting — One value of a Context and where it came from.

  • StorageQuotaExceededError — Raised when the Hub’s storage quota is exceeded.

  • Tag — A tag logged to a run.

  • Tracked — A value returned by a hub_run() function, together with the run that produced it.

  • TrackingConfigWarning — Warning raised for a configuration that works but is probably a mistake, such as an environment key sent to a Hub configured elsewhere.

  • TrackingContextError — Raised when the context cannot be resolved, such as no project anywhere.

  • TrackingFailureWarning — Warning raised in place of an error when a tracking call fails inside a safe scope.

  • TrackingProjectChangedWarning — Warning raised when adopting a run also moved the client to that run’s project.

  • TrackingUsageError — Raised when a tracking call is itself malformed; never downgraded by safe mode.

  • hub_run() — Decorator that runs each call of a function as a run, linked to the run of its Tracked input.

  • resolve_context() — Read the Context without binding anything.

exception embedl_hub.tracking.ApiError(status_code: int, message: str, errors: list[ApiErrorDetail] | None = None, response: Response | None = None)[source]#

Bases: Exception

Raised for API errors with JSON body.

class embedl_hub.tracking.Artifact(*, id: str, runId: str, fileName: str, fileSize: str, status: ArtifactStatus, createdAt: datetime, updatedAt: datetime)[source]#

Bases: Model

created_at: datetime#
file_name: str#
file_size: str#
id: str#
model_config = {'alias_generator': <function to_camel>, 'extra': 'ignore', 'validate_by_name': True}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

run_id: str#
status: ArtifactStatus#
updated_at: datetime#
exception embedl_hub.tracking.ArtifactUploadError(file_path: Path, message: str | None = None)[source]#

Bases: DomainError

Raised when the file upload for an artifact fails.

class embedl_hub.tracking.Client(api_config: ApiConfig | None = None)[source]#

Bases: object

Tracks projects and runs for the Embedl Hub web app.

property active_run: Run#
property api_config: ApiConfig#

Get or create the API config from the resolved settings.

Returns:

The credentials and Hub address this client uses.

Raises:
  • RuntimeError – If no API key is configured.

  • TrackingContextError – If EMBEDL_HUB_API_KEY would go to a Hub set by a workspace that has another key stored, or none.

property api_key: str#

The API key this client authenticates with.

For handing to something else that has to authenticate. Do not print or log it: a key that reaches a terminal, a notebook output or a CI log has to be treated as compromised. api_key_source answers where the key comes from without exposing it.

Returns:

The key in use.

Raises:
  • RuntimeError – If no API key is configured.

  • TrackingContextError – If EMBEDL_HUB_API_KEY would go to a Hub set by a workspace that has another key stored, or none.

property api_key_source: Literal['env', 'workspace', 'config', 'default'] | None#

Which layer supplied the API key this client uses.

Names where the key was read from — the environment or the config file — rather than the key itself, so it is safe to print. Use api_key for the value.

Returns:

"env" or "config" for a key this client resolved, or None when no layer supplied one: either nothing is configured, the client would refuse the environment’s key for this Hub, or the client was handed an explicit configuration, which comes from the caller rather than from anywhere on this machine.

property base_url: str#

The address of the Hub this client sends requests to.

Needs no API key: which Hub is configured is not an authentication question, so this answers before auth has been run.

Returns:

The address, always ending in /.

create_run(type: RunType | str, name: str | None = None, parent_run_id: str | None = None, custom_type: str | None = None, description: str | None = None, *, pending: bool = False, safe: bool = False) → Run | None[source]#

Create a new run for the current project.

Parameters:
  • type – Built-in run type or a custom type label.

  • name – Optional run display name.

  • parent_run_id – Optional parent run ID for lineage.

  • custom_type – Label used when type is RunType.CUSTOM.

  • description – Optional run description. The Hub trims it, stores blank input as no description, and accepts at most 1,000 characters.

  • pending – When True, the run is created pending rather than running: it exists and can be logged to, and the Hub lists it as RunStatus.PENDING until something starts it. For work launched elsewhere, so the run can be annotated before the job that will run in it exists. Its started_at is provisional until then.

  • safe – When True, a failure to reach the Hub emits a TrackingFailureWarning and returns None instead of raising. An invalid run type is a caller mistake, not a Hub failure, so it still raises.

Returns:

The created run, or None if it could not be created and safe is True.

Raises:
  • ValueError – If a custom run type has no label, whatever safe is set to.

  • ApiError – If the Hub rejects the request and safe is False.

get_run_project(run_id: str) → Project[source]#

Look up the project a run belongs to.

Needs no project selected first, so a parent run ID is enough to open the next run in the same project. Pass the project itself to set_project() rather than its name: names are unique per owner only, so a project shared with you may share its name with one of yours:

project = client.get_run_project(parent_run_id)
client.set_project(project)
with client.start_run("train", parent_run_id=parent_run_id):
    ...

Like list_runs(), a failure raises rather than warns.

Parameters:

run_id – The run’s ID.

Returns:

The project the run belongs to.

Raises:
  • ValueError – If run_id is blank.

  • ApiError – If the hub does not know the run, or it is in a project this API key cannot read; either is a 404.

get_run_url(run_id: str) → str[source]#

The web address of a run, on this client’s Hub.

Selects nothing, so it works for any run whatever the client is logging to:

print(client.get_run_url(client.active_run.id))

Like get_run_project(), a failure raises rather than warns.

Parameters:

run_id – The run’s ID.

Returns:

The address of the run’s page.

Raises:
  • ValueError – If run_id is blank.

  • ApiError – If the hub does not know the run, or it is in a project this API key cannot read; either is a 404.

list_runs(*, params: Mapping[str, str] | None = None, statuses: RunStatus | Sequence[RunStatus] | None = None, types: RunType | str | Sequence[RunType | str] | None = None, limit: int | None = None, offset: int | None = None) → RunListPage[source]#

List the current project’s runs, newest first.

Find the run a job logged its own ID on, to link the next job to it:

page = client.list_runs(params={"vertex_ai_job_id": job_id})
parent = page.items[0] if page.items else None

Like get_run_project(), a failure raises rather than warns.

Parameters:
  • params – Parameters the runs must have logged, as name to value. Names and values are normalized the way log_param() stores them, so what was logged is found again.

  • statuses – Only runs with this status, or one of these.

  • types – Only runs of this type, or one of these. A string is read as start_run() reads it: a built-in type name selects that type, any other label selects the custom runs filed under it. Built-in types and labels cannot be combined in one call.

  • limit – Page size; the hub’s default and cap apply.

  • offset – Runs to skip, for paging.

Returns:

One page of run summaries with pagination info.

Raises:
  • ValueError – If a run type label is blank or contains a comma, built-in types are mixed with labels, a parameter name is blank, a parameter name or value contains a NUL character, or two parameter names are the same once trimmed.

  • RuntimeError – If no project is set.

  • ApiError – If the hub rejects the request.

log_artifact(file_path: Path | str, *, file_name: str | None = None, run_id: str | None = None) → Artifact | None[source]#

Log an artifact file for a run and upload it to artifact storage.

If no file_name is given, the name from the file path is used. If no run_id is given, the current active run is used.

Parameters:
  • file_path – Local file path.

  • file_name – Optional file name override.

  • run_id – Optional run ID (defaults to the active run).

Returns:

The Artifact the Hub recorded, or None if it failed inside a safe_log() scope.

Raises:
log_batch(*, metrics: list[tuple[str, float, int | None]] | None = None, params: list[tuple[str, str]] | None = None, external_links: list[tuple[str, str]] | None = None) → None[source]#

Log multiple metrics and params in a single API call.

This is significantly more efficient than calling log_metric() and log_param() in a loop, as it sends all data in one PATCH request instead of one POST per item.

Parameters:
  • metrics – List of (name, value, step) tuples. step may be None for metrics without a step.

  • params – List of (name, value) tuples.

  • external_links – List of (label, url) tuples.

log_dashboard(dashboard: Dashboard | Path | str, *, name: str | None = None, description: str | None = None, default: bool = False, opens_run: bool = False) → RunDashboard | None[source]#

Attach a dashboard to the current run.

Accepts a Dashboard or the path of a file written by save().

Parameters:
  • dashboard – The dashboard, or the path of its JSON file.

  • name – The name to store it under on the run. Overrides the name the dashboard carries; required for a file that holds a bare config.

  • description – Overrides the dashboard’s description.

  • default – Makes it the run’s default dashboard, the one the run’s Dashboard tab opens on. A run has one.

  • opens_run – Opens the run itself on it rather than on the run’s details. Implies default, so there is no need to pass both.

Returns:

The RunDashboard the Hub stored, or None if it failed inside a safe_log() scope.

Raises:
  • DashboardSchemaError – If the file is not a dashboard this SDK reads, the dashboard ends up without a name or with one the Hub would not store, or its sections and panels do not form a valid layout. A broken input rather than a Hub failure, so it is raised even inside a safe_log() scope.

  • FileNotFoundError – If there is no file at the given path. Degrades to a warning inside a safe_log() scope.

Log an external link for the current run.

Parameters:
  • label – The link label.

  • url – The link target.

Returns:

The ExternalLink as the Hub stored it, or None if it failed inside a safe_log() scope.

log_metric(name: str, value: float, step: int | None = None) → Metric | None[source]#

Log a metric for the current run.

Parameters:
  • name – The metric name.

  • value – The metric value.

  • step – Optional step number.

Returns:

The Metric as the Hub stored it, or None if it failed inside a safe_log() scope.

log_param(name: str, value: str) → Parameter | None[source]#

Log a parameter for the current run.

Parameters:
  • name – The parameter name.

  • value – The parameter value.

Returns:

The Parameter as the Hub stored it, or None if it failed inside a safe_log() scope.

log_tag(name: str, value: str) → Tag | None[source]#

Log a tag for the current run.

Parameters:
  • name – The tag name.

  • value – The tag value.

Returns:

The Tag that was recorded, or None if it failed inside a safe_log() scope.

property project: Project#
safe_log() → Iterator[Client][source]#

Downgrade logging failures to warnings inside this scope.

Within the scope, log_param(), log_metric(), log_link(), log_batch(), log_tag(), log_artifact() and log_dashboard() emit a TrackingFailureWarning and return None instead of raising, so a Hub outage cannot abort the surrounding script:

with client.safe_log():
    client.log_metric("accuracy", 0.92)

Scopes nest; leaving one restores the previous state. Only the client’s own logging calls are affected — exceptions raised by your code inside the scope propagate untouched, and calls made outside it raise as usual.

This does not cover starting or ending a run. Pass safe=True to start_run() for that.

Returns:

A context manager yielding this client.

property safe_logging: bool#

Whether logging calls currently warn instead of raising.

True while execution is inside a safe_log() scope. Read-only — safe mode is entered by scope, never by assignment, so a client handed to library code cannot be permanently disarmed.

set_project(name: str | Project, *, safe: bool = False) → None[source]#

Choose the project to record into.

By name, this binds the name without a Hub call: the first run started in the project creates it if it does not exist yet. This is the explicit counterpart of use_context_project(), which takes the name from the environment, the workspace or the global config instead:

client = Client()
client.set_project("my-project")
with client.start_run("training"):
    client.log_metric("loss", 0.1)

A Project already looked up, such as the one get_run_project() returns, is selected as it is. Names are unique per owner only, so a project shared with you may share its name with one of yours; the project itself tells them apart.

Changed in version 0.0.9: No longer looks the project up or creates it here, and returns None. Accepts a Project.

Parameters:
  • name – The project name, or the project itself.

  • safe – Accepted for compatibility with 0.0.8. Binding a name cannot fail, so there is nothing to tolerate.

Raises:

TrackingUsageError – If name is blank, or if a run is active. Moving the project out from under a run would leave the client addressing that run inside a project it is not in, which every log call composes independently and so cannot detect: the requests go to a run that is not there.

set_run(run_id: str, *, switch_project: bool = False, safe: bool | None = None) → Run | None[source]#

Log to a run that already exists, started somewhere else.

For picking up work another process began. The run is looked up by its ID alone, and its project becomes the selection: a run belongs to one project, and logging has to go there:

client = Client()
client.set_run(run_id)
client.log_metric("loss", 0.1)

Unlike set_project(), this asks the Hub: the run has to exist already, and its project is only known from it. Use use_context_run() to take the run from the environment or the workspace instead, as under embedl-hub exec.

Setting a run does not take responsibility for it. Nothing here completes it, and leaving the process does not either: whoever started the run still decides its outcome.

Parameters:
  • run_id – The run to log to.

  • switch_project – What to do when another project is already selected. False raises, since logging would leave the project the caller chose; True moves the client to the run’s project. With no project selected, the run’s is selected either way.

  • safe – When True, a failure to reach the Hub emits a TrackingFailureWarning and returns None instead of raising. Either way the failure leaves nothing selected, not even a project selected before. As elsewhere, this covers an unreliable Hub and not a malformed call. None, the default, takes the answer from the environment: embedl-hub exec --safe sets EMBEDL_HUB_SAFE for the command it wraps.

Returns:

The run, or None if it could not be looked up and safe is True.

Raises:
  • TrackingUsageError – If run_id is blank, if a run is already active, if the run has already finished, or if it is in another project than the one selected and switch_project is False. Raised whatever safe is set to.

  • ApiError – If the Hub rejects the request and safe is False.

start_run(type: RunType | str, name: str | None = None, parent_run_id: str | None = None, custom_type: str | None = None, description: str | None = None, *, safe: bool = False) → Iterator[Run | None][source]#

Start a run and finish it when the context exits.

Parameters:
  • type – Built-in run type or a custom type label.

  • name – Optional run display name.

  • parent_run_id – Optional parent run ID for lineage.

  • custom_type – Label used when type is RunType.CUSTOM.

  • description – Optional run description. The Hub trims it, stores blank input as no description, and accepts at most 1,000 characters.

  • safe – When True, a failure to create or complete the run emits a TrackingFailureWarning instead of raising. If the run cannot be created the body still runs as though tracking had never been added, with nothing active, and the context manager yields None. Guard the body with safe_log() as well if it logs — safe covers only the run lifecycle. Exceptions from the body are never suppressed.

Returns:

An iterator yielding the created run, or None when safe is True and the run could not be created.

Raises:
  • RuntimeError – If a run is already active, whatever safe is set to. Runs do not nest; use parent_run_id to record that one run followed another.

  • ValueError – If a custom run type has no label, whatever safe is set to — that is a mistake in the call, not a Hub failure.

  • ApiError – If the Hub rejects a create or completion request and safe is False.

update_active_run(status: Literal[RunStatus.FINISHED, RunStatus.KILLED, RunStatus.FAILED] | None = None, ended_at: datetime | None = None, metrics: list[Metric] | None = None, params: list[Parameter] | None = None, external_links: list[ExternalLink] | None = None, parent_run_id: str | _RemoveParent | None = None, description: str | None = None) → None[source]#

Update the active run.

Writes metrics, params, links and the description, so it counts as logging: inside a safe_log() scope a failure warns instead of raising.

Parameters:
  • status – Optional terminal run status.

  • ended_at – Optional completion time.

  • metrics – Metrics to append.

  • params – Parameters to append.

  • external_links – External links to append.

  • parent_run_id – Parent run ID, or REMOVE_PARENT to clear the parent.

  • description – New run description. Pass a blank or whitespace-only string to clear it. The Hub accepts at most 1,000 characters.

Returns:

None.

Raises:

ApiError – If the Hub rejects the request and the call is not inside a safe_log() scope.

use_context_project(*, safe: bool | None = None) → Context[source]#

Record into the project the CLI and environment set.

Binds the project resolved from, highest first: the EMBEDL_HUB_PROJECT environment variable, the nearest workspace (set with embedl-hub use project) and the global config, the same project bare embedl-hub use shows. Nothing is sent to the Hub: the first run started creates the project if it does not exist yet. A client that never calls this binds no project from anywhere; set_project() names one in code:

client = Client()
client.use_context_project()
with client.start_run("training"):
    client.log_metric("loss", 0.1)
Parameters:

safe – When True, a context that cannot be resolved — no project anywhere, or a variable that is set but empty — emits a TrackingFailureWarning and binds nothing instead of raising. None, the default, takes the answer from EMBEDL_HUB_SAFE, which embedl-hub exec --safe sets for the command it wraps.

Returns:

The whole resolved context, including the run and batch, which are not bound here; see use_context_run().

Raises:
use_context_run(*, safe: bool | None = None) → Run | None[source]#

Log to the run the context names, started somewhere else.

Resolves the run from, highest first: the EMBEDL_HUB_RUN environment variable that embedl-hub exec exports for the command it wraps, and the nearest workspace (set with embedl-hub use run). Like set_run(), this attaches without taking responsibility: nothing here completes the run, and a pending run stays pending; start and own one with use_pending_run() instead. set_run() names the run in code.

It binds the organization and project of the run it attaches to, which need not be the project use_context_project() would bind: log calls must go where the run is.

When embedl-hub exec skipped tracking it sets EMBEDL_HUB_UNTRACKED, and this warns and returns None rather than falling through to the workspace’s run.

Parameters:

safe – When True, no run in any layer, or a failure to reach the Hub, emits a TrackingFailureWarning and returns None instead of raising. None, the default, takes the answer from EMBEDL_HUB_SAFE.

Returns:

The adopted run, or None if the process is marked untracked, or if nothing was adopted and safe is True.

Raises:
  • TrackingContextError – If no run resolves, or a layer is present but empty, and safe is not True.

  • TrackingUsageError – If a run is already active, or the run has already finished, whatever safe is set to.

  • ApiError – If the Hub rejects the request and safe is not True.

use_inherited_run(*, safe: bool | None = None) → Run | None[source]#

Log to the run this process was handed, if it was handed one.

Deprecated since version 0.0.9: Use use_context_run(), which also reads the workspace’s run. Removed in 0.1.0.

Reads EMBEDL_HUB_RUN and EMBEDL_HUB_PROJECT, which embedl-hub exec exports for the command it wraps, so a script can record into the run the wrapper already created:

embedl-hub exec --type training ./train.py
client = Client()
client.use_inherited_run()
client.log_metric("loss", 0.1)

A missing EMBEDL_HUB_RUN is not an error. It is what exec --safe leaves behind when the Hub could not be reached: the project is set, no run exists, and the command is meant to carry on untracked. So this warns and returns None rather than raising, and a script that treats the return value as optional works under both.

Parameters:

safe – As for set_run(), including that the default defers to EMBEDL_HUB_SAFE, which is set for exactly this case by exec --safe.

Returns:

The adopted run, or None if the environment named none, or if it could not be adopted and safe is True.

Raises:
use_pending_run(run_id: str, project: str | None = None, *, switch_project: bool = False, safe: bool | None = None) → Iterator[Run | None][source]#

Start a pending run and finish it when the context exits.

For the job a pending run was created for: something else made the run with create_run() and pending=True, annotated it, and handed over its ID. This starts it as the work begins and, unlike set_run(), takes responsibility for it — the run is completed from how the block ends, exactly as start_run() completes a run it created:

with client.use_pending_run(run_id):
    client.log_metric("loss", 0.1)

The run is looked up by its ID alone, as set_run() does, and its project becomes the selection.

Changed in version 0.0.9: Finds the run by ID whatever project is selected, and refuses one in another project unless switch_project is set. project is deprecated.

Parameters:
  • run_id – The pending run to start.

  • project – Deprecated; removed in 0.1.0. A name switches to that project first and looks the run up in it, as in 0.0.8. Select the project with set_project() instead to insist on it, or leave it to the run.

  • switch_project – As for set_run(): what to do when another project is already selected. False raises; True moves the client to the run’s project.

  • safe – As for set_run(), including that None defers to EMBEDL_HUB_SAFE. When tolerated, a failure to find or start the run warns, leaves nothing selected, and yields None; the body still runs.

Returns:

An iterator yielding the run, now running, or None if it could not be started and safe is True.

Raises:
  • TrackingUsageError – If run_id is blank, if a run is already active, if the run is in another project than the one selected and switch_project is False, or if the run is not pending — it is running or finished, or something else started it while it was being adopted here — since whoever did that owns its outcome; use set_run() to log to a run something else is running. Raised whatever safe is set to.

  • ApiError – If the Hub rejects a request and safe is False.

use_project(project: Project) → Project[source]#

Select a project already looked up, without a Hub call.

Deprecated since version 0.0.9: Use set_project(), which takes a Project as well as a name. Removed in 0.1.0.

Parameters:

project – The project to select.

Returns:

project, now the current project.

Raises:

TrackingUsageError – If a run is active; see set_project().

use_run(run_id: str, project: str | None = None, *, safe: bool | None = None) → Run | None[source]#

Log to a run that already exists, started somewhere else.

Deprecated since version 0.0.9: Use set_run(), which always selects the run’s own project. Removed in 0.1.0.

Parameters:
  • run_id – The run to log to.

  • project – The project the run is in. None means the project already selected, which the run must then be in; with no project selected, the run is looked up by ID alone and its own project becomes the selection. A name switches to that project first and warns with TrackingProjectChangedWarning.

  • safe – As for set_run().

Returns:

The adopted run, or None if it could not be adopted and safe is True.

Raises:
  • TrackingUsageError – If run_id is blank, if a run is already active, or if the run has already finished. Raised whatever safe is set to.

  • ApiError – If the Hub rejects the request and safe is False.

class embedl_hub.tracking.Context(hub: Setting, project: Setting, run: Setting, batch: Setting)[source]#

Bases: object

The tracking context resolved from every layer.

Variables:
  • hub – The Hub’s address.

  • project – The project new runs start in.

  • run – The run to log to. EMBEDL_HUB_UNTRACKED shows up here as an "env" setting with no value.

  • batch – The batch log commands queue into.

batch: Setting#
hub: Setting#
project: Setting#
run: Setting#
exception embedl_hub.tracking.DomainError[source]#

Bases: Exception

Base class for domain-specific exceptions.

Bases: Model

created_at: datetime | None#
id: int | None#
label: str#
model_config = {'alias_generator': <function to_camel>, 'extra': 'ignore', 'validate_by_name': True}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

url: str#
exception embedl_hub.tracking.FileTooLargeError(file_path: Path, message: str | None = None)[source]#

Bases: DomainError

Raised when the file for an artifact is too large to upload.

exception embedl_hub.tracking.InvalidRunLineageError(message: str | None = None)[source]#

Bases: DomainError

Raised when the API rejects an invalid parent run link.

exception embedl_hub.tracking.NetworkRequestError[source]#

Bases: Exception

Raised when HTTP request fails.

class embedl_hub.tracking.Parameter(*, name: str, value: str, measuredAt: datetime | None = None)[source]#

Bases: Model

measured_at: datetime | None#
model_config = {'alias_generator': <function to_camel>, 'extra': 'ignore', 'validate_by_name': True}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

name: str#
value: str#
class embedl_hub.tracking.Project(*, id: str, name: str)[source]#

Bases: Model

id: str#
model_config = {'alias_generator': <function to_camel>, 'extra': 'ignore', 'validate_by_name': True}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

name: str#
class embedl_hub.tracking.Run(*, id: str, name: str, description: str | None = None, type: RunType, customType: str | None = None, status: RunStatus, parentRunId: str | None = None, createdAt: datetime, startedAt: datetime, endedAt: datetime | None)[source]#

Bases: Model

created_at: datetime#
custom_type: str | None#
description: str | None#
ended_at: datetime | None#
id: str#
model_config = {'alias_generator': <function to_camel>, 'extra': 'ignore', 'validate_by_name': True}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

name: str#
parent_run_id: str | None#
started_at: datetime#
status: RunStatus#
type: RunType#
class embedl_hub.tracking.RunDashboard(*, id: str, name: str, description: str | None = None, config: dict[str, Any], isDefault: bool = False, opensRun: bool = False, createdAt: datetime, updatedAt: datetime)[source]#

Bases: Model

config: dict[str, Any]#
created_at: datetime#
description: str | None#
id: str#
is_default: bool#
model_config = {'alias_generator': <function to_camel>, 'extra': 'ignore', 'validate_by_name': True}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

name: str#
opens_run: bool#
updated_at: datetime#
class embedl_hub.tracking.RunListPage(*, items: list[RunSummary], pagination: RunListPagination)[source]#

Bases: Model

items: list[RunSummary]#
model_config = {'alias_generator': <function to_camel>, 'extra': 'ignore', 'validate_by_name': True}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

pagination: RunListPagination#
class embedl_hub.tracking.RunStatus(value)[source]#

Bases: Enum

FAILED = 'FAILED'#
FINISHED = 'FINISHED'#
KILLED = 'KILLED'#
PENDING = 'PENDING'#
RUNNING = 'RUNNING'#
class embedl_hub.tracking.RunType(value)[source]#

Bases: Enum

COMPILE = 'COMPILE'#
CUSTOM = 'CUSTOM'#
EVAL = 'EVAL'#
GRAPH = 'GRAPH'#
INFERENCE = 'INFERENCE'#
PROFILE = 'PROFILE'#
class embedl_hub.tracking.Setting(value: str | None, origin: Literal['argument', 'env', 'workspace', 'global', 'default'] | None = None, detail: str | None = None)[source]#

Bases: object

One resolved value and where it came from.

A layer that is present but empty — a blank argument, or a variable that is set but empty — has an origin but no value. That is almost always a shell expansion that produced nothing, so it is reported rather than skipped.

Variables:
  • value – The resolved value, or None.

  • origin – The layer that supplied it, or None when no layer has one.

  • detail – The environment variable’s name or the file’s path, when the origin has one.

detail: str | None = None#
origin: Literal['argument', 'env', 'workspace', 'global', 'default'] | None = None#
value: str | None#
exception embedl_hub.tracking.StorageQuotaExceededError(file_path: Path, message: str | None = None)[source]#

Bases: DomainError

Raised when storage quota is exceeded.

class embedl_hub.tracking.Tag(*, name: str, value: str)[source]#

Bases: Model

model_config = {'alias_generator': <function to_camel>, 'extra': 'ignore', 'validate_by_name': True}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

name: str#
value: str#
class embedl_hub.tracking.Tracked(value: _V_co, run: Run | None)[source]#

Bases: Generic[_V_co]

A value together with the run that produced it.

Returned by every hub_run() function. Passing it to another hub_run() function records that run as the parent of the new one, and hands the function value rather than the wrapper.

Parameters:
  • value – What the function returned.

  • run – The run the function ran in, or None when it ran with safe=True and the run could not be created.

run: Run | None#
value: _V_co#
exception embedl_hub.tracking.TrackingConfigWarning[source]#

Bases: UserWarning

Warns about a configuration that works but is probably a mistake.

Raised, for example, when EMBEDL_HUB_API_KEY is sent to a Hub that was configured somewhere else, so the key may belong to a different Hub.

exception embedl_hub.tracking.TrackingContextError[source]#

Bases: RuntimeError

Raised when the tracking context cannot be resolved.

No project in any layer, a variable that is set but empty, or a command that needs a workspace run outside one. Unlike TrackingUsageError this is a problem with the environment the code runs in, so safe=True on use_context_project() and use_context_run() downgrades it to a warning.

exception embedl_hub.tracking.TrackingFailureWarning[source]#

Bases: UserWarning

Warns that a tracking operation failed and was skipped.

Emitted instead of raising when the failing call is covered by a safe scope — a run started with safe=True, or a logging call made inside safe_log(). The script continues, and whether the affected data reached the Hub is unknown: a request that failed while the response was being read may already have been committed. Treat it as uncertain rather than lost, since retrying on the assumption it was lost can duplicate it.

This is its own category so it can be filtered independently of other warnings. Escalating it to an error is not applied to a failed run completion while an exception is already leaving the with body: that exception is the one the caller needs, so it is never replaced:

# Silence them
warnings.filterwarnings("ignore", category=TrackingFailureWarning)

# Or turn them back into errors
warnings.filterwarnings("error", category=TrackingFailureWarning)
exception embedl_hub.tracking.TrackingProjectChangedWarning[source]#

Bases: UserWarning

Warns that selecting a run also changed the active project.

A run belongs to exactly one project, so adopting one from another project has to move the client with it. That is not a failure, and it is not what the caller literally asked for either, so it is said out loud rather than done quietly — a later log_metric would otherwise land somewhere the caller did not choose.

Its own category, so it can be silenced by a script that switches deliberately without also silencing TrackingFailureWarning:

warnings.filterwarnings(
    "ignore", category=TrackingProjectChangedWarning
)
exception embedl_hub.tracking.TrackingUsageError[source]#

Bases: RuntimeError

Raised when a tracking call itself is malformed.

Safe mode (safe=True, safe_log()) tolerates an unreliable Hub, not a malformed call, so this is raised even inside a safe scope: a warning the caller cannot act on would just hide the mistake.

It is marked with its own class rather than inferred from the exception type, because the type does not carry the distinction — a missing project or absent active run raises RuntimeError too, and those are degradable, being the downstream consequence of a failure the caller already chose to tolerate.

Subclasses RuntimeError so that existing handlers and the :raises RuntimeError: contracts keep working.

embedl_hub.tracking.hub_run(run_type: RunType | str, *, name: str | None = None, safe: bool = False) → _HubRunDecorator[source]#

Run each call of the decorated function as a Hub run.

The function takes the Client as its first parameter, after self on a method. Each call starts a run with start_run() and returns the result wrapped in a Tracked. Every Tracked argument, positional or keyword, is unwrapped to its value before the call, and the first one that has a run becomes the parent of the new run. Tracked values inside containers are passed as they are.

@hub_run("train")
def train(client: Client, data: Path) -> Path: ...

@hub_run("evaluate")
def evaluate(client: Client, model: Path) -> float: ...

model = train(client, data)
score = evaluate(client, model)  # a child run of train

Type checkers check the required arguments after the client, up to six, each as its declared type or a Tracked of it. Pass the client and these arguments positionally; given by keyword, they are reported as missing. Arguments for parameters with defaults are not checked. Methods, and functions with more than six required arguments, are checked only for their return type.

Parameters:
  • run_type – A RunType or a custom type label, as start_run() takes.

  • name – The run name. Defaults to the function’s name.

  • safe – Passed to start_run(): when the run cannot be created or finished, warn instead of raising. A function whose run could not be created still runs, and returns a Tracked whose run is None.

Returns:

A decorator for a synchronous function.

Raises:
  • TypeError – If the decorated function is async or a generator, whose run would finish before its body runs; has no parameter for the client; or is a classmethod or staticmethod object, which must be applied above hub_run() instead. At call time, if the client argument is not a Client.

  • ValueError – If run_type is RunType.CUSTOM, which needs a label: pass the label itself instead.

  • TrackingUsageError – At call time, if a run is already active on the client: runs do not nest.

embedl_hub.tracking.resolve_context(*, project: str | None = None, run: str | None = None, batch: str | None = None) → Context[source]#

Resolve the tracking context, changing nothing.

Never raises for a missing value: an unset setting has no origin.

Parameters:
  • project – A project name that outranks every other layer.

  • run – A run ID that outranks every other layer.

  • batch – A batch ID that outranks every other layer.

Returns:

Each value together with where it came from.

Raises:

TrackingContextError – If the global config cannot be read.

Submodules#