aiteamutils 0.2.33__tar.gz → 0.2.35__tar.gz
Sign up to get free protection for your applications and to get access to all the features.
- {aiteamutils-0.2.33 → aiteamutils-0.2.35}/PKG-INFO +1 -1
- {aiteamutils-0.2.33 → aiteamutils-0.2.35}/aiteamutils/security.py +30 -13
- aiteamutils-0.2.35/aiteamutils/version.py +2 -0
- aiteamutils-0.2.33/aiteamutils/version.py +0 -2
- {aiteamutils-0.2.33 → aiteamutils-0.2.35}/.cursorrules +0 -0
- {aiteamutils-0.2.33 → aiteamutils-0.2.35}/.gitignore +0 -0
- {aiteamutils-0.2.33 → aiteamutils-0.2.35}/README.md +0 -0
- {aiteamutils-0.2.33 → aiteamutils-0.2.35}/aiteamutils/__init__.py +0 -0
- {aiteamutils-0.2.33 → aiteamutils-0.2.35}/aiteamutils/base_model.py +0 -0
- {aiteamutils-0.2.33 → aiteamutils-0.2.35}/aiteamutils/base_repository.py +0 -0
- {aiteamutils-0.2.33 → aiteamutils-0.2.35}/aiteamutils/base_service.py +0 -0
- {aiteamutils-0.2.33 → aiteamutils-0.2.35}/aiteamutils/cache.py +0 -0
- {aiteamutils-0.2.33 → aiteamutils-0.2.35}/aiteamutils/config.py +0 -0
- {aiteamutils-0.2.33 → aiteamutils-0.2.35}/aiteamutils/database.py +0 -0
- {aiteamutils-0.2.33 → aiteamutils-0.2.35}/aiteamutils/dependencies.py +0 -0
- {aiteamutils-0.2.33 → aiteamutils-0.2.35}/aiteamutils/enums.py +0 -0
- {aiteamutils-0.2.33 → aiteamutils-0.2.35}/aiteamutils/exceptions.py +0 -0
- {aiteamutils-0.2.33 → aiteamutils-0.2.35}/aiteamutils/validators.py +0 -0
- {aiteamutils-0.2.33 → aiteamutils-0.2.35}/pyproject.toml +0 -0
- {aiteamutils-0.2.33 → aiteamutils-0.2.35}/setup.py +0 -0
@@ -199,7 +199,7 @@ def rate_limit(
|
|
199
199
|
key_func: Optional[Callable] = None
|
200
200
|
):
|
201
201
|
"""Rate limiting 데코레이터."""
|
202
|
-
|
202
|
+
rate_limits: Dict[str, Dict[str, Any]] = {}
|
203
203
|
|
204
204
|
def decorator(func: Callable) -> Callable:
|
205
205
|
@wraps(func)
|
@@ -216,39 +216,56 @@ def rate_limit(
|
|
216
216
|
request = arg
|
217
217
|
break
|
218
218
|
if not request:
|
219
|
-
raise
|
219
|
+
raise CustomException(
|
220
220
|
ErrorCode.INTERNAL_ERROR,
|
221
221
|
detail="Request object not found",
|
222
222
|
source_function="rate_limit"
|
223
223
|
)
|
224
224
|
|
225
|
-
#
|
225
|
+
# 레이트 리밋 키 생성
|
226
226
|
if key_func:
|
227
227
|
rate_limit_key = f"rate_limit:{key_func(request)}"
|
228
228
|
else:
|
229
229
|
client_ip = request.client.host
|
230
230
|
rate_limit_key = f"rate_limit:{client_ip}:{func.__name__}"
|
231
231
|
|
232
|
-
|
233
|
-
|
234
|
-
|
232
|
+
now = datetime.now(UTC)
|
233
|
+
|
234
|
+
# 현재 rate limit 정보 가져오기
|
235
|
+
rate_info = rate_limits.get(rate_limit_key)
|
236
|
+
|
237
|
+
if rate_info is None or (now - rate_info["start_time"]).total_seconds() >= window_seconds:
|
238
|
+
# 새로운 rate limit 설정
|
239
|
+
rate_limits[rate_limit_key] = {
|
240
|
+
"count": 1,
|
241
|
+
"start_time": now
|
242
|
+
}
|
243
|
+
else:
|
244
|
+
# 기존 rate limit 업데이트
|
245
|
+
if rate_info["count"] >= max_requests:
|
246
|
+
# rate limit 초과
|
247
|
+
remaining_seconds = window_seconds - (now - rate_info["start_time"]).total_seconds()
|
235
248
|
raise RateLimitExceeded(
|
236
|
-
detail=
|
249
|
+
detail=rate_limit_key,
|
237
250
|
source_function=func.__name__,
|
238
|
-
remaining_seconds=
|
251
|
+
remaining_seconds=remaining_seconds,
|
239
252
|
max_requests=max_requests,
|
240
253
|
window_seconds=window_seconds
|
241
254
|
)
|
242
|
-
|
255
|
+
rate_info["count"] += 1
|
256
|
+
|
257
|
+
try:
|
258
|
+
# 원래 함수 실행
|
243
259
|
return await func(*args, **kwargs)
|
244
|
-
|
245
|
-
|
260
|
+
except CustomException as e:
|
261
|
+
# CustomException은 그대로 전파
|
246
262
|
raise e
|
247
263
|
except Exception as e:
|
248
|
-
|
264
|
+
# 다른 예외는 INTERNAL_ERROR로 래핑
|
265
|
+
raise CustomException(
|
249
266
|
ErrorCode.INTERNAL_ERROR,
|
250
267
|
detail=str(e),
|
251
|
-
source_function=
|
268
|
+
source_function=func.__name__,
|
252
269
|
original_error=e
|
253
270
|
)
|
254
271
|
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|