File size: 5,924 Bytes
fd5705b
 
 
 
 
 
5921b80
fd5705b
 
 
 
 
942117f
 
 
c993b98
6f5edf8
c993b98
6f5edf8
 
c993b98
6f5edf8
 
c993b98
6f5edf8
 
 
c993b98
6f5edf8
 
 
9e3cf80
6f5edf8
 
 
 
 
 
 
 
 
 
 
 
 
 
9e3cf80
 
 
 
6f5edf8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
fd5705b
9d0662a
 
 
1f8ef74
fd5705b
 
9d0662a
1f8ef74
fd5705b
942117f
 
fd5705b
 
942117f
 
 
9e3cf80
 
 
 
 
942117f
 
b531ecc
 
 
 
 
fd5705b
b531ecc
942117f
 
 
 
5fa7c4d
942117f
 
 
 
fd5705b
 
942117f
fd5705b
 
 
942117f
 
1f8ef74
 
 
 
fd5705b
 
2709379
fd5705b
 
1f8ef74
 
 
 
942117f
ffaa42f
5921b80
9d0662a
5921b80
ffaa42f
 
 
 
 
 
5921b80
 
ffaa42f
 
 
 
 
 
5921b80
fd5705b
80bb3ea
fd5705b
2010338
fd5705b
 
 
 
9d0662a
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
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("""
    # UPDATE: Hugging Snap Available on Apple Store - you can download it for free. No need to wait!!
    """)


if __name__ == "__main__":
    demo.queue().launch()