import os, json, requests, time
from collections import Counter, defaultdict
SM = os.environ["SURVEYMONKEY_TOKEN"]
MV = os.environ["MAVERA_API_KEY"]
SM_BASE = "https://api.surveymonkey.com/v3"
MB = "https://app.mavera.io/api/v1"
SM_H = {"Authorization": f"Bearer {SM}", "Content-Type": "application/json"}
MV_H = {"Authorization": f"Bearer {MV}", "Content-Type": "application/json"}
SURVEY_ID = os.environ.get("SURVEY_ID", "your_survey_id")
# 1. Get survey structure
survey = requests.get(f"{SM_BASE}/surveys/{SURVEY_ID}/details",
headers=SM_H).json()
print(f"Survey: {survey.get('title', 'Untitled')} ({survey.get('response_count', 0)} responses)")
# Build question/answer lookup
questions = {}
choice_labels = {}
for page in survey.get("pages", []):
for q in page.get("questions", []):
qid = q["id"]
questions[qid] = {
"title": q.get("headings", [{}])[0].get("heading", ""),
"type": q.get("family", ""),
"subtype": q.get("subtype", ""),
}
for row in q.get("answers", {}).get("rows", []):
choice_labels[row["id"]] = row.get("text", "")
for choice in q.get("answers", {}).get("choices", []):
choice_labels[choice["id"]] = choice.get("text", "")
for col in q.get("answers", {}).get("columns", []):
choice_labels[col["id"]] = col.get("text", col.get("label", ""))
# 2. Pull all responses (paginated)
all_responses = []
page_num = 1
while True:
r = requests.get(f"{SM_BASE}/surveys/{SURVEY_ID}/responses/bulk",
headers=SM_H, params={"page": page_num, "per_page": 100})
if r.status_code == 429:
retry = int(r.headers.get("X-Ratelimit-App-Global-Day-Reset", 60))
print(f"Rate limited — daily limit. Retry in {retry}s")
time.sleep(min(retry, 60))
continue
r.raise_for_status()
data = r.json()
batch = data.get("data", [])
all_responses.extend(batch)
total = data.get("total", 0)
if len(all_responses) >= total or not batch:
break
page_num += 1
time.sleep(0.6)
print(f"Fetched {len(all_responses)} responses")
# 3. Aggregate answers by question
qa_data = defaultdict(list)
for resp in all_responses:
for page_data in resp.get("pages", []):
for q_data in page_data.get("questions", []):
qid = q_data["id"]
for ans in q_data.get("answers", []):
if "text" in ans:
qa_data[qid].append(ans["text"])
elif "choice_id" in ans:
label = choice_labels.get(ans["choice_id"], ans["choice_id"])
qa_data[qid].append(label)
if "row_id" in ans:
row = choice_labels.get(ans["row_id"], "")
qa_data[qid][-1] = f"{row}: {label}"
# 4. Build analysis summary
summary_parts = []
for qid, answers in qa_data.items():
q_info = questions.get(qid, {})
title = q_info.get("title", qid)
q_type = q_info.get("type", "")
if q_type in ("single_choice", "multiple_choice", "matrix"):
counts = Counter(answers).most_common(10)
dist = ", ".join(f"{label}: {count} ({count/len(answers)*100:.0f}%)"
for label, count in counts)
summary_parts.append(f"**{title}** (n={len(answers)})\n {dist}")
elif q_type == "open_ended":
sample = "; ".join(answers[:15])[:500]
summary_parts.append(f"**{title}** (n={len(answers)}, open-ended)\n Samples: {sample}")
else:
try:
nums = [float(a) for a in answers if a.replace(".", "").replace("-", "").isdigit()]
if nums:
avg = sum(nums) / len(nums)
summary_parts.append(f"**{title}** (n={len(nums)}, avg={avg:.1f})")
except ValueError:
summary_parts.append(f"**{title}** (n={len(answers)})")
summary = "\n\n".join(summary_parts)
# 5. Mave analysis
analysis = requests.post(f"{MB}/mave/chat", headers=MV_H, json={
"message": f"""Analyze {len(all_responses)} survey responses from "{survey.get('title', 'Survey')}".
QUESTION-BY-QUESTION DATA:
{summary}
Tasks:
1) Statistical patterns: Correlations between questions, unexpected distributions
2) Sentiment trends: Overall and per-question sentiment analysis
3) Key findings: Top 5 insights ranked by impact
4) Segment differences: Any visible subgroups in the data
5) Red flags: Responses that indicate problems or risks
6) Recommendations: 5 actionable next steps based on the data
7) Suggested follow-up questions: What should you ask next?"""
}).json()
print(f"\n{'='*60}")
print(f"ANALYSIS: {survey.get('title', 'Survey')} ({len(all_responses)} responses)")
print(f"{'='*60}")
print(analysis.get("content", "")[:3000])
print(f"\nSources: {len(analysis.get('sources', []))}")