« 2011年7月 | トップページ

2011/08/23

PythonのWSGI記事のサンプルプログラムが動かない件

WSGIとPythonでスマートなWebアプリケーション開発を
第2回 WSGIを使ったもう少し複雑なアプリケーションの作成

WSGIについて解説されている日本語サイトは少ないので非常に価値の高いページなんですが
サンプルプログラムが結局、日本語で動かないです。
直したって書いてありますが、実行して日本語でPOSTしてみると

UnicodeEncodeError: 'ascii' codec can't encode characters

というエラーが発生しちゃいます(Mac OS X 10.7.1標準のPython 2.7.1にて確認)

該当するスクリプトの問題は

tmp[key] = str(esc(unicode(value, 'utf-8', 'ignore')))

ここです。

valueをunicodeでutf8にして
エスケープして
それをstr型に変換する

というコードなんですが
unicodeで変換した時点で型はunicodeです。

unicodeからstrに変換しようとするとこのエラーがでます。

サンプル。
u = unicode("てすと", 'utf-8')
s = str(u)
これを実行すると同様のエラーがでます。

pythonは型について、非常にチェックが厳しい言語です(私は良い意味でとらえてます)
str型にする際にはちゃんと、encode関数で文字コードを指定してあげなければいけません。

s = str(u.encode('utf-8'))

これならOK!

というわけで、リンク先記事のプログラムは

tmp[key] = str(esc(unicode(value, 'utf-8', 'ignore')).encode('utf-8'))

とすればちゃんと動きます。

pythonにおける文字コードの良い勉強になりました。

2011/08/22

mod_wgsiでApacheからPythonでWebプログラムを呼び出す

ハマりました〜。

これが、test.wgsi

#! /usr/bin/python
# -*- coding: utf-8 -*-
def application(environ, start_response):
status = '200 OK'
output = 'Hello World!'

response_headers = [('Content-type', 'text/plain'),
('Content-Length', str(len(output)))]
start_response(status, response_headers)

return [output]

で、呼び出すために設定が必要。

まずは、mod_wgsiをインストール

wget http://modwsgi.googlecode.com/files/mod_wsgi-3.3.tar.gz
tar zxvf ./mod_wsgi-3.3.tar.gz
cd ./mod_wsgi-3.3
./configure
make
make install

これで簡単に通ります。

あとは、httpd.confに

LoadModule wsgi_module modules/mod_wsgi.so
を追加して

WSGIScriptAlias /hello /home/www/demo/python/test.wgsi

と指定すると

/hello
を呼び出すと
Hello World!
と表示される。

WSGIについてはこれから勉強です。
Djangoとかから入った方がいいのか、もっとライトなフレームワークから入った方がいいのか…

pythonのez_installセットアップまとめ

Perlでいう所のCPANみたいなものが
Pythonにもあるそうで、それのセットアップ手順メモです。

# python ./distribute_setup.py
Downloading http://pypi.python.org/packages/source/d/distribute/distribute-0.6.21.tar.gz

ここでエラーが出てとまりました。

Traceback (most recent call last):
File "./distribute_setup.py", line 485, in ?
main(sys.argv[1:])
File "./distribute_setup.py", line 480, in main
tarball = download_setuptools()
File "./distribute_setup.py", line 193, in download_setuptools
src = urlopen(url)
File "/usr/lib/python2.4/urllib2.py", line 130, in urlopen
return _opener.open(url, data)
File "/usr/lib/python2.4/urllib2.py", line 358, in open
response = self._open(req, data)
File "/usr/lib/python2.4/urllib2.py", line 376, in _open
'_open', req)
File "/usr/lib/python2.4/urllib2.py", line 337, in _call_chain
result = func(*args)
File "/usr/lib/python2.4/urllib2.py", line 1021, in http_open
return self.do_open(httplib.HTTPConnection, req)
File "/usr/lib/python2.4/urllib2.py", line 996, in do_open
raise URLError(err)
urllib2.URLError:

