Skip to main content



PyPI Python Downloads License

Unitlab.ai is an AI-driven data annotation platform that automates the collection of raw data, facilitating collaboration with human annotators to produce highly accurate labels for your machine learning models. With our service, you can optimize work efficiency, improve data quality, and reduce costs.

Unitlab Python SDK

Native Python and CLI access to Unitlab projects, Ontologies, Assets, datasets, published versions, Batch Queues, Releases, cloud storage, and multimodal Data Groups and Workflow Tasks.

Install

pip install --upgrade unitlab

Python 3.10 or newer is required.

Authenticate

Create an API key in Workspace settings, then use environment variables:

export UNITLAB_API_KEY="YOUR_API_KEY"
export UNITLAB_API_URL="https://api.unitlab.ai"  # optional

Or configure the CLI once:

unitlab configure --api-key YOUR_API_KEY
unitlab configure --api-url https://api.unitlab.ai

You can also pass both values directly:

from unitlab import UnitlabClient

client = UnitlabClient(
    api_key="YOUR_API_KEY",
    api_url="https://api.unitlab.ai",
)

1. Upload multimodal data to a project

from unitlab import UnitlabClient

client = UnitlabClient()
project = client.projects.create("Medical review")
batch = project.upload("./multimodal-data")
status = batch.wait()

print(batch.uploaded, batch.batch_queue_id)

The directory may mix images, video, audio, text, PDFs, DICOM, NIfTI, and NRRD. One call creates one Batch Queue. Call batch.wait() when the next operation depends on server-side processing.

2. Curate in Assets, publish a dataset, and attach it

from unitlab import UnitlabClient

client = UnitlabClient()
project = client.projects.create("Quality review")

uploaded = client.assets.upload(
    "./multimodal-data",
    folder="Raw data",
    tags=["incoming"],
)

dataset = client.datasets.create(
    "Review set",
    folder_ids=[uploaded.folder_id],
)
version = dataset.publish_version("Initial snapshot")

attached = client.attach_dataset(
    project,
    dataset,
    version=version.version_number,
)

print(attached.created_count)

Datasets are version-first. Editing a dataset creates Unpublished changes; publish_version() freezes a version, and projects attach that published snapshot.

3. Import existing cloud data

from unitlab import UnitlabClient

client = UnitlabClient()
project = client.projects.create("Cloud review")
storage = next(
    item for item in client.cloud_storages.list() if item.name == "Production data"
)

batch = project.import_cloud(
    storage,
    ["incoming/study-001/"],
)
status = batch.wait()

print(batch.batch_queue_id)

Directory paths end in /. Cloud credentials are never returned through the SDK; list and browse responses expose only safe storage metadata.

Resource handles

Namespace entrypoints return typed resource handles:

project = client.projects.get("PROJECT_ID")
projects = client.projects.list()
dataset = client.datasets.get("DATASET_ID")
datasets = client.datasets.list()
folder = client.assets.folder("FOLDER_ID")
folders = client.assets.folders()

Ontologies

from unitlab import OntologyStructure, RadioAttribute, Shape

structure = OntologyStructure()
cat = structure.add_object("Cat", Shape.BOUNDING_BOX)
colour = cat.add_attribute(RadioAttribute, "Colour", required=True)
colour.add_option("Black")
colour.add_option("White")

ontology = client.ontologies.create("Cat labels", structure=structure)
project = client.projects.create(
    "Cat review",
    ontology_hash=ontology.id,
)

Use client.ontologies.get(), client.ontologies.list(), and ontology.save() for the rest of the Ontology lifecycle. Project attachment copies the Workspace Ontology so Unitlab can preserve project-specific version history.

Projects and Batch Queues

projects = client.projects.list()
project = client.projects.get("PROJECT_ID")
project = client.projects.create("Road scenes")

batch = project.upload("./data", fps=2.0)
tiled_batch = project.upload("./maps")

status = batch.status()
status = batch.wait(timeout=1800)

