スポンサーリンク

【Python】APIのリトライ処理

記事内に広告が含まれています。

API実行のリトライ処理をPythonで実装する方法をまとめます。


スポンサーリンク

なぜリトライ処理が必要か

APIを利用してデータを取得・送信する際には、ネットワーク遅延やサーバーの一時的な負荷などによりエラーが発生することがあります。

例えば、HTTPステータスコード「429 (Too Many Requests)」「500 (Internal Server Error)」「503 (Service Unavailable)」などが返されることがあり、これらは一度のリクエスト失敗だけで処理を諦めるのではなく、時間を置いて再度リクエストすることで成功する可能性があるため、リトライ処理が役立ちます。


スポンサーリンク

リトライ処理の基本的な方法

Pythonでは、以下の2つの方法でリトライ処理を実装することが多いです。

  • 手動でリトライロジックを組む
  • 外部ライブラリ retrytenacity を使用する

手動でリトライロジックを組む

以下は、単純に指定回数分リトライするコード例です。

import requests
import time

def fetch_data_with_retry(url, retries=3, delay=2):
    for attempt in range(retries):
        try:
            response = requests.get(url)
            # ステータスコードが200番台の場合は成功とみなす
            if response.status_code == 200:
                return response.json()
            else:
                print(f"Attempt {attempt + 1}: Failed with status {response.status_code}")
        except requests.RequestException as e:
            print(f"Attempt {attempt + 1}: Error - {e}")
        time.sleep(delay)  # リトライ間隔

    raise Exception("Failed to fetch data after multiple retries")

上記のコードでは、指定されたリトライ回数だけリクエストを再試行し、成功するまで待機時間(delay)を設けています。

リクエストが成功しなければ、最後に例外が発生します。

tenacityライブラリでリトライ処理を行う

Pythonのtenacityライブラリを使用すると、リトライロジックを簡潔に記述できます。

まずはインストールが必要です。

pip install tenacity

次に、リトライ処理を含む関数の実装例を紹介します。

from tenacity import retry, stop_after_attempt, wait_fixed
import requests

@retry(stop=stop_after_attempt(3), wait=wait_fixed(2))
def fetch_data(url):
    response = requests.get(url)
    response.raise_for_status()  # ステータスコードが200以外の場合、例外が発生
    return response.json()

try:
    data = fetch_data("https://api.example.com/data")
except requests.RequestException as e:
    print(f"Failed to fetch data: {e}")

@retryデコレーターにより、fetch_data関数は最大3回まで試行し、2秒の待機時間を挟んでリトライします。

このように、tenacityを使うとリトライ処理の設定が柔軟に行えます。


エラーハンドリングと条件付きリトライ

場合によっては、特定のエラーコードのときだけリトライしたいこともあります。

例えば、ステータスコードが「500」「503」「429」などの場合にリトライするよう条件を設定することが可能です。

条件付きリトライの例

from tenacity import retry, stop_after_attempt, wait_fixed, retry_if_exception

def retry_if_server_error(exception):
    return isinstance(exception, requests.RequestException) and exception.response.status_code in [500, 503, 429]

@retry(stop=stop_after_attempt(5), wait=wait_fixed(2), retry=retry_if_exception(retry_if_server_error))
def fetch_data(url):
    response = requests.get(url)
    response.raise_for_status()
    return response.json()

ここでは、リトライ条件としてHTTPステータスが500、503、または429のときのみリトライを行う設定をしています。


エクスポネンシャルバックオフを用いたリトライ処理

エクスポネンシャルバックオフは、リトライ間隔を指数関数的に増加させる手法です。

たとえば、最初のリトライ後に2秒待機、次に4秒、8秒、と待機時間を増やすことで、過剰なリクエストを抑制しつつ成功確率を高めます。

エクスポネンシャルバックオフの例

from tenacity import retry, stop_after_attempt, wait_exponential

@retry(stop=stop_after_attempt(5), wait=wait_exponential(multiplier=1, min=2, max=10))
def fetch_data(url):
    response = requests.get(url)
    response.raise_for_status()
    return response.json()

ここでは、wait_exponentialを使用し、2秒から最大10秒までの待機時間でエクスポネンシャルバックオフを設定しています。


リトライ処理の実装時の注意点

  • リトライ回数の上限を設ける
    無限ループに陥らないように、リトライ回数に上限を設けます。
  • APIプロバイダのガイドラインを確認する
    過剰なリトライはサーバーへの負荷が大きいため、APIプロバイダが推奨するリトライポリシーに従うことが重要です。
  • エクスポネンシャルバックオフの利用
    通常の一定時間リトライよりも、エクスポネンシャルバックオフを利用することで、短時間に集中するリクエストを避けられます。

まとめ

Pythonでは、リトライ処理を手動で実装する方法や、tenacityライブラリを用いる方法があり、リトライの条件や待機時間も自由に調整可能です。これらの手法を活用することで、APIの実行における堅牢性を向上させ、安定したデータ取得が可能になります。

スポンサーリンク
Python
著者SNS
タイトルとURLをコピーしました