import gradio as gr import requests import os from dotenv import load_dotenv load_dotenv() GITHUB_CLIENT_ID = os.getenv("GITHUB_CLIENT_ID") GITHUB_CLIENT_SECRET = os.getenv("GITHUB_CLIENT_SECRET") GITHUB_GRAPHQL = "https://api.github.com/graphql" # ---------------- OAuth helpers ---------------- def exchange_code_for_token(code: str) -> str: url = "https://github.com/login/oauth/access_token" headers = {"Accept": "application/json"} data = { "client_id": GITHUB_CLIENT_ID, "client_secret": GITHUB_CLIENT_SECRET, "code": code, } r = requests.post(url, headers=headers, data=data, timeout=20) r.raise_for_status() token = r.json().get("access_token") if not token: raise RuntimeError("GitHub OAuth failed: no access token returned") return token # ---------------- GitHub API ---------------- def github_graphql(query, token): headers = { "Authorization": f"Bearer {token}", "Content-Type": "application/json", } r = requests.post(GITHUB_GRAPHQL, json={"query": query}, headers=headers, timeout=30) r.raise_for_status() return r.json() def fetch_github_wrapped(token): query = """ query { viewer { login contributionsCollection( from: "2025-01-01T00:00:00Z", to: "2025-12-31T23:59:59Z" ) { contributionCalendar { totalContributions } totalCommitContributions totalPullRequestContributions totalIssueContributions } repositories( first: 100, ownerAffiliations: OWNER, orderBy: { field: STARGAZERS, direction: DESC } ) { nodes { name stargazerCount primaryLanguage { name } } } } } """ viewer = github_graphql(query, token)["data"]["viewer"] repos = viewer["repositories"]["nodes"] languages = {} for r in repos: if r["primaryLanguage"]: lang = r["primaryLanguage"]["name"] languages[lang] = languages.get(lang, 0) + 1 return { "username": viewer["login"], "total": viewer["contributionsCollection"]["contributionCalendar"]["totalContributions"], "commits": viewer["contributionsCollection"]["totalCommitContributions"], "prs": viewer["contributionsCollection"]["totalPullRequestContributions"], "issues": viewer["contributionsCollection"]["totalIssueContributions"], "top_language": max(languages, key=languages.get) if languages else "Unknown", "top_repo": repos[0]["name"] if repos else "None", } # ---------------- UI ---------------- def render_wrapped(stats): return f"""

🎉 GitHub Wrapped 2025

@{stats['username']}

🔥 {stats['total']} Contributions
💻 {stats['commits']} Commits
🔁 {stats['prs']} PRs
🐞 {stats['issues']} Issues

✨ Your Coding Style

Favorite Language: {stats['top_language']}

Top Starred Repo: {stats['top_repo']}

Keep shipping amazing code in 2026 🚀

""" def router(request: gr.Request): code = request.query_params.get("code") if not code: return f"""

🎁 GitHub Wrapped 2025

""" token = exchange_code_for_token(code) stats = fetch_github_wrapped(token) return render_wrapped(stats) with gr.Blocks(theme=gr.themes.Soft()) as demo: output = gr.HTML() demo.load(router, None, output) demo.launch(ssr_mode=False,debug=True)