229 Views
September 11, 21
スライド概要
2021.9.11
Python Charity Talks in Japan 2021.09
【Python Charity Talks in Japan 2021.09】 FastAPI を活用した オープンデータAPI の作成 2021. 9. 11 しみず ゆうき 1
おまえ誰よ? しみず ゆうき ● モバイルアプリ エンジニア ○ Android/iOS ● 山梨県甲府市 出身 ● Python は Shingen.py で触れるくらい 2
sli.do で質問を受け付けています! 3
はじめに ● 現在、山梨県のオープンデータサイトでは 12,000件を超えるデータが公開されている ● モバイルアプリで利用したい場合、Web API で提供されていると手軽に試すことができて 嬉しい ● Shingen.py の勉強会で FastAPI を試す機会が あり、オープンデータ利用に活用できないか 検討した 4
FastAPI とは ● OpenAPI に基づいて作られてい る Python フレームワーク ● 作りやすさを意識 ● 「早い・速い・簡単」 ○ ○ ○ 開発が早い それなりにパフォーマンスが出る (速い) 簡単に作れる from typing import Optional from fastapi import FastAPI app = FastAPI() @app.get("/") def read_root(): return {"Hello": "World"} @app.get("/items/{item_id}") def read_item(item_id: int, q: Optional[str] = None): return return {"item_id": item_id, "q": q} 5
例として、 山梨の温泉施設を返却するAPI を FastAPI で作成する ちなみに 山梨は 泉質が多様、景観の良い温泉がとても多いです! 6
県のオープンデータを利用 7
D P ! ! F 8
PDF でも大丈夫! PDF をそのままロードして変換後、 FastAPI で返却するよう実装しました Python 便利ですね 9
chezou/tabula-py ● PDF ファイル内の表を pandas の DataFrame オブジェクトに 変換するライブラリ ○ CSV、TSV、JSON ファイルに変 換することも可能 ● OCR ツールではない ● Java 8 以降が必要 10
main.py - ① PDF 読み込み def get_data(pdf_path): previous_df = pd.DataFrame() dfs = tabula.read_pdf(pdf_path, lattice=True, pages = 'all') PDFを読み込み、DataFrame オブ ジェクトを返却する for df in dfs: # 複数ページの表を結合する if (check_columns(df, previous_df)): df = pd.concat([previous_df, df]) previous_df = df return previous_df def check_columns(df, previous_df): difference1 = set(df.keys()) - set(previous_df.keys()) difference2 = set(previous_df.keys()) - set(df.keys()) 複数ページにまたがる表の項目名 を比較し、同じ表かどうかを判定 する(上の関数から呼ばれる) return (len(difference1) == 0 and len(difference2) == 0) 11
main.py - ② API 作成
app = FastAPI()
pdf_path = "h3012011.pdf"
[get] /
@app.get("/")
def read_root():
data = get_data(pdf_path)
json_data = data.to_json(orient = 'records')
return json.loads(json_data)
全件返却する API
@app.get("/area/{area}")
def read_item(area: str):
data = get_data(pdf_path)
df_mask = data['市町村名'] == area
data = data[df_mask]
json_data = data.to_json(orient = 'records')
return json.loads(json_data)
[get] /area/{area}
指定された市町村のみ返却する
API
12
Docker を使用 tiangolo/uvicorn-gunicorn-fastapi :python3.8-alpine3.10 上記のイメージをベースに openjdk11 をインストール したものを使用 VPS Docker コンテナ Nginx (リバースプロキシ) opendata.yamanashi.dev /api/onsen FastAPI main.py localhost:xxxxx CSV 山梨県 Webサイト PDF 13
https://opendata.yamanashi.dev/api/onsen DEMO 14
https://opendata.yamanashi.dev 山梨県オープンデータAPIプロジェクト ● プロジェクト サイト ○ 県のオープンデータサイトで公開 されているデータを API で提供 ● GitHub ○ ○ ソースコードを公開 更新することで自動デプロイ ● DockerHub ○ FastAPI、Tabula が実行可能な Docker イメージを提供 15
本プロジェクトが目指すところ ● 他のオープンデータへのAPI展開を容易にする ○ リポジトリを複製し、main.py をカスタマイズすれば OK ● オープンデータAPIサーバの起ち上げを容易にする ○ Docker 環境があればワンライナーで起ち上げ可能 データ利用については 山梨県オープンデータサイト利用規約 に従う必要があります 16
さいごに 17
まとめ 「FastAPI を活用した オープンデータAPI の作成」 ● FastAPI はオープンデータから手軽に API を作成するのに向いている ○ Tabula と組み合わせることで、PDF ファイルも FastAPI に載せることが 可能 ● 山梨県オープンデータAPI プロジェクトを起ち上げ ○ API作成・APIサーバ起ち上げを容易にし、オープンデータの利用促進に 繋げたい 18