Skip to content

swanlab.Api

Version Note

This documentation applies to swanlab >= 0.8.0.

  • The new OpenAPI uses an OOP style — all operations start from the Api entry point to retrieve entity objects. Entities support lazy loading (requests are sent when properties are accessed) and uniformly serialize to dict via .json().
  • All operations are also available via swanlab api as CLI commands, useful for scripts, CI/CD, or any scenario where writing Python code is not needed.

Authentication priority: explicitly passed api_key / host > swanlab.login() session > environment variables SWANLAB_API_KEY / SWANLAB_API_HOST

🚀 Quick Start

python
import swanlab

api = swanlab.Api()                              # reads .netrc credentials automatically
api = swanlab.Api(api_key="your-api-key", host="your-host")  # explicit credentials

Self-hosted deployment:

python
api = swanlab.Api(api_key="your-api-key", host="https://your-server.com")

🧱 Path Format

  • Workspace: username
  • Project: username/project-name
  • Experiment: username/project-name/experiment-id

🔨 Core Concepts

The new OpenAPI is organized around three core concepts: WorkspaceProjectExperiment, forming a clear hierarchy:

Workspace
 └── Project
      └── Experiment/Run
           ├── columns (metric column keys/names)
           ├── metrics (scalar metrics)
           ├── medias (media metrics)
           └── logs
ConceptDescription
WorkspaceA collection of projects, corresponding to a team or user. Divided into personal (PERSON) and organization (TEAM).
ProjectA collection of experiments, corresponding to a research task, containing metadata like name, description, labels, and visibility.
ExperimentA single training/inference run, containing metrics, config, logs, environment info, etc.
ColumnA metric column under an experiment, such as loss or acc, supporting FLOAT / STRING / IMAGE and more.
MetricThe metric value corresponding to a specific column in an experiment.

Data Types: metrics / medias / logs

Data under an experiment falls into three categories, accessed through different methods:

TypeMethodDescriptionTypical Use Case
Scalar metricsrun.metrics(keys=[...])Numeric metrics (e.g. loss, acc), supports sampling and range queries, returns structured dataTraining curve analysis, trend comparison
Media metricsrun.medias(keys=[...])Images, audio, video and other unstructured media data, returns presigned URLsVisual inspection, result preview
Logsrun.logs() / run.export_logs()Text logs from experiment runtime, supports level filteringDebugging, troubleshooting, auditing
python
import swanlab

api = swanlab.Api()
run = api.run(path="my-team/my-project/abc123")

# Scalar metrics: loss, acc, etc.
scalars = run.metrics(keys=["loss", "acc"], sample=500)

# Media metrics: images, audio, etc.
media = run.medias(keys=["generated_image"], step=10)

# Logs: text output
logs = run.logs(offset=0, level="INFO")

Notes:

  • metrics() returns sampled data by default, with a sample parameter default cap of 1500 (auto-truncated if exceeded). Set all=True for full data, or use range_query to query exact metric ranges by step or timestamp.
  • medias() returns media data via presigned URLs — download within the validity period.
  • export_logs() can export large volumes of logs to .log files, suitable for persistent storage.

Api

Api is the entry point for all operations. Authentication is completed at construction time, creating an independent Client instance (separate from the SDK runtime).

MethodDescription
api.workspace(username)Get a single workspace
api.workspaces(username)List workspaces (iterator)
api.project(path)Get a single project
api.projects(path, ...)Get project list (iterator)
api.create_project(username, name, ...)Create a project
api.run(path)Get a single experiment
api.runs(path, filters=...)Get experiment list (POST filter mode)
api.runs_get(path, ...)Get experiment list (GET pagination mode)
api.column(path, key)Get a single metric column
api.columns(path, ...)Get metric columns for an experiment
api.user()Get current user info
api.self_hosted()Self-hosted management entry point

Workspace

Workspace properties:

PropertyTypeDescription
namestrWorkspace name
usernamestrWorkspace username (unique ID)
workspace_typestrPERSON or TEAM
rolestrCurrent user RBAC role: OWNER or MEMBER
profiledictProfile info
commentstrWorkspace description
python
import swanlab