queues = project.batch_queues()
queue = project.batch_queue(batch.batch_queue_id)
items = queue.data()
status = queue.wait()

ProcessingStatus exposes total, completed, processing, and failed. Completion means processing == 0; a completed Batch Queue may still report individual failures.

GeoTIFF and whole-slide files are detected automatically. Large tiled files upload directly to storage in bounded parts. Tiled processing can take hours, so use a longer timeout such as batch.wait(timeout=25200) when the next operation depends on the generated COG/DZI derivative.

Data Units and project lifecycle

project.update(name="Road review v2", description="Second collection")

units = project.data_units(data_type="image", status="annotate")
unit = client.get_data_unit(project.id, units[0].id)

for unit in units:
    print(unit.kind, unit.name, unit.status)

A loose file is one datasource Data Unit. A Data Group is one group Data Unit whose items contain its tile summaries; member files are not duplicated in the top-level list. project.delete() soft-deletes the Project and schedules the existing backend cleanup.

Assets and folders

folders = client.assets.folders()
folder = client.assets.create_folder("Raw data")
children = folder.children()
every_folder = client.assets.all_folders()
items = folder.list_items()

result = client.assets.upload("./images", folder_id=folder.id, tags=["train"])
asset = result.assets[0]

tiled = client.assets.upload(
    "./slides",
    folder_id=folder.id,
)
tiled.assets[0].wait()

cloud_folder = client.assets.create_cloud_folder(
    "Incoming",
    "CLOUD_STORAGE_ID",
    prefix="incoming/",
)
cloud_folder.sync_cloud()  # Tiled files are registered as processing Assets.

Datasets and published versions

dataset = client.datasets.create(
    "Training set",
    folder_ids=["FOLDER_ID"],
)

dataset.add_sources(asset_ids=["ASSET_ID"])
changes = dataset.unpublished_changes()
version = dataset.publish_version("Added edge cases")
versions = dataset.versions()
items = dataset.list_items(version=version.version_number)

Workflow Tasks

workflow = project.workflow
annotate = workflow.get_stage(name="Annotate")

for task in annotate.get_tasks():
    task.assign("USER_ID")
    task.submit()

Review Tasks provide approve() and reject(). Managers can use move() for a direct stage override and get_timeline() to inspect Task history.

Attach data

preview = project.attach_preview(dataset_ids=[dataset.id])

result = project.attach(dataset_ids=[dataset.id])

# Attach an exact version instead of latest:
result = project.attach(
    dataset_versions=[
        {"dataset_id": dataset.id, "version_number": 2},
    ]
)

for source in project.attached_sources():
    print(source.name, source.detach_preview())
    # source.detach() removes only the Project copy and keeps annotations.

Video attachment may require fps=. Call attach_preview() when you need counts before committing; attach() validates the same rule and raises an actionable ValidationError if FPS is missing.

Cloud storage

storages = client.cloud_storages.list()
storage = storages[0]

for entry in storage.browse(prefix="incoming/"):
    print(entry.name, entry.type, entry.size)

batch = project.import_cloud(
    storage,
    ["incoming/file.png", "incoming/study/"],
)
status = batch.wait()

Data Groups

Let Unitlab suggest a filename pattern:

folder = client.assets.folder("FOLDER_ID")
grouped = folder.auto_group()

Or compile a literal filename template:

from unitlab import tiles_from_template

config = tiles_from_template(
    "{patient_id}_{view}",
    tile_values={
        "view": ["L_CC", "R_CC", "L_MLO", "R_MLO"],
    },
)

estimate = folder.estimate_grouping(config)
grouped = folder.auto_group(config)

For folders above 5,000 files or estimates above 1,000 groups, auto_group() raises an actionable ValidationError. Split the source into smaller folders and retry; the SDK does not return a job that will never run.

Releases

Releases are exported annotation snapshots. They are separate from Assets datasets.

release = client.releases.create(
    project,
    export_type="UUEF",
    split_ratios={"train": 80, "test": 20},
)

