|
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 |
|
|
|
|
|
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: |
|
|
|
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 username in current_data['userid'].values: |
|
return "exist" |
|
|
|
|
|
new_row = pd.DataFrame([{ |
|
'userid': username, |
|
'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 |
|
) |
|
|
|
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: |
|
|
|
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: |
|
|
|
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 attempt < MAX_RETRIES - 1: |
|
continue |
|
|
|
|
|
if error and "Conflict" in str(error) and attempt < MAX_RETRIES - 1: |
|
continue |
|
|
|
|
|
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: |
|
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) |
|
) |
|
|
|
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) |
|
|
|
|
|
demo.load( |
|
fn=update_ui, |
|
inputs=None, |
|
outputs=[welcome_msg, join_button, status_msg] |
|
) |
|
|
|
|
|
join_button.click(join_waitlist, None, status_msg) |
|
|
|
if __name__ == "__main__": |
|
demo.queue().launch() |