- Web API構築用フレームワークFastAPIとデータ処理用ライブラリPandasを用いたコロナウィルス情報を取得するAPIの作成方法についてメモする。
- 都道府県名を指定し、月別の感染者数とワクチン接種(2回)数を取得する
事前準備
-
ndjson
インストール※ワクチン接種情報がNDJSON形式で提供されているため。pip install ndjson
-
その他、pandas,FastAPI周りも必要に応じインストールすること。
コード
-
都道府県名を指定し、月別の感染者数とワクチン接種(2回)数を取得する2つのAPIを作成する。
-
main.py
from fastapi import FastAPI
from pydantic import BaseModel
import pandas as pd
import requests
from urllib.request import Request, urlopen
import ndjson
app = FastAPI()
# 都道府県 コード-名称 対応辞書
prefcode_with_name = {
1: '北海道', 2: '青森県', 3: '岩手県', 4: '宮城県', 5: '秋田県', 6: '山形県', 7: '福島県', 8: '茨城県', 9: '栃木県', 10: '群馬県', 11: '埼玉県', 12: '千葉県', 13: '東京都', 14: '神奈川県', 15: '新潟県', 16: '富山県', 17: '石川県', 18: '福井県', 19: '山梨県', 20: '長野県', 21: '岐阜県', 22: '静岡県', 23: '愛知県', 24: '三重県', 25: '滋賀県', 26: '京都府', 27: '大阪府', 28: '兵庫県', 29: '奈良県', 30: '和歌山県', 31: '鳥取県', 32: '島根県', 33: '岡山県', 34: '広島県', 35: '山口県', 36: '徳島県', 37: '香川県', 38: '愛媛県', 39: '高知県', 40: '福岡県', 41: '佐賀県', 42: '長崎県', 43: '熊本県', 44: '大分県', 45: '宮崎県', 46: '鹿児島県', 47: '沖縄県'
}
# 指定した都道府県の月別ワクチン摂取情報(2回)を取得する
# 取得元:新型コロナワクチンの接種状況に関するオープンデータ
# https://cio.go.jp/c19vaccine_opendata
def search_covid19_prefectures_monthly_vaccination_data(pref):
result = requests.get(
'https://vrs-data.cio.go.jp/vaccination/opendata/latest/prefecture.ndjson')
# NDJSON形式のデータをDataFrameとして取得
df = pd.DataFrame(ndjson.loads(result.text))
# 都道府県名列の追加
df['都道府県名'] = df.prefecture.map(
lambda x: prefcode_with_name[int(x)])
# データ整形(都道府県名、摂取回数でフィルターをかけ、日付と件数列を抽出)
df = df[(df['都道府県名'] == pref) & (
df['status'] == 2)].loc[:, ['date', 'count']]
df["date"] = pd.to_datetime(df["date"])
# 月別集計
result = df.resample('M', on='date').sum().to_dict()['count']
converted_result = {}
for key in result.keys():
new_key = str(key.year)+"-"+str(key.month)
converted_result[new_key] = result[key]
return converted_result
# 指定した都道府県の月別感染者情報を取得する
# 取得元:新たに確認された感染者数(NHKまとめ)
# https://www3.nhk.or.jp/news/special/coronavirus/data/
def search_covid19_prefectures_monthly_infected_data(pref):
# Pandas.read_csvでは403となったため、urllibを使用する
req = Request(
'https://www3.nhk.or.jp/n-data/opendata/coronavirus/nhk_news_covid19_prefectures_daily_data.csv')
req.add_header(
'User-Agent', 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:77.0) Gecko/20100101 Firefox/77.0')
content = urlopen(req)
df = pd.read_csv(
content, index_col=0, parse_dates=True)
# 選択した都道府県データを抽出
df = df[df['都道府県名'] == pref]
column_name = '各地の感染者数_1日ごとの発表数'
df = df.loc[:, [column_name]]
# 月別合計値を取得
df = df.resample('M').sum()
result = df.to_dict()[column_name]
converted_result = {}
for key in result.keys():
new_key = str(key.year)+"-"+str(key.month)
converted_result[new_key] = result[key]
print(converted_result)
return converted_result
# リクエストボディモデル定義
class SearchQuery(BaseModel):
pref: str
# 都道府県月別 感染者数取得API
@app.post('/search_covid19_prefectures_monthly_infected_data')
def search_covid(searchQuery: SearchQuery):
# リクエストボディに指定された都道府県名を取得
pref = searchQuery.pref
return search_covid19_prefectures_monthly_infected_data(pref)
# 都道府県月別 ワクチン接種者(2回)数取得API
@app.post('/search_covid19_prefectures_monthly_vaccination_data')
def search_covid(searchQuery: SearchQuery):
# リクエストボディに指定された都道府県名を取得
pref = searchQuery.pref
return search_covid19_prefectures_monthly_vaccination_data(pref)
動作確認
-
起動
uvicorn main:app --reload INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) INFO: Started reloader process [1792] using statreload INFO: Started server process [11672] INFO: Waiting for application startup. INFO: Application startup complete.
-
都道府県月別 感染者数取得API
-
リクエスト
POST /search_covid19_prefectures_monthly_infected_data HTTP/1.1 Host: localhost:8000 Content-Type: application/json Content-Length: 22 { "pref":"東京都" }
-
レスポンス
{ "2020-1": 3, "2020-2": 34, "2020-3": 489, "2020-4": 3748, "2020-5": 957, "2020-6": 994, "2020-7": 6464, "2020-8": 8125, "2020-9": 4918, "2020-10": 5350, "2020-11": 9861, "2020-12": 19369, "2021-1": 40367, "2021-2": 10997, "2021-3": 9310, "2021-4": 18090, "2021-5": 21879, "2021-6": 12979, "2021-7": 44034, "2021-8": 61164 }
-
-
都道府県月別 ワクチン接種者(2回)数取得API
-
リクエスト
POST /search_covid19_prefectures_monthly_vaccination_data HTTP/1.1 Host: localhost:8000 Content-Type: application/json Content-Length: 22 { "pref":"東京都" }
-
レスポンス
{ "2021-5": 70807, "2021-6": 1135173, "2021-7": 1968301, "2021-8": 802756 }
-