EmptyPage.jp > Notes > 「さくらのレンタルサーバ」で Python 外部モジュールを使う 改訂版

「さくらのレンタルサーバ」で Python 外部モジュールを使う 改訂版

公開日: 2005-07-08/更新日: 2008-03-30

さくらインターネットの「さくらのレンタルサーバ」サービスで Python の外部モジュールを導入・利用するための覚え書きです。2008年3月30日に一部内容を見直して改訂版としました。

イントロダクション

さくらインターネットのホスティングサービス、「さくらのレンタルサーバ」では、CGI として Python を利用できます。Python には標準モジュールのほかにも、HTMLTemplatePILReportLab などといった豊富な外部モジュールが公開されています。CGI からこれらを利用することができれば、HTML テンプレートやグラフィックス、PDF などを扱う高度な処理を効率的に行うことができます。

「さくらのレンタルサーバ」(スタンダードプラン以上)では、telnet/ssh でホストにログインしての作業が可能なので、いくつかの制限にさえ気をつければ、こうした外部モジュールを自分のホームディレクトリ下にインストールして、CGI から利用できるようにすることが可能です。

以下は自分なりに知っている範囲内で書きましたが、よりよい解決法がありましたら Visitor's Voice より教えていただけるとありがたいです。その他間違いのご指摘、ご意見・ご感想なども歓迎です。よろしく。

外部モジュールをホームディレクトリ下にインストールする

「さくらのレンタルサーバ」は複数のユーザーでひとつのホストを共有する方式なので、勝手にシステムに独自のモジュールをインストールすることはできません。モジュールを追加するのであれば、自分のホームディレクトリにインストールしなくてはいけません。外部モジュールをシステム標準以外の場所にインストールする方法については、ちゃんとドキュメントがあります。

Python モジュールのインストール
http://www.python.jp/doc/release/inst/inst.html

このドキュメントの「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
>>>

外部モジュールをインポートして、エラーが出なければ問題ありません。

CGI から使う

環境変数 PYTHONPATH を設定していれば通常は外部モジュールもインストールパスを気にすることなくインポートできるはずなのですが、CGI として利用する場合はそれでもうまくいかない可能性があります。

Apache が CGI を実行するときの環境変数は .htaccess ファイルに SetEnv ディレクティブを記述することで設定することができますが、Apache の動作モードによっては、セキュリティ上の対策として、CGI に「安全な」環境変数のみが渡されるようになっていることがあります(Apache の suEXEC 機能といいます)。この場合は CGI に PYTHONPATH を渡すことができません。そしてそういう話をここに書くということは、もちろん「さくらのレンタルサーバ」でもそうなっているわけです。

sys.path にパスを追加すればいい

そうなると、手段はひじょうに限られてきたかに思われます。しかし結局のところ、Python のモジュール探索というのは、 sys.path に入っているパスを順番に見ているに過ぎません。だから、スクリプト内で直接 sys.path にパスを追加してもかまわないのです。スクリプトのどこか先頭付近で、外部モジュールをインポートする前に、sys.path に外部モジュールのインストール先のパスを追加します。

#!/usr/bin/env python

import sys

sys.path.append('/home/foo/lib/python')

import spam
...

これで CGI から外部モジュールを使えるようになりました。

別解: #! 部分で PYTHONPATH を設定する

スクリプトの途中にホームディレクトリのパスが入るのが気に入らない場合、スクリプト先頭の #! 部分で環境変数 PYTHONPATH をセットするという方法も考えられます。

#!/usr/bin/env PYTHONPATH=/home/foo/lib/python python

import spam
...

これでも外部モジュールはうまく利用できます。

余談: かつてここに書かれていたもうひとつの方法について

この部分にはもうひとつの方法として、Python の user モジュールの仕組みを利用したトリックを載せていたことがありました。しかしその方法は、上記ふたつの解決策とくらべて可搬性に優れているわけでもないにもかかわらずあたかもそうであるかのように見せかけてしまう、罠の多いものでした。当時自分はその方法がよいものかどうなのかはっきり判断しかねるまま(断り書きを入れて)それを掲載していたのですが、今では載せるべきではなかったと考えています。

user モジュールを使う方法を気に入ってしまった人には申し訳ないのですが、一般的に言って、かつてここに書かれていた方法をとるべきではありません。

ここではその理由については詳述しませんが、興味がある人は筆者の昔の覚え書きを見てください。

まとめ

以上で述べたことをまとめると次のようになります。

以上、自分の試行錯誤をつたない技量でまとめましたが、だれかのお役に立てれば幸いです。

改訂履歴

2008-03-30
user モジュールを使った方法についての記述を削除。その他表現の見直しなどをして改訂版とする。
2005-12-18
さくらのレンタルサーバの Python のバージョンが 2.3.x から 2.4.x になったので、それにあわせて記述を変更。japanese コーデックモジュールなどは不要になったので例からはずした。
2005-07-08
公開。

免責・ライセンス

記述はできるだけ正確なものを心がけてはいますが、作者の知識や調査の不足などから間違ったことが書いてあるかもしれません。この文書の情報にもとづいた行動によって何らかの被害が生じた場合でも、作者はその責任を負いませんので、あしからず。

Copyright (C) Masaaki Shibata.

クリエイティブ・コモンズ・ライセンス この文書は、クリエイティブ・コモンズ・ライセンスの下でライセンスされています。