feat(rate-limit): implement Token Bucket algorithm for rate-limiting middleware for search API protection#1669
Conversation
|
🎉 Welcome to Hybrid Recommender, @koushik-gupta! This is your first contribution here! Labels added: PR Description Checklist: What happens next:
⏱️ Please respond to review comments within 48 hours. |
|
PR #1633 ("fix: Duplicate results-processing loop removed from search_items(#1631)") was just merged into Please rebase your branch to avoid conflicts: Keeping your branch up to date prevents merge conflicts. 🚀 |
|
PR #1640 ("fix: resolve hybrid_model merge conflicts and add explanation string") was just merged into Please rebase your branch to avoid conflicts: Keeping your branch up to date prevents merge conflicts. 🚀 |
|
PR #1641 ("Fix/svd memory leak") was just merged into Please rebase your branch to avoid conflicts: Keeping your branch up to date prevents merge conflicts. 🚀 |
|
PR #1642 ("Feature/evaluation dashboard") was just merged into Please rebase your branch to avoid conflicts: Keeping your branch up to date prevents merge conflicts. 🚀 |
|
PR #1643 ("Feature/streamlit tfidf config") was just merged into Please rebase your branch to avoid conflicts: Keeping your branch up to date prevents merge conflicts. 🚀 |
|
PR #1644 ("Fix/strict csrf origin validation") was just merged into Please rebase your branch to avoid conflicts: Keeping your branch up to date prevents merge conflicts. 🚀 |
|
PR #1645 ("Feature/svd online updating") was just merged into Please rebase your branch to avoid conflicts: Keeping your branch up to date prevents merge conflicts. 🚀 |
|
PR #1647 ("fix: add title query param endpoint to resolve HTTP 422 (#1075)") was just merged into Please rebase your branch to avoid conflicts: Keeping your branch up to date prevents merge conflicts. 🚀 |
|
PR #1648 ("fix(federated): prevent regularization decay in aggregate_updates") was just merged into Please rebase your branch to avoid conflicts: Keeping your branch up to date prevents merge conflicts. 🚀 |
|
PR #1650 ("fix: remove duplicate code block in hybrid_model.py causing Indentati…") was just merged into Please rebase your branch to avoid conflicts: Keeping your branch up to date prevents merge conflicts. 🚀 |
|
PR #1653 ("fix: remove duplicate /api/recommend route") was just merged into Please rebase your branch to avoid conflicts: Keeping your branch up to date prevents merge conflicts. 🚀 |
|
PR #1654 ("build: add faiss dependency for two-tower retrieval") was just merged into Please rebase your branch to avoid conflicts: Keeping your branch up to date prevents merge conflicts. 🚀 |
|
PR #1655 ("fix: enforce stronger signup password validation") was just merged into Please rebase your branch to avoid conflicts: Keeping your branch up to date prevents merge conflicts. 🚀 |
|
PR #1660 ("security: reject unissued csrf tokens") was just merged into Please rebase your branch to avoid conflicts: Keeping your branch up to date prevents merge conflicts. 🚀 |
|
PR #1661 ("feat: add KNN-based user collaborative filtering (Issue #51)") was just merged into Please rebase your branch to avoid conflicts: Keeping your branch up to date prevents merge conflicts. 🚀 |
|
PR #1665 ("fix: add missing faiss-cpu dependency to requirements.txt ") was just merged into Please rebase your branch to avoid conflicts: Keeping your branch up to date prevents merge conflicts. 🚀 |
|
PR #1515 ("feat: harden realtime recommendation WebSocket flow") was just merged into Please rebase your branch to avoid conflicts: Keeping your branch up to date prevents merge conflicts. 🚀 |
b482b5c to
379a1e6
Compare
|
PR #1668 ("fix(ci): resolve syntax and indentation errors breaking upstream main") was just merged into Please rebase your branch to avoid conflicts: Keeping your branch up to date prevents merge conflicts. 🚀 |
…tection Closes leonagoel#887 - Upgraded _apply_rate_limit() from a sliding-window (list of timestamps) to a true **Token Bucket** algorithm (tokens + last_updated dict per bucket). Each (scope, client_ip) pair gets its own bucket that refills continuously at ate_limit / 60 tokens per second. A request is allowed instantly when >= 1 token is available; excess requests receive a standards-compliant 429. - Removed the **duplicate** definitions of _get_rate_limit, _rate_limit_exceeded_response, and _apply_rate_limit that existed at two separate locations due to a prior merge conflict. - Added missing _model_lock = Lock() global that was referenced but never defined, fixing a NameError in the recommendation endpoint. - Removed orphaned eturn result statement from _clear_response_cache(). - Fixed celery_app.py indentation and NameError (�pp -> celery_app). - Fixed src/model/hybrid_model.py rogue merge conflict block inside select_bandit_arm that caused an IndentationError. - Updated ests/test_patches.py to use the correct Token Bucket bucket structure and full _apply_rate_limit() signature. - Documented all rate-limiting env variables in .env.example. ` capacity = rate_limit # max burst = full-minute quota refill_rate = rate_limit / 60.0 # tokens per second tokens = min(capacity, tokens + elapsed * refill_rate) if tokens >= 1: allow (tokens -= 1) else: 429 ` - test_search_rate_limit_returns_headers_before_limit PASSED - test_search_rate_limit_rejects_excess_requests PASSED - test_non_limited_endpoint_does_not_emit_rate_limit_headers PASSED - test_github_webhook_uses_rate_limit_scope PASSED - test_similar_rate_limit_rejects_excess_requests PASSED - test_rate_limiter_dos_mitigation_speed PASSED (< 2ms under 5k IPs)
379a1e6 to
3a452af
Compare
What changed
Implements a Token Bucket rate-limiting algorithm for the
/api/searchendpoint to protect it from scraper floods and rapid automation, as requested in Issue #887.Core changes
backend/main.py: Upgraded_apply_rate_limit()from a sliding-window list to a true Token Bucket algorithm. Each(scope, client_ip)pair gets its own bucket with continuous token refill atrate_limit / 60tokens/second. Requests are allowed when ≥ 1 token is available; excess requests receive a 429._model_lock = Lock()global and orphanedreturn resultin_clear_response_cache().celery_app.py: Fixed IndentationError/NameError from upstream.src/model/hybrid_model.py: Removed rogue merge-conflict block inselect_bandit_arm.tests/test_patches.py: Updated to use correct Token Bucket bucket format and full function signature..env.example: Documented allRATE_LIMIT_*_PER_MINenvironment variables.How Token Bucket works
Test results
test_search_rate_limit_returns_headers_before_limit✅test_search_rate_limit_rejects_excess_requests✅test_non_limited_endpoint_does_not_emit_rate_limit_headers✅test_github_webhook_uses_rate_limit_scope✅test_similar_rate_limit_rejects_excess_requests✅test_rate_limiter_dos_mitigation_speed✅ (< 2ms under 5,000 IP load)Closes #887