Python レートリミッター実装

Pythonで実装するレートリミッター

Pythonで実装するレートリミッター

レートリミッターは、特定の期間内に特定のユーザーやIPアドレスからのリクエスト数を制限する仕組みです。これは、APIの過負荷を防ぎ、悪意のある攻撃(DDoS攻撃など)から保護するために非常に重要です。本記事では、Pythonで簡単なレートリミッターを実装する方法を紹介します。

レートリミッターの基本的な考え方

レートリミッターは、通常、以下の要素で構成されます。

  • 制限数 (Limit): 一定期間内に許可されるリクエストの最大数
  • 時間間隔 (Interval): リクエストが許可される間隔の長さ(通常は秒単位)
  • カウンター (Counter): 許可されたリクエストの数を追跡する変数

これらの要素に基づいて、現在のリクエストが制限を超えているかどうかを判断し、超過している場合はリクエストを拒否します。

Pythonによるレートリミッターの実装例

以下に、Pythonでレートリミッターを実装する簡単な例を示します。


import time

class RateLimiter:
    def __init__(self, limit, interval):
        self.limit = limit
        self.interval = interval
        self.request_times = {} # ユーザーまたはIPアドレスに基づいてリクエスト時刻を記録

    def is_allowed(self, identifier):
        now = time.time()

        if identifier not in self.request_times:
            self.request_times[identifier] = []

        # リクエスト時刻を最新の状態に更新
        self.request_times[identifier].append(now)
        self.request_times[identifier].sort()

        # 最後のリクエストがintervalより古いか確認
        if len(self.request_times[identifier]) > self.limit:
            # 最初のリクエストを削除
            self.request_times[identifier].pop(0)
            
        # 制限を超えていない場合
        if len(self.request_times[identifier]) <= self.limit:
            return True
        else:
            return False

この例では、`RateLimiter`クラスが作成されています。このクラスは、`limit`(制限数)、`interval`(時間間隔)、`request_times`(リクエスト時刻を記録する辞書)の3つの属性を持ちます。

`is_allowed(identifier)`メソッドは、識別子(ユーザーIDやIPアドレスなど)を受け取り、その識別子に対するリクエストが許可されているかどうかを判断します。このメソッドは、リクエスト時刻を記録し、制限を超えていないかを確認し、許可されている場合は`True`を、許可されていない場合は`False`を返します。

使用例

以下に、`RateLimiter`クラスの使用例を示します。


# 制限数: 5リクエスト
# 時間間隔: 1秒
limiter = RateLimiter(limit=5, interval=1)

# 最初のリクエスト (許可される)
if limiter.is_allowed("user123"):
    print("リクエストを送信")

# 2番目のリクエスト (許可される)
if limiter.is_allowed("user123"):
    print("リクエストを送信")

# 3番目のリクエスト (許可される)
if limiter.is_allowed("user123"):
    print("リクエストを送信")

# 4番目のリクエスト (拒否される)
if limiter.is_allowed("user123"):
    print("リクエストを送信")
else:
    print("リクエストは拒否されました")

# 5番目のリクエスト (拒否される)
if limiter.is_allowed("user123"):
    print("リクエストを送信")
else:
    print("リクエストは拒否されました")

# 6番目のリクエスト (拒否される)
if limiter.is_allowed("user123"):
    print("リクエストを送信")
else:
    print("リクエストは拒否されました")

まとめ

この例では、Pythonでレートリミッターを実装する基本的な方法を紹介しました。レートリミッターは、APIの保護に不可欠なツールであり、様々な状況で利用することができます。 より複雑な状況に対応するためには、Redisなどの分散キャッシュシステムと組み合わせることで、より高パフォーマンスなレートリミッターを構築することができます。

Comments

Popular posts from this blog

モノレポ vs マルチレポ 徹底比較

パスワードハッシュ:bcrypt, scrypt, Argon2 徹底解説

Arduino回路入門:Tinkercadで電子工作を学ぶ