Flask でレートリミットを実装する
API に対する過剰なリクエストを防ぐため、レートリミット(流量制限)を実装することは重要である。Flask-Limiter を使えば簡単にレートリミットを導入できる。
Flask-Limiter のセットアップ
pip install flask-limiterfrom flask import Flask
from flask_limiter import Limiter
from flask_limiter.util import get_remote_address
app = Flask(__name__)
limiter = Limiter(
key_func=get_remote_address,
app=app,
default_limits=['200 per day', '50 per hour']
)key_func はリクエストを識別するキーを返す関数である。IP アドレスでの制限が一般的だが、認証済みユーザーの ID を使うこともできる。
エンドポイント単位の制限
@app.route('/api/search')
@limiter.limit('10 per minute')
def search():
return {'results': []}
@app.route('/api/login', methods=['POST'])
@limiter.limit('5 per minute')
def login():
return {'status': 'ok'}制限の書式
| 10 per minute | 1分間に10リクエスト |
| 100 per hour | 1時間に100リクエスト |
| 1000 per day | 1日に1000リクエスト |
| 1 per second | 1秒に1リクエスト |
複数の制限を組み合わせることもできる。
@app.route('/api/data')
@limiter.limit('100 per hour')
@limiter.limit('10 per minute')
def data():
return {'data': 'value'}動的なキー関数
ログインユーザーごとに制限する場合。
def get_user_id():
if hasattr(g, 'user') and g.user:
return str(g.user.id)
return get_remote_address()
limiter = Limiter(key_func=get_user_id, app=app)特定のユーザーを除外
@app.route('/api/data')
@limiter.limit('10 per minute')
@limiter.exempt
def data():
# このエンドポイントは制限なし
return {'data': 'value'}
# または条件付きで除外
def whitelist_check():
return g.user and g.user.is_admin
@app.route('/api/admin')
@limiter.limit('10 per minute', exempt_when=whitelist_check)
def admin():
return {'admin': 'data'}Redis をストレージに使う
デフォルトではメモリ内にカウントを保持するが、本番では Redis を使う。
from flask_limiter import Limiter
from flask_limiter.util import get_remote_address
app.config['RATELIMIT_STORAGE_URI'] = 'redis://localhost:6379'
limiter = Limiter(
key_func=get_remote_address,
app=app,
storage_uri='redis://localhost:6379'
)エラーレスポンスのカスタマイズ
@app.errorhandler(429)
def ratelimit_error(e):
return {
'error': 'Too many requests',
'retry_after': e.description
}, 429ヘッダーの確認
レートリミットの状態はレスポンスヘッダーで確認できる。
| X-RateLimit-Limit | 制限数 |
| X-RateLimit-Remaining | 残りリクエスト数 |
| X-RateLimit-Reset | リセット時刻 |
| Retry-After | 再試行までの秒数(429 時) |
レートリミットは API の安定性を保ち、悪意のあるリクエストからシステムを守るために重要である。



