import os, requests, csv, io, json
from pathlib import Path
SR, MV = os.environ["SEMRUSH_API_KEY"], os.environ["MAVERA_API_KEY"]
MB = "https://app.mavera.io/api/v1"
MH = {"Authorization": f"Bearer {MV}", "Content-Type": "application/json"}
DOMAIN, BF = "yourdomain.com", "semrush_baseline.json"
resp = requests.get("https://api.semrush.com/", params={
"type": "domain_organic", "key": SR, "domain": DOMAIN,
"database": "us", "display_limit": 100, "display_sort": "tr_desc",
"export_columns": "Ph,Po,Pp,Nq,Cp,Ur,Tr,Tc,Co,Kd",
})
reader = csv.reader(io.StringIO(resp.text), delimiter=";")
next(reader)
cur = {}
for r in reader:
if len(r) < 10: continue
cur[r[0]] = {"kw": r[0], "pos": int(r[1] or 100), "prev": int(r[2] or 100),
"vol": int(r[3] or 0), "url": r[5], "tr": float(r[6] or 0)}
bl = json.loads(Path(BF).read_text()) if Path(BF).exists() else {}
up, down, new, lost = [], [], [], []
for kw, d in cur.items():
if kw in bl:
d["chg"] = bl[kw]["pos"] - d["pos"]
(up if d["chg"] > 0 else down if d["chg"] < 0 else []).append(d)
else: d["chg"] = 0; new.append(d)
for kw in bl:
if kw not in cur: lost.append({"kw": kw, "pos": bl[kw]["pos"], "vol": bl[kw].get("vol", 0)})
up.sort(key=lambda x: x["chg"], reverse=True)
down.sort(key=lambda x: x["chg"])
Path(BF).write_text(json.dumps({k: {"pos": v["pos"], "vol": v["vol"]} for k, v in cur.items()}, indent=2))
def fmt(m):
return "\n".join(f"- \"{x['kw']}\" (vol: {x['vol']}): {x.get('prev','?')} → {x['pos']} "
f"({'+' if x.get('chg',0)>0 else ''}{x.get('chg',0)})" for x in m[:10])
total_tr = sum(d["tr"] for d in cur.values())
t10 = sum(1 for d in cur.values() if d["pos"] <= 10)
report = (f"RANKING: {DOMAIN} | KWs: {len(cur)} | Traffic: {total_tr:.0f} | Top10: {t10}\n"
f"Up: {len(up)} | Down: {len(down)} | New: {len(new)} | Lost: {len(lost)}\n\n"
f"IMPROVED:\n{fmt(up)}\n\nDECLINED:\n{fmt(down)}")
mave = requests.post(f"{MB}/mave/chat", headers=MH, json={
"message": f"Executive SEO report.\n\n{report}\n\n"
f"Include: 1) Summary (3 sentences) 2) Wins 3) Risks "
f"4) Priority actions for next 2 weeks. Plain language for VP Marketing.",
}).json()
print(mave.get("content", ""))