Skip to content

Commit 17c81cb

Browse files
yeldarbyclaude
andcommitted
fix(cli): download shorthand now correctly handles project/version format
Replace _parse_url regex with resolve_resource() for non-URL shorthands. The regex couldn't disambiguate "project/version" from "workspace/project" when the second segment was numeric. Now uses the same resolver as all other commands, which checks if the last segment is numeric (version). Before: roboflow download test-detection/1 → workspace=test-detection, project=1 (WRONG) After: roboflow download test-detection/1 → workspace=default, project=test-detection, version=1 (CORRECT) Full URLs (https://universe.roboflow.com/...) still use the URL regex. All 4 download forms verified against staging: - project/version (shorthand) - project (picks latest) - workspace/project/version (full path) - Full URL 405 tests pass, all linting clean. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 246e6a6 commit 17c81cb

1 file changed

Lines changed: 21 additions & 12 deletions

File tree

roboflow/cli/handlers/version.py

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -161,19 +161,28 @@ def _get_version(args: argparse.Namespace) -> None:
161161

162162

163163
def _parse_url(url: str) -> tuple:
164-
"""Parse a Roboflow URL or shorthand into (workspace, project, version)."""
165-
regex = (
166-
r"(?:https?://)?(?:universe|app)\.roboflow\.(?:com|one)/([^/]+)/([^/]+)"
167-
r"(?:/dataset)?(?:/(\d+))?"
168-
r"|([^/]+)/([^/]+)(?:/(\d+))?"
169-
)
170-
match = re.match(regex, url)
164+
"""Parse a Roboflow URL or shorthand into (workspace, project, version).
165+
166+
Supports:
167+
- Full URLs: https://universe.roboflow.com/ws/proj/3
168+
- Three segments: ws/proj/3
169+
- Two segments: ws/proj OR proj/3 (numeric = version, uses default ws)
170+
- One segment: proj (uses default ws, no version)
171+
"""
172+
# Try full URL first
173+
url_regex = r"(?:https?://)?(?:universe|app)\.roboflow\.(?:com|one)/([^/]+)/([^/]+)(?:/dataset)?(?:/(\d+))?"
174+
match = re.match(url_regex, url)
171175
if match:
172-
organization = match.group(1) or match.group(4)
173-
dataset = match.group(2) or match.group(5)
174-
version = match.group(3) or match.group(6)
175-
return organization, dataset, version
176-
return None, None, None
176+
return match.group(1), match.group(2), match.group(3)
177+
178+
# Non-URL shorthand: use resolve_resource for proper disambiguation
179+
from roboflow.cli._resolver import resolve_resource
180+
181+
try:
182+
ws, proj, ver = resolve_resource(url, workspace_override=None)
183+
return ws, proj, str(ver) if ver is not None else None
184+
except ValueError:
185+
return None, None, None
177186

178187

179188
def _download(args: argparse.Namespace) -> None:

0 commit comments

Comments
 (0)