File size: 6,016 Bytes
fd5705b
 
 
 
 
 
5921b80
fd5705b
 
 
 
 
942117f
 
 
c993b98
942117f
c993b98
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
942117f
c993b98
 
 
942117f
ed698f3
c993b98
942117f
c993b98
 
 
 
 
 
 
 
942117f
c993b98
 
 
 
 
 
fd5705b
9d0662a
 
 
1f8ef74
fd5705b
 
9d0662a
1f8ef74
fd5705b
942117f
 
fd5705b
 
942117f
 
 
 
 
 
fd5705b
 
942117f
 
 
 
5fa7c4d
942117f
 
 
 
fd5705b
 
942117f
fd5705b
 
 
942117f
 
1f8ef74
 
 
 
fd5705b
 
2709379
fd5705b
 
1f8ef74
 
 
 
942117f
ffaa42f
5921b80
9d0662a
5921b80
ffaa42f
 
 
 
 
 
5921b80
 
ffaa42f
 
 
 
 
 
5921b80
fd5705b
80bb3ea
fd5705b
 
5921b80
fd5705b
 
9d0662a
5921b80
 
 
9d0662a
5921b80
 
 
 
 
 
9d0662a
 
 
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
157
158
159
160
161
162
163
164
165
166
167
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:
        print(f"First error {str(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 None

    # 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)
        
        try:
            operation = CommitOperationAdd(
                path_in_repo="waitlist.csv",
                path_or_fileobj=tmp.name
            )
        except Exception as e:
            print(f"CommitOperationAdd {str(e)}")     

        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:
            print(f"Second error {str(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 is None:  # Success or already registered
                # Verify user is in the list
                verification_data = pd.read_csv(
                    f"https://huggingface.co/datasets/{DATASET_REPO}/raw/main/waitlist.csv"
                )
                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()