WebAPIとは
pythonでホームページを作成して表示するところはやってきました。ただ、Webはホームページ表示だけではありません。 実は、画面に表示せずに仕事を行うことができます。WebAPIはその一つで、Webに対しての問い合わせ、例えば、この緯度経度は何市何町とか、この町の郵便番号はとかの問い合わせに、ホームページ表示ではなくデータだけを返すやりかたです。 データの返し方はjsonとかxmlとかいう決められたフォーマットで返し、それをプログラムで受信して加工して使用します。
WebAPI
たとえばxmlデータは次のようなフォーマットで、内容に関しては自分で自由で決められます。
<?xml version="1.0" encoding="UTF-8"?> <pocketMoney> <payment> <content> <date>1月20日</date> <train>780</train> <eat>980</eat> <coffee>250</coffee> </content> </payment> </pocketMoney>
jsonデータは、javascript用のフォーマットで次のようなものです。
[
{"id" : "1", "name" : "suzuki"},
{"id" : "2", "name" : "tanoue"}
]
リクエストに対するレスポンスをこのようなxmlやjsonで返すとWEBAPIとして、WEB上または、ローカルから呼び出して利用することができるようになります。
pythonでjsonをレスポンスで返すには、jsonify()関数に返したい辞書を入れてあげれば利用できます。
日付を渡して、その前後の日付を返すWEBAPI
Flaskを使ってローカルで動くWEBAPIを作って、日付を返すWEBAPIの実験をしましょう
webapisampleのソース
webapisampleフォルダーを作成し、app.pyを作成します
#!/usr/bin python3
# -*- coding: utf-8 -*-
# pip install python-dateutil
# flask run
# localhost:5000/?year=2021&month=2&day=25&delta=pd10
# {"day":7,"month":3,"year":2021}
from flask import Flask, jsonify, make_response, request
from dateutil.relativedelta import relativedelta
from datetime import datetime
import json
app = Flask(__name__)
@app.route('/', methods=['GET'])
def retDate():
today = datetime.today()
#パラメータ取得
syear = request.args.get("year",default='')
year = today.year if syear == '' else int(syear)
smonth = request.args.get("month",default='')
month = today.month if smonth == '' else int(smonth)
sday = request.args.get("day",default='')
day = today.day if sday == '' else int(sday)
strDelta = (request.args.get("delta"))
thatday = today.replace(year=year,month=month,day=day)
#deltaパラメータの解析
pmDelata = strDelta[0] #p->plus, m->minus
scaleDelta = strDelta[1] #y->year,m->month,d->day
valueDelta = int(strDelta[2:]) #pm10->+10 month, md3->-3 day
#日付計算
pmValue = 1 if pmDelata=='p' else -1
if scaleDelta=='y':
efectDay = thatday + (relativedelta(years=valueDelta) * pmValue)
elif scaleDelta=='m':
efectDay = thatday + (relativedelta(months=valueDelta) * pmValue)
elif scaleDelta=='d':
efectDay = thatday + (relativedelta(days=valueDelta)*pmValue)
result = {
'year': efectDay.year,
'month': efectDay.month,
'day': efectDay.day
}
return make_response(jsonify(result))
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000,debug=True)
コマンドプロンプトで、webapisampleのフォルダーに移動し、flask runで起動します。
続いて、ブラウザを立ち上げ localhost:5000/?year=2021&month=2&day=25&delta=pd10 と入力します。すると画面に {"day":7,"month":3,"year":2021}と表示されます。これがWEBAPIの答えで、2021年2月25日の10日後は何日かという質問にWEBAPIがjsonで2021年3月7日と答えを返してきたところです。
先に作ったWEBAPIをローカルのpythonから呼び出すプログラム
pythonのプログラムを作り、WEBAPIを経由して日付の計算を行う実験を行います。
webapicall.pyのソース
適当なフォルダーを作成し、webapicall.pyを作成します
#!/usr/bin python3
# -*- coding: utf-8 -*-
# python webapicall.py 2021 2 25 pd10
# 2021/2/21の10日後
# python webapicall.py 2021 2 25 mm2
# 2021/2/21の2ヶ月前
# xynn -> x:plus or minus, y:d day,m month,y year, nn is number
import requests
import sys
from datetime import datetime
year = 0
month = 0
day = 0
pmdata = "pd1"
argc = len(sys.argv)
if argc == 5:
pmdata = (sys.argv[4])
day = int(sys.argv[3])
month = int(sys.argv[2])
year = int(sys.argv[1])
else:
sys.exit()
param = {"year": year, "month": month, "day":day,"delta":pmdata}
url = "http://localhost:5000"
data = requests.get(url, param).json()
ayear = data['year']
amonth = data['month']
aday = data['day']
print(year,"年",month,"月",day,"日->",pmdata,"->",ayear,"年",amonth,"月",aday,"日")
実行すると、このような結果になります
クライアント側 python webapicall.py 2021 2 25 pd10 2021 年 2 月 25 日-> pd10 -> 2021 年 3 月 7 日 python webapicall.py 2021 2 25 mm2 2021 年 2 月 25 日-> mm2 -> 2020 年 12 月 25 日 サーバー側 127.0.0.1 - - [06/Jan/2022 15:01:18] "GET /?year=2021&month=2&day=25&delta=pd10 HTTP/1.1" 200 - 127.0.0.1 - - [06/Jan/2022 15:01:33] "GET /?year=2021&month=2&day=25&delta=mm2 HTTP/1.1" 200 -