-
Notifications
You must be signed in to change notification settings - Fork 163
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[CHORE] Add endpoints to simulate rate-limiting on AWS S3 buckets (#1220
) # Summary Adds FastAPI endpoints for integration tests, simulating rate-limiting on AWS S3 buckets. Drive-by: refactors our code to use FastAPI sub-apps instead of Routers. This is needed to enable better control around rate limiting per-"app", where each app corresponds to an S3 bucket with certain characteristics. Closes: #1179 More work needs to be done here once we support customizable retry policies, so that we can verify that these retry strategies work. --------- Co-authored-by: Jay Chia <[email protected]@users.noreply.github.com>
- Loading branch information
Showing
8 changed files
with
93 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,4 +17,5 @@ uvicorn==0.23.2 | |
uvloop==0.17.0 | ||
watchfiles==0.19.0 | ||
websockets==11.0.3 | ||
pyarrow | ||
pyarrow==12.0.1 | ||
slowapi==0.1.8 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
38 changes: 38 additions & 0 deletions
38
tests/integration/docker-compose/retry_server/routers/rate_limited_echo_gets_bucket.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
from __future__ import annotations | ||
|
||
from fastapi import FastAPI, Request, Response | ||
from slowapi import Limiter | ||
from slowapi.errors import RateLimitExceeded | ||
from slowapi.util import get_remote_address | ||
|
||
from ..utils.responses import get_response | ||
|
||
BUCKET_NAME = "80-per-second-rate-limited-gets-bucket" | ||
OBJECT_KEY_URL = "/{item_id}" | ||
|
||
route = f"/{BUCKET_NAME}" | ||
app = FastAPI() | ||
|
||
|
||
def rate_limit_exceeded_handler(request: Request, exc: RateLimitExceeded) -> Response: | ||
return get_response(request.url, status_code=503) | ||
|
||
|
||
limiter = Limiter(key_func=get_remote_address) | ||
app.state.limiter = limiter | ||
app.add_exception_handler(RateLimitExceeded, rate_limit_exceeded_handler) | ||
|
||
|
||
@app.get(OBJECT_KEY_URL) | ||
@limiter.shared_limit(limit_value="80/second", scope="my_shared_limit") | ||
async def rate_limited_bucket_get(request: Request, item_id: str): | ||
"""This endpoint will just echo the `item_id` and return that as the response body""" | ||
result = item_id.encode("utf-8") | ||
return Response( | ||
status_code=200, | ||
content=result, | ||
headers={ | ||
"Content-Length": str(len(result)), | ||
"Content-Type": "binary/octet-stream", | ||
}, | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
22 changes: 22 additions & 0 deletions
22
tests/integration/io/test_url_download_s3_local_retry_server.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
from __future__ import annotations | ||
|
||
import pytest | ||
|
||
import daft | ||
|
||
|
||
@pytest.mark.integration() | ||
@pytest.mark.skip( | ||
reason="""[IO-RETRIES] This currently fails: we need better retry policies to have this work consistently. | ||
Currently, if all the retries for a given URL happens to land in the same 1-second window, the request fails. | ||
We should be able to get around this with a more generous retry policy, with larger increments between backoffs. | ||
""" | ||
) | ||
def test_url_download_local_retry_server(retry_server_s3_config): | ||
bucket = "80-per-second-rate-limited-gets-bucket" | ||
data = {"urls": [f"s3://{bucket}/foo{i}" for i in range(100)]} | ||
df = daft.from_pydict(data) | ||
df = df.with_column( | ||
"data", df["urls"].url.download(io_config=retry_server_s3_config, use_native_downloader=True, on_error="null") | ||
) | ||
assert df.to_pydict() == {**data, "data": [f"foo{i}".encode() for i in range(100)]} |