Skip to content

Commit

Permalink
Merge branch 'master' into reinier/open-1891-ensure-oauth-credentials…
Browse files Browse the repository at this point in the history
…-are-fresh-before-using-them-in
  • Loading branch information
ntindle authored Oct 10, 2024
2 parents cdee453 + d8145c1 commit 519e396
Show file tree
Hide file tree
Showing 92 changed files with 4,999 additions and 1,014 deletions.
13 changes: 10 additions & 3 deletions autogpt_platform/backend/backend/blocks/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,15 +53,22 @@ def all_subclasses(clz):
if block.id in AVAILABLE_BLOCKS:
raise ValueError(f"Block ID {block.name} error: {block.id} is already in use")

input_schema = block.input_schema.model_fields
output_schema = block.output_schema.model_fields

# Prevent duplicate field name in input_schema and output_schema
duplicate_field_names = set(block.input_schema.model_fields.keys()) & set(
block.output_schema.model_fields.keys()
)
duplicate_field_names = set(input_schema.keys()) & set(output_schema.keys())
if duplicate_field_names:
raise ValueError(
f"{block.name} has duplicate field names in input_schema and output_schema: {duplicate_field_names}"
)

# Make sure `error` field is a string in the output schema
if "error" in output_schema and output_schema["error"].annotation is not str:
raise ValueError(
f"{block.name} `error` field in output_schema must be a string"
)

for field in block.input_schema.model_fields.values():
if field.annotation is bool and field.default not in (True, False):
raise ValueError(f"{block.name} has a boolean field with no default value")
Expand Down
122 changes: 55 additions & 67 deletions autogpt_platform/backend/backend/blocks/ai_shortform_video_block.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import logging
import time
from enum import Enum
from typing import Optional

import requests
from pydantic import Field
Expand Down Expand Up @@ -156,7 +155,7 @@ class Input(BlockSchema):

class Output(BlockSchema):
video_url: str = Field(description="The URL of the created video")
error: Optional[str] = Field(description="Error message if the request failed")
error: str = Field(description="Error message if the request failed")

