import os, requests, time
YT = os.environ["YOUTUBE_API_KEY"]
MV = os.environ["MAVERA_API_KEY"]
YT_BASE = "https://www.googleapis.com/youtube/v3"
MV_BASE = "https://app.mavera.io/api/v1"
MV_H = {"Authorization": f"Bearer {MV}", "Content-Type": "application/json"}
VIDEO_IDS = ["VIDEO_ID_1", "VIDEO_ID_2", "VIDEO_ID_3", "VIDEO_ID_4"]
# 1. Fetch video details with thumbnails (1 quota unit)
details = requests.get(f"{YT_BASE}/videos", params={
"key": YT, "id": ",".join(VIDEO_IDS),
"part": "snippet,statistics",
}).json()
if "error" in details:
raise SystemExit(f"YouTube API error: {details['error']['message']}")
thumbnails = []
for video in details.get("items", []):
snippet = video["snippet"]
stats = video.get("statistics", {})
thumb_url = (
snippet.get("thumbnails", {}).get("maxres", {}).get("url")
or snippet.get("thumbnails", {}).get("high", {}).get("url")
or snippet.get("thumbnails", {}).get("medium", {}).get("url", "")
)
thumbnails.append({
"video_id": video["id"],
"title": snippet["title"],
"thumbnail_url": thumb_url,
"views": int(stats.get("viewCount", 0)),
"ctr_context": f"{snippet['channelTitle']} — {snippet['title'][:60]}",
})
print(f"Collected {len(thumbnails)} thumbnails")
# 2. Create Focus Group personas
persona_ids = []
for name, desc in [
("Casual Browser", "Scrolls YouTube homepage on phone. Clicks based on thumbnail emotion and curiosity gap. Ignores text-heavy thumbnails. Prefers faces and bright colors."),
("Search-Intent Viewer", "Types specific queries into YouTube search. Clicks thumbnails that visually confirm the video matches their query. Values clarity over creativity."),
("Subscriber", "Regular subscriber who sees these in their feed. Already trusts the channel. Clicks based on topic interest — thumbnail is secondary but influences priority."),
("Competitor's Audience", "Watches competitor channels. Unfamiliar with this brand. Thumbnail must prove higher quality or unique angle to earn a click away from known creators."),
]:
p = requests.post(f"{MV_BASE}/personas", headers=MV_H, json={
"name": name, "description": desc,
}).json()
persona_ids.append(p["id"])
time.sleep(0.3)
# 3. Build thumbnail descriptions for focus group
thumb_block = "\n\n".join(
f"THUMBNAIL {chr(65+i)}: \"{t['title']}\"\n"
f" Image URL: {t['thumbnail_url']}\n"
f" Channel context: {t['ctr_context']}\n"
f" Current views: {t['views']:,}"
for i, t in enumerate(thumbnails)
)
# 4. Run Focus Group
fg = requests.post(f"{MV_BASE}/focus-groups", headers=MV_H, json={
"name": "YouTube Thumbnail A/B Test",
"persona_ids": persona_ids,
"questions": [
f"You see these thumbnails on YouTube. Which would you click FIRST? Rate each 1-10 for click likelihood.\n\n{thumb_block}",
"What specific visual element in your top-rated thumbnail made you want to click?",
"Which thumbnail would you NEVER click? What turns you off about it?",
"If you could redesign the lowest-rated thumbnail, what would you change? Be specific about colors, text, faces, and composition.",
"Imagine all these thumbnails appeared in a row on the YouTube homepage. Which stands out most and why?",
],
"responses_per_persona": 2,
}).json()
# 5. Poll for results
for _ in range(20):
time.sleep(5)
data = requests.get(f"{MV_BASE}/focus-groups/{fg['id']}", headers=MV_H).json()
if data.get("status") == "completed":
break
# 6. Output
print("\nTHUMBNAIL A/B FOCUS GROUP RESULTS")
print("=" * 60)
for t in thumbnails:
print(f" [{t['video_id'][:11]}] {t['title'][:50]}")
print(f" Thumbnail: {t['thumbnail_url']}")
print(f" Views: {t['views']:,}\n")
print("PERSONA RESPONSES:")
for resp in data.get("responses", []):
persona_name = next(
(name for pid, name in zip(persona_ids, ["Casual Browser", "Search-Intent", "Subscriber", "Competitor's Audience"])
if pid == resp.get("persona_id")),
"Unknown"
)
print(f"\n[{persona_name}] {resp.get('question', '')[:60]}...")
print(f" → {resp.get('answer', '')[:350]}")