Skip to main content

labeltify

Upload frames, and optionally their annotations, into LabelTify from DeepStream, OpenCV, Ultralytics, or any Python pipeline. The only thing it needs is a pipeline token.

pip install labeltify
  1. On the dataset Upload page, create a pipeline token.
  2. Upload:
from labeltify import LabelTifyClient

client = LabelTifyClient("labeltify_…")  # or set LABELTIFY_TOKEN and call LabelTifyClient()

img = client.upload_image(
    "DATASET_ID",
    jpeg_bytes,
    filename="cam01.jpg",
    camera="cam-01",
    pipeline="ds-prod",
    trigger="low_confidence",
)
client.upload_file("DATASET_ID", "frames/cam02.jpg", camera="cam-02")

The token knows its org, so you don't pass one. Timeouts, 429, and 5xx responses are retried with exponential backoff (max_retries=4 by default). Anything else raises LabelTifyError with the API's message and .status.

Annotations are optional. When you pass labels (COCO, LabelTify, or YOLO JSON bytes), work_state is required: done, in_progress, unsure, or untouched. There is no default; the client raises LabelTifyError before sending if it is missing. Images with no labels stay untouched.

Upload a folder with its annotations

report = client.upload_directory(
    "DATASET_ID",
    "datasets/parking",
    work_state="done",
)
print(len(report["items"]), "images stored in", report["requests"], "requests;", report["imported"])

This sends the folder the way dropping it on the dataset's Upload page would: images, plus COCO (polygons and boxes), YOLO (labels/*.txt with data.yaml or classes.txt), Pascal VOC, LabelMe, CSV, metadata.jsonl, a folder per class, or a LabelTify export. The server reads the annotations; the client only splits the folder into requests (at most 100 images and 80 MB each). A COCO file is cut down to each request's images, so polygons stay polygons.

  • The dataset must already exist. Create it on the site. Parking polygons need type Instance segmentation. Traffic boxes need Object detection.
  • work_state="done" marks every image that received a shape. Images with no shape stay untouched. With any label file in the folder, work_state is required.
  • Create the pipeline token on that dataset's Upload page.
  • One credit covers 10,000 uploaded images. A free dataset holds 100 photos.
  • Frame embeddings follow the dataset setting. Turn them off on the dataset before a large upload when you do not want that charge.
  • Use the portable pixel COCO files. The raw Studio shards store boxes as fractions from 0 to 1, and the server divides by width and height again.
  • Two images with the same file name in different folders stop the upload before anything is sent; rename one.
  • Images over 20 MiB, empty files, and files that are neither images nor annotations are listed in report["files"] and not sent. A zip is sent as it is when it holds at most 200 files and 20 MB; unzip anything bigger.
  • If a request fails after its retries, the error says how many images were already stored; run the folder again and exact duplicates are reported instead of stored twice.
  • compute_dhash=True also skips near-duplicate frames, like the Upload page. It needs Pillow: pip install "labeltify[images]".

upload_bundle(dataset_id, files, work_state=…) sends one such request from bytes you already have (files is a list of {"filename", "data", "content_type"}).

A deployment behind an access proxy can take extra headers on every request: LabelTifyClient(token, base_url=…, headers={"CF-Access-Client-Id": …, "CF-Access-Client-Secret": …}).

Send model proposals to the Loop review queue:

client.propose(
    "DATASET_ID",
    img["id"],
    [{"type": "bbox", "id": "p1", "classId": "car", "box": {"x": 0.1, "y": 0.1, "w": 0.2, "h": 0.2}, "source": "model", "confidence": 0.4}],
    model_ref="deepstream@1",
    uncertainty=0.8,
)

Boxes are normalized [0,1]. Camera, pipeline, and trigger are stored on the image so Loop can filter by them.

Local API: LabelTifyClient("labeltify_…", base_url="http://localhost:8787").

Develop

pip install -e "clients/python[test]"
pytest clients/python/tests

Bump version in pyproject.toml to publish. Each new version that lands on main is published to PyPI by .github/workflows/publish-python.yml.

Metadata

Release files for labeltify 0.4.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for labeltify 0.4.0
File Size Uploaded
labeltify-0.4.0.tar.gz 18.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for labeltify 0.4.0
File Interpreter ABI Platform
labeltify-0.4.0-py3-none-any.whl Python 3 none any Details

Total release size: 31.1 kB

Release files / labeltify-0.4.0.tar.gz

Download URL labeltify-0.4.0.tar.gz
Size 18.5 kB
Tags Source
SHA-256 checksum
How to use checksums
fc1a4766e4a6a4907f478b9c11f3d71c3bd1b77ef986fbdaf5238db6310d9f0e
BLAKE2b-256 checksum
How to use checksums
03718add50256dc1d66593629126106653d9704a48f97a744e5a6875bc0123f1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.12.15

Release files / labeltify-0.4.0-py3-none-any.whl

Download URL labeltify-0.4.0-py3-none-any.whl
Size 12.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
28038fe7a4c0aaa1addef3a328ce9c5a602c3adb20a99c860b77ede41e56436c
BLAKE2b-256 checksum
How to use checksums
f962482063dd237271f3159a23fafb35aa21c0cf66af05ba1719a0964f6ea91b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.12.15

Release history Release notifications | RSS feed

0.4.1

2 release files

This release

0.4.0 This release

2 release files

0.3.0

2 release files

0.2.0

2 release files

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