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/_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/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 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, }, ) 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,