API Rate Limiting এবং Throttling হল দুটি গুরুত্বপূর্ণ কৌশল যা API-এর কর্মক্ষমতা এবং সুরক্ষা বজায় রাখতে সাহায্য করে। এগুলি API তে অযাচিত বা অত্যধিক রিকোয়েস্ট ব্লক করতে এবং সার্ভারের অতিরিক্ত চাপ থেকে সুরক্ষা প্রদান করতে ব্যবহৃত হয়।
Rate Limiting হল একটি পদ্ধতি যা একটি নির্দিষ্ট সময়ের মধ্যে কতগুলি রিকোয়েস্ট একটি ব্যবহারকারী বা ক্লায়েন্ট থেকে গ্রহণ করা হবে তা সীমিত করে।
Throttling হল রিকোয়েস্টের পরিমাণ সীমাবদ্ধ করার একটি কৌশল যা সার্ভারের কর্মক্ষমতা এবং প্রসেসিং শক্তি বজায় রাখে, এবং নির্দিষ্ট সময়ের মধ্যে সর্বাধিক রিকোয়েস্ট সংখ্যা সীমাবদ্ধ করে।
FastAPI তে API Rate Limiting এবং Throttling কনফিগার করার জন্য আমরা বিভিন্ন পদ্ধতি ব্যবহার করতে পারি, যেমন Redis, Rate Limiting Libraries বা কাস্টম লজিক।
এখানে আমরা দেখব কিভাবে FastAPI তে API Rate Limiting এবং Throttling সেটআপ করা যায়।
Step 1: Rate Limiting Libraries ব্যবহার করা
FastAPI তে Rate Limiting এবং Throttling কনফিগার করার জন্য বেশ কিছু জনপ্রিয় লাইব্রেরি আছে। এর মধ্যে slowapi হল একটি খুবই সহজ এবং জনপ্রিয় লাইব্রেরি যা Redis-এর সাথে কাজ করে।
slowapi লাইব্রেরি ব্যবহার করা
slowapi লাইব্রেরি Redis-এর সাহায্যে FastAPI অ্যাপে Rate Limiting যোগ করতে সহায়ক। Redis ব্যবহার করা হলে, এটি বিভিন্ন রিকোয়েস্টের জন্য ভ্যালিডেশন এবং লিমিটেশন পরিচালনা করতে সাহায্য করে।
- প্রথমে
slowapiইনস্টল করুন:
pip install slowapi
pip install redis
- তারপরে FastAPI অ্যাপে এটি ব্যবহার করতে পারেন।
উদাহরণ: FastAPI তে Rate Limiting
from fastapi import FastAPI, Request
from slowapi import Limiter
from slowapi.util import get_remote_address
from fastapi.responses import JSONResponse
# Redis কনফিগারেশন
limiter = Limiter(key_func=get_remote_address)
app = FastAPI()
# Rate Limiting middleware
app.state.limiter = limiter
@app.get("/items/")
@limiter.limit("5/minute") # 5 রিকোয়েস্ট/মিনিট সীমা
async def get_items(request: Request):
return {"message": "This is a rate-limited endpoint!"}
@app.exception_handler(429)
async def ratelimit_error(request: Request, exc: Exception):
return JSONResponse(
status_code=429,
content={"detail": "Rate limit exceeded. Try again later."},
)
এখানে:
limiter.limit("5/minute"): এটি একটি পাথের জন্য প্রতি মিনিটে ৫টি রিকোয়েস্টের সীমা নির্ধারণ করে।- Redis ব্যাকএন্ডের মাধ্যমে এক্সপোনেনশিয়াল ব্যাকঅফ বা থ্রটলিংও বাস্তবায়ন করা যায়।
রেসপন্স (যদি Rate Limit অতিক্রম করা হয়):
{
"detail": "Rate limit exceeded. Try again later."
}
Step 2: Custom Rate Limiting এবং Throttling
আপনি যদি Redis ব্যবহার না করতে চান, তবে কাস্টম লজিক ব্যবহার করে FastAPI তে Rate Limiting এবং Throttling সেটআপ করতে পারেন।
উদাহরণ: Custom Rate Limiting Using in-memory Counter
from fastapi import FastAPI, HTTPException
from fastapi.responses import JSONResponse
from collections import defaultdict
import time
app = FastAPI()
# Memory based rate limit tracking
rate_limits = defaultdict(list)
MAX_REQUESTS = 5 # Max requests per minute
TIME_FRAME = 60 # Time frame in seconds (1 minute)
@app.get("/limited/")
async def limited_endpoint(ip: str = None):
ip = ip or "127.0.0.1" # Using a fallback IP for simplicity
current_time = time.time()
request_times = rate_limits[ip]
# Remove requests that are older than the time window
rate_limits[ip] = [t for t in request_times if current_time - t < TIME_FRAME]
# Check if rate limit is exceeded
if len(rate_limits[ip]) >= MAX_REQUESTS:
raise HTTPException(
status_code=429,
detail="Rate limit exceeded. Try again later."
)
# Add the current request time
rate_limits[ip].append(current_time)
return {"message": "Request accepted!"}
এখানে:
rate_limits: এটি একটি ইন-মেমরি ডিকশনারি, যেখানে IP অ্যাড্রেস অনুযায়ী রিকোয়েস্টের টাইমস্ট্যাম্প রাখা হয়।MAX_REQUESTS = 5: প্রতি মিনিটে সর্বাধিক ৫টি রিকোয়েস্ট অনুমোদিত।TIME_FRAME = 60: রিকোয়েস্টের সময়কাল ১ মিনিট।
রেসপন্স (Rate Limit অতিক্রম করলে):
{
"detail": "Rate limit exceeded. Try again later."
}
Step 3: Exponential Backoff for Throttling
Throttling এর জন্য আপনি এক্সপোনেনশিয়াল ব্যাকঅফও বাস্তবায়ন করতে পারেন, যেখানে ব্যবহারকারী যদি অনেক বেশি রিকোয়েস্ট পাঠায়, তবে সময়সীমা বৃদ্ধি পাবে।
উদাহরণ: Exponential Backoff with Throttling
import time
from fastapi import FastAPI, HTTPException
app = FastAPI()
# Throttle settings
throttle_times = defaultdict(int)
@app.get("/throttled/")
async def throttled_endpoint(ip: str = None):
ip = ip or "127.0.0.1" # Using a fallback IP for simplicity
current_time = time.time()
# Throttling logic (increase wait time for consecutive requests)
throttle_times[ip] += 1
wait_time = 2 ** throttle_times[ip] # Exponential backoff: 2^n
if wait_time > 60: # Maximum wait time of 60 seconds
wait_time = 60
if time.time() - current_time < wait_time:
raise HTTPException(
status_code=429,
detail=f"Too many requests, try again in {wait_time} seconds."
)
return {"message": "Request accepted."}
এখানে, একাধিক রিকোয়েস্ট পাঠানোর পর ব্যবহৃত exponential backoff পদ্ধতিতে, পরবর্তী রিকোয়েস্টের জন্য অপেক্ষার সময় বাড়ানো হচ্ছে।
Step 4: Throttling Using Redis
Redis ব্যবহার করে Exponential Throttling কৌশল সহজেই বাস্তবায়ন করা সম্ভব। Redis-এ আপনি খুব সহজেই সময়ের ভিত্তিতে রিকোয়েস্টের সংখ্যা ট্র্যাক করতে পারেন এবং এক্সপোনেনশিয়াল ব্যাকঅফ থ্রটলিং সেটআপ করতে পারেন।
pip install redis
উদাহরণ: Redis এবং Throttling ব্যবহার
import redis
import time
from fastapi import FastAPI, HTTPException
app = FastAPI()
# Redis client setup
r = redis.StrictRedis(host='localhost', port=6379, db=0)
@app.get("/redis-throttle/")
async def redis_throttle(ip: str = None):
ip = ip or "127.0.0.1"
# Track requests in Redis (with expiration)
request_key = f"requests:{ip}"
current_time = time.time()
# Count requests for the IP
request_count = r.get(request_key)
if request_count and int(request_count) >= 5:
raise HTTPException(status_code=429, detail="Rate limit exceeded, try again later.")
# Increment the request count
r.incr(request_key)
r.expire(request_key, 60) # Expire the key after 1 minute
return {"message": "Request accepted!"}
এখানে, Redis ব্যবহার করে IP-based rate limiting এবং expiration বাস্তবায়ন করা হয়েছে।
FastAPI তে API Rate Limiting এবং Throttling সহজেই কনফিগার করা যায়। আপনি Redis, slowapi, অথবা কাস্টম লজিক ব্যবহার করে API রিকোয়েস্টের সংখ্যা নিয়ন্ত্রণ করতে পারেন। এর মাধ্যমে আপনি API-কে অযাচিত বা অত্যধিক লোড থেকে সুরক্ষা দিতে পারেন এবং সার্ভারের কর্মক্ষমতা বজায় রাখতে পারেন।
Read more