Open
Conversation
Adds project and version lifecycle management mirroring the soft-delete and Trash features that just landed in the web app. Projects and versions are moved to Trash on delete (30-day retention) and can be restored within the retention window; any in-flight training jobs are cancelled automatically on the server. New rfapi functions: - delete_project, delete_version - list_trash, restore_trash_item - trash_delete_immediately, empty_trash New SDK methods: - Project.delete(), Project.restore() - Version.delete(), Version.restore() - Workspace.trash(), Workspace.restore_from_trash(), Workspace.delete_from_trash(), Workspace.empty_trash() New CLI commands: - roboflow project delete / restore - roboflow version delete / restore - roboflow trash list / empty / delete All existing tests pass; new commands have --yes / -y to skip the confirmation prompt for scripted use. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- CLI-COMMANDS.md: new "Delete and restore" section covering project, version, and trash commands; added `trash` to the command-groups table. - tests/cli/test_project_handler.py: registration + delete/restore unit tests. - tests/cli/test_version_handler.py: registration + delete/restore unit tests (including the parent-project disambiguation lookup). - tests/cli/test_trash_handler.py: full coverage for list/empty/delete commands with mocked rfapi. SDK-side (`docs/core/*.md`) is auto-generated via mkdocstrings from docstrings, so no changes needed there — the new methods are already documented via their docstrings. 479 tests pass (20 new), ruff clean. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Permanent deletion destroys data irrecoverably. Exposing it on the public API — and through the SDK/CLI that wraps it — makes it one stray curl or for-loop away from catastrophe, with no undo. It stays available only in the web UI's Trash view, which has an explicit confirmation dialog; items left in Trash are cleaned up automatically after 30 days either way. Removed: - rfapi.trash_delete_immediately(), rfapi.empty_trash() - Workspace.delete_from_trash(), Workspace.empty_trash() - roboflow trash empty, roboflow trash delete commands - Corresponding tests (replaced with guard tests that fail if the permanent-delete surface is ever re-added by accident) - CLI-COMMANDS.md references Kept (soft-delete + restore + list only): - Project.delete() / Project.restore() - Version.delete() / Version.restore() - Workspace.trash() / Workspace.restore_from_trash() - roboflow project delete|restore - roboflow version delete|restore - roboflow trash list Paired with the corresponding backend removal in roboflow/roboflow#11131 — the public REST API no longer exposes POST /:ws/trash/deleteImmediately or POST /:ws/trash/empty. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
CONTRIBUTING.md's Agent Experience checklist asks that every
output_error() include an actionable hint. The delete/restore/list
commands shipped with hints on some paths but not others. Fills in
the gaps so agents get a consistent "what went wrong AND what to do"
pair on every failure:
- resolver ValueError: tell them the valid shorthand formats
- API RoboflowError: point at the specific scope that's likely missing
('project:update' / 'version:update' / 'project:read')
- 'not in trash' on version restore: additionally note that a parent
project in trash must be restored first
No behavior change — same error paths, same exit codes, same JSON
schema. Just more useful text.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The delete_project() docstring still mentioned trash_delete_immediately as a follow-on action, but that helper was removed. Replace with a note about the 30-day cleanup cron so the lifecycle is documented without pointing at a symbol that doesn't exist. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Mirrors delete_project() / delete_version() — wraps DELETE /:workspace/workflows/:workflowUrl on the public API (added in the paired backend PR). Workflow restore was already available via restore_trash_item(..., \"workflow\", ...) through the generic trash endpoint, so this closes the symmetry gap. Intentionally not adding Workflow.delete() / .restore() SDK methods or a `roboflow workflow delete|restore` CLI subcommand in this PR — there is no Workflow handle object in the SDK yet, and adding that is significant scope. Agents/scripts that want workflow lifecycle control can call rfapi.delete_workflow() and Workspace.restore_from_trash() directly. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Completes the CLI surface for soft-delete — workflows now have the same delete/restore subcommands as projects and versions. Both commands: - call rfapi.delete_workflow / rfapi.restore_trash_item under the hood (the public API endpoints added in the paired backend PR) - honor --json for structured output - honor --yes / -y on delete to skip the confirmation prompt for scripted use - emit output_error(..., hint=..., exit_code=N) with actionable hints per the Agent Experience checklist: which scope to check, what to run to see what's in Trash, etc. - accept either the workflow URL slug (e.g. slow-webhooks) or its Firestore id (e.g. wf_abc123) on restore Restore looks the workflow up in the workspace Trash by URL (falling back to id), just like project/version restore. CLI-COMMANDS.md gets a one-line update in the "Delete and restore" section. 485 tests pass (6 new: 2 registration + 4 handler). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds project and version lifecycle management mirroring the soft-delete and Trash features added to the web app in roboflow/roboflow#11131. Deleting a project or version now moves it to Trash (30-day retention) and cancels any in-flight training jobs on it; items can be restored within the retention window.
Project.delete()/Project.restore()Version.delete()/Version.restore()Workspace.trash(),Workspace.restore_from_trash()roboflow project delete|restore,roboflow version delete|restore,roboflow trash listDetails
New rfapi functions (
roboflow/adapters/rfapi.py):delete_project(api_key, workspace_url, project_url)—DELETE /:workspace/:projectdelete_version(api_key, workspace_url, project_url, version)—DELETE /:workspace/:project/:versionlist_trash(api_key, workspace_url)—GET /:workspace/trashrestore_trash_item(api_key, workspace_url, item_type, item_id, parent_id=None)—POST /:workspace/trash/restoreSDK methods —
Project.delete()returns the server response.Project.restore()looks the project up by slug in the workspace Trash and restores it (raisesRuntimeErrorif not found). Same shape forVersion. For scripts without a live handle,Workspace.trash()returns the list of items andWorkspace.restore_from_trash(type, id, parent_id)restores by id.CLI commands — destructive commands (
project delete,version delete) prompt for confirmation interactively and accept--yes/-yfor scripted use. All commands honor--jsonfor structured output and useoutput_error()with actionable hints on every error path (per the Agent Experience checklist inCONTRIBUTING.md).Permanent deletion is intentionally web-UI-only
Emptying Trash or immediately deleting a single Trash item destroys data irrecoverably, so it's not exposed on the SDK or CLI — those actions 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 ensure
rfapi.trash_delete_immediately,rfapi.empty_trash,Workspace.delete_from_trash,Workspace.empty_trash,roboflow trash empty, androboflow trash deletestay off the SDK/CLI surface going forward.Backward compatibility
Purely additive — no existing APIs changed. The new routes require
project:update(for projects) orversion:update(for versions) scopes, which most existing keys already have.Test plan
python -m unittest) — 20 new tests covering project / version / trash CLI handlers and guard tests for the removed permanent-delete surfaceruff check+ruff format --checkclean on all new/modified filesmypy roboflowcleantest_soft_delete_flow.py, in-tree but untracked) drives the CLI through delete project → restore project → delete version → restore version, with real HTTP round-trips tolocalapi.roboflow.one--helpoutput lists the new commands (roboflow project --help,roboflow version --help,roboflow trash --help)CONTRIBUTING.md:--json, no interactive prompts when--yes/--jsonset,output_error(..., hint=..., exit_code=N)on every failure path, exit codes0/1/2/3Dependencies
Blocked on the backend soft-delete PR: roboflow/roboflow#11131. That PR adds the server-side endpoints this SDK calls. Do not merge this until that one is in prod.
Companion docs PR
roboflow/roboflow-dev-reference#5 — CLI, REST API, and Python SDK docs pages for the new flow.
🤖 Generated with Claude Code