releases = client.releases.list()
release = client.releases.get(release.id)

annotation_path = release.download(split="train", dest="./release-annotations")
files_folder = release.download_files(dest="./release-files")

Release item download tokens are persistent Unitlab URLs. For files stored in customer cloud storage, the URL redirects to a signed target URL; only that target URL is temporary.

CLI quick reference

# Projects and Batch Queues
unitlab project create "Medical review" --ontology ONTOLOGY_ID
unitlab project list
unitlab project detail PROJECT_ID
unitlab project update PROJECT_ID --name "Medical review v2"
unitlab project data-units PROJECT_ID --data-type image
unitlab project data-unit PROJECT_ID DATA_UNIT_ID
unitlab project sources PROJECT_ID
unitlab project detach-source PROJECT_ID SOURCE_LINK_ID --preview
unitlab project upload PROJECT_ID --source ./data
unitlab project upload PROJECT_ID --source ./maps
unitlab batch-queue list PROJECT_ID
unitlab batch-queue detail PROJECT_ID BATCH_QUEUE_ID
unitlab batch-queue status PROJECT_ID BATCH_QUEUE_ID
unitlab batch-queue data PROJECT_ID BATCH_QUEUE_ID
unitlab batch-queue wait PROJECT_ID BATCH_QUEUE_ID --timeout 1800

# Cloud import and attach
unitlab project import-cloud PROJECT_ID CLOUD_STORAGE_ID incoming/study/
unitlab project attach PROJECT_ID --dataset DATASET_ID
unitlab project attach PROJECT_ID --dataset DATASET_ID --preview
unitlab project attach PROJECT_ID --dataset-version DATASET_ID:2

# Assets
unitlab assets upload ./data --folder "Raw data" --tag incoming
unitlab assets upload ./slides --folder "Slides"

# Folders
unitlab folders create "Raw data"
unitlab folders create "Incoming" \
  --cloud-storage CLOUD_STORAGE_ID --prefix incoming/
unitlab folders list
unitlab folders list --parent PARENT_FOLDER_ID
unitlab folders detail FOLDER_ID
unitlab assets upload ./data --folder-id FOLDER_ID
unitlab folders sync-cloud FOLDER_ID

# Data Groups
unitlab assets group FOLDER_ID --config grouping.json
unitlab assets group FOLDER_ID --config grouping.json --preview
unitlab assets group FOLDER_ID --preview
unitlab assets group FOLDER_ID \
  --template '{patient_id}_{view}' \
  --tile-values view=L_CC,R_CC,L_MLO,R_MLO

# Datasets
unitlab dataset list
unitlab dataset create "Training set" --folder FOLDER_ID
unitlab dataset detail DATASET_ID
unitlab dataset add-sources DATASET_ID --asset ASSET_ID
unitlab dataset unpublished-changes DATASET_ID
unitlab dataset publish DATASET_ID --title "Initial snapshot"
unitlab dataset versions DATASET_ID

# Releases
unitlab release create PROJECT_ID --format UUEF --splits train=100
unitlab release list
unitlab release detail RELEASE_ID
unitlab release download RELEASE_ID --split-type train --dest ./release-annotations

# Ontologies
unitlab ontology list
unitlab ontology list --title-like Medical --created-after 2026-01-01
unitlab ontology create "Medical labels" --structure ontology.json
unitlab ontology update ONTOLOGY_ID --title "Medical labels v2"

# Cloud storage
unitlab cloud list
unitlab cloud browse CLOUD_STORAGE_ID --prefix incoming/

Run unitlab COMMAND --help for every option.

License

MIT

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

