-
Notifications
You must be signed in to change notification settings - Fork 44.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'dev' into reinier/make-providername-enum
- Loading branch information
Showing
111 changed files
with
5,536 additions
and
1,774 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
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 |
---|---|---|
|
@@ -173,3 +173,4 @@ LICENSE.rtf | |
autogpt_platform/backend/settings.py | ||
/.auth | ||
/autogpt_platform/frontend/.auth | ||
.test-contents |
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
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
3 changes: 2 additions & 1 deletion
3
autogpt_platform/autogpt_libs/autogpt_libs/feature_flag/client_test.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
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 |
---|---|---|
|
@@ -23,7 +23,6 @@ | |
|
||
|
||
class LoggingConfig(BaseSettings): | ||
|
||
level: str = Field( | ||
default="INFO", | ||
description="Logging level", | ||
|
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
Empty file.
31 changes: 31 additions & 0 deletions
31
autogpt_platform/autogpt_libs/autogpt_libs/rate_limit/config.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,31 @@ | ||
from pydantic import Field | ||
from pydantic_settings import BaseSettings, SettingsConfigDict | ||
|
||
|
||
class RateLimitSettings(BaseSettings): | ||
redis_host: str = Field( | ||
default="redis://localhost:6379", | ||
description="Redis host", | ||
validation_alias="REDIS_HOST", | ||
) | ||
|
||
redis_port: str = Field( | ||
default="6379", description="Redis port", validation_alias="REDIS_PORT" | ||
) | ||
|
||
redis_password: str = Field( | ||
default="password", | ||
description="Redis password", | ||
validation_alias="REDIS_PASSWORD", | ||
) | ||
|
||
requests_per_minute: int = Field( | ||
default=60, | ||
description="Maximum number of requests allowed per minute per API key", | ||
validation_alias="RATE_LIMIT_REQUESTS_PER_MINUTE", | ||
) | ||
|
||
model_config = SettingsConfigDict(case_sensitive=True, extra="ignore") | ||
|
||
|
||
RATE_LIMIT_SETTINGS = RateLimitSettings() |
51 changes: 51 additions & 0 deletions
51
autogpt_platform/autogpt_libs/autogpt_libs/rate_limit/limiter.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,51 @@ | ||
import time | ||
from typing import Tuple | ||
|
||
from redis import Redis | ||
|
||
from .config import RATE_LIMIT_SETTINGS | ||
|
||
|
||
class RateLimiter: | ||
def __init__( | ||
self, | ||
redis_host: str = RATE_LIMIT_SETTINGS.redis_host, | ||
redis_port: str = RATE_LIMIT_SETTINGS.redis_port, | ||
redis_password: str = RATE_LIMIT_SETTINGS.redis_password, | ||
requests_per_minute: int = RATE_LIMIT_SETTINGS.requests_per_minute, | ||
): | ||
self.redis = Redis( | ||
host=redis_host, | ||
port=int(redis_port), | ||
password=redis_password, | ||
decode_responses=True, | ||
) | ||
self.window = 60 | ||
self.max_requests = requests_per_minute | ||
|
||
async def check_rate_limit(self, api_key_id: str) -> Tuple[bool, int, int]: | ||
""" | ||
Check if request is within rate limits. | ||
Args: | ||
api_key_id: The API key identifier to check | ||
Returns: | ||
Tuple of (is_allowed, remaining_requests, reset_time) | ||
""" | ||
now = time.time() | ||
window_start = now - self.window | ||
key = f"ratelimit:{api_key_id}:1min" | ||
|
||
pipe = self.redis.pipeline() | ||
pipe.zremrangebyscore(key, 0, window_start) | ||
pipe.zadd(key, {str(now): now}) | ||
pipe.zcount(key, window_start, now) | ||
pipe.expire(key, self.window) | ||
|
||
_, _, request_count, _ = pipe.execute() | ||
|
||
remaining = max(0, self.max_requests - request_count) | ||
reset_time = int(now + self.window) | ||
|
||
return request_count <= self.max_requests, remaining, reset_time |
32 changes: 32 additions & 0 deletions
32
autogpt_platform/autogpt_libs/autogpt_libs/rate_limit/middleware.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,32 @@ | ||
from fastapi import HTTPException, Request | ||
from starlette.middleware.base import RequestResponseEndpoint | ||
|
||
from .limiter import RateLimiter | ||
|
||
|
||
async def rate_limit_middleware(request: Request, call_next: RequestResponseEndpoint): | ||
"""FastAPI middleware for rate limiting API requests.""" | ||
limiter = RateLimiter() | ||
|
||
if not request.url.path.startswith("/api"): | ||
return await call_next(request) | ||
|
||
api_key = request.headers.get("Authorization") | ||
if not api_key: | ||
return await call_next(request) | ||
|
||
api_key = api_key.replace("Bearer ", "") | ||
|
||
is_allowed, remaining, reset_time = await limiter.check_rate_limit(api_key) | ||
|
||
if not is_allowed: | ||
raise HTTPException( | ||
status_code=429, detail="Rate limit exceeded. Please try again later." | ||
) | ||
|
||
response = await call_next(request) | ||
response.headers["X-RateLimit-Limit"] = str(limiter.max_requests) | ||
response.headers["X-RateLimit-Remaining"] = str(remaining) | ||
response.headers["X-RateLimit-Reset"] = str(reset_time) | ||
|
||
return response |
Empty file.
Oops, something went wrong.