api = swanlab.Api()

# username: specify workspace username, uses current logged-in user when None
ws = api.workspace(username="my-team")

data = ws.json()
print(data["name"], data["username"], data["workspace_type"])
python
import swanlab

api = swanlab.Api()

# username: specify username, uses current logged-in user when None
for ws in api.workspaces("my-team"):
    print(ws.name)
python
import swanlab

api = swanlab.Api()


ws = api.workspace(username="my-team")

# sort optional parameters:
# - create: sort by creation time
# - name: sort by name
# None: defaults to "recently updated" sorting

# search: fuzzy search keyword
projects = ws.projects(sort="create", search="v1")
print(projects.json())
python
import swanlab

api = swanlab.Api()


ws = api.workspace(username="my-team")

project = ws.create_project(name="my_project", visibility="PUBLIC")

Project

Project properties

PropertyTypeDescription
namestrProject name
pathstrProject path username/project-name
descriptionstrProject description
labelslistProject labels
created_atstrCreation time (ISO 8601 UTC)
updated_atstrUpdate time
urlstrProject web page URL
visibilitystrPUBLIC or PRIVATE
countdictStats (experiment count, collaborator count, etc.)

Project method examples

python
import swanlab

api = swanlab.Api()

# path: format is 'username/project-name'
project = api.project(path="my-team/my-project")

print(project.json())
python
import swanlab

api = swanlab.Api()

"""
- path: workspace name 'username'
- sort: sort order, supports `create` or `name` for creation time or name sorting, defaults to update time
- search: fuzzy search keyword
- detail: whether to return detailed info, bool type
- page: start page, default 1
- size: items per page, default 100
- all: whether to get all data, default False
"""
for p in api.projects(path="my-team", sort="name", search="image"):
    print(p.name, p.path)
python
import swanlab

api = swanlab.Api()

project = api.project(path="my-team/my-project")

"""
- filters: list of filter rules, each item is a dict with {key, type, op, value}
"""
# Example: return finished experiments under the project
runs = project.runs(filters=[{"key": "state", "type": "STABLE", "op": "EQ", "value": ["FINISHED"]}])
print(runs.json())
python
import swanlab

api = swanlab.Api()

project = api.project(path="my-team/my-project")

# Max page size is 100
runs = project.runs_get(page=1, size=100)
print(runs.json())
python
import swanlab

api = swanlab.Api()

project = api.create_project(
    username="my-team",
    name="new-project",
    visibility="PRIVATE",
    description="Project description",
)
python
import swanlab

api = swanlab.Api()

project = api.project(path="my-team/my-project")
project.delete(commit=False)  # commit=False only prints pending deletion info, does not actually delete
python
import swanlab

api = swanlab.Api()

project = api.project(path="my-team/my-project")
project.delete_runs(["run_id_1", "run_id_2"], commit=True)  # commit=True confirms deletion, verify before proceeding

Experiment (Run)

Run properties

PropertyTypeDescription
namestrExperiment name
descriptionstrExperiment description
statestrExperiment state: RUNNING, FINISHED, CRASHED, ABORTED, OFFLINE
labelslistExperiment labels
groupstrExperiment group name
job_typestrJob type
created_atstrCreation time
finished_atstrEnd time, None if not finished
urlstrExperiment web page URL
showboolWhether shown in comparison view
profiledictExperiment config, environment, dependencies, etc.
userdictCreator info

Run method examples

1. Get single experiment

Get a single experiment's info, input must match the format username/project_name/run_id

python
import swanlab

api = swanlab.Api()

run = api.run(path="my-team/my-project/abc123")

data = run.json()

2. Get experiment list (filter mode)

Fetch experiment list under a project via conditional filtering.

ParameterTypeDescription
pathstrProject path username/project
filterslist[dict]Filter rules, each item is a dict containing exactly 4 keys: {key, type, op, value}

Filter rule fields:

FieldTypeRequiredDescription
keystrField name
typestrField type: STABLE, CONFIG, SCALAR
opstrOperator: EQ(=), NEQ(≠), GTE(≥), LTE(≤), IN(element exists in set), NOT IN(element does not exist in set), CONTAIN(contains)
valuelistComparison value