def __init__(self):
super().__init__(
Expand Down Expand Up @@ -239,69 +238,58 @@ def wait_for_video(
raise TimeoutError("Video creation timed out")

def run(self, input_data: Input, **kwargs) -> BlockOutput:
try:
# Create a new Webhook.site URL
webhook_token, webhook_url = self.create_webhook()
logger.debug(f"Webhook URL: {webhook_url}")

audio_url = input_data.background_music.audio_url

payload = {
"frameRate": input_data.frame_rate,
"resolution": input_data.resolution,
"frameDurationMultiplier": 18,
"webhook": webhook_url,
"creationParams": {
"mediaType": input_data.video_style,
"captionPresetName": "Wrap 1",
"selectedVoice": input_data.voice.voice_id,
"hasEnhancedGeneration": True,
"generationPreset": input_data.generation_preset.name,
"selectedAudio": input_data.background_music,
"origin": "/create",
"inputText": input_data.script,
"flowType": "text-to-video",
"slug": "create-tiktok-video",
"hasToGenerateVoice": True,
"hasToTranscript": False,
"hasToSearchMedia": True,
"hasAvatar": False,
"hasWebsiteRecorder": False,
"hasTextSmallAtBottom": False,
"ratio": input_data.ratio,
"sourceType": "contentScraping",
"selectedStoryStyle": {"value": "custom", "label": "Custom"},
"hasToGenerateVideos": input_data.video_style
!= VisualMediaType.STOCK_VIDEOS,
"audioUrl": audio_url,
},
}

logger.debug("Creating video...")
response = self.create_video(input_data.api_key.get_secret_value(), payload)
pid = response.get("pid")

if not pid:
logger.error(
f"Failed to create video: No project ID returned. API Response: {response}"
)
yield "error", "Failed to create video: No project ID returned"
else:
logger.debug(
f"Video created with project ID: {pid}. Waiting for completion..."
)
video_url = self.wait_for_video(
input_data.api_key.get_secret_value(), pid, webhook_token
)
logger.debug(f"Video ready: {video_url}")
yield "video_url", video_url
# Create a new Webhook.site URL
webhook_token, webhook_url = self.create_webhook()
logger.debug(f"Webhook URL: {webhook_url}")

audio_url = input_data.background_music.audio_url

payload = {
"frameRate": input_data.frame_rate,
"resolution": input_data.resolution,
"frameDurationMultiplier": 18,
"webhook": webhook_url,
"creationParams": {
"mediaType": input_data.video_style,
"captionPresetName": "Wrap 1",
"selectedVoice": input_data.voice.voice_id,
"hasEnhancedGeneration": True,
"generationPreset": input_data.generation_preset.name,
"selectedAudio": input_data.background_music,
"origin": "/create",
"inputText": input_data.script,
"flowType": "text-to-video",
"slug": "create-tiktok-video",
"hasToGenerateVoice": True,
"hasToTranscript": False,
"hasToSearchMedia": True,
"hasAvatar": False,
"hasWebsiteRecorder": False,
"hasTextSmallAtBottom": False,
"ratio": input_data.ratio,
"sourceType": "contentScraping",
"selectedStoryStyle": {"value": "custom", "label": "Custom"},
"hasToGenerateVideos": input_data.video_style
!= VisualMediaType.STOCK_VIDEOS,
"audioUrl": audio_url,
},
}

except requests.RequestException as e:
logger.exception("Error creating video")
yield "error", f"Error creating video: {str(e)}"
except ValueError as e:
logger.exception("Error in video creation process")
yield "error", str(e)
except TimeoutError as e:
logger.exception("Video creation timed out")
yield "error", str(e)
logger.debug("Creating video...")
response = self.create_video(input_data.api_key.get_secret_value(), payload)
pid = response.get("pid")

if not pid:
logger.error(
f"Failed to create video: No project ID returned. API Response: {response}"
)
raise RuntimeError("Failed to create video: No project ID returned")
else:
logger.debug(
f"Video created with project ID: {pid}. Waiting for completion..."
)
video_url = self.wait_for_video(
input_data.api_key.get_secret_value(), pid, webhook_token
)
logger.debug(f"Video ready: {video_url}")
yield "video_url", video_url
48 changes: 21 additions & 27 deletions autogpt_platform/backend/backend/blocks/basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -330,20 +330,17 @@ def __init__(self):
)

def run(self, input_data: Input, **kwargs) -> BlockOutput:
try:
# If no dictionary is provided, create a new one
if input_data.dictionary is None:
updated_dict = {}
else:
# Create a copy of the input dictionary to avoid modifying the original
updated_dict = input_data.dictionary.copy()
# If no dictionary is provided, create a new one
if input_data.dictionary is None:
updated_dict = {}
else:
# Create a copy of the input dictionary to avoid modifying the original
updated_dict = input_data.dictionary.copy()

# Add the new key-value pair
updated_dict[input_data.key] = input_data.value
# Add the new key-value pair
updated_dict[input_data.key] = input_data.value

yield "updated_dictionary", updated_dict
except Exception as e:
yield "error", f"Failed to add entry to dictionary: {str(e)}"
yield "updated_dictionary", updated_dict


class AddToListBlock(Block):
Expand Down Expand Up @@ -401,23 +398,20 @@ def __init__(self):
)

def run(self, input_data: Input, **kwargs) -> BlockOutput:
try:
# If no list is provided, create a new one
if input_data.list is None:
updated_list = []
else:
# Create a copy of the input list to avoid modifying the original
updated_list = input_data.list.copy()
# If no list is provided, create a new one
if input_data.list is None:
updated_list = []
else:
# Create a copy of the input list to avoid modifying the original
updated_list = input_data.list.copy()