なんじゃ?と思って調べてみたら名前解決ができてないwobbly

# wget http://pypi.python.org/packages/source/d/distribute/distribute-0.6.21.tar.gz
--2011-08-22 16:17:18-- http://pypi.python.org/packages/source/d/distribute/distribute-0.6.21.tar.gz
pypi.python.org をDNSに問いあわせています... 失敗しました: 名前解決時の一時的な失敗.
wget: ホストアドレス `pypi.python.org' を解決できませんでした。

仕方が無いので、名前解決できるホストからIPを調べてhostsに記入

vi /etc/hosts
82.94.164.168 pypi.python.org

もう一度。

# python ./distribute_setup.py
Downloading http://pypi.python.org/packages/source/d/distribute/distribute-0.6.21.tar.gz
Extracting in /tmp/tmpvxQGVw
Now working in /tmp/tmpvxQGVw/distribute-0.6.21
Installing Distribute
Before install bootstrap.
Scanning installed packages
No setuptools distribution found
running install
running bdist_egg
running egg_info
writing distribute.egg-info/PKG-INFO
writing top-level names to distribute.egg-info/top_level.txt
writing dependency_links to distribute.egg-info/dependency_links.txt
writing entry points to distribute.egg-info/entry_points.txt
reading manifest file 'distribute.egg-info/SOURCES.txt'
reading manifest template 'MANIFEST.in'
writing manifest file 'distribute.egg-info/SOURCES.txt'
installing library code to build/bdist.linux-i686/egg
running install_lib
running build_py
creating build
creating build/lib
copying pkg_resources.py -> build/lib
copying easy_install.py -> build/lib
copying site.py -> build/lib
creating build/lib/setuptools
copying setuptools/archive_util.py -> build/lib/setuptools
copying setuptools/package_index.py -> build/lib/setuptools
copying setuptools/dist.py -> build/lib/setuptools
copying setuptools/depends.py -> build/lib/setuptools
copying setuptools/sandbox.py -> build/lib/setuptools
copying setuptools/__init__.py -> build/lib/setuptools
copying setuptools/extension.py -> build/lib/setuptools
creating build/lib/setuptools/tests
copying setuptools/tests/server.py -> build/lib/setuptools/tests
copying setuptools/tests/test_develop.py -> build/lib/setuptools/tests
copying setuptools/tests/test_build_ext.py -> build/lib/setuptools/tests
copying setuptools/tests/test_packageindex.py -> build/lib/setuptools/tests
copying setuptools/tests/doctest.py -> build/lib/setuptools/tests
copying setuptools/tests/test_easy_install.py -> build/lib/setuptools/tests
copying setuptools/tests/test_sandbox.py -> build/lib/setuptools/tests
copying setuptools/tests/test_upload_docs.py -> build/lib/setuptools/tests
copying setuptools/tests/__init__.py -> build/lib/setuptools/tests
copying setuptools/tests/test_resources.py -> build/lib/setuptools/tests
creating build/lib/setuptools/command
copying setuptools/command/saveopts.py -> build/lib/setuptools/command
copying setuptools/command/alias.py -> build/lib/setuptools/command
copying setuptools/command/bdist_wininst.py -> build/lib/setuptools/command
copying setuptools/command/bdist_rpm.py -> build/lib/setuptools/command
copying setuptools/command/rotate.py -> build/lib/setuptools/command
copying setuptools/command/install_scripts.py -> build/lib/setuptools/command
copying setuptools/command/develop.py -> build/lib/setuptools/command
copying setuptools/command/setopt.py -> build/lib/setuptools/command
copying setuptools/command/upload.py -> build/lib/setuptools/command
copying setuptools/command/egg_info.py -> build/lib/setuptools/command
copying setuptools/command/test.py -> build/lib/setuptools/command
copying setuptools/command/register.py -> build/lib/setuptools/command
copying setuptools/command/sdist.py -> build/lib/setuptools/command
copying setuptools/command/bdist_egg.py -> build/lib/setuptools/command
copying setuptools/command/easy_install.py -> build/lib/setuptools/command
copying setuptools/command/__init__.py -> build/lib/setuptools/command
copying setuptools/command/build_ext.py -> build/lib/setuptools/command
copying setuptools/command/build_py.py -> build/lib/setuptools/command
copying setuptools/command/install_lib.py -> build/lib/setuptools/command
copying setuptools/command/install.py -> build/lib/setuptools/command
copying setuptools/command/install_egg_info.py -> build/lib/setuptools/command
copying setuptools/command/upload_docs.py -> build/lib/setuptools/command
copying setuptools/gui.exe -> build/lib/setuptools
copying setuptools/cli.exe -> build/lib/setuptools
creating build/bdist.linux-i686
creating build/bdist.linux-i686/egg
creating build/bdist.linux-i686/egg/setuptools
copying build/lib/setuptools/gui.exe -> build/bdist.linux-i686/egg/setuptools
copying build/lib/setuptools/archive_util.py -> build/bdist.linux-i686/egg/setuptools
creating build/bdist.linux-i686/egg/setuptools/tests
copying build/lib/setuptools/tests/server.py -> build/bdist.linux-i686/egg/setuptools/tests
copying build/lib/setuptools/tests/test_develop.py -> build/bdist.linux-i686/egg/setuptools/tests
copying build/lib/setuptools/tests/test_build_ext.py -> build/bdist.linux-i686/egg/setuptools/tests
copying build/lib/setuptools/tests/test_packageindex.py -> build/bdist.linux-i686/egg/setuptools/tests
copying build/lib/setuptools/tests/doctest.py -> build/bdist.linux-i686/egg/setuptools/tests
copying build/lib/setuptools/tests/test_easy_install.py -> build/bdist.linux-i686/egg/setuptools/tests
copying build/lib/setuptools/tests/test_sandbox.py -> build/bdist.linux-i686/egg/setuptools/tests
copying build/lib/setuptools/tests/test_upload_docs.py -> build/bdist.linux-i686/egg/setuptools/tests
copying build/lib/setuptools/tests/__init__.py -> build/bdist.linux-i686/egg/setuptools/tests
copying build/lib/setuptools/tests/test_resources.py -> build/bdist.linux-i686/egg/setuptools/tests
copying build/lib/setuptools/package_index.py -> build/bdist.linux-i686/egg/setuptools
creating build/bdist.linux-i686/egg/setuptools/command
copying build/lib/setuptools/command/saveopts.py -> build/bdist.linux-i686/egg/setuptools/command
copying build/lib/setuptools/command/alias.py -> build/bdist.linux-i686/egg/setuptools/command
copying build/lib/setuptools/command/bdist_wininst.py -> build/bdist.linux-i686/egg/setuptools/command
copying build/lib/setuptools/command/bdist_rpm.py -> build/bdist.linux-i686/egg/setuptools/command
copying build/lib/setuptools/command/rotate.py -> build/bdist.linux-i686/egg/setuptools/command
copying build/lib/setuptools/command/install_scripts.py -> build/bdist.linux-i686/egg/setuptools/command
copying build/lib/setuptools/command/develop.py -> build/bdist.linux-i686/egg/setuptools/command
copying build/lib/setuptools/command/setopt.py -> build/bdist.linux-i686/egg/setuptools/command
copying build/lib/setuptools/command/upload.py -> build/bdist.linux-i686/egg/setuptools/command
copying build/lib/setuptools/command/egg_info.py -> build/bdist.linux-i686/egg/setuptools/command
copying build/lib/setuptools/command/test.py -> build/bdist.linux-i686/egg/setuptools/command
copying build/lib/setuptools/command/register.py -> build/bdist.linux-i686/egg/setuptools/command
copying build/lib/setuptools/command/sdist.py -> build/bdist.linux-i686/egg/setuptools/command
copying build/lib/setuptools/command/bdist_egg.py -> build/bdist.linux-i686/egg/setuptools/command
copying build/lib/setuptools/command/easy_install.py -> build/bdist.linux-i686/egg/setuptools/command
copying build/lib/setuptools/command/__init__.py -> build/bdist.linux-i686/egg/setuptools/command
copying build/lib/setuptools/command/build_ext.py -> build/bdist.linux-i686/egg/setuptools/command
copying build/lib/setuptools/command/build_py.py -> build/bdist.linux-i686/egg/setuptools/command
copying build/lib/setuptools/command/install_lib.py -> build/bdist.linux-i686/egg/setuptools/command
copying build/lib/setuptools/command/install.py -> build/bdist.linux-i686/egg/setuptools/command
copying build/lib/setuptools/command/install_egg_info.py -> build/bdist.linux-i686/egg/setuptools/command
copying build/lib/setuptools/command/upload_docs.py -> build/bdist.linux-i686/egg/setuptools/command
copying build/lib/setuptools/dist.py -> build/bdist.linux-i686/egg/setuptools
copying build/lib/setuptools/depends.py -> build/bdist.linux-i686/egg/setuptools
copying build/lib/setuptools/sandbox.py -> build/bdist.linux-i686/egg/setuptools
copying build/lib/setuptools/__init__.py -> build/bdist.linux-i686/egg/setuptools
copying build/lib/setuptools/cli.exe -> build/bdist.linux-i686/egg/setuptools
copying build/lib/setuptools/extension.py -> build/bdist.linux-i686/egg/setuptools
copying build/lib/easy_install.py -> build/bdist.linux-i686/egg
copying build/lib/pkg_resources.py -> build/bdist.linux-i686/egg
copying build/lib/site.py -> build/bdist.linux-i686/egg
byte-compiling build/bdist.linux-i686/egg/setuptools/archive_util.py to archive_util.pyc
byte-compiling build/bdist.linux-i686/egg/setuptools/tests/server.py to server.pyc
byte-compiling build/bdist.linux-i686/egg/setuptools/tests/test_develop.py to test_develop.pyc
byte-compiling build/bdist.linux-i686/egg/setuptools/tests/test_build_ext.py to test_build_ext.pyc
byte-compiling build/bdist.linux-i686/egg/setuptools/tests/test_packageindex.py to test_packageindex.pyc
byte-compiling build/bdist.linux-i686/egg/setuptools/tests/doctest.py to doctest.pyc
byte-compiling build/bdist.linux-i686/egg/setuptools/tests/test_easy_install.py to test_easy_install.pyc
byte-compiling build/bdist.linux-i686/egg/setuptools/tests/test_sandbox.py to test_sandbox.pyc
byte-compiling build/bdist.linux-i686/egg/setuptools/tests/test_upload_docs.py to test_upload_docs.pyc
byte-compiling build/bdist.linux-i686/egg/setuptools/tests/__init__.py to __init__.pyc
byte-compiling build/bdist.linux-i686/egg/setuptools/tests/test_resources.py to test_resources.pyc
byte-compiling build/bdist.linux-i686/egg/setuptools/package_index.py to package_index.pyc
byte-compiling build/bdist.linux-i686/egg/setuptools/command/saveopts.py to saveopts.pyc
byte-compiling build/bdist.linux-i686/egg/setuptools/command/alias.py to alias.pyc
byte-compiling build/bdist.linux-i686/egg/setuptools/command/bdist_wininst.py to bdist_wininst.pyc
byte-compiling build/bdist.linux-i686/egg/setuptools/command/bdist_rpm.py to bdist_rpm.pyc
byte-compiling build/bdist.linux-i686/egg/setuptools/command/rotate.py to rotate.pyc
byte-compiling build/bdist.linux-i686/egg/setuptools/command/install_scripts.py to install_scripts.pyc
byte-compiling build/bdist.linux-i686/egg/setuptools/command/develop.py to develop.pyc
byte-compiling build/bdist.linux-i686/egg/setuptools/command/setopt.py to setopt.pyc
byte-compiling build/bdist.linux-i686/egg/setuptools/command/upload.py to upload.pyc
byte-compiling build/bdist.linux-i686/egg/setuptools/command/egg_info.py to egg_info.pyc
byte-compiling build/bdist.linux-i686/egg/setuptools/command/test.py to test.pyc
byte-compiling build/bdist.linux-i686/egg/setuptools/command/register.py to register.pyc
byte-compiling build/bdist.linux-i686/egg/setuptools/command/sdist.py to sdist.pyc
byte-compiling build/bdist.linux-i686/egg/setuptools/command/bdist_egg.py to bdist_egg.pyc
byte-compiling build/bdist.linux-i686/egg/setuptools/command/easy_install.py to easy_install.pyc
byte-compiling build/bdist.linux-i686/egg/setuptools/command/__init__.py to __init__.pyc
byte-compiling build/bdist.linux-i686/egg/setuptools/command/build_ext.py to build_ext.pyc
byte-compiling build/bdist.linux-i686/egg/setuptools/command/build_py.py to build_py.pyc
byte-compiling build/bdist.linux-i686/egg/setuptools/command/install_lib.py to install_lib.pyc
byte-compiling build/bdist.linux-i686/egg/setuptools/command/install.py to install.pyc
byte-compiling build/bdist.linux-i686/egg/setuptools/command/install_egg_info.py to install_egg_info.pyc
byte-compiling build/bdist.linux-i686/egg/setuptools/command/upload_docs.py to upload_docs.pyc
byte-compiling build/bdist.linux-i686/egg/setuptools/dist.py to dist.pyc
byte-compiling build/bdist.linux-i686/egg/setuptools/depends.py to depends.pyc
byte-compiling build/bdist.linux-i686/egg/setuptools/sandbox.py to sandbox.pyc
byte-compiling build/bdist.linux-i686/egg/setuptools/__init__.py to __init__.pyc
byte-compiling build/bdist.linux-i686/egg/setuptools/extension.py to extension.pyc
byte-compiling build/bdist.linux-i686/egg/easy_install.py to easy_install.pyc
byte-compiling build/bdist.linux-i686/egg/pkg_resources.py to pkg_resources.pyc
byte-compiling build/bdist.linux-i686/egg/site.py to site.pyc
creating build/bdist.linux-i686/egg/EGG-INFO
copying distribute.egg-info/PKG-INFO -> build/bdist.linux-i686/egg/EGG-INFO
copying distribute.egg-info/SOURCES.txt -> build/bdist.linux-i686/egg/EGG-INFO
copying distribute.egg-info/dependency_links.txt -> build/bdist.linux-i686/egg/EGG-INFO
copying distribute.egg-info/entry_points.txt -> build/bdist.linux-i686/egg/EGG-INFO
copying distribute.egg-info/entry_points.txt.orig -> build/bdist.linux-i686/egg/EGG-INFO
copying distribute.egg-info/not-zip-safe -> build/bdist.linux-i686/egg/EGG-INFO
copying distribute.egg-info/top_level.txt -> build/bdist.linux-i686/egg/EGG-INFO
creating dist
creating 'dist/distribute-0.6.21-py2.4.egg' and adding 'build/bdist.linux-i686/egg' to it
removing 'build/bdist.linux-i686/egg' (and everything under it)
Processing distribute-0.6.21-py2.4.egg
creating /usr/lib/python2.4/site-packages/distribute-0.6.21-py2.4.egg
Extracting distribute-0.6.21-py2.4.egg to /usr/lib/python2.4/site-packages
Adding distribute 0.6.21 to easy-install.pth file
Installing easy_install script to /usr/bin
Installing easy_install-2.4 script to /usr/bin

Installed /usr/lib/python2.4/site-packages/distribute-0.6.21-py2.4.egg
Processing dependencies for distribute==0.6.21
Finished processing dependencies for distribute==0.6.21
After install bootstrap.
Creating /usr/lib/python2.4/site-packages/setuptools-0.6c11-py2.4.egg-info
Creating /usr/lib/python2.4/site-packages/setuptools.pth

成功したっぽい?

続いて、ez_setup.pyをダウンロードしてsetuptoolsをインストール

wget http://peak.telecommunity.com/dist/ez_setup.py
python ez_setup.py setuptools

Searching for distribute
Best match: distribute 0.6.21
Processing distribute-0.6.21-py2.4.egg
distribute 0.6.21 is already the active version in easy-install.pth
Installing easy_install script to /usr/bin
Installing easy_install-2.4 script to /usr/bin

Using /usr/lib/python2.4/site-packages/distribute-0.6.21-py2.4.egg
Processing dependencies for distribute
Finished processing dependencies for distribute

お、入ったかな?


Djangoとかも、ez_installから一発インストールできるようです。
使ってみるかなぁ〜

2011/08/10

pythonで日付計算

最近、サーバーの内部処理はPythonで書いてます。

今日は日付計算のレシピ

>>> import datetime
>>> print datetime.datetime.today()
2011-08-10 16:41:00.272610
>>> print datetime.datetime.today() - datetime.timedelta(1)
2011-08-09 16:41:03.737893
>>> print datetime.datetime.today() + datetime.timedelta(1)
2011-08-11 16:44:23.008940

datetime.datetime.today()で本日を取得できます。
datetime.timedelta()で日付計算ができます。
+で明日、
ーで昨日。

簡単だなー

2011/08/04

Pythonでの文字出力

昨日からPython勉強中です。

文字列の結合は+演算子でオッケーです。
>>> print 'aaa' + 'bbb'
aaabbb

でも数字が入ってくるとうまく行きません。

>>> print 'aaa' + 123
Traceback (most recent call last):
File "", line 1, in ?
TypeError: cannot concatenate 'str' and 'int' objects

文字列型と整数型を厳密にチェックしてます。

じゃあどうすれば良いのか、と調べたところ

>>> print 'aaa %d' % (123)
aaa 123

正解はこうでした。
C言語でいうところのsprintfみたいな感じですねー

>>> print '%s %d %f' % ('aaa', 123, 3.14)
aaa 123 3.140000

つまりこういう事。

%で区切って、括弧のなかでリストアップ。

Pythonって型に関してはうるさい?言語ですねー。

print 'id = ' + row['id'] + ', point=' + row['point'] + ', user_id =' + row['user_id']

2011/08/03

PythonでMySQLに接続し、辞書で値を受け取る

現在作っているサービス。裏側のcronスクリプトは
rubyかpythonかどっちかで作ろうか悩んでました。

rubyの方が人気がある気がしたので先に試したのですが、
最新版のgemがそもそもうまくインストールできない。

仕方がないので、ruby自体をソースコードからインストール。
今度は最新版のgemをインストールできたのですが、
gem install mysql
が全くうまく行かない。

こりゃ、perlのCPAN入れるのと同じくらい、しんどそうと判断。

逆にpythonのMySQL接続ライブラリはCentOS5に標準インストールされていた。
うーん、pythonでやってみるか。とちょっと調べて書いてみました。

import MySQLdb
from MySQLdb.cursors import DictCursor

connect = MySQLdb.connect(db="test", host="localhost", port=3306, user="root", charset="utf8")
cur = connect.cursor(DictCursor)
cur.execute("SELECT id, name FROM users")
rows = cur.fetchall()

for row in rows:
print row
cur.close()
connect.close()

こりゃ簡単にかける。

from MySQLdb.cursors import DictCursor

この、辞書(連想配列みたいなものですな)でカーソルを使うためのモジュールをインポートしておいて

cur = connect.cursor(DictCursor)

カーソルは辞書で受け取りますよ。って宣言してあげれば。

{'id': 21L, 'name': u'\u30bb\u30d4\u30a2'}

こういう形で入ってきます。

print row['name']

できちんと、UTF8の文字列が表示されました。

この方向でいってみよう!

« 2011年7月 | トップページ