unitlab-3.0.2.tar.gz (58.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

unitlab-3.0.2-py3-none-any.whl (52.1 kB view details)

Uploaded Python 3

File details

Details for the file unitlab-3.0.2.tar.gz.

File metadata

  • Download URL: unitlab-3.0.2.tar.gz
  • Upload date:
  • Size: 58.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.10.12

File hashes

Hashes for unitlab-3.0.2.tar.gz
Algorithm Hash digest
SHA256 11ea68d1260843aad3cb1ab9b91ac7f8f618e01029586d07bfb13d7ea19bcda8
MD5 e656b58fec567e1aa8d34d0de72b23bd
BLAKE2b-256 86dec1a02d07bb25af2196e9ef82a0edbfe15c2e3e9a68dcd7000ddeade13f7b

See more details on using hashes here.

File details

Details for the file unitlab-3.0.2-py3-none-any.whl.

File metadata

  • Download URL: unitlab-3.0.2-py3-none-any.whl
  • Upload date:
  • Size: 52.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.10.12

File hashes

Hashes for unitlab-3.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 fefd755835bb1340091c337e08d04bcde311fabdd11f4f06afbc879fbb04c2ab
MD5 7c39f258e8d2d52b65826e5c0c3b9bea
BLAKE2b-256 eae645d7ce8d61012e03bc16fb20e457219f943c05f425e3137238c627533dc4

See more details on using hashes here.

Release history Release notifications | RSS feed

3.0.3

2 files

This release

3.0.2 This release

2 files

3.0.1

2 files

3.0.0

2 files

2.5.1

2 files

2.5.0

2 files

2.4.6

2 files

2.4.5

2 files

2.4.4

2 files

2.4.3

2 files

2.4.2

2 files

2.4.1

2 files

2.4.0

2 files

2.3.48

2 files

2.3.47

1 file

2.3.46

1 file

2.3.45

1 file

2.3.44

2 files

2.3.43

2 files

2.3.42

2 files

2.3.41

2 files

2.3.40

2 files

2.3.39

2 files

2.3.38

2 files

2.3.37

2 files

2.3.36

2 files

2.3.35

2 files

2.3.34

2 files

2.3.33

2 files

2.3.32

2 files

2.3.29

2 files

2.3.28

2 files

2.3.27

2 files

2.3.26

2 files

2.3.25

2 files

2.3.23

2 files

2.3.20

2 files

2.3.18

2 files

2.3.17

2 files

2.3.16

2 files

2.3.15

2 files

2.3.14

2 files

2.3.13

2 files

2.3.12

2 files

2.3.11

2 files

2.3.10

2 files

2.3.9

2 files

2.3.8

2 files

2.3.7

2 files

2.3.6

1 file

2.3.5

2 files

2.3.4

2 files

2.3.3

2 files

2.3.0

2 files

2.2.0

1 file

2.1.9

1 file

2.1.8

1 file

2.1.7

1 file

2.1.6

1 file

2.1.5

1 file

2.1.4

1 file

2.1.3

1 file

2.1.2

1 file

2.1.1

1 file

2.1.0

1 file

2.0.9

1 file

2.0.8

1 file

2.0.7

1 file

2.0.6

1 file

2.0.5

1 file

2.0.4

1 file

2.0.3

1 file

2.0.2

1 file

2.0.1

1 file

2.0.0

1 file

1.9.9

1 file

1.9.8

1 file

1.9.7

1 file

1.9.6

1 file

1.9.5

1 file

1.9.4

1 file

1.9.3

1 file

1.9.2

1 file

1.9.1

1 file

1.9.0

1 file

1.8.9

1 file

1.8.8

1 file

1.8.7

1 file

1.8.6

1 file

1.8.5

1 file

1.8.4

1 file

1.8.3

1 file

1.8.2

1 file

1.8.1

1 file

1.8.0

1 file

1.7.9

1 file

1.7.8

1 file

1.7.7

1 file

1.7.6

1 file

1.7.5

1 file

1.7.4

1 file

1.7.3

1 file

1.7.2

1 file

1.7.1

1 file

1.7.0

1 file

1.6.0

1 file

1.5.0

1 file

1.4.4

1 file

1.1.0

1 file

0.9

1 file

0.8

1 file

0.7

1 file

0.6

1 file

0.5

1 file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page