web.pyを入れてみる

http://webpy.org/install
にあるインストール方法によると、site-packages ディレクトリにコピーするだけということだ。
Debian環境では、site-packagesは"/usr/lib/python2.4/site-packages/"にある。
web.pyの本体をもらってきてコピーする。

# wget http://webpy.org/web.py
# cp web.py /usr/lib/python2.4/site-packages/
# chmod 644 /usr/lib/python2.4/site-packages/web.py

とりあえず、動作しているthttpdを使って動かして見ることに。
速度的な問題になるようなら、reddit.comでやっているように、lighttpd上でfastcgiすればいいだろう。
ここのcgi-binにはBASIC認証が設定されているのがちょっと面倒だ。
トップページのサンプルを入力する。cgi実行になるので、シェルから呼ぶコマンドの起動パスは追記する。

# cd /var/www/cgi-bin/
# vi sample.py
#!/usr/bin/python
import web

urls = (
'/(.*)', 'hello'
)

class hello:
def GET(self, name):
i = web.input(times=1)
if not name: name = 'world'
for c in xrange(int(i.times)): print 'Hello,', name+'!'

if __name__ == "__main__": web.run(urls)

# chown www-data.www-data sample.py
# chmod 755 sample.py

素で実行してみる。

# ./sample.py
Traceback (most recent call last):
File "./sample.py", line 2, in ?
import web
ImportError: No module named web

ありゃ、認識してないな。