# Add the new entry
if input_data.position is None:
updated_list.append(input_data.entry)
else:
updated_list.insert(input_data.position, input_data.entry)
# Add the new entry
if input_data.position is None:
updated_list.append(input_data.entry)
else:
updated_list.insert(input_data.position, input_data.entry)

yield "updated_list", updated_list
except Exception as e:
yield "error", f"Failed to add entry to list: {str(e)}"
yield "updated_list", updated_list


class NoteBlock(Block):
Expand Down
8 changes: 3 additions & 5 deletions autogpt_platform/backend/backend/blocks/block.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,12 @@ def run(self, input_data: Input, **kwargs) -> BlockOutput:
if search := re.search(r"class (\w+)\(Block\):", code):
class_name = search.group(1)
else:
yield "error", "No class found in the code."
return
raise RuntimeError("No class found in the code.")

if search := re.search(r"id=\"(\w+-\w+-\w+-\w+-\w+)\"", code):
file_name = search.group(1)
else:
yield "error", "No UUID found in the code."
return
raise RuntimeError("No UUID found in the code.")

block_dir = os.path.dirname(__file__)
file_path = f"{block_dir}/{file_name}.py"
Expand All @@ -63,4 +61,4 @@ def run(self, input_data: Input, **kwargs) -> BlockOutput:
yield "success", "Block installed successfully."
except Exception as e:
os.remove(file_path)
yield "error", f"[Code]\n{code}\n\n[Error]\n{str(e)}"
raise RuntimeError(f"[Code]\n{code}\n\n[Error]\n{str(e)}")
7 changes: 2 additions & 5 deletions autogpt_platform/backend/backend/blocks/decoder_block.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,5 @@ def __init__(self):
)

def run(self, input_data: Input, **kwargs) -> BlockOutput:
try:
decoded_text = codecs.decode(input_data.text, "unicode_escape")
yield "decoded_text", decoded_text
except Exception as e:
yield "error", f"Error decoding text: {str(e)}"
decoded_text = codecs.decode(input_data.text, "unicode_escape")
yield "decoded_text", decoded_text
37 changes: 15 additions & 22 deletions autogpt_platform/backend/backend/blocks/email_block.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,35 +67,28 @@ def __init__(self):
def send_email(
creds: EmailCredentials, to_email: str, subject: str, body: str
) -> str:
try:
smtp_server = creds.smtp_server
smtp_port = creds.smtp_port
smtp_username = creds.smtp_username.get_secret_value()
smtp_password = creds.smtp_password.get_secret_value()
smtp_server = creds.smtp_server
smtp_port = creds.smtp_port
smtp_username = creds.smtp_username.get_secret_value()
smtp_password = creds.smtp_password.get_secret_value()

msg = MIMEMultipart()
msg["From"] = smtp_username
msg["To"] = to_email
msg["Subject"] = subject
msg.attach(MIMEText(body, "plain"))
msg = MIMEMultipart()
msg["From"] = smtp_username
msg["To"] = to_email
msg["Subject"] = subject
msg.attach(MIMEText(body, "plain"))

with smtplib.SMTP(smtp_server, smtp_port) as server:
server.starttls()
server.login(smtp_username, smtp_password)
server.sendmail(smtp_username, to_email, msg.as_string())
with smtplib.SMTP(smtp_server, smtp_port) as server:
server.starttls()
server.login(smtp_username, smtp_password)
server.sendmail(smtp_username, to_email, msg.as_string())

return "Email sent successfully"
except Exception as e:
return f"Failed to send email: {str(e)}"
return "Email sent successfully"

def run(self, input_data: Input, **kwargs) -> BlockOutput:
status = self.send_email(
yield "status", self.send_email(
input_data.creds,
input_data.to_email,
input_data.subject,
input_data.body,
)
if "successfully" in status:
yield "status", status
else:
yield "error", status
Loading

0 comments on commit 519e396

Please sign in to comment.