Google App Engine で dropbox API を使うにあたって

dropbox for developers の このページで公開されている python のライブラリを Google App Engine 上で使うに当たって、いろいろと下準備をしないといけなかった。
他の人も公開されているライブラリを Google App Engine 上で使うかもしれないので、下準備について書いておこうと思う。

パッケージのダウンロード

Google App Engine ではこのドキュメントにあるとおり、必要最低限のPython のパッケージモジュールしか Google App Engine にインストールされていない。
このため、dropbox で公開しているライブラリを使うためには、以下のパッケージが必要になる。

  • oauth
  • poster
  • dropbox client library

ブラウザかコマンドで上記のパッケージをダウンロードしてきましょう。

以下は、wget でダウンロードしてきたもの。

$ wget http://pypi.python.org/packages/source/o/oauth/oauth-1.0.1.tar.gz#md5=30ed3cc8c11d7841a89feab437aabf81
$ wget http://pypi.python.org/packages/2.5/p/poster/poster-0.6.0-py2.5.egg#md5=5153835c7b82cb5f1a7a2197c7f0d2a2
$ wget https://www.dropbox.com/static/developers/dropbox-client-python-BETA.tar.gz

oauth と poster は pypiで公開されている正式パッケージをダウンロードする。
現時点では、oauth のバージョンは 1.0.1、poster のバージョンは 0.6.0 が最新バージョンみたい。
dropbox client library のパッケージは、dropbox 本家で公開されているものをダウンロードする。

zip アーカイブ

次に、ダウンロードしたパッケージを zip アーカイブする。
Google App Enginepypi などでダウンロードしてきたパッケージを利用するにはいろいろな方法があると思うが、zip 形式でアーカイブされたパッケージを sys.path.insert でインポートする方法がパッケージの管理が楽なためこの方法で行う。
zip アーカイブされたパッケージをインポートする方法は後で説明する。

ダウンロードしてきた、poster のパッケージである poster-0.6.0-py2.5.egg は既に zip アーカイブされているため、これに関してはこれをそのまま利用する。
oauth、dropbox client library はソースファイルであるため、zip アーカイブする必要がある。

oauth の zip アーカイブ

以下のコマンドを実行。

$ tar xvf oauth-1.0.1.tar.gz
x oauth-1.0.1/
x oauth-1.0.1/._LICENSE.txt
x oauth-1.0.1/LICENSE.txt
x oauth-1.0.1/oauth/
x oauth-1.0.1/oauth/__init__.py
x oauth-1.0.1/oauth/example/
x oauth-1.0.1/oauth/example/client.py
x oauth-1.0.1/oauth/example/._server.py
x oauth-1.0.1/oauth/example/server.py
x oauth-1.0.1/oauth/._oauth.py
x oauth-1.0.1/oauth/oauth.py
x oauth-1.0.1/oauth.egg-info/
x oauth-1.0.1/oauth.egg-info/dependency_links.txt
x oauth-1.0.1/oauth.egg-info/PKG-INFO
x oauth-1.0.1/oauth.egg-info/SOURCES.txt
x oauth-1.0.1/oauth.egg-info/top_level.txt
x oauth-1.0.1/oauth.egg-info/zip-safe
x oauth-1.0.1/PKG-INFO
x oauth-1.0.1/setup.cfg
x oauth-1.0.1/._setup.py
x oauth-1.0.1/setup.py
$ cd oauth-1.0.1
$ sudo python setup.py bdist_egg
running bdist_egg
running egg_info
writing oauth.egg-info/PKG-INFO
writing top-level names to oauth.egg-info/top_level.txt
writing dependency_links to oauth.egg-info/dependency_links.txt
reading manifest file 'oauth.egg-info/SOURCES.txt'
writing manifest file 'oauth.egg-info/SOURCES.txt'
installing library code to build/bdist.macosx-10.6-i386/egg
running install_lib
running build_py
creating build
creating build/lib
creating build/lib/oauth
copying oauth/__init__.py -> build/lib/oauth
copying oauth/oauth.py -> build/lib/oauth
creating build/bdist.macosx-10.6-i386
creating build/bdist.macosx-10.6-i386/egg
creating build/bdist.macosx-10.6-i386/egg/oauth
copying build/lib/oauth/__init__.py -> build/bdist.macosx-10.6-i386/egg/oauth
copying build/lib/oauth/oauth.py -> build/bdist.macosx-10.6-i386/egg/oauth
byte-compiling build/bdist.macosx-10.6-i386/egg/oauth/__init__.py to __init__.pyc
byte-compiling build/bdist.macosx-10.6-i386/egg/oauth/oauth.py to oauth.pyc
creating build/bdist.macosx-10.6-i386/egg/EGG-INFO
copying oauth.egg-info/PKG-INFO -> build/bdist.macosx-10.6-i386/egg/EGG-INFO
copying oauth.egg-info/SOURCES.txt -> build/bdist.macosx-10.6-i386/egg/EGG-INFO
copying oauth.egg-info/dependency_links.txt -> build/bdist.macosx-10.6-i386/egg/EGG-INFO
copying oauth.egg-info/top_level.txt -> build/bdist.macosx-10.6-i386/egg/EGG-INFO
copying oauth.egg-info/zip-safe -> build/bdist.macosx-10.6-i386/egg/EGG-INFO
creating dist
creating 'dist/oauth-1.0.1-py2.5.egg' and adding 'build/bdist.macosx-10.6-i386/egg' to it
removing 'build/bdist.macosx-10.6-i386/egg' (and everything under it)