# /usr/bin/python
Python 2.3.5 (#2, Sep 11 2005, 02:13:21)
[GCC 3.3.5 (Debian 1:3.3.5-13)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>
(Ctrl+Dで抜ける)
# ls -al /usr/bin/python
lrwxrwxrwx 1 root root 9 Jan 1 1970 /usr/bin/python -> python2.3

起動するPythonは2.3になっている。コマンドパスが問題だったのね。
書き直して再実行。

# vi sample.py
#!/usr/bin/python2.4

# ./sample.py
Launching server: http://0.0.0.0:8080/
Traceback (most recent call last):
File "./sample.py", line 14, in ?
if __name__ == "__main__": web.run(urls)
File "/usr/lib/python2.4/site-packages/web.py", line 1400, in run
return runwsgi(wsgifunc(webpyfunc(inp, fvars, autoreload), *middleware))
File "/usr/lib/python2.4/site-packages/web.py", line 1421, in runwsgi
return runsimple(func, listget(sys.argv, 1, 8080))
File "/usr/lib/python2.4/site-packages/web.py", line 1531, in runsimple
WSGIServer(func).serve_forever()
File "/usr/lib/python2.4/site-packages/web.py", line 1526, in __init__
BaseHTTPServer.HTTPServer.__init__(self, ("0.0.0.0", int(port)), WSGIHandler)
File "/usr/lib/python2.4/SocketServer.py", line 330, in __init__
self.server_bind()
File "/usr/lib/python2.4/BaseHTTPServer.py", line 99, in server_bind
SocketServer.TCPServer.server_bind(self)
File "/usr/lib/python2.4/SocketServer.py", line 341, in server_bind
self.socket.bind(self.server_address)
File "", line 1, in bind
socket.error: (98, 'Address already in use')

ダイレクトに起動してみると、webサーバーを自分で上げようとして、8080ポートが使用されているので落ちてしまう。
ブラウザから参照してみる。

# wget http://admin:@192.168.123.25/cgi-bin/sample.py

=> `sample.py.1'
Connecting to 192.168.123.25:80... connected.
HTTP request sent, awaiting response... 200 OK
End of file while parsing headers.
Retrying.

FireFoxから見ても何も戻らない。
Hellow, worldが返るはずなんだけどな。
ヘッダが何も返られないからかな?
そういうのはweb.pyで補ってくれるんじゃないのか?
もちっと正攻法にするか。
BASIC認証があるが、キーを手動生成して telnet でやってみる。
キーの生成には、使った openssl enc -e -base64 の他に base64 -e, nkf -MB,perl -MMIME::Base64 -ne 'print encode_base64($_)' なども使える。

# apt-get install telnet
# echo -n 'admin:' | openssl enc -e -base64
YWRtaW46
# telnet 192.168.0.25 80
Trying 192.168.0.25...
Connected to 192.168.123.25.
Escape character is '^]'.
GET /cgi-bin/sample.py HTTP/1.0
Authorization: Basic YWRtaW46

HTTP/1.0 200 OK
Traceback (most recent call last):
File "sample.py", line 14, in ?
if __name__ == "__main__": web.run(urls)
File "/usr/lib/python2.4/site-packages/web.py", line 1400, in run
return runwsgi(wsgifunc(webpyfunc(inp, fvars, autoreload), *middleware))
File "/usr/lib/python2.4/site-packages/web.py", line 1413, in runwsgi
import flup.server.fcgi
ImportError: No module named flup.server.fcgi
Connection closed by foreign host.

flup.server.fcgiのimportに失敗したので表示しないらしい。
http://www.saddi.com/software/flup/ にあるものがそれらしい。
そういえば、動作環境にWSGIが必要だったような。cgi動作には、さらにそのcgiプラグインもいるのか。
最新版は、egg形式で配布になっている。Python-setuptoolsは入れてあるのでそのまま使える。

# wget http://www.saddi.com/software/flup/dist/flup-0.5-py2.4.egg

# dpkg -l | grep setup
ii python-setupto 0.6a8-1 Python Distutils Enhancements
# easy_install flup-0.5-py2.4.egg
Processing flup-0.5-py2.4.egg
creating /usr/lib/python2.4/site-packages/flup-0.5-py2.4.egg
Extracting flup-0.5-py2.4.egg to /usr/lib/python2.4/site-packages
Adding flup 0.5 to easy-install.pth file

Installed /usr/lib/python2.4/site-packages/flup-0.5-py2.4.egg
Processing dependencies for flup==0.5

# telnet 192.168.123.25 80
Trying 192.168.123.25...
Connected to 192.168.123.25.
Escape character is '^]'.
GET /cgi-bin/sample.py HTTP/1.0
Authorization: Basic YWRtaW46

HTTP/1.0 404 Not Found
Status: 404 Not Found
Content-Type: text/html
Content-Length: 9

not foundUnhandled exception in thread started by
Error in sys.excepthook:

Original exception was:
Connection closed by foreign host.

おぇ、もうメゲそうだ。
sysモジュールで、例外の補足に失敗して落ちちゃったって言ってますね。
このへんかな...

def djangoerror():
exception_type, exception_value, tb = sys.exc_info()

中身まで踏み込まれるともう追えないよ...
 
手をかえて、起動ポート番号を変更して単独動作させてみよう。
web.pyの中でどっかでポート定義しているところを探して書き換えるか。
このへんだな。

def runwsgi(func):
# command line:
return runsimple(func, listget(sys.argv, 1, 8080))

def runsimple(func, port=8080):

なんだ、pydocで書いてあるじゃん。

def run(inp, *middleware):
"""
Starts handling requests. If called in a CGI or FastCGI context, it will follow
that protocol. If called from the command line, it will start an HTTP
server on the port named in the first command line argument, or, if there
is no argument, on port 8080.

起動時に第一引数でポート番号を渡せばいいのだね。

# ./sample.py 8081
Launching server: http://0.0.0.0:8081/

ブラウザで"http://192.168.0.25:8081/"にアクセス。

Hello, world!

と表示される。
コンソールにログが出る。

192.168.0.6 - - [09/Mar/2006 16:50:17] "GET / HTTP/1.1" 200 -
192.168.0.6 - - [09/Mar/2006 16:50:18] "GET /favicon.ico HTTP/1.1" 200 -

http://192.168.123.25:8081/kinnekoにアクセスすると、

Hello, kinneko!

が返る。nameはフルパスを返しているのね。
とりあえず、サンプルコードの動作は確認できた。
cgi実行については、またこんどだな。このペースだと、RDBMSとかテンプレートエンジンとかはいつになることやら...