Python で bit.ly API モジュール的なもの
python-twitter 見てたら、API のラッパモジュール作るのが楽しそうだなと思いつつ、ちょっと bit.ly の API を使いたかったので、ザックリと書きなぐってみた。
もちろん、既に多くの先達の皆さんが、もっと素敵なコードで書いてらっしゃいますが!そして当然のように参考にさせてもらってますが!書いて参考にして直して勉強、ということで、そこはあえて!!
今のとこ
- shorten - longUrl を渡して shortUrl だけを返す
- expand - shortUrl を渡して longUrl だけを返す(hash とか知らない)
って感じで、自分が欲しい機能だけ実装してしまい、厳密な API のラッパじゃありません。ホントすいません。
あ、あと simplejson を使用してます。
ということで晒します。
bitly.py
#!/usr/bin/env python # -*- coding:utf-8 -*- import urllib import urllib2 import logging import simplejson as json #logging.basicConfig(level=logging.DEBUG) class BitlyError(Exception): """Base class for Bitly errors """ pass class BitlyRequestError(BitlyError): """Bitly API request error class """ def __init__(self, code, msg): self.code = code self.msg = msg def __str__(self): return "Bit.ly API request error: %s (code: %s)" \ % (self.msg, self.code) class BitlyResponseError(BitlyError): """Bitly API response error class """ def __init__(self, code, msg): self.code = code self.msg = msg def __str__(self): return "Bit.ly API response error: %s (code: %s)" \ % (self.msg, self.code) class Api(object): def __init__(self): self.base_url = 'http://api.bit.ly' self.login = None self.apikey = None @property def base_query_dict(self): return { 'login': self.login, 'apiKey': self.apikey, 'version': '2.0.1', 'format': 'json', 'history': 1, } def mk_query(self, **kwd): """クエリ文字列を生成 """ query_dict = self.base_query_dict query_dict.update(kwd) return urllib.urlencode(query_dict) def set_account(self, login, apikey): """API 実行アカウントを設定 """ self.login = login self.apikey = apikey def shorten(self, longUrl): """Given a long url, returns a shorter one. """ command_name = 'shorten' query = self.mk_query(longUrl=longUrl) url = "%s/%s?%s" % (self.base_url, command_name, query) logging.debug("[%s] url: %s", command_name, url) data = self._get_data(command_name, url) logging.debug("[%s] data: %s", command_name, data) return data['results'][longUrl]['shortUrl'] def expand(self, shortUrl): """Given a bit.ly url, return long source url. """ command_name = 'expand' query = self.mk_query(shortUrl=shortUrl) url = "%s/%s?%s" % (self.base_url, command_name, query) logging.debug("[%s] url: %s", command_name, url) data = self._get_data(command_name, url) logging.debug("[%s] data: %s", command_name, data) shortened = shortUrl.split('/')[-1] return data['results'][shortened]['longUrl'] def _get_data(self, command_name, url): """指定APIを実行して結果を返す """ data = {} f = urllib2.urlopen(url) try: if not (200 <= f.code < 300): e = BitlyRequestError(f.code, f.msg) logging.error("[%s] BitlyRequestError: %s", command_name, e) raise e data = json.load(f) finally: f.close() self._check_api_success(command_name, data) return data def _check_api_success(self, command_name, data): """API 処理が失敗したら例外を発生させる """ if data.get('statusCode', '') == 'OK': return code = data.get('errorCode', 0) msg = data.get('errorMessage', '') e = BitlyResponseError(code, msg) logging.error("[%s] BitlyResponseError: %s", command_name, e) raise e
使い方は、bit.ly にサインインすると取得できる API Key を利用して、
>>> import bitly >>> api = bily.Api() >>> api.set_account('bitly_login', 'bitly_apikey') >>> api.shorten("http://google.co.jp") 'http://bit.ly/LhudI' >>> api.expand("http://bit.ly/LhudI") 'http://google.co.jp/'
てな感じです。