【FastAPI】APIから別のAPIをリダイレクトで呼び出し(RedirectResponse)【備忘録】

お疲れ様です。

今回はAPIから別のAPIをリダイレクトで直接呼び出すような実装をしたので、その復習も兼ねてメモを書いておきます。

以前requestsモジュールを使ってAPIの処理の中で別のAPIを呼び出してその結果を処理の中で使うということもやったのですが、その時とは少しイメージが異なります。
自作APIとの通信をするPythonコードのメモ(requestsモジュール)

FastAPIでのリダイレクトについて

fastapi.tiangolo.com

FastAPIでリダイレクトをするときはこのRedirectResponseを使用します。 クライアントから呼び出したAPIから,さらに別の呼び出したいAPIのURLを指定して直接APIを呼び出し、そのAPIのレスポンスを自身のレスポンスとしてクライアントに返してくれます。

デフォルトでは307ステータスコード (Temporary Redirect) になります。 他のリダイレクトのステータスコードも指定できます。以下参考に。
qiita.com

今回はデフォルトの307ステータスコードのTemporary Redirectを扱います。 こちらについて詳しくは下記サイトが参考になります。
developer.mozilla.org

特徴としては以下の2点が挙げられるかなと思います。
- 一時的にURLを指定した別のURL変える
- HTTPメソッド(post,getなど)はそのまま保持する

コード

例によってソースコードGitHubに置いてありますので併せてご参考ください。 記事内ではRedirectResponseを使用したコードの説明のみとしますが、ソースコードの方には比較用に通常のAPI呼び出しも記載しています。
github.com

では、実際に動かしてみます。
下記で2つのエンドポイントを同時に立ち上げます。コマンドは1,2どちらでもOKです。

  • endpoint_1.py
     1. python endpoint_1.py
     2. uvicorn endpoint_1:app --reload --port 8000

  • endpoint_2.py
     1. python endpoint_2.py
     2. uvicorn endpoint_2:app --reload --port 8080

エンドポイント1の方からHTMLResponseで表示したクライアントを開きます。

http://localhost:8000/

いくつかボタンがあるうちの以下を使用します。
クライアント

<p>
  <h4><b>endpoint_1</b>から<b>endpoint_2</b>の画像取得APIを呼び出し</h4>
  <a href="http://localhost:8000/img_2" target="_blank">
    <button>画像ダウンロード</button>
  </a>
</p>

エンドポイント1経由でエンドポイント2の画像ダウンロードAPIを呼び出します。 それぞれのAPIが以下。エンドポイント1でRedirectResponseを使用しています。

  • エンドポイント1
api_url = "http://localhost:8080"

@app.get("/img_2")
def show_img_2() -> RedirectResponse:
    """ファイルをダウンロードするAPI
    """
    return RedirectResponse(api_url+"/img", status_code=307)
  • エンドポイント2
@app.get("/img")
def show_img() -> FileResponse:
    """ファイルをダウンロードするAPI
    """
    filepath = Path("./data/cat.png")
    
    return FileResponse(filepath, media_type="image/png", filename=filepath.name)

この設定でWeb画面の「画像ダウンロード」ボタンを押すと、エンドポイント2の"cat.png"がダウンロードされました。 ダウンロード

エンドポイント1のコマンドラインでは「307 Temporary Redirect」の表示があります。 endpoint_1

エンドポイント2ではしっかり"/img"のAPIが呼び出されています。 endpoint_2