From 39ccd8889f5f0b1621d4542404221bed9c15ef2e Mon Sep 17 00:00:00 2001 From: ashish-spext <115700058+ashish-spext@users.noreply.github.com> Date: Fri, 16 Jan 2026 09:48:38 +0530 Subject: [PATCH 1/2] Add rtstream namespace collection search --- videodb/collection.py | 66 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 62 insertions(+), 4 deletions(-) diff --git a/videodb/collection.py b/videodb/collection.py index 6cd6601..9f0db6b 100644 --- a/videodb/collection.py +++ b/videodb/collection.py @@ -13,7 +13,7 @@ from videodb.audio import Audio from videodb.image import Image from videodb.meeting import Meeting -from videodb.rtstream import RTStream +from videodb.rtstream import RTStream, RTStreamSearchResult, RTStreamShot from videodb.search import SearchFactory, SearchResult logger = logging.getLogger(__name__) @@ -427,7 +427,13 @@ def search( score_threshold: Optional[float] = None, dynamic_score_percentage: Optional[float] = None, filter: List[Dict[str, Any]] = [], - ) -> SearchResult: + namespace: Optional[str] = None, + scene_index_id: Optional[str] = None, + stitch: Optional[bool] = None, + rerank: Optional[bool] = None, + rerank_params: Optional[Dict[str, Any]] = None, + index_platform: Optional[str] = None, + ) -> Union[SearchResult, RTStreamSearchResult]: """Search for a query in the collection. :param str query: Query to search for @@ -436,10 +442,62 @@ def search( :param int result_threshold: Number of results to return (optional) :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 namespace: Search namespace (optional, "rtstream" to search RTStreams) + :param str scene_index_id: Filter by specific scene index (optional) + :param bool stitch: Merge adjacent results (optional) + :param bool rerank: Enable reranking (optional) + :param dict rerank_params: Reranking configuration (optional) + :param str index_platform: Vector index platform (optional) :raise SearchError: If the search fails - :return: :class:`SearchResult ` object - :rtype: :class:`videodb.search.SearchResult` + :return: :class:`SearchResult ` or + :class:`RTStreamSearchResult ` object + :rtype: Union[:class:`videodb.search.SearchResult`, + :class:`videodb.rtstream.RTStreamSearchResult`] """ + if namespace == "rtstream": + data = {"query": query} + if scene_index_id is not None: + data["scene_index_id"] = scene_index_id + if result_threshold is not None: + data["result_threshold"] = result_threshold + if score_threshold is not None: + data["score_threshold"] = score_threshold + if dynamic_score_percentage is not None: + data["dynamic_score_percentage"] = dynamic_score_percentage + if stitch is not None: + data["stitch"] = stitch + if filter is not None: + data["filter"] = filter + if rerank is not None: + data["rerank"] = rerank + if rerank_params is not None: + data["rerank_params"] = rerank_params + if index_platform is not None: + data["index_platform"] = index_platform + + search_data = self._connection.post( + path=f"{ApiPath.rtstream}/{ApiPath.collection}/{self.id}/{ApiPath.search}", + data=data, + ) + results = search_data.get("results", []) + shots = [ + RTStreamShot( + _connection=self._connection, + rtstream_id=result.get("rtstream_id") or result.get("id"), + rtstream_name=result.get("rtstream_name"), + start=result.get("start"), + end=result.get("end"), + text=result.get("text"), + search_score=result.get("score"), + scene_index_id=result.get("scene_index_id"), + scene_index_name=result.get("scene_index_name"), + metadata=result.get("metadata"), + ) + for result in results + ] + return RTStreamSearchResult(collection_id=self.id, shots=shots) + search = SearchFactory(self._connection).get_search(search_type) return search.search_inside_collection( collection_id=self.id, From b4e61394f8405dd97dc23b19ae8ecaba0a7f12c6 Mon Sep 17 00:00:00 2001 From: Rohit Garg Date: Fri, 16 Jan 2026 15:46:23 +0530 Subject: [PATCH 2/2] Remove stitch, rerank params from rtstream collection search Align collection.search(namespace="rtstream") with RTStream.search() by removing params not accepted by RTStream.search: stitch, rerank, rerank_params, and index_platform. --- videodb/collection.py | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/videodb/collection.py b/videodb/collection.py index 9f0db6b..9316fd0 100644 --- a/videodb/collection.py +++ b/videodb/collection.py @@ -429,10 +429,6 @@ def search( filter: List[Dict[str, Any]] = [], namespace: Optional[str] = None, scene_index_id: Optional[str] = None, - stitch: Optional[bool] = None, - rerank: Optional[bool] = None, - rerank_params: Optional[Dict[str, Any]] = None, - index_platform: Optional[str] = None, ) -> Union[SearchResult, RTStreamSearchResult]: """Search for a query in the collection. @@ -445,10 +441,6 @@ def search( :param list filter: Additional metadata filters (optional) :param str namespace: Search namespace (optional, "rtstream" to search RTStreams) :param str scene_index_id: Filter by specific scene index (optional) - :param bool stitch: Merge adjacent results (optional) - :param bool rerank: Enable reranking (optional) - :param dict rerank_params: Reranking configuration (optional) - :param str index_platform: Vector index platform (optional) :raise SearchError: If the search fails :return: :class:`SearchResult ` or :class:`RTStreamSearchResult ` object @@ -465,16 +457,8 @@ def search( data["score_threshold"] = score_threshold if dynamic_score_percentage is not None: data["dynamic_score_percentage"] = dynamic_score_percentage - if stitch is not None: - data["stitch"] = stitch if filter is not None: data["filter"] = filter - if rerank is not None: - data["rerank"] = rerank - if rerank_params is not None: - data["rerank_params"] = rerank_params - if index_platform is not None: - data["index_platform"] = index_platform search_data = self._connection.post( path=f"{ApiPath.rtstream}/{ApiPath.collection}/{self.id}/{ApiPath.search}",