-
Notifications
You must be signed in to change notification settings - Fork 68
[Feat] new video generation providers #368
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -1,17 +1,17 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||
import base64 | ||||||||||||||||||||||||||||||||||||||||||||||||
import json | ||||||||||||||||||||||||||||||||||||||||||||||||
import mimetypes | ||||||||||||||||||||||||||||||||||||||||||||||||
from datetime import datetime, timezone | ||||||||||||||||||||||||||||||||||||||||||||||||
from io import BytesIO | ||||||||||||||||||||||||||||||||||||||||||||||||
from pathlib import Path | ||||||||||||||||||||||||||||||||||||||||||||||||
from time import sleep, time | ||||||||||||||||||||||||||||||||||||||||||||||||
from typing import Any, Dict, List | ||||||||||||||||||||||||||||||||||||||||||||||||
from typing import Any, Dict, List, Optional | ||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||
import requests | ||||||||||||||||||||||||||||||||||||||||||||||||
from dateutil.parser import parse | ||||||||||||||||||||||||||||||||||||||||||||||||
from google.cloud import videointelligence | ||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||
from edenai_apis.apis.amazon.helpers import check_webhook_result | ||||||||||||||||||||||||||||||||||||||||||||||||
from edenai_apis.apis.google.google_helpers import ( | ||||||||||||||||||||||||||||||||||||||||||||||||
GoogleVideoFeatures, | ||||||||||||||||||||||||||||||||||||||||||||||||
calculate_usage_tokens, | ||||||||||||||||||||||||||||||||||||||||||||||||
google_video_get_job, | ||||||||||||||||||||||||||||||||||||||||||||||||
score_to_content, | ||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -69,6 +69,9 @@ | |||||||||||||||||||||||||||||||||||||||||||||||
VideoTextBoundingBox, | ||||||||||||||||||||||||||||||||||||||||||||||||
VideoTextFrames, | ||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||
from edenai_apis.features.video.generation_async.generation_async_dataclass import ( | ||||||||||||||||||||||||||||||||||||||||||||||||
GenerationAsyncDataClass, | ||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||
from edenai_apis.features.video.video_interface import VideoInterface | ||||||||||||||||||||||||||||||||||||||||||||||||
from edenai_apis.utils.exception import ( | ||||||||||||||||||||||||||||||||||||||||||||||||
ProviderException, | ||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -82,6 +85,10 @@ | |||||||||||||||||||||||||||||||||||||||||||||||
AsyncResponseType, | ||||||||||||||||||||||||||||||||||||||||||||||||
ResponseType, | ||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||
from edenai_apis.utils.upload_s3 import ( | ||||||||||||||||||||||||||||||||||||||||||||||||
USER_PROCESS, | ||||||||||||||||||||||||||||||||||||||||||||||||
upload_file_bytes_to_s3, | ||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||
class GoogleVideoApi(VideoInterface): | ||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -918,3 +925,93 @@ def video__question_answer_async__get_job_result( | |||||||||||||||||||||||||||||||||||||||||||||||
standardized_response=standardized_response, | ||||||||||||||||||||||||||||||||||||||||||||||||
provider_job_id=provider_job_id, | ||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||
def video__generation_async__launch_job( | ||||||||||||||||||||||||||||||||||||||||||||||||
self, | ||||||||||||||||||||||||||||||||||||||||||||||||
text: str, | ||||||||||||||||||||||||||||||||||||||||||||||||
duration: Optional[int] = 6, | ||||||||||||||||||||||||||||||||||||||||||||||||
fps: Optional[int] = 24, | ||||||||||||||||||||||||||||||||||||||||||||||||
dimension: Optional[str] = "1280x720", | ||||||||||||||||||||||||||||||||||||||||||||||||
seed: Optional[float] = 12, | ||||||||||||||||||||||||||||||||||||||||||||||||
file: Optional[str] = None, | ||||||||||||||||||||||||||||||||||||||||||||||||
file_url: Optional[str] = None, | ||||||||||||||||||||||||||||||||||||||||||||||||
model: Optional[str] = None, | ||||||||||||||||||||||||||||||||||||||||||||||||
**kwargs, | ||||||||||||||||||||||||||||||||||||||||||||||||
) -> AsyncLaunchJobResponseType: | ||||||||||||||||||||||||||||||||||||||||||||||||
api_key = self.api_settings.get("genai_api_key") | ||||||||||||||||||||||||||||||||||||||||||||||||
url = f"https://generativelanguage.googleapis.com/v1beta/models/{model}:predictLongRunning?key={api_key}" | ||||||||||||||||||||||||||||||||||||||||||||||||
prompt = {"prompt": text} | ||||||||||||||||||||||||||||||||||||||||||||||||
if file: | ||||||||||||||||||||||||||||||||||||||||||||||||
with open(file, "rb") as file_: | ||||||||||||||||||||||||||||||||||||||||||||||||
file_content = file_.read() | ||||||||||||||||||||||||||||||||||||||||||||||||
input_image_base64 = base64.b64encode(file_content).decode("utf-8") | ||||||||||||||||||||||||||||||||||||||||||||||||
mime_type = mimetypes.guess_type(file)[0] | ||||||||||||||||||||||||||||||||||||||||||||||||
image = { | ||||||||||||||||||||||||||||||||||||||||||||||||
"bytesBase64Encoded": input_image_base64, | ||||||||||||||||||||||||||||||||||||||||||||||||
"mimeType": mime_type, | ||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||
prompt["image"] = image | ||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||
payload = { | ||||||||||||||||||||||||||||||||||||||||||||||||
"instances": [prompt], | ||||||||||||||||||||||||||||||||||||||||||||||||
"parameters": { | ||||||||||||||||||||||||||||||||||||||||||||||||
"durationSeconds": duration, | ||||||||||||||||||||||||||||||||||||||||||||||||
# "personGeneration": "allow_adult", | ||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||
response = requests.post(url=url, json=payload) | ||||||||||||||||||||||||||||||||||||||||||||||||
try: | ||||||||||||||||||||||||||||||||||||||||||||||||
original_response = response.json() | ||||||||||||||||||||||||||||||||||||||||||||||||
except json.JSONDecodeError as exc: | ||||||||||||||||||||||||||||||||||||||||||||||||
raise ProviderException( | ||||||||||||||||||||||||||||||||||||||||||||||||
"An error occurred while parsing the response." | ||||||||||||||||||||||||||||||||||||||||||||||||
) from exc | ||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||
if response.status_code != 200: | ||||||||||||||||||||||||||||||||||||||||||||||||
raise ProviderException( | ||||||||||||||||||||||||||||||||||||||||||||||||
message=original_response["error"]["message"], | ||||||||||||||||||||||||||||||||||||||||||||||||
code=response.status_code, | ||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||
# {'name': 'models/veo-2.0-generate-001/operations/0gbm5qefte2y'} | ||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||
provider_job_id = original_response["name"] | ||||||||||||||||||||||||||||||||||||||||||||||||
return AsyncLaunchJobResponseType(provider_job_id=provider_job_id) | ||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||
def video__generation_async__get_job_result( | ||||||||||||||||||||||||||||||||||||||||||||||||
self, provider_job_id: str | ||||||||||||||||||||||||||||||||||||||||||||||||
) -> GenerationAsyncDataClass: | ||||||||||||||||||||||||||||||||||||||||||||||||
api_key = self.api_settings.get("genai_api_key") | ||||||||||||||||||||||||||||||||||||||||||||||||
url = f"https://generativelanguage.googleapis.com/v1beta/{provider_job_id}?key={api_key}" | ||||||||||||||||||||||||||||||||||||||||||||||||
response = requests.get(url) | ||||||||||||||||||||||||||||||||||||||||||||||||
try: | ||||||||||||||||||||||||||||||||||||||||||||||||
original_response = response.json() | ||||||||||||||||||||||||||||||||||||||||||||||||
except json.JSONDecodeError as exc: | ||||||||||||||||||||||||||||||||||||||||||||||||
raise ProviderException( | ||||||||||||||||||||||||||||||||||||||||||||||||
"An error occurred while parsing the response." | ||||||||||||||||||||||||||||||||||||||||||||||||
) from exc | ||||||||||||||||||||||||||||||||||||||||||||||||
if "error" in original_response: | ||||||||||||||||||||||||||||||||||||||||||||||||
raise ProviderException( | ||||||||||||||||||||||||||||||||||||||||||||||||
message=original_response["error"]["message"], | ||||||||||||||||||||||||||||||||||||||||||||||||
code=original_response["error"]["code"], | ||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||
if original_response.get("done") is True: | ||||||||||||||||||||||||||||||||||||||||||||||||
uri = original_response["response"]["generateVideoResponse"][ | ||||||||||||||||||||||||||||||||||||||||||||||||
"generatedSamples" | ||||||||||||||||||||||||||||||||||||||||||||||||
][0]["video"]["uri"] | ||||||||||||||||||||||||||||||||||||||||||||||||
headers = {"x-goog-api-key": api_key} | ||||||||||||||||||||||||||||||||||||||||||||||||
response = requests.get(uri, headers=headers) | ||||||||||||||||||||||||||||||||||||||||||||||||
file_content = response.content | ||||||||||||||||||||||||||||||||||||||||||||||||
base64_encoded_string = base64.b64encode(file_content).decode("utf-8") | ||||||||||||||||||||||||||||||||||||||||||||||||
resource_url = upload_file_bytes_to_s3( | ||||||||||||||||||||||||||||||||||||||||||||||||
BytesIO(file_content), ".mp4", USER_PROCESS | ||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+1002
to
+1007
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Add error handling for S3 upload and consider memory usage for large videos.
Consider streaming the video content or implementing error handling: response = requests.get(uri, headers=headers)
+if response.status_code != 200:
+ raise ProviderException(
+ message=f"Failed to download video: {response.status_code}",
+ code=response.status_code
+ )
file_content = response.content
base64_encoded_string = base64.b64encode(file_content).decode("utf-8")
-resource_url = upload_file_bytes_to_s3(
- BytesIO(file_content), ".mp4", USER_PROCESS
-)
+try:
+ resource_url = upload_file_bytes_to_s3(
+ BytesIO(file_content), ".mp4", USER_PROCESS
+ )
+except Exception as exc:
+ raise ProviderException(
+ message=f"Failed to upload video to S3: {str(exc)}",
+ code=500
+ ) from exc 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents
|
||||||||||||||||||||||||||||||||||||||||||||||||
standardized_response = GenerationAsyncDataClass( | ||||||||||||||||||||||||||||||||||||||||||||||||
video=base64_encoded_string, video_resource_url=resource_url | ||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||
return AsyncResponseType[GenerationAsyncDataClass]( | ||||||||||||||||||||||||||||||||||||||||||||||||
original_response=original_response, | ||||||||||||||||||||||||||||||||||||||||||||||||
standardized_response=standardized_response, | ||||||||||||||||||||||||||||||||||||||||||||||||
provider_job_id=provider_job_id, | ||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||
return AsyncPendingResponseType(provider_job_id=provider_job_id) |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1353,6 +1353,9 @@ | |
] | ||
}, | ||
"version": "v1Beta" | ||
}, | ||
"generation_async": { | ||
"version": "v1Beta" | ||
} | ||
}, | ||
"image": { | ||
|
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,113 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||
import base64 | ||||||||||||||||||||||||||||||||||||||||||||||||||||
import json | ||||||||||||||||||||||||||||||||||||||||||||||||||||
from io import BytesIO | ||||||||||||||||||||||||||||||||||||||||||||||||||||
from typing import Optional | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
import requests | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
from edenai_apis.features.video.generation_async.generation_async_dataclass import ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||
GenerationAsyncDataClass, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
from edenai_apis.features.video.video_interface import VideoInterface | ||||||||||||||||||||||||||||||||||||||||||||||||||||
from edenai_apis.utils.exception import ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||
ProviderException, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
from edenai_apis.utils.types import ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||
AsyncLaunchJobResponseType, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
AsyncPendingResponseType, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
AsyncResponseType, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
from edenai_apis.utils.upload_s3 import ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||
USER_PROCESS, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
upload_file_bytes_to_s3, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
class MicrosoftVideoApi(VideoInterface): | ||||||||||||||||||||||||||||||||||||||||||||||||||||
def video__generation_async__launch_job( | ||||||||||||||||||||||||||||||||||||||||||||||||||||
self, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
text: str, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
duration: Optional[int] = 6, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
fps: Optional[int] = 24, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
dimension: Optional[str] = "1280x720", | ||||||||||||||||||||||||||||||||||||||||||||||||||||
seed: Optional[float] = 12, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
file: Optional[str] = None, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
file_url: Optional[str] = None, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
model: Optional[str] = None, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
**kwargs, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+27
to
+37
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove unused parameters to match implementation. The following parameters are not used in the implementation:
Remove these parameters or implement them in the request payload. 🧰 Tools🪛 Pylint (3.3.7)[refactor] 27-27: Too many arguments (9/7) (R0913) [refactor] 27-27: Too many positional arguments (9/5) (R0917) 🤖 Prompt for AI Agents
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
) -> AsyncLaunchJobResponseType: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
base_url = self.azure_ai_credentials.get("azure_api_sora") | ||||||||||||||||||||||||||||||||||||||||||||||||||||
api_key = self.azure_ai_credentials.get("azure_api_key") | ||||||||||||||||||||||||||||||||||||||||||||||||||||
url = f"{base_url}openai/v1/video/generations/jobs?api-version=preview" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
try: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
height, width = dimension.split("x") | ||||||||||||||||||||||||||||||||||||||||||||||||||||
except (ValueError, AttributeError) as exc: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
raise ProviderException( | ||||||||||||||||||||||||||||||||||||||||||||||||||||
message=f"Invalid dimension format: {dimension}. Expected format: 'heightxwidth' (e.g., '1280x720')", | ||||||||||||||||||||||||||||||||||||||||||||||||||||
code=400, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
) from exc | ||||||||||||||||||||||||||||||||||||||||||||||||||||
payload = { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
"model": model, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
"prompt": text, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
"height": height, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
"width": width, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
"n_seconds": duration, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
response = requests.post( | ||||||||||||||||||||||||||||||||||||||||||||||||||||
url=url, json=payload, headers={"Authorization": api_key} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
try: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
original_response = response.json() | ||||||||||||||||||||||||||||||||||||||||||||||||||||
except json.JSONDecodeError as exc: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
raise ProviderException( | ||||||||||||||||||||||||||||||||||||||||||||||||||||
"An error occurred while parsing the response." | ||||||||||||||||||||||||||||||||||||||||||||||||||||
) from exc | ||||||||||||||||||||||||||||||||||||||||||||||||||||
if response.status_code > 201: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
raise ProviderException( | ||||||||||||||||||||||||||||||||||||||||||||||||||||
message=original_response["error"]["message"], | ||||||||||||||||||||||||||||||||||||||||||||||||||||
code=response.status_code, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
provider_job_id = original_response["id"] | ||||||||||||||||||||||||||||||||||||||||||||||||||||
return AsyncLaunchJobResponseType(provider_job_id=provider_job_id) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
def video__generation_async__get_job_result( | ||||||||||||||||||||||||||||||||||||||||||||||||||||
self, provider_job_id: str | ||||||||||||||||||||||||||||||||||||||||||||||||||||
) -> GenerationAsyncDataClass: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
base_url = self.azure_ai_credentials.get("azure_api_sora") | ||||||||||||||||||||||||||||||||||||||||||||||||||||
api_key = self.azure_ai_credentials.get("azure_api_key") | ||||||||||||||||||||||||||||||||||||||||||||||||||||
url = f"{base_url}openai/v1/video/generations/jobs/{provider_job_id}?api-version=preview" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
response = requests.get(url, headers={"Authorization": api_key}) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
try: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
original_response = response.json() | ||||||||||||||||||||||||||||||||||||||||||||||||||||
except json.JSONDecodeError as exc: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
raise ProviderException( | ||||||||||||||||||||||||||||||||||||||||||||||||||||
"An error occurred while parsing the response." | ||||||||||||||||||||||||||||||||||||||||||||||||||||
) from exc | ||||||||||||||||||||||||||||||||||||||||||||||||||||
if "error" in original_response: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
raise ProviderException( | ||||||||||||||||||||||||||||||||||||||||||||||||||||
message=original_response["error"]["message"], | ||||||||||||||||||||||||||||||||||||||||||||||||||||
code=original_response["error"]["code"], | ||||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
if original_response.get("status") == "succeeded": | ||||||||||||||||||||||||||||||||||||||||||||||||||||
generations = original_response.get("generations", []) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
generation_id = generations[0].get("id") | ||||||||||||||||||||||||||||||||||||||||||||||||||||
video_url = f"{base_url}openai/v1/video/generations/{generation_id}/content/video?api-version=preview" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
video_response = requests.get(video_url, headers={"Authorization": api_key}) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
base64_encoded_string = base64.b64encode(video_response.content).decode( | ||||||||||||||||||||||||||||||||||||||||||||||||||||
"utf-8" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
resource_url = upload_file_bytes_to_s3( | ||||||||||||||||||||||||||||||||||||||||||||||||||||
BytesIO(video_response.content), ".mp4", USER_PROCESS | ||||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+97
to
+103
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Add error handling for video download and S3 upload. The code lacks error handling for:
Apply this fix: video_response = requests.get(video_url, headers={"Authorization": api_key})
+if video_response.status_code != 200:
+ raise ProviderException(
+ message=f"Failed to download video: {video_response.status_code}",
+ code=video_response.status_code
+ )
base64_encoded_string = base64.b64encode(video_response.content).decode(
"utf-8"
)
-resource_url = upload_file_bytes_to_s3(
- BytesIO(video_response.content), ".mp4", USER_PROCESS
-)
+try:
+ resource_url = upload_file_bytes_to_s3(
+ BytesIO(video_response.content), ".mp4", USER_PROCESS
+ )
+except Exception as exc:
+ raise ProviderException(
+ message=f"Failed to upload video to S3: {str(exc)}",
+ code=500
+ ) from exc 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
standardized_response = GenerationAsyncDataClass( | ||||||||||||||||||||||||||||||||||||||||||||||||||||
video=base64_encoded_string, video_resource_url=resource_url | ||||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
return AsyncResponseType[GenerationAsyncDataClass]( | ||||||||||||||||||||||||||||||||||||||||||||||||||||
original_response=original_response, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
standardized_response=standardized_response, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
provider_job_id=provider_job_id, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
return AsyncPendingResponseType(provider_job_id=provider_job_id) |
Large diffs are not rendered by default.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove or implement unused parameters.
The following parameters are accepted but not used in the implementation:
dimension
(line 935)fps
(line 934)seed
(line 936)file_url
(line 938)Either implement these parameters in the request payload or remove them from the method signature to avoid confusion.
🧰 Tools
🪛 Pylint (3.3.7)
[refactor] 929-929: Too many arguments (9/7)
(R0913)
[refactor] 929-929: Too many positional arguments (9/5)
(R0917)
🤖 Prompt for AI Agents