概要
- 為替確認APIからレートのリストを取得する
- コマンドライン引数で受け取った値をドルから円に変換する
$ brew tap kei-sato/usdex
$ brew install usdex
$ usdex -p 2.5 -v
1(USD) => 122.54078(JPY)
2.5(USD) => 306.35195(JPY)
Gistはこちらです
https://gist.github.com/kei-sato/98675769952ec7538d6a
brew install出来るようにする方法はこちらです
Pythonで作ったコマンドラインツールをbrew install出来るようにする
解説
現在の為替情報をJSONを始めとした様々なフォーマットで公開(http://api.aoikujira.com/kawase/)してくださっている方がいらっしゃったので、これを利用して、コマンドラインからドルを円に換算するコマンドを作成しました。
まずは、APIから返ってくる値を確認します。
$ curl -s http://api.aoikujira.com/kawase/json/usd | jq .
{
"result": "ok",
"basecode": "USD",
"update": "2015-07-13 17:41:44",
"source": "*",
"API_URL": "http://api.aoikujira.com/kawase/",
...(中略)
"JPY": "123.44644",
"KRW": "1131.46557",
"HKD": "7.75138",
...(中略)
"LBP": "1514.20449"
}
JPYに1ドルを円換算した値が入っているのが分かります。(他にもKRW(ウォン)やHKD(香港ドル)もありますね)
とりあえず、この値を抜き取って、引数で与えられた数値に掛けあわせるだけの、簡単なスクリプトを書いてみます。
#coding:utf-8
import sys
import urllib
import json
URL = "http://api.aoikujira.com/kawase/json/usd"
if __name__ == "__main__":
price = float(sys.argv[1])
response = urllib.urlopen(URL)
data = json.loads(response.read())
rate = float(data[u'JPY'])
print "{0}(USD) => {1}(JPY)".format(1, rate)
print "{0}(USD) => {1}(JPY)".format(price, price * rate)
$ python exchange1.py 2.5
1(USD) => 122.568(JPY)
2.5(USD) => 306.42(JPY)
引数で2.5(ドル)を与えると、306円という答えが返ってきました。
ついでに1ドルあたりの円も返しています。
目的達成ですね。
以上、終了です。
といきたいところなのですが、今回は公開したいので、もう少しマシにします。
API叩き過ぎ防止
連続でAPI叩くのも良くないので、APIへのアクセスは1日1回にしようと思います。
import urllib
import json
URL = "http://api.aoikujira.com/kawase/json/usd"
FPATH = "/tmp/exchange"
def readCache():
with open(FPATH, 'r') as f:
body = f.read()
return body
def writeCache(body):
with open(FPATH, 'w') as f:
f.write(body)
def fetchRates():
# fetch rate list from remote
response = urllib.urlopen(URL)
body = response.read()
writeCache(body)
return body
fetchRatesでAPIへアクセスし、writeCacheで内容をファイルに保存するようにします。
readCacheでファイルに保存された内容を読み取ります。
import os.path
from datetime import date, datetime
FPATH = "/tmp/exchange"
def hasCache():
if os.path.isfile(FPATH):
d = date.today()
today = datetime.combine(d, datetime.min.time())
mtime = datetime.fromtimestamp(os.path.getmtime(FPATH))
if mtime > today:
return True
return False
hasCacheでキャッシュファイルがあるかどうか確認し、最終更新日時が今日だったら、Trueを返します。
キャッシュファイルが無いか、キャッシュファイルの最終更新日時が今日より前だったら、Falseを返します。
合わせると、次のようになります
#!/usr/bin/env python
import sys
import os.path
from datetime import date, datetime
import urllib
import json
URL = "http://api.aoikujira.com/kawase/json/usd"
FPATH = "/tmp/exchange"
def hasCache():
if os.path.isfile(FPATH):
d = date.today()
today = datetime.combine(d, datetime.min.time())
mtime = datetime.fromtimestamp(os.path.getmtime(FPATH))
if mtime > today:
return True
return False
def readCache():
with open(FPATH, 'r') as f:
body = f.read()
return body
def writeCache(body):
with open(FPATH, 'w') as f:
f.write(body)
def fetchRates():
# fetch rate list from remote
response = urllib.urlopen(URL)
body = response.read()
writeCache(body)
return body
if __name__ == "__main__":
price = float(sys.argv[1])
if hasCache():
body = readCache()
else:
body = fetchRates()
data = json.loads(body)
rate = float(data[u'JPY'])
print "{0}(USD) => {1}(JPY)".format(1, rate)
print "{0}(USD) => {1}(JPY)".format(price, price * rate)
hasCacheがTrueを返したら、readCacheでキャッシュファイルから読み込み、Falseを返したら、fetchRatesでAPIから取得するようにしています。
コマンドラインツールっぽくしたい
argparseを使って簡単にコマンドラインツールを作ることが出来ます
#coding:utf-8
import argparse
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='convert usd to any currency.')
parser.add_argument('-p', '--price', nargs='?', type=float, help='price', default=1.0)
parser.add_argument('-c', '--currency', nargs='?', help='currency', default=u'JPY')
parser.add_argument('-r', '--reverse', action='store_true', help='reverse the direction')
parser.add_argument('-v', '--verbosity', action='count', help='increase output verbosity')
args = parser.parse_args()
price = args.price
currency = args.currency
reverse = args.reverse
verbosity = args.verbosity
print "price:", price
print "currency:", currency
print "reverse:", reverse
print "verbosity:", verbosity
上記を保存して、実行してみましょう
# 引数なし
$ python options.py
price: 1.0
currency: JPY
reverse: False
verbosity: None
# 引数つき
$ python options.py -p 2.5 -c EUR -r -vvv
price: 2.5
currency: EUR
reverse: True
verbosity: 3
# ヘルプメッセージが自動生成されている
$ python options.py -h
usage: options.py [-h] [-p [PRICE]] [-c [CURRENCY]] [-r] [-v]
convert usd to any currency.
optional arguments:
-h, --help show this help message and exit
-p [PRICE], --price [PRICE]
price
-c [CURRENCY], --currency [CURRENCY]
currency
-r, --reverse reverse the direction
-v, --verbosity increase output verbosity
簡単ですね!
ここまでの、すべてを合わせたものがGistに上がっています
https://gist.github.com/kei-sato/98675769952ec7538d6a
まとめ
- Pythonを使ってWebAPIをコマンドラインツールに落としこむ流れを紹介しました
- urllibとjsonで簡単にAPIを取り扱うことが出来ます
- 過度にAPIを叩きすぎないようキャッシュをつけてあげると親切だと思います
- argparseで簡単にコマンドラインツールが作れます
- brew installも簡単にできます -> Pythonで作ったコマンドラインツールをbrew install出来るようにする