8000 Ankit/add collection crud by ankit-v2-3 · Pull Request #15 · video-db/videodb-python · GitHub
[go: up one dir, main page]

Skip to content

Ankit/add collection crud #15

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Mar 26, 2024
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
2 changes: 1 addition & 1 deletion videodb/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@

logger: logging.Logger = logging.getLogger("videodb")

__version__ = "0.1.0"
__version__ = "0.1.1"
__author__ = "videodb"

__all__ = [
Expand Down
1 change: 1 addition & 0 deletions videodb/_constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ class ApiPath:
image = "image"
stream = "stream"
thumbnail = "thumbnail"
thumbnails = "thumbnails"
upload_url = "upload_url"
transcription = "transcription"
index = "index"
Expand Down
7 changes: 5 additions & 2 deletions videodb/_utils/_http_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ def _make_request(

def _handle_request_error(self, e: requests.exceptions.RequestException) -> None:
"""Handle request errors"""

self.show_progress = False
if isinstance(e, requests.exceptions.HTTPError):
try:
error_message = e.response.json().get("message", "Unknown error")
Expand Down Expand Up @@ -198,8 +198,11 @@ def get(
self.show_progress = show_progress
return self._make_request(method=self.session.get, path=path, **kwargs)

def post(self, path: str, data=None, **kwargs) -> requests.Response:
def post(
self, path: str, data=None, show_progress: Optional[bool] = False, **kwargs
) -> requests.Response:
"""Make a post request"""
self.show_progress = show_progress
return self._make_request(self.session.post, path, json=data, **kwargs)

def put(self, path: str, data=None, **kwargs) -> requests.Response:
Expand Down
45 changes: 45 additions & 0 deletions vi 8000 deodb/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from typing import (
Optional,
Union,
List,
)

from videodb._constants import (
Expand Down Expand Up @@ -39,6 +40,50 @@ def get_collection(self, collection_id: Optional[str] = "default") -> Collection
collection_data.get("description"),
)

def get_collections(self) -> List[Collection]:
collections_data = self.get(path=ApiPath.collection)
return [
Collection(
self,
collection.get("id"),
collection.get("name"),
collection.get("description"),
)
for collection in collections_data.get("collections")
]

def create_collection(self, name: str, description: str) -> Collection:
collection_data = self.post(
path=ApiPath.collection,
data={
"name": name,
"description": description,
},
)
self.collection_id = collection_data.get("id", "default")
return Collection(
sel 8000 f,
collection_data.get("id"),
collection_data.get("name"),
collection_data.get("description"),
)

def update_collection(self, id: str, name: str, description: str) -> Collection:
collection_data = self.patch(
path=f"{ApiPath.collection}/{id}",
data={
"name": name,
"description": description,
},
)
self.collection_id = collection_data.get("id", "default")
return Collection(
self,
collection_data.get("id"),
collection_data.get("name"),
collection_data.get("description"),
)

def upload(
self,
file_path: str = None,
Expand Down
47 changes: 38 additions & 9 deletions videodb/collection.py
8000
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,25 @@ def __init__(self, _connection, id: str, name: str = None, description: str = No
self.name = name
self.description = description

def __repr__(self) -> str:
return (
f"Collection("
f"id={self.id}, "
f"name={self.name}, "
f"description={self.description})"
)

def get_videos(self) -> List[Video]:
videos_data = self._connection.get(path=f"{ApiPath.video}")
videos_data = self._connection.get(
path=f"{ApiPath.video}",
params={"collection_id": self.id},
)
return [Video(self._connection, **video) for video in videos_data.get("videos")]

def get_video(self, video_id: str) -> Video:
video_data = self._connection.get(path=f"{ApiPath.video}/{video_id}")
video_data = self._connection.get(
path=f"{ApiPath.video}/{video_id}", params={"collection_id": self.id}
)
return Video(self._connection, **video_data)

def delete_video(self, video_id: str) -> None:
Expand All @@ -43,29 +56,45 @@ def delete_video(self, video_id: str) -> None:
:return: None if the delete is successful
:rtype: None
"""
return self._connection.delete(path=f"{ApiPath.video}/{video_id}")
return self._connection.delete(
path=f"{ApiPath.video}/{video_id}", params={"collection_id": self.id}
)

def get_audios(self) -> List[Audio]:
audios_data = self._connection.get(path=f"{ApiPath.audio}")
audios_data = self._connection.get(
path=f"{ApiPath.audio}",
params={"collection_id": self.id},
)
return [Audio(self._connection, **audio) for audio in audios_data.get("audios")]

def get_audio(self, audio_id: str) -> Audio:
audio_data = self._connection.get(path=f"{ApiPath.audio}/{audio_id}")
audio_data = self._connection.get(
path=f"{ApiPath.audio}/{audio_id}", params={"collection_id": self.id}
)
return Audio(self._connection, **audio_data)

def delete_audio(self, audio_id: str) -> None:
return self._connection.delete(path=f"{ApiPath.audio}/{audio_id}")
return self._connection.delete(
path=f"{ApiPath.audio}/{audio_id}", params={"collection_id": self.id}
)

def get_images(self) -> List[Image]:
images_data = self._connection.get(path=f"{ApiPath.image}")
images_data = self._connection.get(
path=f"{ApiPath.image}",
params={"collection_id": self.id},
)
return [Image(self._connection, **image) for image in images_data.get("images")]

def get_image(self, image_id: str) -> Image:
image_data = self._connection.get(path=f"{ApiPath.image}/{image_id}")
image_data = self._connection.get(
path=f"{ApiPath.image}/{image_id}", params={"collection_id": self.id}
)
return Image(self._connection, **image_data)

def delete_image(self, image_id: str) -> None:
return self._connection.delete(path=f"{ApiPath.image}/{image_id}")
return self._connection.delete(
path=f"{ApiPath.image}/{image_id}", params={"collection_id": self.id}
)

def search(
self,
Expand Down
4 changes: 3 additions & 1 deletion videodb/image.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@ def __init__(self, _connection, id: str, collection_id: str, **kwargs) -> None:
self.id = id
self.collection_id = collection_id
self.name = kwargs.get("name", None)
self.url = kwargs.get("url", None)

def __repr__(self) -> str:
return (
f"Image("
f"id={self.id}, "
f"collection_id={self.collection_id}, "
f"name={self.name})"
f"name={self.name}, "
f"url={self.url})"
)

def delete(self) -> None:
Expand Down
27 changes: 23 additions & 4 deletions videodb/video.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
SubtitleStyle,
Workflows,
)
from videodb.image import Image
from videodb.search import SearchFactory, SearchResult
from videodb.shot import Shot

Expand Down Expand Up @@ -88,15 +89,31 @@ def generate_stream(self, timeline: Optional[List[Tuple[int, int]]] = None) -> s
)
return stream_data.get("stream_url", None)

def generate_thumbnail(self):
if self.thumbnail_url:
def generate_thumbnail(self, time: Optional[float] = None) -> Union[str, Image]:
if self.thumbnail_url and not time:
return self.thumbnail_url

if time:
thumbnail_data = self._connection.post(
path=f"{ApiPath.video}/{self.id}/{ApiPath.thumbnail}",
data={
"time": time,
},
)
return Image(self._connection, **thumbnail_data)

thumbnail_data = self._connection.get(
path=f"{ApiPath.video}/{self.id}/{ApiPath.thumbnail}"
)
self.thumbnail_url = thumbnail_data.get("thumbnail_url")
return self.thumbnail_url

def get_thumbnails(self) -> List[Image]:
thumbnails_data = self._connection.get(
path=f"{ApiPath.video}/{self.id}/{ApiPath.thumbnails}"
)
return [Image(self._connection, **thumbnail) for thumbnail in thumbnails_data]

def _fetch_transcript(self, force: bool = False) -> None:
if self.transcript and not force:
return
Expand All @@ -116,19 +133,21 @@ def get_transcript_text(self, force: bool = False) -> str:
self._fetch_transcript(force)
return self.transcript_text

def index_spoken_words(self) -> None:
def index_spoken_words(self, force: bool = False, callback_url: str = None) -> None:
"""Semantic indexing of spoken words in the video

:raises InvalidRequestError: If the video is already indexed
:return: None if the indexing is successful
:rtype: None
"""
self._fetch_transcript()
self._connection.post(
path=f"{ApiPath.video}/{self.id}/{ApiPath.index}",
data={
"index_type": IndexType.semantic,
"force": force,
"callback_url": callback_url,
},
show_progress=True,
)

def index_scenes(
Expand Down
0