Spaces:
Sleeping
Sleeping
| """Nalandadata — contact / data-licensing lead form. | |
| A Gradio Space that captures licensing enquiries and appends each one as a row to | |
| the PRIVATE Nalandadata/leads dataset. | |
| Auth: reads a write-scoped token from the Space secret HF_WRITE_TOKEN. | |
| """ | |
| import os | |
| import io | |
| import csv | |
| import datetime | |
| import gradio as gr | |
| from huggingface_hub import HfApi, hf_hub_download | |
| LEADS_REPO = "Nalandadata/leads" | |
| LEADS_FILE = "leads.csv" | |
| TOKEN = os.environ.get("HF_WRITE_TOKEN") # set as a Space secret | |
| SITE = "https://nalandadata.ai/?utm_source=huggingface&utm_medium=contact_space&utm_campaign=lead_form" | |
| DATASETS = [ | |
| "NalandaJEENEETBench", | |
| "nalanda-image-qa", | |
| "DrishtiTable", | |
| "Other / custom data", | |
| ] | |
| COLUMNS = ["timestamp", "name", "email", "organization", "role", | |
| "use_case", "datasets_of_interest", "message", "source"] | |
| api = HfApi(token=TOKEN) | |
| def _valid_email(e): | |
| return isinstance(e, str) and "@" in e and "." in e.split("@")[-1] and len(e) >= 6 | |
| def submit(name, email, organization, role, use_case, datasets, message): | |
| if not name or not name.strip(): | |
| return gr.update(value="⚠️ Please enter your name.", visible=True) | |
| if not _valid_email(email): | |
| return gr.update(value="⚠️ Please enter a valid work email.", visible=True) | |
| if not organization or not organization.strip(): | |
| return gr.update(value="⚠️ Please enter your organization.", visible=True) | |
| if not TOKEN: | |
| return gr.update( | |
| value="⚠️ The form is not yet configured (missing write token). " | |
| "Please email info@nalandadata.ai directly.", visible=True) | |
| row = { | |
| "timestamp": datetime.datetime.now(datetime.timezone.utc).isoformat(timespec="seconds"), | |
| "name": name.strip(), | |
| "email": email.strip(), | |
| "organization": organization.strip(), | |
| "role": (role or "").strip(), | |
| "use_case": (use_case or "").strip(), | |
| "datasets_of_interest": "|".join(datasets or []), | |
| "message": (message or "").strip().replace("\r", " ").replace("\n", " "), | |
| "source": "contact-space", | |
| } | |
| try: | |
| # download current leads.csv, append, re-upload | |
| try: | |
| path = hf_hub_download(LEADS_REPO, LEADS_FILE, repo_type="dataset", token=TOKEN) | |
| with open(path, encoding="utf-8") as f: | |
| existing = f.read() | |
| except Exception: | |
| existing = ",".join(COLUMNS) + "\n" | |
| buf = io.StringIO() | |
| buf.write(existing if existing.endswith("\n") else existing + "\n") | |
| w = csv.writer(buf) | |
| w.writerow([row[c] for c in COLUMNS]) | |
| data = buf.getvalue().encode("utf-8") | |
| api.upload_file( | |
| path_or_fileobj=data, | |
| path_in_repo=LEADS_FILE, | |
| repo_id=LEADS_REPO, | |
| repo_type="dataset", | |
| commit_message=f"New lead: {row['organization']} ({row['timestamp']})", | |
| ) | |
| except Exception as e: | |
| return gr.update( | |
| value=f"⚠️ Couldn't record your enquiry automatically ({type(e).__name__}). " | |
| f"Please email info@nalandadata.ai and we'll respond quickly.", | |
| visible=True) | |
| return gr.update( | |
| value=(f"✅ **Thank you, {row['name']}!** Your enquiry has been received.\n\n" | |
| f"We'll reply to **{row['email']}** shortly. " | |
| f"In the meantime, explore more at [nalandadata.ai]({SITE})."), | |
| visible=True) | |
| # Theme aligned to Nalandadata/nalanda-live-demos (dark + gold) | |
| THEME_CSS = """ | |
| :root{ | |
| --bg:#0c0c0e; --panel:#141417; --panel2:#1b1b20; --line:#2a2a31; | |
| --ink:#ece7da; --sub:#9d958a; --gold:#d8b65a; --gold2:#f0d488; | |
| --ok:#7bd88f; --err:#e08a8a; | |
| } | |
| .gradio-container, .gradio-container *{ | |
| font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif !important; | |
| -webkit-font-smoothing:antialiased; | |
| } | |
| .gradio-container{ | |
| max-width:860px !important; margin:0 auto !important; | |
| background:radial-gradient(1200px 600px at 50% -10%, #16161b 0%, var(--bg) 60%) !important; | |
| color:var(--ink) !important; | |
| } | |
| /* surrounding chrome */ | |
| body, gradio-app{ background:var(--bg) !important; } | |
| #nd-hero{ text-align:center; padding:34px 16px 6px; } | |
| #nd-hero .brand{ | |
| font-size:13px; letter-spacing:.32em; text-transform:uppercase; | |
| color:var(--gold); font-weight:600; | |
| } | |
| #nd-hero h1{ | |
| font-size:30px; font-weight:700; letter-spacing:-.01em; | |
| margin:8px 0 6px; color:var(--ink); | |
| } | |
| #nd-hero p{ | |
| color:var(--sub); font-size:14.5px; line-height:1.55; | |
| max-width:560px; margin:0 auto; | |
| } | |
| /* form card */ | |
| .gradio-container .block, .gradio-container .form{ | |
| background:var(--panel) !important; border:1px solid var(--line) !important; | |
| border-radius:14px !important; | |
| } | |
| .gradio-container label span, .gradio-container .gr-box label span{ | |
| color:var(--sub) !important; font-weight:600 !important; font-size:13px !important; | |
| } | |
| .gradio-container input[type=text], .gradio-container textarea, | |
| .gradio-container input:not([type=checkbox]){ | |
| background:var(--panel2) !important; border:1px solid var(--line) !important; | |
| color:var(--ink) !important; border-radius:10px !important; font-size:15px !important; | |
| } | |
| .gradio-container input:focus, .gradio-container textarea:focus{ | |
| outline:none !important; border-color:var(--gold) !important; box-shadow:none !important; | |
| } | |
| /* checkboxes */ | |
| .gradio-container .gr-check-radio, .gradio-container [data-testid="checkbox-group"] label{ | |
| color:var(--ink) !important; | |
| } | |
| .gradio-container input[type=checkbox]:checked{ accent-color:var(--gold) !important; } | |
| /* primary button -> gold gradient */ | |
| .gradio-container button.primary, .gradio-container .primary{ | |
| background:linear-gradient(180deg,var(--gold2),var(--gold)) !important; | |
| color:#1a1407 !important; border:none !important; font-weight:700 !important; | |
| border-radius:10px !important; | |
| } | |
| .gradio-container button.primary:hover{ filter:brightness(1.05); } | |
| /* result markdown */ | |
| #nd-result, #nd-result *{ color:var(--ink) !important; } | |
| #nd-result a{ color:var(--gold) !important; } | |
| #nd-footer{ text-align:center; margin-top:18px; font-size:12.5px; color:var(--sub); } | |
| #nd-footer a{ color:var(--gold); text-decoration:none; font-weight:500; } | |
| #nd-footer a:hover{ text-decoration:underline; } | |
| """ | |
| INTRO = """ | |
| <div id="nd-hero"> | |
| <div class="brand">Nalandadata</div> | |
| <h1>Work with us</h1> | |
| <p> | |
| We license verified, curriculum-aligned Indian STEM data for AI training, | |
| post-training, and evaluation — JEE/NEET reasoning, scientific multimodal QA, | |
| and annotated document tables. Tell us what you're building and we'll get | |
| back to you with access and licensing options. | |
| </p> | |
| </div> | |
| """ | |
| with gr.Blocks(title="Contact Nalandadata", | |
| css=THEME_CSS, | |
| theme=gr.themes.Base( | |
| primary_hue="yellow", secondary_hue="stone", | |
| neutral_hue="stone", | |
| font=["-apple-system", "BlinkMacSystemFont", "Segoe UI", "sans-serif"], | |
| )) as demo: | |
| gr.HTML(INTRO) | |
| with gr.Row(): | |
| with gr.Column(): | |
| name = gr.Textbox(label="Name *", placeholder="Your full name") | |
| email = gr.Textbox(label="Work email *", placeholder="you@company.com") | |
| organization = gr.Textbox(label="Organization *", placeholder="Company / institution") | |
| role = gr.Textbox(label="Role (optional)", placeholder="e.g. ML Lead, Researcher") | |
| with gr.Column(): | |
| datasets = gr.CheckboxGroup(DATASETS, label="Datasets of interest") | |
| use_case = gr.Textbox(label="Use case", placeholder="How do you plan to use the data/models?") | |
| message = gr.Textbox(label="Message", lines=3, placeholder="Anything else we should know?") | |
| submit_btn = gr.Button("Send enquiry", variant="primary") | |
| result = gr.Markdown(visible=False, elem_id="nd-result") | |
| submit_btn.click( | |
| submit, | |
| inputs=[name, email, organization, role, use_case, datasets, message], | |
| outputs=result, | |
| ) | |
| gr.HTML( | |
| f'<div id="nd-footer" style="text-align:center;margin-top:16px;">' | |
| f'Prefer email? <a href="mailto:info@nalandadata.ai">info@nalandadata.ai</a> · ' | |
| f'<a href="{SITE}" target="_blank">nalandadata.ai</a></div>' | |
| ) | |
| if __name__ == "__main__": | |
| demo.launch() | |