type field values:

typekey valuesvalue
STABLEExperiment built-in fields: state, name, description, show, pin, baseline, colors, cluster, job, createdAt, updatedAt, finishedAt, pinnedAt, labelsCorresponding field value
CONFIGConfig parameter name, e.g. param_2 (no config. prefix)Config parameter value
SCALARScalar metric nameMetric value
python
# Filter example
# Experiments under my-team/my-project that are [finished] AND name contains `v2`
for run in api.runs(path="my-team/my-project", filters=[
    {"key": "state", "type": "STABLE", "op": "EQ", "value": ["FINISHED"]},
    {"key": "name", "type": "STABLE", "op": "CONTAIN", "value": ["v2"]},
]):
    print(run.name)

3. Get experiment list (pagination mode)

Fetch experiment list via standard pagination, returns minimal info. Does not support filtering.

ParameterTypeDefaultDescription
pathstrProject path username/project
pageint1Start page
sizeint100Items per page
allboolFalseAuto-paginate to get all results
python
import swanlab

api = swanlab.Api()

for run in api.runs_get(path="my-team/my-project", page=1, size=100, all=True):
    print(run.name, run.state)

4. metrics

Fetch scalar metric data (e.g. loss, acc), supports sampling control and range queries, returns structured data.

ParameterTypeDefaultDescription
keyslist[str]Metric key list, e.g. ["loss", "acc"]
sampleint1500Sample count (SCALAR max 1500), ignored when all or range_query is set
allboolFalseGet full data (no sampling limit)
range_querydict or RangeQueryNoneRange query, only valid for SCALAR type
ignore_timestampboolFalseWhether to remove timestamp fields

RangeQuery fields:

FieldTypeDefaultDescription
typestr"step"Filter axis: "step" or "timestamp"
startintNoneLower bound (inclusive), None means from the beginning. When type is timestamp, input must be a UNIX timestamp
endintNoneUpper bound (inclusive), None means up to the last step. When type is timestamp, input must be a UNIX timestamp
lastintNoneLast N milliseconds (mutually exclusive with start/end)
headintNoneTake first N data points (mutually exclusive with tail), post-sampled
tailintNoneTake last N data points (mutually exclusive with head), post-sampled

Mutual exclusion rules:

  • last is mutually exclusive with start/end
  • head and tail are mutually exclusive, with the lowest priority
  • head/tail can be combined with start/end or last (range filter first, then truncate)
python
from swanlab.api.typings.common import RangeQuery

# By step range
rq = RangeQuery(type="step", start=100, end=500)

# Take last 50 items
rq = RangeQuery(tail=50)

# By timestamp range (milliseconds, auto-padded if fewer than 13 digits)
rq = RangeQuery(type="timestamp", start=1715769600000, end=1715773200000)

# Last 5 minutes
rq = RangeQuery(last=300_000)

# Or use dict directly — metrics with step in [100, 500]
result = run.metrics(keys=["loss"], range_query={"type": "step", "start": 100, "end": 500})
python
import swanlab

api = swanlab.Api()

run = api.run(path="my-team/my-project/abc123")

# Get metric data, returns dict
result = run.metrics(keys=["loss", "acc"])

# Specify sample count (default 1500, max 1500)
result = run.metrics(keys=["loss"], sample=500)

# Full data (no sampling limit)
result = run.metrics(keys=["loss"], all=True)

# Range query by step
result = run.metrics(
    keys=["loss"],
    range_query={"type": "step", "start": 100, "end": 500},
)

# Range query by timestamp (milliseconds, auto-padded if fewer than 13 digits)
result = run.metrics(
    keys=["loss"],
    range_query={"type": "timestamp", "start": 1715769600000, "end": 1715773200000},
)

# Data from the last 5 minutes
result = run.metrics(keys=["loss"], range_query={"last": 300_000})

# Step range + take first 50 points
result = run.metrics(
    keys=["loss"],
    range_query={"start": 0, "end": 500, "head": 50},
)

# Take last 30 data points
result = run.metrics(keys=["loss"], range_query={"tail": 30})

