I'm having a problem. When I make too many requests from browser or postman rightly the API (slowapi) blocks me as I have correctly set, but if I make a request via AJAX and jquery's $ .getJSON, the APIs don't block me. How can I solve? My code (extracted from the complete code):
from fastapi import FastAPI, Request, Response, status
from fastapi.middleware.cors import CORSMiddleware
from slowapi import Limiter, _rate_limit_exceeded_handler
from slowapi.util import get_remote_address
from slowapi.errors import RateLimitExceeded
from slowapi.middleware import SlowAPIMiddleware
limiter = Limiter(key_func=get_remote_address, default_limits=["2/5seconds"])
app = FastAPI()
app.state.limiter = limiter
app.add_exception_handler(RateLimitExceeded, _rate_limit_exceeded_handler)
app.add_middleware(
CORSMiddleware,
allow_origins=origins,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
app.add_middleware(SlowAPIMiddleware)
@app.get('/schools/{regione}/{provincia}/{comune}')
def search_school(request: Request, response: Response, regione: str, provincia: str, comune: str):
if(request.headers.get("Provider") == "Test-User-Provider"):
return {"message": "OK", "status": "success", "code": 200}
else:
response.status_code = status.HTTP_400_BAD_REQUEST
return {"message": "Provider not found", "status": "error", "code": 400}
Browser result (WORK):
{"error":"Rate limit exceeded: 2 per 5 second"}
Jquery code (NOT WORK):
$.getJSON(apiURL "/schools/Test/Test/Test", function(data) {
console.log(data)
});
Obviously with jquery I tried to make a lot of requests per second Console browser result (Not limited!):
{message: '...', status: 'success', code: 200}
A thousand thanks.
UPDATE
Through jquery I tried to make requests to other paths and it is correctly rate-limited. If I make the request to this path /schools/{region}/{province}/{municipality}
the rate-limit does not work
UPDATE 2
I refer the updated and tested code. When I send a request to path /testpath /{region}
it is correctly rate-limited. If instead I send a request to some sub-paths (/schools/{region}/{province}/{municipality}
it is not rate-limited.
The jQuery code is the same as listed above
from fastapi import FastAPI, Request, Response, status
from fastapi.middleware.cors import CORSMiddleware
from slowapi import Limiter, _rate_limit_exceeded_handler
from slowapi.util import get_remote_address
from slowapi.errors import RateLimitExceeded
from slowapi.middleware import SlowAPIMiddleware
limiter = Limiter(key_func=get_remote_address, default_limits=["2/5seconds"])
app = FastAPI()
app.state.limiter = limiter
app.add_exception_handler(RateLimitExceeded, _rate_limit_exceeded_handler)
origins = ["http://127.0.0.1/", "http://localhost", "http://192.168.1.75"] ## CORS
app.add_middleware(
CORSMiddleware,
allow_origins=origins,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
app.add_middleware(SlowAPIMiddleware) ## Rate-limit all request
@app.get('/schools/{regione}/{provincia}/{comune}')
def search_school(request: Request, response: Response, regione: str, provincia: str, comune: str):
return {"message": 'No schools found!', "status": 'error', "code": 200} ## Or if found return schools informations
@app.get('/testpath/{regione}') ## Works with one path. If I add "provincia" and "comune" non work
def search_school(request: Request, response: Response, regione: str, provincia: str, comune: str):
return {"message": 'No schools found!', "status": 'error', "code": 200} ## Or if found return schools informations
If i use testpath it's correct rate-limited:
CodePudding user response:
Tested your code and works fine, as long as you replace the closing double quote ”
with a straight double quote "
in the getJSON()
method:
$.getJSON(apiURL "/security/validate_token", function(data) {
console.log(data)
});
Above you wrote "the status response is personalized and I decided it myself". So, if you still get a {message: '...', status: 'success', code: 200}
response, I would suggest you try returning a simple message instead, e.g., return {"status": "success"}
, and see if that works as expected. If not, it might be something not implemented in the right way in your custom response.
Update
The below should work as expected. If it doesn't, then the issue likely lies elsewhere in code that is not inlcuded in your question. I would also suggest to add it as a tempalte to your app, as from the error you posted you seem to be getting Cross-Origin
warnings.
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script type="text/javascript" >
function on_click(){
$.getJSON("http://127.0.0.1:8000/schools/Test/Test/Test", function(data) {
console.log(data)
});
}
</script>
</head>
<body>
<input type="button" value="submit" onclick="on_click()">
</body>
</html>