Flaskで内部APIと外部APIを実行する方法

FlaskにおけるAPI連携の例を解説します。

概要

Flaskは、Pythonの軽量なWebアプリケーションフレームワークで、APIとの連携によく使用されます。APIとの連携を実現するためには、リクエストの送信やレスポンスの処理が必要となります。

ここでは、以下バージョンを使用した、FlaskでAPIとの連携を行う方法を説明します。

Flask v2.0.2
Python v3.10.1

また、今回作成するコードは全て、GitHubに掲載しています。

フロントエンドからAPIを実行する方法

フロントエンドでAPIを使用することは一般的なシナリオで、JavaScriptのFetch APIを使うと簡単に実装できます。Fetch APIはブラウザがネイティブで提供するAPIで、非同期HTTP(Ajax)リクエストを行うことができます。

以下の例では、Flaskで作成した/usersエンドポイントにPOSTリクエストを送信し、新しいユーザーを作成します。

また今回から、CORSエラーが発生することが予想されるので、事前に以下をインストールして下さい。

CORS(Cross-Origin Resource Sharing)エラーは、異なるオリジン間でのリソースの共有を試みるときに発生します。ブラウザは同一オリジンポリシーにより、異なるオリジンからのリソースの読み込みを制限します。CORSは、サーバーがレスポンスに特定のヘッダーを含めることで、これらの制限を緩和または解除する仕組みです。

pip install flask_cors

index.html

<!DOCTYPE html>
<html>
<body>
  <!-- ユーザー情報の入力フォームを追加 -->
  <input id="name" type="text" placeholder="Enter name">
  <input id="age" type="number" placeholder="Enter age">
  <!-- ボタンを追加 -->
  <button onclick="createUser()">Create User</button>

  <!-- ユーザー情報の表示領域 -->
  <div id="userInfo"></div>

  <script>
    async function createUser() {
      const name = document.getElementById('name').value;
      const age = document.getElementById('age').value;

      const response = await fetch('http://localhost:5000/users', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({ name: name, age: age })
      });

      if (!response.ok) {
        const message = await response.text();
        throw new Error(`An error has occurred: ${message}`);
      }

      const user = await response.json();

      // ユーザー情報をHTMLに出力
      const userInfo = document.getElementById('userInfo');
      userInfo.textContent = `Created User: Name - ${user.name}, Age - ${user.age}`;
    }
  </script>
</body>
</html>

internal.py

# モジュールをインポートします
from flask import Flask, request, jsonify
from flask.helpers import send_from_directory
from flask_cors import CORS, cross_origin  
import os

# Flaskアプリケーションを作成します
app = Flask(__name__, static_url_path='')

CORS(app)

# ユーザーを保存するための仮のデータストア
users = []

@app.route('/')
def root():
    return send_from_directory('', 'templates/index.html')

@app.route('/users', methods=['GET'])
def get_users():
    # ユーザーデータをレスポンスとして返す
    return jsonify(users)

@app.route('/users', methods=['POST'])
def create_user():
    # リクエストボディからユーザーデータを取得
    user = request.get_json()
    # ユーザーをデータストアに追加
    users.append(user)
    # 新しく作成されたユーザーをレスポンスとして返す
    return jsonify(user), 201

if __name__ == "__main__":
    app.run(port=5000, debug=True)

ここまで完成したら、以下のコマンドを実行してサーバーを起動します。

export FLASK_APP=internal.py
flask run

実行が完了したら、ブラウザでhttp://localhost:5000にアクセスしてみましょう。 ボタンをクリックすると、ユーザーが作成されます。 ユーザーが作成された、http://localhost:5000/usersにアクセスすると、作成されたユーザーの一覧が表示されます。

以下に、Flaskを用いたPython版の解説とコードを提供します。同様に、外部APIへのリクエストを行いますが、ここではPython標準ライブラリのrequestsを利用します。

Flaskで外部APIへのリクエストを送信する

PythonのWebフレームワークであるFlaskを利用して外部APIへのリクエストを送信する方法を説明します。HTTPクライアントライブラリとして、Python標準のrequestsを使用します。

external.py

from flask import Flask, jsonify
import requests

app = Flask(__name__)

@app.route('/data')
def get_data():
    try:
        response = requests.get('https://jsonplaceholder.typicode.com/posts')
        return jsonify(response.json())
    except Exception as e:
        return jsonify({"message": "Error occurred"}), 500

if __name__ == '__main__':
    app.run(port=5000, debug=True)

解説

上記のコードは、JSONプレースホルダーAPIからデータを取得し、そのデータをレスポンスとして返すFlaskアプリケーションを作成します。

  • モジュールのインポート:
from flask import Flask, jsonify
import requests

この部分で、flaskからFlaskjsonify、そしてrequestsモジュールをインポートします。FlaskはWebサーバーフレームワーク、requestsはHTTPクライアントライブラリです。

  • Flaskアプリケーションの作成:
app = Flask(__name__)

ここでFlaskアプリケーションを作成します。

  • ルートの定義:
@app.route('/data')
def get_data():
    try:
        response = requests.get('https://jsonplaceholder.typicode.com/posts')
        return jsonify(response.json())
    except Exception as e:
        return jsonify({"message": "Error occurred"}), 500

/dataエンドポイントへのGETリクエストが来たときのハンドラーを定義します。requests.getを使って外部APIからデータを取得し、そのデータをJSONレスポンスとして送信します。エラーが発生した場合は、ステータスコード500とエラーメッセージを含むレスポンスを送信します。

  • サーバーの起動:
if __name__ == '__main__':
    app.run(port=5000, debug=True)

最後に、アプリケーションを起動し、ポート5000でリッスンします。debug=Trueを設定することで、開発中に発生するエラーをブラウザで確認することができます。

export FLASK_APP=external.py
flask run

テスト

curl http://localhost:5000/data

まとめ

Flaskを使用したPythonによる外部APIへのリクエスト送信方法を説明しました。requestsライブラリを使うことで、簡潔にAPIからデータを取得し、それをクライアントに返すことが可能です。また、エラーハンドリングを行い、問題が発生した場合には適切なエラーメッセージをクライアントに通知できます。