5. summary

Get statistical summary of scalar metrics (min / max / avg / median / latest), each metric uses the latest value as the authoritative value.

ParameterTypeDescription
keyslist[str]Scalar keys to query, None means all keys
python
import swanlab

api = swanlab.Api()

run = api.run(path="my-team/my-project/abc123")

summary = run.summary(keys=["loss", "acc"])
# Returns stats for each key
print(summary)

6. medias

Fetch images, audio, video, echarts and other unstructured media data stored in object storage, response returns only presigned URLs.

ParameterTypeDefaultDescription
keyslist[str]Media metric key list
stepint0Specific step, omit to get latest
allboolFalseGet all historical media data
python
import swanlab

api = swanlab.Api()

run = api.run(path="my-team/my-project/abc123")

# Get media data at a specific step
result = run.medias(keys=["generated_image"], step=10)
print(result)

# Get all media data
result = run.medias(keys=["generated_image"], all=True)
print(result)

WARNING

Returned media data is provided via presigned URLs — download before the expiration time.

7. logs

Fetch text logs from experiment runtime, supports level filtering; can also export as .log file.

ParameterTypeDefaultDescription
offsetint0Pagination offset
levelstr"INFO"Log level: DEBUG, INFO, WARN, ERROR
ignore_timestampboolFalseWhether to remove timestamp fields
ParameterTypeDefaultDescription
startint0Export start line (0-based)
rowsint500000Number of rows to export, max 500000
python
import swanlab

api = swanlab.Api()

run = api.run(path="my-team/my-project/abc123")

# Get logs
logs = run.logs(offset=0, level="INFO")
print(logs)

8. export_logs

Export logs as .log file (returns presigned download link)

python
import swanlab

api = swanlab.Api()

run = api.run(path="my-team/my-project/abc123")

result = run.export_logs(start=0, rows=500)
if result.ok:
    print(result.data["url"])

9. columns

Get metric column names under an experiment, or get a single column by key.

columns parameters:

ParameterTypeDefaultDescription
pageint1Start page
sizeint100Items per page
searchstrNoneFuzzy search keyword (case-insensitive, matches column name field)
column_classstrNoneColumn class: CUSTOM or SYSTEM
column_typestrNoneColumn data type: FLOAT, STRING, IMAGE, etc.
allboolFalseAuto-paginate to get all results

column parameters:

ParameterTypeDefaultDescription
pathstrExperiment path username/project/run_id
keystrSearch keyword (fuzzy matches column name, returns first match)
column_classstr"CUSTOM"Column class: CUSTOM or SYSTEM
column_typestr"FLOAT"Column data type: FLOAT, STRING, IMAGE, etc.
python
import swanlab

api = swanlab.Api()
run = api.run(path="my-team/my-project/abc123")

# Get all metric columns
for col in run.columns(all=True):
    print(col.name)

# Fuzzy search (matches column name)
for col in run.columns(search="loss"):
    print(col.name)

# Get a single column (fuzzy match, returns first)
col = run.column(key="loss", column_type="FLOAT")

10. delete

Delete experiment, controls actual deletion behavior via commit.

python
import swanlab

api = swanlab.Api()
run = api.run(path="my-team/my-project/abc123")

run.delete(commit=False)  # commit=False does not actually delete

Column

Represents metric names reported via swanlab.log().

Column properties

PropertyTypeDescription
namestrColumn display name
keystrColumn key
column_classstrColumn class: CUSTOM or SYSTEM
column_typestrData type: FLOAT, STRING, IMAGE, VIDEO, OBJECT3D, etc.
created_atintCreation timestamp

Column method examples

column parameters:

ParameterTypeDefaultDescription
pathstrExperiment path username/project/run_id
keystrSearch keyword (fuzzy matches column name, returns first match)
column_classstr"CUSTOM"Column class: CUSTOM or SYSTEM
column_typestrNoneColumn data type: FLOAT, STRING, IMAGE, VIDEO, etc.

columns parameters:

