2013-09-16

Google App Engine から backlog.jp の API にアクセスする

Google App Engine から backlog.jp の API にアクセスしようとしたら、何やらエラーが出ました。 libbacklog は xmlrpc を使っていて、xmlrpc は socket を使っていて、Google App Engine では無料枠では socket 使えないのですよね。ちょっとしたツールを作ることが目的だったので、まずはその場しのぎすることにしました。Making XML-RPC calls from a Google App Engine application をちょっと変えただけです。

"""Provides patch for backloglib to work on Google App Engine
Usage:
>>> import backloglib
>>> import gaebackloglib
>>> gaebackloglib.patch(backloglib)
"""
import sys
import xmlrpclib
import logging
import re
from base64 import b64encode
from google.appengine.api import urlfetch
def patch(backloglib):
"""Patches backloglib for Gooble App Engine"""
backloglib.ServerProxy = ServerProxyWrapper
class GAEXMLRPCTransport(object):
"""Handles an HTTP transaction to an XML-RPC server."""
def __init__(self):
pass
def request(self, host, handler, request_body, verbose=0):
result = None
m = re.match('(.*)@(.*)', host)
host = m.group(2)
credential = b64encode(m.group(1))
url = 'https://%s%s' % (host, handler)
try:
response = urlfetch.fetch(url,
payload=request_body,
method=urlfetch.POST,
headers={
'Content-Type': 'text/xml',
'Authorization': 'Basic ' + credential
}
)
except:
msg = 'Failed to fetch %s' % url
logging.error(msg)
raise xmlrpclib.ProtocolError(host + handler, 500, msg, {})
if response.status_code != 200:
logging.error('%s returned status code %s' %
(url, response.status_code))
raise xmlrpclib.ProtocolError(host + handler,
response.status_code,
"",
response.headers)
else:
result = self.__parse_response(response.content)
return result
def __parse_response(self, response_body):
p, u = xmlrpclib.getparser(use_datetime=False)
p.feed(response_body)
return u.close()
def ServerProxyWrapper(url):
return xmlrpclib.ServerProxy(url, GAEXMLRPCTransport())
結局、このツールは使う必要がなくなったのですが、もしものときのために書き置きしておきます。