|
import os |
|
import gradio as gr |
|
from huggingface_hub import HfApi, CommitOperationAdd, create_commit |
|
import pandas as pd |
|
from datetime import datetime |
|
import tempfile |
|
from typing import Optional |
|
|
|
|
|
hf_api = HfApi(token=os.getenv("HF_TOKEN")) |
|
DATASET_REPO = "HuggingFaceTB/smolvlm2-iphone-waitlist" |
|
MAX_RETRIES = 3 |
|
|
|
def commit_signup(username: str, email: str, current_data: pd.DataFrame) -> Optional[str]: |
|
"""Attempt to commit new signup atomically""" |
|
|
|
|
|
new_row = pd.DataFrame([{ |
|
'userid': username, |
|
'email': email, |
|
'joined_at': datetime.utcnow().isoformat() |
|
}]) |
|
updated_data = pd.concat([current_data, new_row], ignore_index=True) |
|
|
|
|
|
with tempfile.NamedTemporaryFile(mode='w', suffix='.csv', delete=False) as tmp: |
|
updated_data.to_csv(tmp.name, index=False) |
|
|
|
|
|
operation = CommitOperationAdd( |
|
path_in_repo="waitlist.csv", |
|
path_or_fileobj=tmp.name, |
|
commit_message=f"Add user {username} to waitlist" |
|
) |
|
|
|
try: |
|
|
|
create_commit( |
|
repo_id=DATASET_REPO, |
|
repo_type="dataset", |
|
operations=[operation], |
|
commit_message=f"Add user {username} to waitlist" |
|
) |
|
os.unlink(tmp.name) |
|
return None |
|
except Exception as e: |
|
os.unlink(tmp.name) |
|
return str(e) |
|
|
|
def join_waitlist( |
|
token: gr.OAuthToken | None, |
|
profile: gr.OAuthProfile | None, |
|
) -> str: |
|
"""Add user to the SmolVLM2 iPhone waitlist with retry logic for concurrent updates""" |
|
|
|
if token is None or profile is None: |
|
gr.Warning("Please log in to Hugging Face first!") |
|
return None |
|
|
|
for attempt in range(MAX_RETRIES): |
|
try: |
|
|
|
try: |
|
current_data = pd.read_csv( |
|
f"https://huggingface.co/datasets/{DATASET_REPO}/raw/main/waitlist.csv" |
|
) |
|
except: |
|
current_data = pd.DataFrame(columns=['userid', 'email', 'joined_at']) |
|
|
|
|
|
if profile.username in current_data['userid'].values: |
|
return "You're already on the waitlist! We'll keep you updated." |
|
|
|
|
|
error = commit_signup(profile.username, profile.email, current_data) |
|
|
|
if error is None: |
|
return "Thanks for joining the waitlist! We'll keep you updated on SmolVLM2 iPhone app." |
|
|
|
|
|
if "Conflict" in str(error) and attempt < MAX_RETRIES - 1: |
|
continue |
|
|
|
|
|
gr.Error(f"An error occurred: {str(error)}") |
|
return "Sorry, something went wrong. Please try again later." |
|
|
|
except Exception as e: |
|
if attempt == MAX_RETRIES - 1: |
|
gr.Error(f"An error occurred: {str(e)}") |
|
return "Sorry, something went wrong. Please try again later." |
|
|
|
|
|
with gr.Blocks() as demo: |
|
gr.Markdown(""" |
|
# Join SmolVLM2 iPhone Waitlist 📱 |
|
Sign up to be notified when the SmolVLM2 iPhone app and source code are released. |
|
|
|
By joining the waitlist, you'll get: |
|
- Early access to the SmolVLM2 iPhone app |
|
- Updates on development progress |
|
- First look at the source code when available |
|
""") |
|
|
|
with gr.Row(): |
|
gr.LoginButton() |
|
|
|
join_button = gr.Button("Join Waitlist", variant="primary") |
|
output = gr.Markdown(visible=False) |
|
|
|
join_button.click( |
|
fn=join_waitlist, |
|
outputs=output, |
|
) |
|
|
|
if __name__ == "__main__": |
|
demo.launch(auth_required=True) |