python + google app engineでspreadsheetにアクセス
spreadsheetをDBにするってなんかかっこいいよね!ってことでやってみました。
最初はgae+flaskでspreadsheetをイジイジしようと思ったんですが、
全然うまく行かなかったので、Googleさんが提供してくれてるwebappを使うことに。。。
とりあえず今回はspreadsheetにアクセスできることを確認しました。
*ここを参考にしました
http://code.google.com/apis/spreadsheets/data/1.0/developers_guide_python.html
http://code.google.com/apis/accounts/docs/AuthSub.html
http://gdata-python-client.googlecode.com/hg/pydocs/gdata.spreadsheet.service.html#SpreadsheetsService
http://mars.shehas.net/~tmatsuo/misc/gdata-ja.html
方針
基本的にはここを参考にするとわかりやすい、きがする。
http://code.google.com/apis/accounts/docs/AuthSub.html
要約すると、
(1)auth_tokenという一回限りのトークンを発行
(2)そのトークンを使ってトークンをアップグレードしてセッション管理してね
みたいな感じらしいです。
a) まず、GenerateAuthSubURLって関数で認証URLを発行。
b) すると、googleの認証画面が出てきて、指定したサービスに対して許可しますか?って聞かれる。
c) Acceptすると、リダイレクトされる。この時に、リダイレクトURLの後ろにワンタイムトークンみたいなものがくっついてくる。
d) c)で作られたトークンを使ってUpgradeToSessionTokenで恒久的なトークンを作成。
って流れだと思います。
ソースコード
どっかのサンプルコードを改造しました。ソースコード汚い。。。
結構情報が古かったり、サンプルコードそのままじゃ動かなかったりしたので大変だった。。。
http://gdata-python-client.googlecode.comのPyDocを読みながら、試行錯誤して動きました。
この例では、コンソールに自分のプライベートなスプレッドシートの一覧が表示されます。
import wsgiref.handlers from google.appengine.ext import webapp from google.appengine.api import users import atom.url import gdata.service import gdata.alt.appengine import gdata.spreadsheet.service import settings import logging class Fetcher(webapp.RequestHandler): def GetAuthSubUrl(self): next = 'http://localhost:8080/' scope = 'https://spreadsheets.google.com/feeds/' secure = False session = True self.gd_client = gdata.spreadsheet.service.SpreadsheetsService() return self.gd_client.GenerateAuthSubURL(next, scope, secure, session); def get(self): # Write our pages title self.response.out.write("""<html><head><title> Google Data Feed Fetcher: read Google Data API Atom feeds</title>""") self.response.out.write('</head><body>') # Allow the user to sign in or sign out next_url = atom.url.Url('http', settings.HOST_NAME, path='/') logging.debug(users.get_current_user()); if users.get_current_user(): self.response.out.write('<a href="%s">Sign Out</a><br>' % ( users.create_logout_url(str(next_url)))) else: self.response.out.write('<a href="%s">Sign In</a><br>' % ( users.create_login_url(str(next_url)))) self.response.out.write('<div id="main"></div>') self.response.out.write( '<div id="sidebar"><div id="scopes"><h4>Request a token</h4><ul>') self.response.out.write('<li><a href="%s">Google Documents</a></li>' % (self.GetAuthSubUrl())) self.response.out.write('</ul></div><br/><div id="tokens">') # Initialize a client to talk to Google Data API services. client = gdata.service.GDataService() gdata.alt.appengine.run_on_appengine(client) session_token = None # Find the AuthSub token and upgrade it to a session token. auth_token = gdata.auth.extract_auth_sub_token_from_url(self.request.uri) if auth_token: self.gd_client.SetAuthSubToken(auth_token) logging.debug('upgrading...') self.gd_client.UpgradeToSessionToken() logging.debug('get feed...') feed = self.gd_client.GetSpreadsheetsFeed() logging.debug(feed) if session_token and users.get_current_user(): client.token_store.add_token(session_token) elif session_token: client.current_token = session_token def main(): logging.getLogger().setLevel(logging.DEBUG) application = webapp.WSGIApplication([('/.*', Fetcher), ], debug=True) wsgiref.handlers.CGIHandler().run(application) if __name__ == '__main__': main()
これを、とりあえずローカルで実行。
認証後、ログに大量のXMLが流れてきます。
タイトルを見ると、ちゃんと自分のシートがあることが確認できます。
かなり時間がかかりました^^;
力不足を体感しまくり。。。
スプレッドシートをDBにするには、
gdata.spreadsheet.text_db
ってモジュールが使いやすかったので、それを使っていこうかと思います。
認証方法(3)のClientLoginを使って、DB操作方法だけ勉強してから
認証方法(2)で認証の勉強をして、
Webアプリケーションのに組み込んでいくとすんなりいけるかと。
SpreadsheetをDBにできたら、GAEのDB使わなくてもいいかもねー、とか思ったりしてます。
まぁやってみないとパフォーマンスもわからないよね。
ドキュメント全部英語だし、サンプルコード少ないし、結構大変だなーと思う次第です。
おしまい!