dist/ に zip アーカイブされたパッケージである oauth-1.0.1-py2.5.egg が作られる。

dropbox client library の zip アーカイブ

dropbox client library の場合 egg を作成する前に、ソースをちょっといじらないといけない。
ダウンロードしてきたソースを解凍してみよう。

$ tar xvf dropbox-client-python-BETA.tar.gz
x dropbox-client-python/
x dropbox-client-python/bin/
x dropbox-client-python/bin/cli_client.py
x dropbox-client-python/bin/oauth_diff.py
x dropbox-client-python/config/
x dropbox-client-python/config/testing.ini.example
x dropbox-client-python/config/trusted_testing.ini.example
x dropbox-client-python/dropbox/
x dropbox-client-python/dropbox/__init__.py
x dropbox-client-python/dropbox/auth.py
x dropbox-client-python/dropbox/client.py
x dropbox-client-python/dropbox/rest.py
x dropbox-client-python/LICENSE
x dropbox-client-python/Makefile
x dropbox-client-python/setup.py
x dropbox-client-python/tests/
x dropbox-client-python/tests/dropbox_tests/
x dropbox-client-python/tests/dropbox_tests/__init__.py
x dropbox-client-python/tests/dropbox_tests/auth_tests.py
x dropbox-client-python/tests/dropbox_tests/client_tests.py
x dropbox-client-python/tests/dropbox_tests/helpers.py
x dropbox-client-python/tests/dropbox_tests/rest_tests.py
x dropbox-client-python/tests/dropbox_tests/trusted_client_tests.py
x dropbox-client-python/tests/file with spaces.txt
x dropbox-client-python/tests/sample_photo.jpg
x dropbox-client-python/tests/中文.txt

dropbox-client-python/dropbox の配下にある3つのスクリプトdropbox client lirbrary で利用するモジュールである。
これら3つのスクリプトでは simplejson が利用されている。しかし、simplejson は Google App Engine では既に django パッケージで利用されているためか、ダウンロートしたソースの状態で利用するとエラーが発生して dropbox client library がまともに動作しない。なので、これら3つのスクリプトで simplejson を利用しているコードを修正する。
修正はこれら3つのスクリプトに記載された、

import simplejson as json

の部分を、

from django.utils import simplejson as json

に書き換えるだけである。
3つのスクリプトを書き換えたら、以下のコマンドを実行する。

