import os, requests, time
VM = os.environ["VIMEO_ACCESS_TOKEN"]
MV = os.environ["MAVERA_API_KEY"]
VM_BASE = "https://api.vimeo.com"
MV_BASE = "https://app.mavera.io/api/v1"
VM_H = {"Authorization": f"Bearer {VM}", "Accept": "application/vnd.vimeo.*+json;version=3.4"}
MV_H = {"Authorization": f"Bearer {MV}", "Content-Type": "application/json"}
ALBUM_ID = "12345678"
# 1. Fetch all videos in the showcase/album (series)
album_resp = requests.get(f"{VM_BASE}/me/albums/{ALBUM_ID}/videos", headers=VM_H, params={
"per_page": 50, "sort": "manual",
"fields": "uri,name,link,duration,stats,created_time,description",
}).json()
if "error" in album_resp:
raise SystemExit(f"Vimeo API error: {album_resp.get('developer_message', '')}")
sessions = []
for v in album_resp.get("data", []):
vid_id = v["uri"].split("/")[-1]
stats = v.get("stats", {})
sessions.append({
"id": vid_id, "name": v["name"], "link": v["link"],
"duration": v.get("duration", 0),
"plays": stats.get("plays", 0),
"finishes": stats.get("finishes", 0),
"finish_rate": round(stats.get("finishes", 0) / max(stats.get("plays", 1), 1) * 100, 1),
"created": v.get("created_time", "")[:10],
"description": v.get("description", "")[:200],
})
# 2. Get album metadata
album_meta = requests.get(f"{VM_BASE}/me/albums/{ALBUM_ID}", headers=VM_H, params={
"fields": "name,description,metadata.connections.videos.total",
}).json()
series_name = album_meta.get("name", f"Album {ALBUM_ID}")
print(f"Series: \"{series_name}\" — {len(sessions)} sessions")
# 3. Analyze each session via Mavera
session_scores = []
for i, session in enumerate(sessions):
print(f" Analyzing session {i+1}/{len(sessions)}: \"{session['name'][:40]}\"")
upload = requests.post(f"{MV_BASE}/assets", headers=MV_H, json={
"url": session["link"], "name": f"[S{i+1}] {session['name'][:60]}", "type": "video",
}).json()
analysis = requests.post(f"{MV_BASE}/video-analysis", headers=MV_H, json={
"asset_id": upload["id"],
"analysis_types": [
"emotional_arc", "hook_score", "pacing", "cognitive_load",
"message_clarity", "behavioral_effectiveness",
],
"metadata": {"session_number": i + 1, "series": series_name},
}).json()
for _ in range(30):
time.sleep(3)
status = requests.get(
f"{MV_BASE}/video-analysis/{analysis['id']}", headers=MV_H
).json()
if status.get("status") == "completed":
break
r = status.get("results", {})
session_scores.append({
**session,
"session_num": i + 1,
"hook": r.get("hook_score", {}).get("score", 0),
"emotion_avg": r.get("emotional_arc", {}).get("intensity_avg", 0),
"emotion_peak": r.get("emotional_arc", {}).get("peak_intensity", 0),
"clarity": r.get("message_clarity", {}).get("score", 0),
"pacing_score": r.get("pacing", {}).get("score", 0),
"cog_load": r.get("cognitive_load", {}).get("average", 0),
"arc_summary": r.get("emotional_arc", {}).get("summary", ""),
})
time.sleep(1)
# 4. Series arc analysis via Mave
session_block = "\n\n".join(
f"SESSION {s['session_num']}: \"{s['name']}\"\n"
f" Date: {s['created']} | Duration: {s['duration']}s | Plays: {s['plays']:,} | Finish Rate: {s['finish_rate']}%\n"
f" Hook: {s['hook']}/100 | Emotion Avg: {s['emotion_avg']:.1f}/10 | Peak: {s['emotion_peak']:.1f}/10\n"
f" Clarity: {s['clarity']}/100 | Pacing: {s['pacing_score']:.1f}/10 | Cog Load: {s['cog_load']:.1f}/10\n"
f" Arc: {s['arc_summary'][:150]}"
for s in session_scores
)
series_analysis = requests.post(f"{MV_BASE}/mave/chat", headers=MV_H, json={
"message": f"""Analyze engagement patterns across this webinar series.
SERIES: "{series_name}" ({len(session_scores)} sessions)
{session_block}
Produce:
1. **Engagement Arc**: How does audience engagement shift across sessions? Where does it peak and where does it drop?
2. **Drop-Off Diagnosis**: At which session do we lose the most viewers? What specifically about that session's creative quality explains the drop?
3. **Session Comparison**: Which session is the strongest and weakest? What makes them different?
4. **Pacing Pattern**: Does the series maintain energy or does it fatigue viewers? Is cognitive load increasing across sessions?
5. **Recommendations**: How should we restructure the next series to maintain engagement? Specific changes to session order, content density, and hook strategy.
6. **Recovery Opportunities**: Can we save the weakest session with a re-edit? What specifically should change?""",
}).json()
print(f"\nWEBINAR SERIES INTELLIGENCE — \"{series_name}\"")
print("=" * 65)
print(f"{'Session':<8} {'Title':<30} {'Plays':>7} {'Finish%':>8} {'Hook':>6} {'Emotion':>8} {'Clarity':>8}")
print("-" * 65)
for s in session_scores:
print(f" S{s['session_num']:<5} {s['name'][:28]:<30} {s['plays']:>7,} {s['finish_rate']:>7.1f}% "
f"{s['hook']:>5} {s['emotion_avg']:>7.1f} {s['clarity']:>7}")
print("\n" + series_analysis.get("content", "")[:2500])