From e57ef0dbca30878081572137c1e47d3d87243472 Mon Sep 17 00:00:00 2001 From: Rohit Garg Date: Tue, 24 Mar 2026 21:00:25 +0530 Subject: [PATCH 1/3] sort_docs_on for videodb search --- videodb/_constants.py | 1 + videodb/collection.py | 3 +++ videodb/search.py | 2 ++ 3 files changed, 6 insertions(+) diff --git a/videodb/_constants.py b/videodb/_constants.py index 287b10e..b546fab 100644 --- a/videodb/_constants.py +++ b/videodb/_constants.py @@ -49,6 +49,7 @@ class ReframeMode: class SemanticSearchDefaultValues: result_threshold = 5 score_threshold = 0.2 + sort_docs_on = None class Segmenter: diff --git a/videodb/collection.py b/videodb/collection.py index 2ca76d6..04c8d05 100644 --- a/videodb/collection.py +++ b/videodb/collection.py @@ -468,6 +468,7 @@ def search( score_threshold: Optional[float] = None, dynamic_score_percentage: Optional[float] = None, filter: List[Dict[str, Any]] = [], + sort_docs_on: Optional[str] = None, namespace: Optional[str] = None, scene_index_id: Optional[str] = None, ) -> Union[SearchResult, RTStreamSearchResult]: @@ -480,6 +481,7 @@ def search( :param float score_threshold: Threshold score for the search (optional) :param float dynamic_score_percentage: Percentage of dynamic score to consider (optional) :param list filter: Additional metadata filters (optional) + :param str sort_docs_on: Sort docs within each video by "score" or "start" (optional) :param str namespace: Search namespace (optional, "rtstream" to search RTStreams) :param str scene_index_id: Filter by specific scene index (optional) :raise SearchError: If the search fails @@ -532,6 +534,7 @@ def search( result_threshold=result_threshold, score_threshold=score_threshold, dynamic_score_percentage=dynamic_score_percentage, + sort_docs_on=sort_docs_on, filter=filter, ) diff --git a/videodb/search.py b/videodb/search.py index f2b9207..4fea368 100644 --- a/videodb/search.py +++ b/videodb/search.py @@ -157,6 +157,7 @@ def search_inside_collection( result_threshold: Optional[int] = None, score_threshold: Optional[float] = None, dynamic_score_percentage: Optional[float] = None, + sort_docs_on: Optional[str] = SemanticSearchDefaultValues.sort_docs_on, **kwargs, ): search_data = self._connection.post( @@ -172,6 +173,7 @@ def search_inside_collection( if result_threshold is not None else SemanticSearchDefaultValues.result_threshold, "dynamic_score_percentage": dynamic_score_percentage, + "sort_docs_on": sort_docs_on, **kwargs, }, ) From b2297bbe2836ffdd43e199af274ede570a0eb9ef Mon Sep 17 00:00:00 2001 From: Rohit Garg Date: Wed, 25 Mar 2026 21:00:42 +0530 Subject: [PATCH 2/3] model_config support in scene.describe() method --- videodb/scene.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/videodb/scene.py b/videodb/scene.py index 41ef669..7bd651a 100644 --- a/videodb/scene.py +++ b/videodb/scene.py @@ -1,4 +1,4 @@ -from typing import List +from typing import Dict, List, Optional from videodb._constants import ApiPath @@ -59,11 +59,17 @@ def to_json(self): "metadata": self.metadata, } - def describe(self, prompt: str = None, model_name=None) -> None: + def describe( + self, + prompt: Optional[str] = None, + model_name: Optional[str] = None, + model_config: Optional[Dict] = None, + ) -> None: """Describe the scene. :param str prompt: (optional) The prompt to use for the description :param str model_name: (optional) The model to use for the description + :param dict model_config: (optional) The model configuration for the description :return: The description of the scene :rtype: str """ @@ -71,7 +77,11 @@ def describe(self, prompt: str = None, model_name=None) -> None: raise ValueError("Connection is required to describe a scene") description_data = self._connection.post( path=f"{ApiPath.video}/{self.video_id}/{ApiPath.scene}/{self.id}/{ApiPath.describe}", - data={"prompt": prompt, "model_name": model_name}, + data={ + "prompt": prompt, + "model_name": model_name, + "model_config": model_config, + }, ) self.description = description_data.get("description", None) return self.description From ed8311d865f313bbd4c2002e5cbe9885034eac08 Mon Sep 17 00:00:00 2001 From: Lalit Gupta Date: Thu, 26 Mar 2026 00:50:53 +0530 Subject: [PATCH 3/3] feat: add video.update() method, bump version to 0.4.4, capture-bin>=0.3.0 - Add Video.update(name=) method to update video metadata - Bump version to 0.4.4 - Update capture binary requirement to >=0.3.0 --- setup.py | 2 +- videodb/__about__.py | 2 +- videodb/video.py | 17 +++++++++++++++++ 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index efa1423..6cf5171 100644 --- a/setup.py +++ b/setup.py @@ -39,7 +39,7 @@ "websockets>=11.0.3", ], extras_require={ - "capture": ["videodb-capture-bin>=0.2.10"], + "capture": ["videodb-capture-bin>=0.3.0"], }, classifiers=[ "Intended Audience :: Developers", diff --git a/videodb/__about__.py b/videodb/__about__.py index 0cdd560..ddfe2be 100644 --- a/videodb/__about__.py +++ b/videodb/__about__.py @@ -2,7 +2,7 @@ -__version__ = "0.4.3" +__version__ = "0.4.4" __title__ = "videodb" __author__ = "videodb" __email__ = "contact@videodb.io" diff --git a/videodb/video.py b/videodb/video.py index 367ba87..20996cd 100644 --- a/videodb/video.py +++ b/videodb/video.py @@ -63,6 +63,23 @@ def __repr__(self) -> str: def __getitem__(self, key): return self.__dict__[key] + def update(self, name: Optional[str] = None) -> None: + """Update the video's metadata. + + :param str name: (optional) New name for the video + """ + data = {} + if name is not None: + data["name"] = name + if not data: + return + response_data = self._connection.patch( + path=f"{ApiPath.video}/{self.id}", + data=data, + ) + if name is not None: + self.name = response_data.get("name", name) + def search( self, query: str,