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 -