| """ICML 2026 Open Reproductions β Certificate Generator |
| ======================================================= |
| 1. Sign in with Hugging Face (OAuth). |
| 2. Eligibility is checked against the frozen challenge verdicts: every |
| participant with at least one claim judged `verified` qualifies |
| (baked into eligible.json at challenge close β 267 participants). |
| 3. The display name is editable; the certificate renders to PNG with headless |
| Chromium (installed via packages.txt) β no external renderer dependency. |
| """ |
|
|
| import json |
| import os |
| import shutil |
| import subprocess |
| import tempfile |
| import urllib.parse |
| from html import escape |
|
|
| import gradio as gr |
| import uvicorn |
| from fastapi import FastAPI |
| from fastapi.responses import RedirectResponse |
|
|
| DISCUSSIONS_URL = "https://huggingface.co/spaces/ICML-2026-agent-repro/challenge/discussions" |
| CANVAS = (2000, 1414) |
|
|
| _HERE = os.path.dirname(__file__) |
| with open(os.path.join(_HERE, "certificate_template.html"), encoding="utf-8") as f: |
| TEMPLATE = f.read() |
| with open(os.path.join(_HERE, "eligible.json"), encoding="utf-8") as f: |
| ELIGIBLE = json.load(f) |
|
|
|
|
| def find_chromium(): |
| candidates = [ |
| "chromium", "chromium-browser", "google-chrome", "google-chrome-stable", |
| "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome", |
| ] |
| for c in candidates: |
| path = shutil.which(c) or (c if os.path.exists(c) else None) |
| if path: |
| return path |
| raise RuntimeError("No Chromium binary found β is `chromium` in packages.txt?") |
|
|
|
|
| def render_html(html: str) -> str: |
| out = os.path.join(tempfile.mkdtemp(), "certificate.png") |
| with tempfile.NamedTemporaryFile("w", delete=False, suffix=".html", encoding="utf-8") as f: |
| f.write(html) |
| src = f.name |
| try: |
| subprocess.run( |
| [find_chromium(), "--headless=new", "--no-sandbox", "--disable-gpu", |
| "--hide-scrollbars", "--force-device-scale-factor=1", |
| f"--window-size={CANVAS[0]},{CANVAS[1]}", f"--screenshot={out}", |
| f"file://{src}"], |
| check=True, capture_output=True, timeout=120, |
| ) |
| finally: |
| try: |
| os.unlink(src) |
| except OSError: |
| pass |
| return out |
|
|
|
|
| def plural(n, word): |
| return f"{n} {word}" + ("" if n == 1 else "s") |
|
|
|
|
| def stats_line(rec): |
| return (f"{plural(rec['verified_claims'], 'claim')} verified across " |
| f"{plural(rec['verified_papers'], 'paper')}") |
|
|
|
|
| def auth_control(profile: gr.OAuthProfile | None): |
| """Render OAuth controls that work inside the sandboxed Space iframe.""" |
| if profile is None: |
| href = "/oauth-login" |
| target = "_blank" |
| label = "π€ Sign in with Hugging Face" |
| else: |
| href = "/logout?_target_url=/" |
| target = "_self" |
| label = f"Logout (@{escape(profile.username)})" |
| return ( |
| f'<a href="{href}" target="{target}" rel="noopener" role="button" ' |
| 'style="display:inline-block;background:#111827;color:#fff;font-weight:700;' |
| 'padding:10px 18px;border-radius:8px;text-decoration:none">' |
| f"{label}</a>" |
| ) |
|
|
|
|
| def on_load(profile: gr.OAuthProfile | None): |
| if profile is None: |
| return (auth_control(profile), gr.update(visible=False), |
| "### π Sign in with Hugging Face to check your eligibility.", "") |
| rec = ELIGIBLE.get(profile.username.lower()) |
| if rec is None: |
| return (auth_control(profile), gr.update(visible=False), |
| f"### Sorry @{profile.username} β no verified logbook found.\n" |
| "Certificates go to participants with at least one claim judged " |
| "**verified** by the Logbook Judge before the Aug 2 deadline. " |
| f"If you believe this is an error, please open a thread in the " |
| f"[challenge discussions]({DISCUSSIONS_URL}).", "") |
| return (auth_control(profile), gr.update(visible=True), |
| f"### π Congratulations @{profile.username} β you qualify!\n" |
| f"Your record: **{stats_line(rec)}** ({plural(rec['logbooks'], 'logbook')} judged). " |
| "Adjust how your name should appear, then generate your certificate.", |
| profile.name or profile.username) |
|
|
|
|
| def linkedin_url(name): |
| p = { |
| "startTask": "CERTIFICATION_NAME", |
| "name": "ICML 2026 Open Reproductions β Certificate of Participation", |
| "organizationName": "Hugging Face", |
| "issueYear": "2026", "issueMonth": "8", |
| "certUrl": "https://huggingface.co/spaces/ICML-2026-agent-repro/certificate-generator", |
| } |
| return "https://www.linkedin.com/profile/add?" + urllib.parse.urlencode(p) |
|
|
|
|
| def create_certificate(display_name, profile: gr.OAuthProfile | None): |
| if profile is None: |
| return None, "β Please sign in first.", gr.update(visible=False) |
| rec = ELIGIBLE.get(profile.username.lower()) |
| if rec is None: |
| return None, "β No verified logbook found for your account.", gr.update(visible=False) |
| name = (display_name or "").strip() or profile.name or profile.username |
| html = TEMPLATE.replace("{participant_name}", name).replace("{stats_line}", stats_line(rec)) |
| try: |
| image_path = render_html(html) |
| except Exception as e: |
| return None, f"β Rendering failed: {e}. Please try again in a minute.", gr.update(visible=False) |
| btn = (f'<a href="{linkedin_url(name)}" target="_blank" ' |
| f'style="display:inline-block;background:#0a66c2;color:#fff;font-weight:700;' |
| f'padding:10px 22px;border-radius:8px;text-decoration:none">Add to LinkedIn profile β</a>') |
| return image_path, "π Your certificate is ready β download it or add it to your LinkedIn profile below.", gr.update(value=btn, visible=True) |
|
|
|
|
| THEME = gr.themes.Base( |
| primary_hue=gr.themes.colors.orange, |
| neutral_hue=gr.themes.colors.stone, |
| ) |
|
|
| CSS = """ |
| .gradio-container { |
| background-color: #fdfcf9 !important; |
| background-image: |
| linear-gradient(rgba(31,41,55,.045) 1px, transparent 1px), |
| linear-gradient(90deg, rgba(31,41,55,.045) 1px, transparent 1px); |
| background-size: 26px 26px; |
| } |
| .dark .gradio-container { |
| background-color: #17181c !important; |
| background-image: |
| linear-gradient(rgba(253,252,249,.04) 1px, transparent 1px), |
| linear-gradient(90deg, rgba(253,252,249,.04) 1px, transparent 1px); |
| } |
| #hero h1 { font-family: ui-serif, "Iowan Old Style", Georgia, serif; } |
| """ |
|
|
| with gr.Blocks(title="ICML 2026 Open Reproductions β Certificates", theme=THEME, css=CSS) as demo: |
| gr.Markdown("# π ICML 2026 Open Reproductions β Certificate of Participation", elem_id="hero") |
| gr.Markdown( |
| "Every participant with **at least one claim judged `verified`** in the challenge " |
| "(July 15 β August 2, 2026) can generate their certificate here." |
| ) |
| |
| |
| |
| gr.LoginButton(visible=False) |
| auth = gr.HTML() |
| status = gr.Markdown() |
| with gr.Column(visible=False) as main_box: |
| name_box = gr.Textbox(label="Name on the certificate") |
| gen_btn = gr.Button("Generate my certificate π", variant="primary") |
| cert_image = gr.Image(label="Your certificate", type="filepath", interactive=False) |
| note = gr.Markdown() |
| linkedin = gr.HTML(visible=False) |
|
|
| demo.load(on_load, inputs=None, outputs=[auth, main_box, status, name_box]) |
| gen_btn.click(create_certificate, inputs=[name_box], outputs=[cert_image, note, linkedin]) |
|
|
|
|
| app = FastAPI(docs_url=None, redoc_url=None, openapi_url=None) |
|
|
|
|
| @app.get("/oauth-login", include_in_schema=False) |
| def oauth_login(): |
| """Start OAuth after removing session state left by an interrupted login.""" |
| response = RedirectResponse("/login/huggingface?_target_url=/", status_code=303) |
| response.delete_cookie( |
| "session", path="/", secure=True, httponly=True, samesite="none" |
| ) |
| return response |
|
|
|
|
| |
| |
| |
| app = gr.mount_gradio_app(app, demo, path="/", ssr_mode=False) |
|
|
|
|
| if __name__ == "__main__": |
| uvicorn.run( |
| app, |
| host=os.getenv("GRADIO_SERVER_NAME", "0.0.0.0"), |
| port=int(os.getenv("GRADIO_SERVER_PORT", "7860")), |
| ) |
|
|