Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

All notable changes to this project will be documented in this file.

## Unreleased
## 1.3.9

### Added — Model evaluations SDK & CLI

Expand Down Expand Up @@ -45,6 +45,12 @@ The endpoints require the `model-eval:read` scope. The base URL is
configurable via `API_URL` (set to `https://localapi.roboflow.one` to
test against a local API server).

### Fixed
- rf-detr model upload: accept checkpoints whose `args` is a plain dict (e.g. EMA checkpoints) when extracting class names, instead of raising `TypeError` from `vars()`.

### Changed
- Pin `typer<0.26` and declare `click` explicitly: typer 0.26 vendors its own click and drops the external dependency, which broke the CLI and its type checks.

## 1.3.7

### Added — Soft-delete / Trash support
Expand Down
3 changes: 2 additions & 1 deletion requirements-slim.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ tqdm>=4.41.0
PyYAML>=5.3.1
requests_toolbelt
filetype
typer>=0.12.0
typer>=0.12.0,<0.26 # 0.26 vendors click, dropping the external dep the CLI imports
click>=8.0
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CI broken without this

python-dateutil
python-dotenv
six
3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,5 @@ tqdm>=4.41.0
PyYAML>=5.3.1
requests_toolbelt
filetype
typer>=0.12.0
typer>=0.12.0,<0.26 # 0.26 vendors click, dropping the external dep the CLI imports
click>=8.0
4 changes: 3 additions & 1 deletion roboflow/util/model_processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,9 @@ def get_classnames_txt_for_rfdetr(model_path: str, pt_file: str, checkpoint=None
import torch

checkpoint = torch.load(os.path.join(model_path, pt_file), map_location="cpu", weights_only=False)
args = vars(checkpoint["args"])
raw_args = checkpoint["args"]
# args may be a plain dict in some checkpoints
args = raw_args if isinstance(raw_args, dict) else vars(raw_args)
if "class_names" in args:
with open(class_names_path, "w") as f:
for class_name in args["class_names"]:
Expand Down
20 changes: 20 additions & 0 deletions tests/util/test_model_processor.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import os
import tempfile
import unittest
from types import SimpleNamespace

from roboflow.config import TASK_CLS, TASK_DET, TASK_OBB, TASK_POSE, TASK_SEG
from roboflow.util.model_processor import (
_detect_rfdetr_task,
_detect_yolo_task,
get_classnames_txt_for_rfdetr,
task_of_model_type,
)

Expand Down Expand Up @@ -84,5 +87,22 @@ def test_unrecognized_returns_none(self):
self.assertIsNone(_detect_rfdetr_task({"args": SimpleNamespace(other=1)}))


class GetClassnamesTxtForRfdetrTest(unittest.TestCase):
def _classnames(self, args):
with tempfile.TemporaryDirectory() as model_path:
get_classnames_txt_for_rfdetr(model_path, "weights.pt", checkpoint={"args": args})
with open(os.path.join(model_path, "class_names.txt")) as f:
return f.read().splitlines()

def test_dict_args(self):
self.assertEqual(self._classnames({"class_names": ["cat", "dog"]}), ["background_class83422", "cat", "dog"])

def test_namespace_args(self):
self.assertEqual(
self._classnames(SimpleNamespace(class_names=["cat", "dog"])),
["background_class83422", "cat", "dog"],
)


if __name__ == "__main__":
unittest.main()
Loading