LoginSignup
16
11

More than 1 year has passed since last update.

Flask2.0でAPIに非同期通信する。

Posted at

今回は、Webcomicを提供しているAPIからコミック画像を取得してブラウザに表示するプログラムを通して、flask2.0での非同期処理の使い方を紹介していきます。

app.py
# pip install httpx
# pip install flask
# pip install flask[async]

from flask import Flask
import httpx
import asyncio
from random import randint

app = Flask(__name__)

async def get_image(client):
  """ 非同期で行いたい処理 """
  random = randint(0, 300)
  # APIに通信
  result = await client.get(f'http://xkcd.com/{random}/info.0.json')
  # 画像のURLのみ返す
  return result.json()['img']

@app.get('/async_api')
async def async_api():
  # httpxで非同期通信
  async with httpx.AsyncClient() as client:
    # 非同期の対象処理をリストにまとめる
    tasks = [get_image(client) for _ in range(5)]
    # 非同期処理の結果を受け取る
    urls = await asyncio.gather(*tasks)

  html = ""
  for url in urls:
    html += f"<img src='{url}'><br><br>"
  return html

app.pyのあるディレクトリに移動してflask runを実行し、http://127.0.0.1:5000/async_api にアクセスすると、APIで取得したコミック画像が表示されます。ただ、これだけだと同期通信との違いは分からないので、比較するために同期通信のプログラムもapp.pyに追加します。

app.py
....

@app.get('/sync')
def sync():
  urls = []
  for _ in range(5):
    random = randint(0, 300)
    response = httpx.get(f'http://xkcd.com/{random}/info.0.json')
    urls.append(response.json()['img'])
  html = ""
  for url in urls:
    html += f"<img src='{url}'><br><br>"
  return html

同様にflask runを再実行し、http://127.0.0.1:5000/async_apihttp://127.0.0.1:5000/sync で画像の表示速度を比べてみてください。定量的に比較したい方は処理にかかる時間を表示できるようにしてみるとよいかもしれません。

今回紹介した非同期処理ですが、CPUに待ち時間が発生するI/O処理では速度が上がりますが、CPUに依存する処理を対象にしても処理速度は速くならないと思うので注意してください。

16
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
11