Files
troupe-standup/wizard-work/ledger/fetch_repos.py
T

63 lines
2.2 KiB
Python

#!/usr/bin/env python3
"""Fetch the top 20 most-starred public Python repos and write the artifact."""
import json
import urllib.request
import urllib.parse
from datetime import datetime, timezone
OUT = "/root/.hermes/wizard-outputs/ledger/python-repos-top20.json"
CSV_OUT = "/root/.hermes/wizard-outputs/ledger/python-repos-top20.csv"
QUERY = "language:python"
PAGE = 20
def fetch(url):
req = urllib.request.Request(url, headers={"User-Agent": "ledger-wizard"})
with urllib.request.urlopen(req, timeout=60) as r:
return json.loads(r.read().decode("utf-8"))
def main():
q = urllib.parse.quote(QUERY)
url = f"https://api.github.com/search/repositories?q={q}&sort=stars&order=desc&per_page={PAGE}"
data = fetch(url)
items = data.get("items", [])
# search API returns already-ordered by stars desc; we still enforce order.
rows = []
for i, it in enumerate(items, start=1):
rows.append({
"rank": i,
"name": it["name"],
"full_name": it["full_name"],
"owner": it["owner"]["login"],
"stars": it["stargazers_count"],
"url": it["html_url"],
"description": (it.get("description") or "").replace("\n", " ")[:400],
})
payload = {
"source": "https://api.github.com/search/repositories",
"query": f"language:python sort:stars order:desc per_page={PAGE}",
"total_count": data.get("total_count"),
"incomplete_results": data.get("incomplete_results"),
"fetched_at": datetime.now(timezone.utc).isoformat(),
"rows": rows,
}
with open(OUT, "w", encoding="utf-8") as f:
json.dump(payload, f, indent=2)
with open(CSV_OUT, "w", encoding="utf-8") as f:
f.write("rank,name,owner,stars,url,description\n")
for r in rows:
desc = r["description"].replace(",", " ").replace("\n", " ")
f.write(f'{r["rank"]},{r["name"]},{r["owner"]},{r["stars"]},{r["url"]},{desc}\n')
print(f"wrote {OUT}")
print(f"wrote {CSV_OUT}")
print(f"total_count={payload['total_count']} rows={len(rows)} top_stars={rows[0]['stars']}")
print("top:", rows[0]["full_name"], rows[0]["stars"])
if __name__ == "__main__":
main()