Skip to content

Releases: roboflow/roboflow-python

v1.3.7 — Soft-delete / Trash + workflow autowrap fix

29 Apr 04:09
d384863

Choose a tag to compare

Soft-delete / Trash support — SDK + CLI

Mirrors the soft-delete and Trash features added to the Roboflow web app (roboflow/roboflow#11131). Deleting a project, version, or workflow now moves it to Trash with a 30-day retention window (and cancels any in-flight training jobs); items can be restored within that window. Companion docs: roboflow-dev-reference#5.

SDK

  • Project.delete() — soft-deletes the project. Returns the server response.
  • Project.restore() — looks the project up in the workspace Trash by slug and restores it; raises RuntimeError if not currently in Trash.
  • Version.delete() / Version.restore() — same shape on a version handle.
  • Workspace.trash() — lists everything in a workspace's Trash, grouped by projects / versions / workflows. Returns the raw API payload (so you have access to parentId, parentUrl, scheduledCleanupAt, etc.).
  • Workspace.restore_from_trash(item_type, item_id, parent_id=None) — restores by id when you don't have a live SDK handle. item_type is "project", "version", or "workflow"; parent_id is required when restoring a version.
import roboflow
rf = roboflow.Roboflow(api_key="...")
ws = rf.workspace()

# Discover what's in Trash
trash = ws.trash()
for item in trash["items"]:
    print(item["type"], item["name"], "cleanup:", item["scheduledCleanupAt"])

# Restore a project you don't have a handle for
project_in_trash = trash["sections"]["projects"][0]
ws.restore_from_trash("project", project_in_trash["id"])

CLI

roboflow project delete <slug>      [--yes] [--json]
roboflow project restore <slug>     [--yes] [--json]
roboflow version delete <slug>/<v>  [--yes] [--json]
roboflow version restore <slug>/<v> [--yes] [--json]
roboflow workflow delete <url>      [--yes] [--json]
roboflow workflow restore <url>     [--yes] [--json]
roboflow trash list                 [--json]

Destructive commands prompt for confirmation interactively; pass --yes / -y for scripted use. Every command supports --json for structured output and emits actionable hints with stable exit codes (0 success, 1 error, 2 auth, 3 not-found).

Low-level (roboflow.adapters.rfapi)

New helpers: delete_project, delete_version, delete_workflow, list_trash, restore_trash_item. RoboflowError messages now extract the error field from JSON response bodies (e.g. "Not authorized to view trash") instead of returning raw response text.

Permanent deletion is intentionally web-UI-only

Emptying Trash and immediately deleting a single Trash item destroy data irrecoverably and live only in the Roboflow app's Trash view, which has an explicit confirmation dialog. Items left in Trash are cleaned up automatically after 30 days. Guard tests in this release ensure those actions stay off the SDK/CLI surface going forward.

Fixed — workflows created via SDK/CLI now execute successfully

Workspace.create_workflow() and roboflow workflow create --definition now auto-wrap bare workflow definitions in {"specification": ...} before POSTing to the backend, matching what the web app does (#460). Previously, the user-facing flat shape ({version, inputs, steps, outputs}) — the shape published in the Workflows docs — was sent verbatim, so executing the resulting workflow returned HTTP 502 with MalformedWorkflowResponseError: Workflow specification not found in Roboflow API response.

Workflows already wrapped (top-level specification key) are passed through unchanged. Non-workflow dicts and non-JSON strings are also passed through verbatim so custom payloads aren't second-guessed.

Workflows that were stored with the bare shape before this fix will still 502 until re-saved. Run roboflow workflow update <url> --definition <file> once per affected workflow to migrate.

Other changes

  • upload_image no longer re-encodes images client-side (#464) — uploads original bytes instead of round-tripping through JPEG.

Backward compatibility

Purely additive on the public API surface. The new endpoints require project:update, version:update, or workflow:update scopes — most existing keys already have these.

Action Required scope
project delete / project restore project:update
version delete / version restore version:update
workflow delete / workflow restore workflow:update
trash list project:read

Full diff: v1.3.6...v1.3.7

v1.3.6

27 Apr 21:27
7ad6093

Choose a tag to compare

What's Changed

  • fix: upload original image bytes instead of re-encoding to JPEG (ENT-1169) by @rvirani1 in #464
  • bump version to 1.3.6 by @rvirani1 in #466

Full Changelog: v1.3.5...v1.3.6

v1.3.5

23 Apr 18:31
68b6495

Choose a tag to compare

What's Changed

New Contributors

Full Changelog: v1.3.3...v1.3.5

v1.3.3 - Introducing roboflow-slim

15 Apr 18:52
4c093b8

Choose a tag to compare

New Features

Vision Events SDK & CLI (#451)

  • New SDK support for the Vision Events API: write single/batch events, query with pagination, list use cases, and upload images.
  • New roboflow vision-events CLI command group with subcommands: write, write-batch, query, use-cases, upload-image.
  • Thin-client design — no client-side validation, so new event types and fields work without a SDK update.

roboflow-slim package (#451)

  • New lightweight roboflow-slim install option for environments where PIL/OpenCV aren't needed (e.g. event ingestion pipelines, serverless functions).

Default inference URLs updated to Serverless V2 (#377)

  • Object detection and instance segmentation now default to serverless.roboflow.com instead of the legacy detect.roboflow.com / outline.roboflow.com endpoints.

Bug Fixes

  • Improved error messages when image upload fails with an unexpected error — now shows the filename and a clear "FAILED: Unknown error" instead of a cryptic 'str' object has no attribute 'get' traceback. (#450)

Chores

  • Pre-commit hook updates: bandit 1.9.3 → 1.9.4, ruff v0.15.2 → v0.15.10. (#443)

v1.3.1 - The CLI Rewrite: Built for Agents

03 Apr 21:48
a3c7eba

Choose a tag to compare

This release rewrites the Roboflow CLI from the ground up to serve as the canonical machine interface for the Roboflow platform. Every command now supports --json for structured output, follows a consistent noun verb pattern, and provides actionable error messages to make Roboflow accessible to coding agents, CI/CD pipelines, and automation workflows.

Highlights

🏗️ Modular CLI architecture — The monolithic CLI has been decomposed into 18 handler modules organized by resource (project, version, image, model, workspace, etc.), each with a clean noun-verb pattern. (#445)

📡 REST API feature parity — 22 new API adapter functions and corresponding CLI commands for folders, annotation batches/jobs, workflows, workspace stats, version creation, video status, and universe search. (#446)

⚡ Typer framework migration — Migrated from argparse to typer for Rich-formatted help, built-in shell completion, type-safe parameters, and consistency with the Roboflow Inference CLI. (#447)

New Commands

Group Commands
annotation batch list, get
annotation job list, get, create
folder list, create, delete
workflow list, get, create, update, version-list, fork
workspace stats team, usage, plan
version create Create new dataset versions from CLI
video status Check async video inference job status
universe search Search public datasets and models
model infer Run inference (canonical form of infer)
image search Unified workspace/project search with optional -p flag
completion bash, zsh, fish — shell completion scripts

Agent Experience (AX)

  • --json everywhere — Every command supports --json for structured output with a stable schema
  • Structured errors{"error": {"message": "...", "hint": "..."}} on stderr with exit codes (0=success, 1=error, 2=auth, 3=not found)
  • No interactive prompts when all required flags are provided
  • Actionable hints — Errors tell you what went wrong AND what to do next
  • Auto-detected plan limits — Plan-gated errors automatically suggest upgrade paths
  • API key sanitization — Credentials are stripped from error messages

Developer Experience (DX)

  • Rich-formatted help — Color-coded commands, options, and descriptions
  • Alphabetized commands and options at every level
  • Flattened top-level helproboflow --help shows all commands as noun verb in a single view
  • Shell completionroboflow completion bash/zsh/fish generates completion scripts

SDK Additions

  • Workspace.list_folders(), create_folder(), delete_folder()
  • Workspace.get_team_stats(), get_usage_stats(), get_plan_info()
  • Project.list_batches(), get_batch(), list_jobs(), get_job(), create_job()
  • Project.list_workflows(), get_workflow(), create_workflow(), update_workflow()
  • Workspace.delete_image() (#442)
  • Key-value metadata support for image upload (#440)
  • Search export with download and extraction (#439)

Breaking Changes

  • Python 3.9 dropped — Minimum version is now Python 3.10+
  • typer>=0.12.0 added as a dependency (replaces argparse for CLI)

Backwards Compatibility

All legacy CLI commands and flags continue to work. The old roboflow upload, roboflow download, roboflow login forms are preserved as hidden aliases. Scripts importing from roboflow.roboflowpy remain functional.

Other Changes

  • Added confidence argument to keypoint detection model (#354)
  • Added large RF-DETR sizes and segmentation model upload (#434)
  • Flexible annotation/image filename matching (#417)
  • Project.delete_images() method (#424)
  • Configurable training epochs (#420)
  • Pre-commit hooks updated (#387)

Full Changelog: v1.2.16...v1.3.1

Workspace level new methods

03 Mar 11:33
257423d

Choose a tag to compare

At the workspace level you can now search and delete images.

Sample code using both:


"""Delete all orphan images matching a workspace-level search query.

Usage:
    python tests/manual/demo_search_delete.py
"""

from roboflow import Roboflow

QUERY = "project:false"
PAGE_SIZE = 100
DELETE_BATCH_SIZE = 1000
DRY_RUN = False  # set to False to actually delete

WORKSPACE_SLUG = "workspace"


def main():
    rf = Roboflow()
    workspace = rf.workspace(WORKSPACE_SLUG)

    print(f"Workspace: {workspace.url}")
    print(f"Query: {QUERY}")
    print(f"Dry run: {DRY_RUN}")
    print()

    # Collect all matching image IDs.
    # When deleting (not dry run), skip continuation tokens because deleted
    # images shift the result set — always re-search from page 1.
    all_ids = []
    token = None
    while True:
        page = workspace.search(
            QUERY,
            page_size=PAGE_SIZE,
            fields=["filename"],
            continuation_token=token,
        )
        results = page.get("results", [])
        if not results:
            break
        total = page.get("total", "?")
        all_ids.extend(img["id"] for img in results)
        print(f"Found {len(all_ids)}/{total} images so far...")
        token = page.get("continuationToken")
        if not token:
            break

    print(f"\nTotal images matching '{QUERY}': {len(all_ids)}")

    if not all_ids:
        print("Nothing to delete.")
        return

    if DRY_RUN:
        print("\n[DRY RUN] Would delete the above images. Set DRY_RUN=False to proceed.")
        return

    for i in range(0, len(all_ids), DELETE_BATCH_SIZE):
        batch = all_ids[i : i + DELETE_BATCH_SIZE]
        print(f"Deleting batch {i // DELETE_BATCH_SIZE + 1} ({len(batch)} images)...")
        result = workspace.delete_images(batch)
        print(f"  deleted={result.get('deletedSources')}, skipped={result.get('skippedSources')}")

    print(f"\nDone. Deleted {len(all_ids)} images.")


if __name__ == "__main__":
    main()

1.2.15 - Upload images with metadata

25 Feb 17:10
1eb8238

Choose a tag to compare

We now make it available to the python sdk to upload metadata when starting upload

Export search results functionality

18 Feb 14:21
7fee9f4

Choose a tag to compare

We provide a new method to export images and annotations based on search queries.
It replicates the Asset Library Download functionality on the CLI.

RFDETR large and seg models upload

23 Jan 23:51
4e4d79f

Choose a tag to compare

Includes model upload for new rf-detr models.
pi_heif discontinued Python3.9 support, so this is handled in the release as well.

Add yolo26 upload

15 Jan 10:03
0596010

Choose a tag to compare

Users can now upload yolo26 models from ultralytics 8.4.1 or higher