Storing data science artifacts#
skore provides a Project class to store data science artifacts. The storage
is either local or remote, based on the value passed to the parameter mode at
initialization. When mode is set to hub, the project is configured to communicate
with Skore Hub. Authentication uses an API key, in this order:
the
SKORE_HUB_API_KEYenvironment variable, which always wins. The key is bound to a workspace; using it against another workspace fails at runtime.otherwise the local credentials registry for the hub host and workspace:
$ skore hub api-key generate --host <host> --workspace <workspace>
See Using Skore Hub to generate, list, and revoke keys from the command line.
Refer to the documentation of Project for the detailed API.
Creating a project#
All modes share the same constructor shape: pass name, mode, and any
mode-specific keyword arguments.
from pathlib import Path
from skore import Project
# Local persistence
project_local = Project(name="my-xp", mode="local", workspace=Path("/tmp/skore"))
# Skore Hub (requires an API key in the registry or SKORE_HUB_API_KEY)
project_hub = Project(
name="my-xp",
mode="hub",
workspace="my-workspace",
host="my-host",
)
# MLflow experiment
project_mlflow = Project(
name="my-experiment",
mode="mlflow",
tracking_uri="http://localhost:5000",
)
Note
Databricks managed MLflow (tracking_uri="databricks") only accepts experiment
names that are absolute workspace paths, so name must be one, for example
"/Users/me@example.com/my-experiment". skore places the internal experiment in
which it stores report objects in the home directory of the workspace user.
Working with reports#
Once a project is created, store an EstimatorReport or
CrossValidationReport via Project.put().
To retrieve the reports stored in the project, use the project summary by calling the
method Project.summarize(). This method returns a Summary object that holds
the metadata and metrics of the stored reports and renders as an interactive table in
Jupyter-like environments. Reports are listed in ascending order of their date.
The interactive view provides different views to sort, group by, and filter the reports;
the selection produces a query string ready to pass to Summary.query(...). Once the
reports are filtered, retrieve them by calling the compare method on the object
returned by Project.summarize(). This method returns a list of
EstimatorReport or CrossValidationReport instances (or a
ComparisonReport when called with return_as="report").
To retrieve a specific report for which you have its id (as returned by
Project.summarize()), use the Project.get() method.
Project.delete() removes the project itself.
Synchronizing projects#
Use Project.sync() to transfer reports between projects. The project on which the
method is called is the source. Synchronizing projects runs the same transfer from the shell.
project_hub = Project(
name=project_local.name,
mode="hub",
workspace="my-workspace",
host="my-host",
)
result = project_local.sync(project_hub)
The caller is the source; reverse the call for the opposite direction. Set
bidirectional=True to transfer missing reports in both directions.
When both projects have the same name, pass the destination mode as a shortcut. The destination is built with the caller’s name and the supplied mode-specific arguments.
result = project_local.sync("hub", workspace="my-workspace", host="my-host")
Reports are matched using the report_id column returned by
Project.summarize().frame() and copied with their keys. Existing IDs are skipped;
contents and metadata are not compared. Reports without a report_id are ignored.
Set dry_run=True to return the transfer plan without loading or storing reports.
The returned pandas.DataFrame is indexed by report_id. Its direction
column is "outbound" from the caller to the other project, "inbound" from the
other project to the caller, or missing when a report is skipped. Its status column
is "planned", "transferred", or "skipped".
Note
Two MLflow projects must use the same tracking URI because MLflow uses process-global tracking state. Synchronization does not provide concurrency control.