mfarre's picture
mfarre HF staff
update
9e3cf80
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, Tuple
# Initialize Hugging Face client
hf_api = HfApi(token=os.getenv("HF_TOKEN"))
DATASET_REPO = "HuggingFaceTB/smolvlm2-iphone-waitlist"
MAX_RETRIES = 3
def commit_signup(username: str) -> Optional[str]:
"""Attempt to commit new signup atomically, always reading latest data before commit"""
try:
# Always get the latest data right before committing
try:
file_content = hf_api.hf_hub_download(
repo_id=DATASET_REPO,
repo_type="dataset",
filename="waitlist.csv",
token=os.getenv("HF_TOKEN")
)
current_data = pd.read_csv(file_content)
if 'userid' not in current_data.columns or 'joined_at' not in current_data.columns:
current_data = pd.DataFrame(columns=['userid', 'joined_at'])
except Exception as e:
current_data = pd.DataFrame(columns=['userid', 'joined_at'])
# If user already exists in the latest data, don't add them again
if username in current_data['userid'].values:
return "exist"
# Add new user with timestamp
new_row = pd.DataFrame([{
'userid': username,
'joined_at': datetime.utcnow().isoformat()
}])
# Combine with latest data
updated_data = pd.concat([current_data, new_row], ignore_index=True)
# Save to temp file
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
)
try:
create_commit(
repo_id=DATASET_REPO,
repo_type="dataset",
operations=[operation],
commit_message=f"Add user {username} to waitlist",
token=os.getenv("HF_TOKEN"),
)
os.unlink(tmp.name)
return None
except Exception as e:
os.unlink(tmp.name)
return str(e)
except Exception as e:
return str(e)
def join_waitlist(
profile: gr.OAuthProfile | None,
oauth_token: gr.OAuthToken | None
) -> gr.update:
"""Add user to the SmolVLM2 iPhone waitlist with retry logic for concurrent updates"""
if profile is None or oauth_token is None:
return gr.update(value="Please log in with your Hugging Face account first!")
username = profile.username
for attempt in range(MAX_RETRIES):
try:
# Try to commit the update (which will get latest data internally)
error = commit_signup(username)
if error == "exist":
return gr.update(
value="## You are already in our waitlist, we will come back with news soon!",
visible=True
)
if error is None: # Success or already registered
# Verify user is in the list
file_content = hf_api.hf_hub_download(
repo_id=DATASET_REPO,
repo_type="dataset",
filename="waitlist.csv",
token=os.getenv("HF_TOKEN")
)
verification_data = pd.read_csv(file_content)
if username in verification_data['userid'].values:
return gr.update(
value="## 🎉 Thanks for joining the waitlist! We'll keep you updated on SmolVLM2 iPhone app.",
visible=True
)
# If verification failed and we have retries left, try again
if attempt < MAX_RETRIES - 1:
continue
# If we got a conflict error, retry
if error and "Conflict" in str(error) and attempt < MAX_RETRIES - 1:
continue
# Other error or last attempt
if error:
gr.Error(f"An error occurred: {str(error)}")
return gr.update(
value="## 🫠 Sorry, something went wrong. Please try again later.",
visible=True
)
except Exception as e:
print(str(e))
if attempt == MAX_RETRIES - 1: # Last attempt
gr.Error(f"An error occurred: {str(e)}")
return gr.update(
value="## 🫠 Sorry, something went wrong. Please try again later.",
visible=True
)
def update_ui(profile: gr.OAuthProfile | None) -> Tuple[gr.update, gr.update, gr.update]:
"""Update UI elements based on login status"""
if profile is None:
return (
gr.update(
value="## Please sign in with your Hugging Face account to join the waitlist.",
visible=True
),
gr.update(visible=False),
gr.update(visible=False)
)
return (
gr.update(
value=f"## Welcome {profile.name} 👋 Click the button below 👇 to receive any updates related with the SmolVLM2 iPhone application",
visible=True
),
gr.update(visible=True),
gr.update(visible=True)
)
# Create the interface
with gr.Blocks(title="SmolVLM2 Waitlist") as demo:
gr.Markdown("""
# Join SmolVLM2 iPhone Waitlist 📱
## Please log-in using your Hugging Face Id to continue
""")
gr.LoginButton()
welcome_msg = gr.Markdown(visible=True)
join_button = gr.Button("Join Waitlist", variant="primary", visible=False)
status_msg = gr.Markdown(visible=False)
# Update UI elements on load and auth change
demo.load(
fn=update_ui,
inputs=None,
outputs=[welcome_msg, join_button, status_msg]
)
# Handle join button click
join_button.click(join_waitlist, None, status_msg)
if __name__ == "__main__":
demo.queue().launch()