EmptyPage.jp > Notes > 「さくらのレンタルサーバ」で Python 外部モジュールを使う 改訂版
公開日: 2005-07-08/更新日: 2008-03-30
さくらインターネットの「さくらのレンタルサーバ」サービスで Python の外部モジュールを導入・利用するための覚え書きです。2008年3月30日に一部内容を見直して改訂版としました。
さくらインターネットのホスティングサービス、「さくらのレンタルサーバ」では、CGI として Python を利用できます。Python には標準モジュールのほかにも、HTMLTemplate や PIL、ReportLab などといった豊富な外部モジュールが公開されています。CGI からこれらを利用することができれば、HTML テンプレートやグラフィックス、PDF などを扱う高度な処理を効率的に行うことができます。
「さくらのレンタルサーバ」(スタンダードプラン以上)では、telnet/ssh でホストにログインしての作業が可能なので、いくつかの制限にさえ気をつければ、こうした外部モジュールを自分のホームディレクトリ下にインストールして、CGI から利用できるようにすることが可能です。
以下は自分なりに知っている範囲内で書きましたが、よりよい解決法がありましたら Visitor's Voice より教えていただけるとありがたいです。その他間違いのご指摘、ご意見・ご感想なども歓迎です。よろしく。
「さくらのレンタルサーバ」は複数のユーザーでひとつのホストを共有する方式なので、勝手にシステムに独自のモジュールをインストールすることはできません。モジュールを追加するのであれば、自分のホームディレクトリにインストールしなくてはいけません。外部モジュールをシステム標準以外の場所にインストールする方法については、ちゃんとドキュメントがあります。
このドキュメントの「3.1 別の場所へのインストール: home スキーム」を読みましょう。これを読むと、--home オプション付きでインストールスクリプトを実行すれば、任意の場所にモジュールを導入できることがわかります。
%python setup.py install --home=~
これで、ホームディレクトリ下、~/lib/python にモジュールがインストールされるわけです。
本稿は CGI から外部モジュールを利用する方法についてが主旨で、ホストにログインした状態でシェルから Python スクリプトを実行するといったことは必須の話ではありません。とはいえインストールしたモジュールのテストをしたいということなどもあるので、これについても書いておきます。
--home オプション付きで独自にインストールしたモジュールは、Python インタプリタ自身はそれがどこにインストールされたかを知らないので、そのままではスクリプトから import 文を使ってインポートできるようにはなっていません(カレントディレクトリにある場合は別ですが)。インストールしたモジュールを探索できるよう、Python にそのパスを教えてやる必要があります。
前出のドキュメント「Python モジュールのインストール」の「4 カスタムのインストール」に書かれているように、Python は sys.path に格納されているパスからモジュールを探すので、これにモジュールのインストールされているパスを追加してやればいいわけですが、「4 カスタムのインストール」の記事にある方法の中のうち、.pth ファイルを置く方法や site.py を編集する方法は使えません(それをする権限があればそもそもモジュールを自分のホームディレクトリに入れて使ったりする必要はないわけで……)。ここでは環境変数 PYTHONPATH を設定する方法がいいでしょう。ホームディレクトリの .cshrc には各種環境変数を設定している部分があるので、ここに1行追加します。
... setenv EDITOR vi setenv PAGER more setenv BLOCKSIZE K setenv PKG_DBDIR ~/db/pkg setenv PYTHONPATH ~/lib/python ...
対話モードで Python を起動してみて、sys.path の値を確認し、インストールしたモジュールをインポートしてみましょう。
%python Python 2.4.2 (#2, Nov 14 2005, 12:00:29) [GCC 2.95.4 20020320 [FreeBSD]] on freebsd4 Type "help", "copyright", "credits" or "license" for more information. >>> import sys >>> sys.path ['', '/home/foo/lib/python', '/usr/local/lib/python24.zip', '/usr/local/lib/pyt hon2.4', '/usr/local/lib/python2.4/plat-freebsd4', '/usr/local/lib/python2.4/lib -tk', '/usr/local/lib/python2.4/lib-dynload', '/usr/local/lib/python2.4/site-pac kages'] >>> import spam >>>
外部モジュールをインポートして、エラーが出なければ問題ありません。
環境変数 PYTHONPATH を設定していれば通常は外部モジュールもインストールパスを気にすることなくインポートできるはずなのですが、CGI として利用する場合はそれでもうまくいかない可能性があります。
Apache が CGI を実行するときの環境変数は .htaccess ファイルに SetEnv ディレクティブを記述することで設定することができますが、Apache の動作モードによっては、セキュリティ上の対策として、CGI に「安全な」環境変数のみが渡されるようになっていることがあります(Apache の suEXEC 機能といいます)。この場合は CGI に PYTHONPATH を渡すことができません。そしてそういう話をここに書くということは、もちろん「さくらのレンタルサーバ」でもそうなっているわけです。
そうなると、手段はひじょうに限られてきたかに思われます。しかし結局のところ、Python のモジュール探索というのは、 sys.path に入っているパスを順番に見ているに過ぎません。だから、スクリプト内で直接 sys.path にパスを追加してもかまわないのです。スクリプトのどこか先頭付近で、外部モジュールをインポートする前に、sys.path に外部モジュールのインストール先のパスを追加します。
#!/usr/bin/env python import sys sys.path.append('/home/foo/lib/python') import spam ...
これで CGI から外部モジュールを使えるようになりました。
スクリプトの途中にホームディレクトリのパスが入るのが気に入らない場合、スクリプト先頭の #! 部分で環境変数 PYTHONPATH をセットするという方法も考えられます。
#!/usr/bin/env PYTHONPATH=/home/foo/lib/python python import spam ...
これでも外部モジュールはうまく利用できます。
この部分にはもうひとつの方法として、Python の user モジュールの仕組みを利用したトリックを載せていたことがありました。しかしその方法は、上記ふたつの解決策とくらべて可搬性に優れているわけでもないにもかかわらずあたかもそうであるかのように見せかけてしまう、罠の多いものでした。当時自分はその方法がよいものかどうなのかはっきり判断しかねるまま(断り書きを入れて)それを掲載していたのですが、今では載せるべきではなかったと考えています。
user モジュールを使う方法を気に入ってしまった人には申し訳ないのですが、一般的に言って、かつてここに書かれていた方法をとるべきではありません。
ここではその理由については詳述しませんが、興味がある人は筆者の昔の覚え書きを見てください。
以上で述べたことをまとめると次のようになります。
「さくらのレンタルサーバ」では外部モジュールをシステム標準の場所にはインストールできない。そこでセットアップスクリプトの --home オプションを使う。
インストールした外部モジュールをインポートできるように、環境変数 PYTHONPATH を設定する。しかしこれはホストにログインした環境でしか使えない。
CGI では、.htaccess に SetEnv ディレクティブを記述することで環境変数をセットできるのだが、「さくらのレンタルサーバ」のようにこれができない場合もある。
そういうときはスクリプト内で sys.path に外部モジュールのパスを直接追加すればよい。
スクリプトの #! 行で PYTHONPATH を追加する方法もある(オプション)。
以上、自分の試行錯誤をつたない技量でまとめましたが、だれかのお役に立てれば幸いです。
記述はできるだけ正確なものを心がけてはいますが、作者の知識や調査の不足などから間違ったことが書いてあるかもしれません。この文書の情報にもとづいた行動によって何らかの被害が生じた場合でも、作者はその責任を負いませんので、あしからず。
Copyright (C) Masaaki Shibata.
この文書は、クリエイティブ・コモンズ・ライセンスの下でライセンスされています。