GithubWrapped / app.py
Pranesh64's picture
Added debugging
86d7d71 verified
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"""
<div style="
font-family: Poppins, sans-serif;
padding: 40px;
background: linear-gradient(135deg,#0f2027,#203a43,#2c5364);
color: white;
border-radius: 24px;
max-width: 900px;
margin: auto;
">
<h1 style="text-align:center;font-size:3em;">πŸŽ‰ GitHub Wrapped 2025</h1>
<h2 style="text-align:center;">@{stats['username']}</h2>
<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:20px;margin-top:40px;">
<div class="card">πŸ”₯ {stats['total']} Contributions</div>
<div class="card">πŸ’» {stats['commits']} Commits</div>
<div class="card">πŸ” {stats['prs']} PRs</div>
<div class="card">🐞 {stats['issues']} Issues</div>
</div>
<div style="margin-top:40px;">
<h3>✨ Your Coding Style</h3>
<p><b>Favorite Language:</b> {stats['top_language']}</p>
<p><b>Top Starred Repo:</b> {stats['top_repo']}</p>
</div>
<p style="text-align:center;margin-top:40px;">
Keep shipping amazing code in 2026 πŸš€
</p>
</div>
<style>
.card {{
background: rgba(255,255,255,0.15);
padding: 26px;
border-radius: 18px;
font-size: 1.4em;
font-weight: 600;
text-align: center;
backdrop-filter: blur(8px);
}}
</style>
"""
def router(request: gr.Request):
code = request.query_params.get("code")
if not code:
return f"""
<div style="text-align:center;padding:40px;">
<h1>🎁 GitHub Wrapped 2025</h1>
<a href="https://github.com/login/oauth/authorize
?client_id={GITHUB_CLIENT_ID}
&scope=read:user repo">
<button style="font-size:18px;padding:14px 24px;border-radius:10px;">
Login with GitHub
</button>
</a>
</div>
"""
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)