Files
wehub-resource-sync 5621867692
Sync browser-act to plugin repo / sync (push) Failing after 0s
chore: import upstream snapshot with attribution
2026-07-13 12:30:35 +08:00

244 lines
9.1 KiB
Python

import os
import time
import requests
import json
import sys
import datetime
import io
# Force UTF-8 encoding for standard output and error streams
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8')
# API Configuration
SINGLE_TEMPLATE_ID = "87197468034420377"
BATCH_TEMPLATE_ID = "87198942474882969"
API_BASE_URL = "https://api.browseract.com/v2/workflow"
def run_single_video_task(api_key, target_url):
"""
Starts a single YouTube video transcript extraction task and polls for completion.
Returns the transcript and metadata as a string, or None on failure.
"""
headers = {"Authorization": f"Bearer {api_key}"}
payload = {
"workflow_template_id": SINGLE_TEMPLATE_ID,
"input_parameters": [
{"name": "TargetURL", "value": target_url}
]
}
# 1. Start Task
print(f"[Single Mode] Starting transcript extraction for: {target_url}", flush=True)
try:
res = requests.post(
f"{API_BASE_URL}/run-task-by-template",
json=payload, headers=headers, timeout=30
).json()
except Exception as e:
print(f"Error: Connection to API failed - {e}", flush=True)
return None
if "id" not in res:
res_str = str(res)
if "Invalid authorization" in res_str:
print("Error: Invalid authorization. Please check your BrowserAct API Key.", flush=True)
elif "concurrent" in res_str.lower() or "too many running tasks" in res_str.lower():
print("Error: Concurrent task limit reached. Please upgrade your plan at https://www.browseract.com/reception/recharge", flush=True)
else:
print(f"Error: Could not start task. Response: {res}", flush=True)
return None
task_id = res["id"]
print(f"Task started. ID: {task_id}", flush=True)
# 2. Poll for Completion
max_poll_time = 900
poll_start = time.time()
finished = False
while time.time() - poll_start < max_poll_time:
try:
status_res = requests.get(
f"{API_BASE_URL}/get-task-status?task_id={task_id}",
headers=headers, timeout=30
).json()
status = status_res.get("status")
timestamp = datetime.datetime.now().strftime("%H:%M:%S")
print(f"[{timestamp}] Task Status: {status}", flush=True)
if status == "finished":
print(f"[{timestamp}] Task finished successfully.", flush=True)
finished = True
break
elif status in ["failed", "canceled"]:
print(f"Error: Task {status}. Please check your BrowserAct dashboard.", flush=True)
return None
except Exception as e:
timestamp = datetime.datetime.now().strftime("%H:%M:%S")
print(f"[{timestamp}] Polling error: {e}. Retrying...", flush=True)
time.sleep(10)
if not finished:
print(f"Error: Task polling timed out after {max_poll_time} seconds.", flush=True)
return None
# 3. Get Results
try:
task_info = requests.get(
f"{API_BASE_URL}/get-task?task_id={task_id}",
headers=headers, timeout=30
).json()
output = task_info.get("output", {})
result_string = output.get("string")
if result_string:
return result_string
else:
return json.dumps(task_info, ensure_ascii=False)
except Exception as e:
print(f"Error: Failed to retrieve results - {e}", flush=True)
return None
def run_batch_video_task(api_key, keywords, upload_date="This week", limit=3):
"""
Starts a batch YouTube video transcript extraction task and polls for completion.
Returns transcripts and metadata for multiple videos as a string, or None on failure.
"""
headers = {"Authorization": f"Bearer {api_key}"}
payload = {
"workflow_template_id": BATCH_TEMPLATE_ID,
"input_parameters": [
{"name": "KeyWords", "value": keywords},
{"name": "Upload_date", "value": upload_date},
{"name": "Datelimit", "value": str(limit)}
]
}
# 1. Start Task
print(f"[Batch Mode] Searching for '{keywords}' | Upload date: {upload_date} | Limit: {limit}", flush=True)
try:
res = requests.post(
f"{API_BASE_URL}/run-task-by-template",
json=payload, headers=headers, timeout=30
).json()
except Exception as e:
print(f"Error: Connection to API failed - {e}", flush=True)
return None
if "id" not in res:
res_str = str(res)
if "Invalid authorization" in res_str:
print("Error: Invalid authorization. Please check your BrowserAct API Key.", flush=True)
elif "concurrent" in res_str.lower() or "too many running tasks" in res_str.lower():
print("Error: Concurrent task limit reached. Please upgrade your plan at https://www.browseract.com/reception/recharge", flush=True)
else:
print(f"Error: Could not start task. Response: {res}", flush=True)
return None
task_id = res["id"]
print(f"Task started. ID: {task_id}", flush=True)
# 2. Poll for Completion
max_poll_time = 900
poll_start = time.time()
finished = False
while time.time() - poll_start < max_poll_time:
try:
status_res = requests.get(
f"{API_BASE_URL}/get-task-status?task_id={task_id}",
headers=headers, timeout=30
).json()
status = status_res.get("status")
timestamp = datetime.datetime.now().strftime("%H:%M:%S")
print(f"[{timestamp}] Task Status: {status}", flush=True)
if status == "finished":
print(f"[{timestamp}] Task finished successfully.", flush=True)
finished = True
break
elif status in ["failed", "canceled"]:
print(f"Error: Task {status}. Please check your BrowserAct dashboard.", flush=True)
return None
except Exception as e:
timestamp = datetime.datetime.now().strftime("%H:%M:%S")
print(f"[{timestamp}] Polling error: {e}. Retrying...", flush=True)
time.sleep(10)
if not finished:
print(f"Error: Task polling timed out after {max_poll_time} seconds.", flush=True)
return None
# 3. Get Results
try:
task_info = requests.get(
f"{API_BASE_URL}/get-task?task_id={task_id}",
headers=headers, timeout=30
).json()
output = task_info.get("output", {})
result_string = output.get("string")
if result_string:
return result_string
else:
return json.dumps(task_info, ensure_ascii=False)
except Exception as e:
print(f"Error: Failed to retrieve results - {e}", flush=True)
return None
if __name__ == "__main__":
if len(sys.argv) < 3:
print("Usage:", flush=True)
print(" Single video: python youtube_transcript_analysis_api.py single \"<YouTube_URL>\"", flush=True)
print(" Batch videos: python youtube_transcript_analysis_api.py batch \"<keywords>\" [upload_date] [limit]", flush=True)
sys.exit(1)
api_key = os.getenv("BROWSERACT_API_KEY")
if not api_key:
print("\n[!] ERROR: BrowserAct API Key is missing.", flush=True)
print("Please follow these steps:", flush=True)
print("1. Go to: https://www.browseract.com/reception/integrations", flush=True)
print("2. Copy your API Key.", flush=True)
print("3. Provide it to me or set it as an environment variable (BROWSERACT_API_KEY).", flush=True)
sys.exit(1)
mode = sys.argv[1].lower()
if mode == "single":
target_url = sys.argv[2]
result = run_single_video_task(api_key, target_url)
if result:
print("\n" + "=" * 60, flush=True)
print("TRANSCRIPT EXTRACTION RESULT", flush=True)
print("=" * 60, flush=True)
print(result, flush=True)
print("\n" + "=" * 60, flush=True)
print("EXTRACTION COMPLETE — Agent should now perform a concise, bullet-point 8-dimension analysis on the transcript without outputting the full raw text.", flush=True)
print("=" * 60, flush=True)
elif mode == "batch":
keywords = sys.argv[2]
upload_date = sys.argv[3] if len(sys.argv) > 3 else "This week"
limit = int(sys.argv[4]) if len(sys.argv) > 4 else 3
result = run_batch_video_task(api_key, keywords, upload_date, limit)
if result:
print("\n" + "=" * 60, flush=True)
print("BATCH TRANSCRIPT EXTRACTION RESULT", flush=True)
print("=" * 60, flush=True)
print(result, flush=True)
print("\n" + "=" * 60, flush=True)
print("EXTRACTION COMPLETE — Agent should now perform a concise, bullet-point 8-dimension analysis on each transcript without outputting the full raw text.", flush=True)
print("=" * 60, flush=True)
else:
print(f"Error: Unknown mode '{mode}'. Use 'single' or 'batch'.", flush=True)
sys.exit(1)