Skip to content

Commit 49fa491

Browse files
committed
fix: search and vision interface
1 parent 62a7bc5 commit 49fa491

File tree

5 files changed

+43
-13
lines changed

5 files changed

+43
-13
lines changed

videodb/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from videodb._utils._video import play_stream
88
from videodb._constants import (
99
VIDEO_DB_API,
10+
IndexType,
1011
SceneExtractionType,
1112
MediaType,
1213
SearchType,
@@ -30,6 +31,7 @@
3031
"VideodbError",
3132
"AuthenticationError",
3233
"InvalidRequestError",
34+
"IndexType",
3335
"SearchError",
3436
"play_stream",
3537
"MediaType",

videodb/_constants.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,12 @@ class SearchType:
1818

1919

2020
class IndexType:
21-
semantic = "semantic"
21+
spoken = "spoken"
2222
scene = "scene"
2323

2424

2525
class SceneExtractionType:
26-
scene_based = "scene"
26+
shot_based = "shot"
2727
time_based = "time"
2828

2929

videodb/collection.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
)
1111
from videodb._constants import (
1212
ApiPath,
13+
IndexType,
1314
SearchType,
1415
)
1516
from videodb.video import Video
@@ -100,6 +101,7 @@ def search(
100101
self,
101102
query: str,
102103
search_type: Optional[str] = SearchType.semantic,
104+
index_type: Optional[str] = IndexType.spoken,
103105
result_threshold: Optional[int] = None,
104106
score_threshold: Optional[float] = None,
105107
dynamic_score_percentage: Optional[float] = None,
@@ -108,6 +110,8 @@ def search(
108110
return search.search_inside_collection(
109111
collection_id=self.id,
110112
query=query,
113+
search_type=search_type,
114+
index_type=index_type,
111115
result_threshold=result_threshold,
112116
score_threshold=score_threshold,
113117
dynamic_score_percentage=dynamic_score_percentage,

videodb/search.py

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from abc import ABC, abstractmethod
22
from videodb._utils._video import play_stream
33
from videodb._constants import (
4+
IndexType,
45
SearchType,
56
ApiPath,
67
SemanticSearchDefaultValues,
@@ -109,6 +110,8 @@ def search_inside_video(
109110
self,
110111
video_id: str,
111112
query: str,
113+
search_type: str,
114+
index_type: str,
112115
result_threshold: Optional[int] = None,
113116
score_threshold: Optional[float] = None,
114117
dynamic_score_percentage: Optional[float] = None,
@@ -117,7 +120,8 @@ def search_inside_video(
117120
search_data = self._connection.post(
118121
path=f"{ApiPath.video}/{video_id}/{ApiPath.search}",
119122
data={
120-
"index_type": SearchType.semantic,
123+
"search_type": search_type,
124+
"index_type": index_type,
121125
"query": query,
122126
"score_threshold": score_threshold
123127
or SemanticSearchDefaultValues.score_threshold,
@@ -133,6 +137,8 @@ def search_inside_collection(
133137
self,
134138
collection_id: str,
135139
query: str,
140+
search_type: str,
141+
index_type: str,
136142
result_threshold: Optional[int] = None,
137143
score_threshold: Optional[float] = None,
138144
dynamic_score_percentage: Optional[float] = None,
@@ -141,7 +147,8 @@ def search_inside_collection(
141147
search_data = self._connection.post(
142148
path=f"{ApiPath.collection}/{collection_id}/{ApiPath.search}",
143149
data={
144-
"index_type": SearchType.semantic,
150+
"search_type": search_type,
151+
"index_type": index_type,
145152
"query": query,
146153
"score_threshold": score_threshold
147154
or SemanticSearchDefaultValues.score_threshold,
@@ -162,6 +169,8 @@ def search_inside_video(
162169
self,
163170
video_id: str,
164171
query: str,
172+
search_type: str,
173+
index_type: str,
165174
result_threshold: Optional[int] = None,
166175
score_threshold: Optional[float] = None,
167176
dynamic_score_percentage: Optional[float] = None,
@@ -170,7 +179,8 @@ def search_inside_video(
170179
search_data = self._connection.post(
171180
path=f"{ApiPath.video}/{video_id}/{ApiPath.search}",
172181
data={
173-
"index_type": SearchType.keyword,
182+
"search_type": search_type,
183+
"index_type": index_type,
174184
"query": query,
175185
"score_threshold": score_threshold,
176186
"result_threshold": result_threshold,
@@ -190,6 +200,8 @@ def search_inside_video(
190200
self,
191201
video_id: str,
192202
query: str,
203+
search_type: str,
204+
index_type: str,
193205
result_threshold: Optional[int] = None,
194206
score_threshold: Optional[float] = None,
195207
dynamic_score_percentage: Optional[float] = None,
@@ -198,7 +210,8 @@ def search_inside_video(
198210
search_data = self._connection.post(
199211
path=f"{ApiPath.video}/{video_id}/{ApiPath.search}",
200212
data={
201-
"index_type": SearchType.scene,
213+
"search_type": search_type,
214+
"index_type": IndexType.scene,
202215
"query": query,
203216
"score_threshold": score_threshold,
204217
"result_threshold": result_threshold,

videodb/video.py

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ def search(
4949
self,
5050
query: str,
5151
search_type: Optional[str] = SearchType.semantic,
52+
index_type: Optional[str] = IndexType.spoken,
5253
result_threshold: Optional[int] = None,
5354
score_threshold: Optional[float] = None,
5455
dynamic_score_percentage: Optional[float] = None,
@@ -58,6 +59,8 @@ def search(
5859
return search.search_inside_video(
5960
video_id=self.id,
6061
query=query,
62+
search_type=search_type,
63+
index_type=index_type,
6164
result_threshold=result_threshold,
6265
score_threshold=score_threshold,
6366
dynamic_score_percentage=dynamic_score_percentage,
@@ -152,7 +155,7 @@ def index_spoken_words(
152155
self._connection.post(
153156
path=f"{ApiPath.video}/{self.id}/{ApiPath.index}",
154157
data={
155-
"index_type": IndexType.semantic,
158+
"index_type": IndexType.spoken,
156159
"language_code": language_code,
157160
"force": force,
158161
"callback_url": callback_url,
@@ -207,11 +210,11 @@ def _format_scene_collection(self, scene_collection_data: dict) -> SceneCollecti
207210

208211
def extract_scenes(
209212
self,
210-
extraction_type: SceneExtractionType = SceneExtractionType.scene_based,
213+
extraction_type: SceneExtractionType = SceneExtractionType.shot_based,
211214
extraction_config: dict = {},
212215
force: bool = False,
213216
callback_url: str = None,
214-
):
217+
) -> Optional[SceneCollection]:
215218
scenes_data = self._connection.post(
216219
path=f"{ApiPath.video}/{self.id}/{ApiPath.scenes}",
217220
data={
@@ -225,10 +228,14 @@ def extract_scenes(
225228
return None
226229
return self._format_scene_collection(scenes_data.get("scene_collection"))
227230

228-
def get_scene_collection(self, collection_id: str):
231+
def get_scene_collection(self, collection_id: str) -> Optional[SceneCollection]:
232+
if not collection_id:
233+
raise ValueError("collection_id is required")
229234
scenes_data = self._connection.get(
230235
path=f"{ApiPath.video}/{self.id}/{ApiPath.scenes}/{collection_id}"
231236
)
237+
if not scenes_data:
238+
return None
232239
return self._format_scene_collection(scenes_data.get("scene_collection"))
233240

234241
def list_scene_collection(self):
@@ -238,13 +245,15 @@ def list_scene_collection(self):
238245
return scene_collections_data.get("scene_collections", [])
239246

240247
def delete_scene_collection(self, collection_id: str) -> None:
248+
if not collection_id:
249+
raise ValueError("collection_id is required")
241250
self._connection.delete(
242251
path=f"{ApiPath.video}/{self.id}/{ApiPath.scenes}/{collection_id}"
243252
)
244253

245254
def index_scenes(
246255
self,
247-
extraction_type: SceneExtractionType = SceneExtractionType.scene_based,
256+
extraction_type: SceneExtractionType = SceneExtractionType.shot_based,
248257
extraction_config: Dict = {},
249258
prompt: Optional[str] = None,
250259
model: Optional[str] = None,
@@ -253,7 +262,7 @@ def index_scenes(
253262
scenes: Optional[List[Scene]] = None,
254263
force: Optional[bool] = False,
255264
callback_url: Optional[str] = None,
256-
) -> Optional[List]:
265+
) -> Optional[str]:
257266
scenes_data = self._connection.post(
258267
path=f"{ApiPath.video}/{self.id}/{ApiPath.index}/{ApiPath.scene}",
259268
data={
@@ -270,7 +279,7 @@ def index_scenes(
270279
)
271280
if not scenes_data:
272281
return None
273-
return scenes_data.get("scene_index_records", [])
282+
return scenes_data.get("scene_index_id")
274283

275284
def list_scene_index(self) -> List:
276285
index_data = self._connection.get(
@@ -287,6 +296,8 @@ def get_scene_index(self, scene_index_id: str) -> Optional[List]:
287296
return index_data.get("scene_index_records", [])
288297

289298
def delete_scene_index(self, scene_index_id: str) -> None:
299+
if not scene_index_id:
300+
raise ValueError("scene_index_id is required")
290301
self._connection.delete(
291302
path=f"{ApiPath.video}/{self.id}/{ApiPath.index}/{ApiPath.scene}/{scene_index_id}"
292303
)

0 commit comments

Comments
 (0)