ParameterTypeDefaultDescription
pathstrExperiment path username/project/run_id
pageint1Start page
sizeint100Items per page
searchstrNoneFuzzy search keyword (case-insensitive, matches column name field)
column_classstrNoneColumn class: CUSTOM or SYSTEM
column_typestrNoneColumn data type
allboolFalseAuto-paginate to get all results

Column.metric() parameters:

ParameterTypeDefaultDescription
sampleint1500Sample count (SCALAR max 1500)
metric_typestr"SCALAR"Metric type, auto-inferred from column type, usually no need to specify manually
ignore_timestampboolFalseWhether to remove timestamp fields
media_stepintNoneOnly effective for MEDIA type, specifies the step

Columns.total property:

PropertyTypeDescription
totalintTotal number of matching columns (triggers one request on first access)
python
import swanlab

api = swanlab.Api()

col = api.column(
    path="my-team/my-project/abc123",
    key="loss",
    column_type="FLOAT",
)
python
import swanlab

api = swanlab.Api()

for col in api.columns(
    path="my-team/my-project/abc123",
    page=1,
    size=100,
    all=True,
    column_type="FLOAT",
):
    print(col.name)
python
import swanlab

api = swanlab.Api()

# search parameter does case-insensitive contains match on column name, paginated query
for col in api.columns(
    path="my-team/my-project/abc123",
    search="loss",
):
    print(col.name)
python
import swanlab

api = swanlab.Api()

for col in api.columns(
    path="my-team/my-project/abc123",
    all=True,
    column_type="FLOAT",
):
    print(col.name)
python
import swanlab

api = swanlab.Api()

cols = api.columns(path="my-team/my-project/abc123")
print(cols.total)  # returns the total number of matching columns
python
import swanlab

api = swanlab.Api()

col = api.column(path="my-team/my-project/abc123", key="loss")
data = col.metric(sample=500)
python
import swanlab

api = swanlab.Api()

col = api.column(path="my-team/my-project/abc123", key="loss")
result = col.export_csv()
if result.ok:
    print(result.data["url"])  # CSV download link

User

User properties

PropertyTypeDescription
usernamestrUsername
namestrDisplay name
biostrBio
institutionstrInstitution
schoolstrSchool
emailstrEmail
locationstrLocation
urlstrPersonal website

User method examples

python
import swanlab

api = swanlab.Api()
user = api.user()  # no parameters, uses the user info from the Api instance

data = user.json()

Self-hosted Management (self_hosted)

Applies only to self-hosted deployments and requires super admin privileges.

SelfHosted properties

PropertyTypeDescription
enabledboolWhether self-hosted mode is enabled
expiredboolWhether license is expired
rootboolWhether current user is super admin
planstrLicense type: free or commercial
seatsintLicense seat count

SelfHosted method examples

python
import swanlab

api = swanlab.Api()
sh = api.self_hosted()

data = sh.json()
print(data["enabled"], data["plan"], data["seats"])
python
import swanlab

api = swanlab.Api()
sh = api.self_hosted()

sh.create_user(username="newuser", password="pass123")

for user in sh.get_users(page=1, size=100, all=True):
    print(user)
python
import swanlab

api = swanlab.Api()
sh = api.self_hosted()

# Filter by state + creator
for proj in sh.get_projects(
    page=1, size=100, all=True,
    search="image", state="FINISHED", creator="admin",
):
    print(proj)

# Filter by organization workspace
for proj in sh.get_projects(group="my-team", sort="create"):
    print(proj)
python
import swanlab

api = swanlab.Api()
sh = api.self_hosted()

# Filter by type
for group in sh.get_groups(all=True, type="TEAM", sort="name"):
    print(group)
python
import swanlab

api = swanlab.Api()
sh = api.self_hosted()

result = sh.get_usage_summary()
print(result.data if result.ok else result.errmsg)

Type Reference

ApiResponseType — Unified response wrapper for OpenAPI. All API calls returning ApiResponseType guarantee no exceptions. Actual return data is in the data field.

PropertyTypeDescription
okboolWhether the request succeeded
errmsgstrError message, empty string on success
dataAnyResponse data, None on failure
MethodDescription
json()Serialize to dict, automatically calls .json() on entity data