freddyaboulton HF Staff commited on
Commit
6842903
Β·
verified Β·
1 Parent(s): bd5657b

Upload folder using huggingface_hub

Browse files
Files changed (4) hide show
  1. README.md +7 -7
  2. requirements.txt +2 -0
  3. run.ipynb +1 -0
  4. run.py +114 -0
README.md CHANGED
@@ -1,12 +1,12 @@
 
1
  ---
2
- title: Rate Limit Main
3
- emoji: πŸ“š
4
- colorFrom: red
5
- colorTo: red
6
  sdk: gradio
7
  sdk_version: 5.43.1
8
- app_file: app.py
9
  pinned: false
 
10
  ---
11
-
12
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
+
2
  ---
3
+ title: rate_limit_main
4
+ emoji: πŸ”₯
5
+ colorFrom: indigo
6
+ colorTo: indigo
7
  sdk: gradio
8
  sdk_version: 5.43.1
9
+ app_file: run.py
10
  pinned: false
11
+ hf_oauth: true
12
  ---
 
 
requirements.txt ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ gradio-client @ git+https://github.com/gradio-app/gradio@e16e45c57d0293dd82b40c6ba6260100544937f3#subdirectory=client/python
2
+ https://gradio-pypi-previews.s3.amazonaws.com/e16e45c57d0293dd82b40c6ba6260100544937f3/gradio-5.43.1-py3-none-any.whl
run.ipynb ADDED
@@ -0,0 +1 @@
 
 
1
+ {"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: rate_limit"]}, {"cell_type": "code", "execution_count": null, "id": "272996653310673477252411125948039410165", "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": "288918539441861185822528903084949547379", "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "from datetime import datetime, timedelta\n", "from collections import defaultdict\n", "import threading\n", "\n", "rate_limit_data = defaultdict(list)\n", "lock = threading.Lock()\n", "\n", "UNAUTH_RATE_LIMIT = 3\n", "AUTH_RATE_LIMIT = 30\n", "RATE_LIMIT_WINDOW = 60\n", "\n", "def clean_old_entries(user_id):\n", " \"\"\"Remove entries older than the rate limit window\"\"\"\n", " current_time = datetime.now()\n", " cutoff_time = current_time - timedelta(seconds=RATE_LIMIT_WINDOW)\n", " rate_limit_data[user_id] = [\n", " timestamp for timestamp in rate_limit_data[user_id]\n", " if timestamp > cutoff_time\n", " ]\n", "\n", "def get_user_identifier(profile: gr.OAuthProfile | None, request: gr.Request) -> tuple[str, bool]:\n", " \"\"\"Get user identifier and whether they're authenticated\"\"\"\n", " if profile is not None:\n", " return profile.username, True\n", " else:\n", " if request:\n", " return f\"ip_{request.client.host}\", False\n", " return \"ip_unknown\", False\n", "\n", "def check_rate_limit(user_id: str, is_authenticated: bool) -> tuple[bool, int, int]:\n", " \"\"\"\n", " Check if user has exceeded rate limit\n", " Returns: (can_proceed, clicks_used, max_clicks)\n", " \"\"\"\n", " with lock:\n", " clean_old_entries(user_id)\n", " \n", " max_clicks = AUTH_RATE_LIMIT if is_authenticated else UNAUTH_RATE_LIMIT\n", " clicks_used = len(rate_limit_data[user_id])\n", " \n", " can_proceed = clicks_used < max_clicks\n", " \n", " return can_proceed, clicks_used, max_clicks\n", "\n", "def add_click(user_id: str):\n", " \"\"\"Add a click timestamp for the user\"\"\"\n", " with lock:\n", " rate_limit_data[user_id].append(datetime.now())\n", "\n", "def update_status(profile: gr.OAuthProfile | None, request: gr.Request) -> str:\n", " \"\"\"Update the status message showing current rate limit info\"\"\"\n", " user_id, is_authenticated = get_user_identifier(profile, request)\n", " _, clicks_used, max_clicks = check_rate_limit(user_id, is_authenticated)\n", " \n", " if is_authenticated:\n", " return f\"\u2705 You are logged in as '{profile.username}'. You have clicked {clicks_used} times this minute. You have {max_clicks} total clicks per minute.\" # type: ignore\n", " else:\n", " return f\"\u26a0\ufe0f You are not logged in. You have clicked {clicks_used} times this minute. You have {max_clicks} total clicks per minute.\"\n", "\n", "def run_action(profile: gr.OAuthProfile | None, request: gr.Request) -> tuple[str, str]:\n", " \"\"\"Handle the run button click with rate limiting\"\"\"\n", " user_id, is_authenticated = get_user_identifier(profile, request)\n", " can_proceed, clicks_used, max_clicks = check_rate_limit(user_id, is_authenticated)\n", " \n", " if not can_proceed:\n", " result = f\"\u274c Rate limit exceeded! You've used all {max_clicks} clicks for this minute. Please wait before trying again.\"\n", " status = update_status(profile, request)\n", " return result, status\n", " \n", " add_click(user_id)\n", " \n", " _, new_clicks_used, _ = check_rate_limit(user_id, is_authenticated)\n", " \n", " result = f\"\u2705 Action executed successfully! (Click #{new_clicks_used})\"\n", " status = update_status(profile, request)\n", " \n", " return result, status\n", "\n", "with gr.Blocks(title=\"Rate Limiting Demo\") as demo:\n", " gr.Markdown(\"# Rate Limiting Demo App\")\n", " gr.Markdown(\"This app demonstrates rate limiting based on authentication status.\")\n", " \n", " gr.LoginButton()\n", " \n", " status_text = gr.Markdown(\"Loading status...\")\n", " \n", " with gr.Row():\n", " run_btn = gr.Button(\"\ud83d\ude80 Run Action\", variant=\"primary\", scale=1)\n", " \n", " result_text = gr.Markdown(\"\")\n", " \n", " demo.load(update_status, inputs=None, outputs=status_text)\n", " \n", " run_btn.click(\n", " run_action,\n", " inputs=None,\n", " outputs=[result_text, status_text]\n", " )\n", " \n", " gr.Markdown(\"---\")\n", " gr.Markdown(\"\"\"\n", " ### Rate Limits:\n", " - **Not logged in:** 3 clicks per minute (based on IP address)\n", " - **Logged in:** 30 clicks per minute (based on HF username)\n", " \n", " ### How it works:\n", " - Click the **Login** button to authenticate with Hugging Face\n", " - Click the **Run Action** button to test the rate limiting\n", " - The system tracks your clicks over a rolling 1-minute window\n", " \"\"\")\n", "\n", "if __name__ == \"__main__\":\n", " demo.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5}
run.py ADDED
@@ -0,0 +1,114 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from datetime import datetime, timedelta
3
+ from collections import defaultdict
4
+ import threading
5
+
6
+ rate_limit_data = defaultdict(list)
7
+ lock = threading.Lock()
8
+
9
+ UNAUTH_RATE_LIMIT = 3
10
+ AUTH_RATE_LIMIT = 30
11
+ RATE_LIMIT_WINDOW = 60
12
+
13
+ def clean_old_entries(user_id):
14
+ """Remove entries older than the rate limit window"""
15
+ current_time = datetime.now()
16
+ cutoff_time = current_time - timedelta(seconds=RATE_LIMIT_WINDOW)
17
+ rate_limit_data[user_id] = [
18
+ timestamp for timestamp in rate_limit_data[user_id]
19
+ if timestamp > cutoff_time
20
+ ]
21
+
22
+ def get_user_identifier(profile: gr.OAuthProfile | None, request: gr.Request) -> tuple[str, bool]:
23
+ """Get user identifier and whether they're authenticated"""
24
+ if profile is not None:
25
+ return profile.username, True
26
+ else:
27
+ if request:
28
+ return f"ip_{request.client.host}", False
29
+ return "ip_unknown", False
30
+
31
+ def check_rate_limit(user_id: str, is_authenticated: bool) -> tuple[bool, int, int]:
32
+ """
33
+ Check if user has exceeded rate limit
34
+ Returns: (can_proceed, clicks_used, max_clicks)
35
+ """
36
+ with lock:
37
+ clean_old_entries(user_id)
38
+
39
+ max_clicks = AUTH_RATE_LIMIT if is_authenticated else UNAUTH_RATE_LIMIT
40
+ clicks_used = len(rate_limit_data[user_id])
41
+
42
+ can_proceed = clicks_used < max_clicks
43
+
44
+ return can_proceed, clicks_used, max_clicks
45
+
46
+ def add_click(user_id: str):
47
+ """Add a click timestamp for the user"""
48
+ with lock:
49
+ rate_limit_data[user_id].append(datetime.now())
50
+
51
+ def update_status(profile: gr.OAuthProfile | None, request: gr.Request) -> str:
52
+ """Update the status message showing current rate limit info"""
53
+ user_id, is_authenticated = get_user_identifier(profile, request)
54
+ _, clicks_used, max_clicks = check_rate_limit(user_id, is_authenticated)
55
+
56
+ if is_authenticated:
57
+ return f"βœ… You are logged in as '{profile.username}'. You have clicked {clicks_used} times this minute. You have {max_clicks} total clicks per minute." # type: ignore
58
+ else:
59
+ return f"⚠️ You are not logged in. You have clicked {clicks_used} times this minute. You have {max_clicks} total clicks per minute."
60
+
61
+ def run_action(profile: gr.OAuthProfile | None, request: gr.Request) -> tuple[str, str]:
62
+ """Handle the run button click with rate limiting"""
63
+ user_id, is_authenticated = get_user_identifier(profile, request)
64
+ can_proceed, clicks_used, max_clicks = check_rate_limit(user_id, is_authenticated)
65
+
66
+ if not can_proceed:
67
+ result = f"❌ Rate limit exceeded! You've used all {max_clicks} clicks for this minute. Please wait before trying again."
68
+ status = update_status(profile, request)
69
+ return result, status
70
+
71
+ add_click(user_id)
72
+
73
+ _, new_clicks_used, _ = check_rate_limit(user_id, is_authenticated)
74
+
75
+ result = f"βœ… Action executed successfully! (Click #{new_clicks_used})"
76
+ status = update_status(profile, request)
77
+
78
+ return result, status
79
+
80
+ with gr.Blocks(title="Rate Limiting Demo") as demo:
81
+ gr.Markdown("# Rate Limiting Demo App")
82
+ gr.Markdown("This app demonstrates rate limiting based on authentication status.")
83
+
84
+ gr.LoginButton()
85
+
86
+ status_text = gr.Markdown("Loading status...")
87
+
88
+ with gr.Row():
89
+ run_btn = gr.Button("πŸš€ Run Action", variant="primary", scale=1)
90
+
91
+ result_text = gr.Markdown("")
92
+
93
+ demo.load(update_status, inputs=None, outputs=status_text)
94
+
95
+ run_btn.click(
96
+ run_action,
97
+ inputs=None,
98
+ outputs=[result_text, status_text]
99
+ )
100
+
101
+ gr.Markdown("---")
102
+ gr.Markdown("""
103
+ ### Rate Limits:
104
+ - **Not logged in:** 3 clicks per minute (based on IP address)
105
+ - **Logged in:** 30 clicks per minute (based on HF username)
106
+
107
+ ### How it works:
108
+ - Click the **Login** button to authenticate with Hugging Face
109
+ - Click the **Run Action** button to test the rate limiting
110
+ - The system tracks your clicks over a rolling 1-minute window
111
+ """)
112
+
113
+ if __name__ == "__main__":
114
+ demo.launch()