rate_limit_main / run.py
freddyaboulton's picture
Upload folder using huggingface_hub
6842903 verified
raw
history blame
4.1 kB
import gradio as gr
from datetime import datetime, timedelta
from collections import defaultdict
import threading
rate_limit_data = defaultdict(list)
lock = threading.Lock()
UNAUTH_RATE_LIMIT = 3
AUTH_RATE_LIMIT = 30
RATE_LIMIT_WINDOW = 60
def clean_old_entries(user_id):
"""Remove entries older than the rate limit window"""
current_time = datetime.now()
cutoff_time = current_time - timedelta(seconds=RATE_LIMIT_WINDOW)
rate_limit_data[user_id] = [
timestamp for timestamp in rate_limit_data[user_id]
if timestamp > cutoff_time
]
def get_user_identifier(profile: gr.OAuthProfile | None, request: gr.Request) -> tuple[str, bool]:
"""Get user identifier and whether they're authenticated"""
if profile is not None:
return profile.username, True
else:
if request:
return f"ip_{request.client.host}", False
return "ip_unknown", False
def check_rate_limit(user_id: str, is_authenticated: bool) -> tuple[bool, int, int]:
"""
Check if user has exceeded rate limit
Returns: (can_proceed, clicks_used, max_clicks)
"""
with lock:
clean_old_entries(user_id)
max_clicks = AUTH_RATE_LIMIT if is_authenticated else UNAUTH_RATE_LIMIT
clicks_used = len(rate_limit_data[user_id])
can_proceed = clicks_used < max_clicks
return can_proceed, clicks_used, max_clicks
def add_click(user_id: str):
"""Add a click timestamp for the user"""
with lock:
rate_limit_data[user_id].append(datetime.now())
def update_status(profile: gr.OAuthProfile | None, request: gr.Request) -> str:
"""Update the status message showing current rate limit info"""
user_id, is_authenticated = get_user_identifier(profile, request)
_, clicks_used, max_clicks = check_rate_limit(user_id, is_authenticated)
if is_authenticated:
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
else:
return f"⚠️ You are not logged in. You have clicked {clicks_used} times this minute. You have {max_clicks} total clicks per minute."
def run_action(profile: gr.OAuthProfile | None, request: gr.Request) -> tuple[str, str]:
"""Handle the run button click with rate limiting"""
user_id, is_authenticated = get_user_identifier(profile, request)
can_proceed, clicks_used, max_clicks = check_rate_limit(user_id, is_authenticated)
if not can_proceed:
result = f"❌ Rate limit exceeded! You've used all {max_clicks} clicks for this minute. Please wait before trying again."
status = update_status(profile, request)
return result, status
add_click(user_id)
_, new_clicks_used, _ = check_rate_limit(user_id, is_authenticated)
result = f"βœ… Action executed successfully! (Click #{new_clicks_used})"
status = update_status(profile, request)
return result, status
with gr.Blocks(title="Rate Limiting Demo") as demo:
gr.Markdown("# Rate Limiting Demo App")
gr.Markdown("This app demonstrates rate limiting based on authentication status.")
gr.LoginButton()
status_text = gr.Markdown("Loading status...")
with gr.Row():
run_btn = gr.Button("πŸš€ Run Action", variant="primary", scale=1)
result_text = gr.Markdown("")
demo.load(update_status, inputs=None, outputs=status_text)
run_btn.click(
run_action,
inputs=None,
outputs=[result_text, status_text]
)
gr.Markdown("---")
gr.Markdown("""
### Rate Limits:
- **Not logged in:** 3 clicks per minute (based on IP address)
- **Logged in:** 30 clicks per minute (based on HF username)
### How it works:
- Click the **Login** button to authenticate with Hugging Face
- Click the **Run Action** button to test the rate limiting
- The system tracks your clicks over a rolling 1-minute window
""")
if __name__ == "__main__":
demo.launch()