$ sudo python setup.py bdist_egg
running bdist_egg
running egg_info
creating dropbox_client.egg-info
writing requirements to dropbox_client.egg-info/requires.txt
writing dropbox_client.egg-info/PKG-INFO
writing top-level names to dropbox_client.egg-info/top_level.txt
writing dependency_links to dropbox_client.egg-info/dependency_links.txt
writing manifest file 'dropbox_client.egg-info/SOURCES.txt'
reading manifest file 'dropbox_client.egg-info/SOURCES.txt'
writing manifest file 'dropbox_client.egg-info/SOURCES.txt'
installing library code to build/bdist.macosx-10.6-i386/egg
running install_lib
running build_py
creating build
creating build/lib
creating build/lib/dropbox
copying dropbox/__init__.py -> build/lib/dropbox
copying dropbox/auth.py -> build/lib/dropbox
copying dropbox/client.py -> build/lib/dropbox
copying dropbox/rest.py -> build/lib/dropbox
creating build/bdist.macosx-10.6-i386
creating build/bdist.macosx-10.6-i386/egg
creating build/bdist.macosx-10.6-i386/egg/dropbox
copying build/lib/dropbox/__init__.py -> build/bdist.macosx-10.6-i386/egg/dropbox
copying build/lib/dropbox/auth.py -> build/bdist.macosx-10.6-i386/egg/dropbox
copying build/lib/dropbox/client.py -> build/bdist.macosx-10.6-i386/egg/dropbox
copying build/lib/dropbox/rest.py -> build/bdist.macosx-10.6-i386/egg/dropbox
byte-compiling build/bdist.macosx-10.6-i386/egg/dropbox/__init__.py to __init__.pyc
byte-compiling build/bdist.macosx-10.6-i386/egg/dropbox/auth.py to auth.pyc
byte-compiling build/bdist.macosx-10.6-i386/egg/dropbox/client.py to client.pyc
byte-compiling build/bdist.macosx-10.6-i386/egg/dropbox/rest.py to rest.pyc
creating build/bdist.macosx-10.6-i386/egg/EGG-INFO
copying dropbox_client.egg-info/PKG-INFO -> build/bdist.macosx-10.6-i386/egg/EGG-INFO
copying dropbox_client.egg-info/SOURCES.txt -> build/bdist.macosx-10.6-i386/egg/EGG-INFO
copying dropbox_client.egg-info/dependency_links.txt -> build/bdist.macosx-10.6-i386/egg/EGG-INFO
copying dropbox_client.egg-info/requires.txt -> build/bdist.macosx-10.6-i386/egg/EGG-INFO
copying dropbox_client.egg-info/top_level.txt -> build/bdist.macosx-10.6-i386/egg/EGG-INFO
zip_safe flag not set; analyzing archive contents...
creating dist
creating 'dist/dropbox_client-1.0-py2.5.egg' and adding 'build/bdist.macosx-10.6-i386/egg' to it
removing 'build/bdist.macosx-10.6-i386/egg' (and everything under it)

zip アーカイブが正常に完了すれば、dist/ に dropbox_client-1.0-py2.5.egg が作られているはず。

zip アーカイブの配置

作成した zip アーカイブのパッケージを、Google App Engine で動作するアプリケーションに配置する。
zip アーカイブのパッケージの配置に関してはいろいろとあると思うが、ここでは、アプリケーションディレクトリの直下に eggs というディレクトリを作成してそこに配置する。
ダウンロードしてきた poster のパッケージと、zip アーカイブを作成した oauth と dropbox client library のパッケージ配置すると以下のようになる。

myapp/eggs
myapp/eggs/oauth-1.0.1-py2.5.egg
myapp/eggs/poster-0.6.0-py2.5.egg
myapp/eggs/dropbox_client-1.0-py2.5.egg

zip アーカイブのインポート

dropbox client library を利用するスクリプトの py ファイルの先頭に以下のコードを記載する。

# import eggs
import os
import sys
for arch in os.listdir('eggs'):
    sys.path.insert(0, os.path.join('eggs', arch))

このコードは、myapp/eggs にある zip アーカイブされた拡張子 egg ファイルを読み込んで、zip インポートを実行するコードである。

これでこのコード以降、dropbox client library が利用できるようになる。
後は、お好きなように♪