Consider this FastAPI endpoint using a simple rate limiter that allows 3 requests per minute per client IP.
from fastapi import FastAPI, Request, HTTPException
from time import time
app = FastAPI()
request_times = {}
@app.get("/data")
async def get_data(request: Request):
ip = request.client.host
now = time()
window = 60
limit = 3
times = request_times.get(ip, [])
times = [t for t in times if now - t < window]
if len(times) >= limit:
raise HTTPException(status_code=429, detail="Too many requests")
times.append(now)
request_times[ip] = times
return {"message": "Success"}What will the client receive on the 4th request within one minute?
from fastapi import FastAPI, Request, HTTPException from time import time app = FastAPI() request_times = {} @app.get("/data") async def get_data(request: Request): ip = request.client.host now = time() window = 60 limit = 3 times = request_times.get(ip, []) times = [t for t in times if now - t < window] if len(times) >= limit: raise HTTPException(status_code=429, detail="Too many requests") times.append(now) request_times[ip] = times return {"message": "Success"}
Think about what happens when the number of requests exceeds the limit in the code.
The code tracks request times per IP and raises an HTTPException with status 429 when the limit is reached. So the 4th request within one minute triggers this exception, returning a 429 error.
Which option correctly fixes the syntax error in this code snippet?
from fastapi import FastAPI, Request, HTTPException
app = FastAPI()
@app.get("/limit")
async def limit(request: Request):
ip = request.client.host
if ip not in request_times
request_times[ip] = []
return {"status": "ok"}from fastapi import FastAPI, Request, HTTPException app = FastAPI() @app.get("/limit") async def limit(request: Request): ip = request.client.host if ip not in request_times request_times[ip] = [] return {"status": "ok"}
Python requires a colon at the end of if statements.
The if statement is missing a colon at the end, which causes a syntax error. Adding ':' fixes it.
Given this code snippet:
from fastapi import FastAPI, Request
from time import time
app = FastAPI()
request_times = {}
@app.get("/check")
async def check(request: Request):
ip = request.client.host
now = time()
window = 60
times = request_times.get(ip, [])
times = [t for t in times if now - t < window]
times.append(now)
request_times[ip] = times
return {"count": len(times)}If the same client IP makes 3 requests within 30 seconds, what will be the value of request_times[ip] after the third request?
from fastapi import FastAPI, Request from time import time app = FastAPI() request_times = {} @app.get("/check") async def check(request: Request): ip = request.client.host now = time() window = 60 times = request_times.get(ip, []) times = [t for t in times if now - t < window] times.append(now) request_times[ip] = times return {"count": len(times)}
Consider how the code filters timestamps and adds the current time.
The code keeps timestamps within the last 60 seconds and adds the current time. After 3 requests within 30 seconds, all 3 timestamps remain in the list.
Consider this code snippet:
from fastapi import FastAPI, Request, HTTPException
from time import time
app = FastAPI()
request_counts = {}
@app.get("/limit")
async def limit(request: Request):
ip = request.client.host
count, start = request_counts.get(ip, (0, time()))
if time() - start > 60:
count = 0
start = time()
count += 1
if count > 5:
raise HTTPException(status_code=429, detail="Too many requests")
request_counts[ip] = (count, start)
return {"count": count}Why might the count never reset after 1 minute?
from fastapi import FastAPI, Request, HTTPException from time import time app = FastAPI() request_counts = {} @app.get("/limit") async def limit(request: Request): ip = request.client.host count, start = request_counts.get(ip, (0, time())) if time() - start > 60: count = 0 start = time() count += 1 if count > 5: raise HTTPException(status_code=429, detail="Too many requests") request_counts[ip] = (count, start) return {"count": count}
Look at when the start time is updated and when the dictionary is updated.
The start time is reset inside the if block, but count is incremented before updating the dictionary. This causes the timing window to be inconsistent, so the count may not reset as expected.
You want to implement rate limiting in a FastAPI app deployed on multiple servers behind a load balancer. Which approach below best ensures accurate rate limiting across all servers?
Think about how to share state across multiple servers.
Using a shared external store like Redis allows all servers to access and update the same rate limit data, ensuring accurate limits across distributed instances.