2010年11月21日日曜日

Python 環境構築 At Debian Squeeze



最近 Python 周りの記事を漁ってたら、pip やら virtualenv やら pythonbrew やら素敵ツールの存在を知ったのでその辺りを使った Python 環境構築の手順をまとめてみます。OS は Debian Squeeze です。


今回使うツール一覧



  • pythonbrew


複数バージョンの Python 環境を管理するツールです。HOME 以下にインストールできるので、レンタルサーバなど root 権限が取得できない場合でも問題なく使えます



  • pip


easy_install の代替を目指して開発されているライブラリマネージャです。perl で言うところの cpan, ruby で言うところの gem に当たります。



  • virtualenv


Python の仮想環境を作成するツールです。これを使うことで、あるライブラリを複数バージョンで使い分けたり、他のライブラリとの依存関係を壊すことなく最新バージョンのライブラリを試したり、といったことができるようになります



  • virtualenvwrapper


virtualenv を手軽に使うためのツールです。


OS インストール


最小構成でインストールします。


通常は一般ユーザ作成してそちらで作業しますが、今回はめんどくさかったのでそのまま root で作業してます。


必要なライブラリをインストール



# aptitude install build-essential ssh python curl zlib1g-dev


pythonbrew をインストール



# wget http://github.com/utahta/pythonbrew/raw/master/pythonbrew-install --no-check-certificate
# chmod +x pythonbrew-install
# ./pythonbrew-install
# echo "source /root/.pythonbrew/etc/bashrc" >> ~/.bashrc
# source ~/.bashrc


最後の二行では、シェルの設定ファイルに



source /root/.pythonbrew/etc/bashrc


という一行を書きこんでます。zsh など bash 以外のシェルを使っている場合は適宜変更する必要があります。


pythonbrew で Python をインストールしてみる


今回は Python 2.6.6 をインストールしてみます。



# pythonbrew install 2.6.6 --force


インストールした環境を使用するために以下のコマンドを入力します。



# pythonbrew switch 2.6.6


異なるバージョンに切り替える場合も同様です。


virtualenv, virtualenvwrapper をインストールする



# pip install virtualenv virtualenvwrapper
# echo "source /root/.pythonbrew/pythons/Python-2.6.6/bin/virtualenvwrapper.sh" >> ~/.bashrc
# mkdir ~/.virtualenvs


これで、virtualenv による仮想環境を扱えるようになりました。


実際に仮想環境を作成してみます。



# mkvirtualenv 2.6.6


コマンドを入力すると、プロンプトの前に (2.6.6) と表示されるようになったと思います。


これが現在使用している仮想環境です。


使用をやめる場合は deactivate 、仮想環境を使用する場合は workon <仮想環境名> と入力します。


また、仮想環境を削除する場合は rmvirtualenv <仮想環境名> です。



# deactivate
# workon 2.6.6
# deactivate
# rmvirtualenv 2.6.6


とりあえず使い方がわかったのでここまでで終了。実際に使い込んでないのでいろいろ問題がある可能性がありますが……。


みんなのPython 改訂版
みんなのPython 改訂版
posted with amazlet at 10.09.23
柴田 淳
ソフトバンククリエイティブ
売り上げランキング: 75071


初めてのPython 第3版
初めてのPython 第3版
posted with amazlet at 10.09.23
Mark Lutz
オライリージャパン
売り上げランキング: 57132





2010年9月27日月曜日

gunicorn で web.py 製のアプリケーションを動かす



gunicorn とは Ruby の unicorn を元に開発された Python 用の HTTP サーバです。この gunicorn を使って web.py 製のアプリケーションを動かすことができたのでその備忘録。


後々 nginx と連携させて自作の Web アプリをデプロイしたいなーとか思ってます。


今回構築した環境は



  • OS: Mac OS X Snow Leopard

  • Python: 2.6.6 (MacPortsより)

  • web.py: 0.33 (easy_install にて)

  • gunicorn: 0.8.1 (easy_install にて)


web.py と gunicorn はそれぞれ



$ sudo easy_install-2.6 web.py
$ sudo easy_install-2.6 gunicorn


でインストールしました。


また、MacPorts からインストールした easy_install を使った場合、gunicorn は /opt/local/Library/Frameworks/Python.framework/Versions/2.6/bin にインストールされます。PATH が通ってない場合はあらかじめ設定しておく必要があります。


今回使ったソースは web.py の公式でも紹介されている 'Hello World!' アプリです。


app.py



#!/usr/bin/env python
# -*- coding:utf-8 -*-
import web

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

app = web.application(urls, globals())

class hello:
def GET(self, name):
if not name:
name = 'World'
return 'Hello, ' + name + '!'

if __name__ == '__main__':
app.run()


このソースを一行書き換えれば gunicorn (というか WSGI)への対応完了です。


app.py



#!/usr/bin/env python
# -*- coding:utf-8 -*-
import web

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

app = web.application(urls, globals()).wsgifunc() # <- .wsgifunc() を追加!

class hello:
def GET(self, name):
if not name:
name = 'World'
return 'Hello, ' + name + '!'

if __name__ == '__main__':
app.run()


次に、gunicorn での起動方法です。app.py が置いてあるディレクトリで以下のコマンドを実行します。



$ gunicorn app:app
2010-09-26 22:23:50 [93920] [INFO] Arbiter booted
2010-09-26 22:23:50 [93920] [INFO] Listening at: http://127.0.0.1:8000
2010-09-26 22:23:50 [93922] [INFO] Worker spawned (pid: 93922)


これで起動完了です。 gunicorn に渡す引数は、(モジュール名):(変数名) です。今回の場合は app.py でモジュール名が app、wsgifunc()の返り値を代入してる変数名が app なので、app:app となります。


ファイルの変更が動的に反映されるので、開発時にはかなり便利ですね。


次は nginx と連携して動作させる設定を行なってみようと思います。


みんなのPython 改訂版
みんなのPython 改訂版
posted with amazlet at 10.09.23
柴田 淳
ソフトバンククリエイティブ
売り上げランキング: 75071


初めてのPython 第3版
初めてのPython 第3版
posted with amazlet at 10.09.23
Mark Lutz
オライリージャパン
売り上げランキング: 57132





2010年9月25日土曜日

nose を複数バージョンの Python で使う



nose とは Python 用のテストフレームワークです。Python には他にも unittest や doctest などがありますが、使いやすいという理由でこれを使ってます。


python_select で Python のバージョンを切り替えながら nose を使っていると、どうやら python_select による変更が反映されてないのではないか?ということに気づきました。


easy_install によってインストールされた nosetests は /usr/local/bin 以下に設置されていたので、中身を見てみます。



#!/usr/bin/python
# EASY-INSTALL-ENTRY-SCRIPT: 'nose==0.11.4','console_scripts','nosetests'
__requires__ = 'nose==0.11.4'
import sys
from pkg_resources import load_entry_point

sys.exit(
load_entry_point('nose==0.11.4', 'console_scripts', 'nosetests')()
)


一行目を見る限り、どうやらデフォルトでインストールされている Python を利用しているようです。


そこで、以下のように修正しました。



#!/usr/bin/env python
# EASY-INSTALL-ENTRY-SCRIPT: 'nose==0.11.4','console_scripts','nosetests'
__requires__ = 'nose==0.11.4'
import sys
from pkg_resources import load_entry_point

sys.exit(
load_entry_point('nose==0.11.4', 'console_scripts', 'nosetests')()
)


これで、python_select による変更が反映されるようになりました。


ただし、nose を新しいバージョンにアップデートするたびに修正が必要になるのが面倒ですね。


nose や unittest などのテストフレームワークについては


エキスパートPythonプログラミング
Tarek Ziade
アスキー・メディアワークス
売り上げランキング: 8790


に詳しく載ってます。今読んでますが難しい……。





2010年9月24日金曜日

Python 入門(環境構築編 At Mac OSX Snow Leopard)



github に Python 入門的な記事を上げてるのですが、こっちでも紹介したいと思います。環境構築なども含めて。


今回は Mac OSX 10.6 を前提にしています。


ちなみに、github に上げてる記事はこちら→Python 基礎:目次


Python インタプリタのインストール


OSX では、Python インタプリタが大きく3系統に分けられます。



  • デフォルトでインストールされている Python

  • Python の公式サイトにあるインストーラを利用してインストールした Python

  • MacPorts を利用してインストールした Python


これらはそれぞれ、



  • /usr/bin/python

  • /usr/local/bin/python

  • /opt/local/bin/python


にインストールされます。


今回はバージョン管理が簡単な MacPorts 版の Python をインストールしようと思います。


MacPorts のインストール

既に MacPorts がインストール済みの方は読み飛ばしてください。


MacPorts とは、Mac で使用可能なパッケージ管理システムです。


Python 開発で必要なツールはだいたいこれで揃います。


インストーラは http://www.macports.org/install.php からダウンロードできます。


OS のバージョンごとにインストーラが異なるので気をつけましょう。


今回は Snow Leopard のインストーラをダウンロードします。


インストーラでは基本的に [続ける] or [Agree] をポチポチ押してれば問題ありません。


MacPorts 用の PATH設定

以下は bash, zsh 用の設定です。


追記(2010/9/23): 記述修正しました。



PATH=/opt/local/bin:/opt/local/sbin/:$PATH
PATH=$PATH:/opt/local/Library/Frameworks/Python.framework/Versions/2.7/bin


2行目はこれからインストールする Python 用の記述です。


MacPorts のアップデート

MacPorts を最新の状態にアップデートします。



$ sudo port -d selfupdate
$ sudo port -d sync


Python インタプリタのインストール

今回は Python 2.7 をインストールします。



$ sudo port install python27


これで、後はインストール完了を待ちます(しばらく時間がかかるかもしれません)。


ちなみに、現在 Python は 2.x 系列と 3.x 系列が並行してリリースされています。


2.x と 3.x は互換性が無いため、過去の資産が使えない 3.x よりは 2.x の方が利用される例が多いようです。


そのため、今回は 2.x 系列の最新版である 2.7 で進めることとします。


インタプリタを動かしてみる


まずは、Python が正しくインストールされたか確認します。以下のコマンドを実行して、「Python 2.7」と表示されるか確認しましょう。



$ python -V
Python 2.7


このとき、「Python 2.6.1」と表示された場合、正しく PATH が通ってないことが考えられます。


設定を改めて確認しましょう。


次にインタプリタを動かしてみます。



$ python
Python 2.7 (r27:82500, Sep 23 2010, 18:11:42)
[GCC 4.2.1 (Apple Inc. build 5664)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>>


こんな感じで表示されたら OK です。


では、Hello world を実行してみます。



>>> print 'Hello world!'
Hello world!


次に Python インタプリタを終了します。


Ctrl-D か、exit() と入力すると終了します。


sitecustomize.py の設定


Python はデフォルトだと文字コードが ascii になってるので、これを UTF-8 に変更します。


以下のように、site-packages というディレクトリの中に sitecustomize.py を作成します。



$ sudo vim /opt/local/Library/Frameworks/Python.framework/Versions/Current/lib/python2.7/site-packages/sitecustomize.py


sitecustomize.py には以下のように記述します。



#!/usr/bin/env python
import sys
sys.setdefaultencoding("utf-8")


easy_install のインストール


easy_install とは、Python のモジュールのインストールやアップデートを行うためのツールです。


Perl の CPAN や、Ruby における RubyGems にあたります。


MacPorts 用の easy_install は、py27-setuptools というパッケージをインストールすると一緒にインストールされます。



$ sudo port install py27-setuptools


easy_install の使い方

引数として、インストールしたいモジュールのモジュール名を指定します。


例えば BeautifulSoup というモジュールをインストールする場合は以下のようにします。


アップデートする場合も同様です。



$ sudo easy_install BeautifulSoup


まとめ


とりあえずここまですれば、最低限の開発環境になってるかと思います。


続きはまたいつか。


みんなのPython 改訂版
みんなのPython 改訂版
posted with amazlet at 10.09.23
柴田 淳
ソフトバンククリエイティブ
売り上げランキング: 75071


初めてのPython 第3版
初めてのPython 第3版
posted with amazlet at 10.09.23
Mark Lutz
オライリージャパン
売り上げランキング: 57132





2010年5月9日日曜日

pep8 を使ってみた



PEP 8 -- Style Guide for Python Code という Python のコーディングスタイルがあります。これに沿って書くとコードが読みやすくなるよ、というものなんですが、ソースコードがこの pep8 に沿っているかどうか確認するツールがあります。Python Package Index : pep8 0.6.1です。


試しにインストールしてみましたが、日本語で書かれたソースに対してこのツールを使うと 80 文字を越えてないはずの文字列に対して



test.py:3:80: E501 line too long (89 characters)


といったような警告を出してきます。


おそらく str 型のまま文字列を扱ってるんだろうな、ということで修正することにします。



$ wget http://pypi.python.org/packages/source/p/pep8/pep8-0.5.0.tar.gz#md5=512a818af9979290cd619cce8e9c2e2b
$ tar zxvf pep8-0.5.0.tar.gz
$ cd pep8-0.5.0


ディレクトリ内に pep8.py というファイルがあったのでこれを修正しました。



$ diff pep8.py.orig pep8.py
211c211
< length = len(physical_line.rstrip())
---
> length = len(physical_line.rstrip().decode('utf-8'))


こんな感じで、(おそらく)str 型のままだった箇所を unicode 型に decode しました。


UTF-8 で決め打ちしちゃったのでどっかでこける可能性もありますが…。





2010年4月29日木曜日

OSXのApache2でDjangoをデプロイするには



Snow Leopard付属のApacheでDjangoを動かしてみたのでまとめておこうと思います。


CGIだとやたら遅いのでFastCGIを使うことにします。


Apache で FastCGI を扱うモジュールのうち、今回は mod_fcgid を試してみました。


mod_fcgid をインストール


http://httpd.apache.org/mod_fcgid/ に svn レポジトリのURLがあるのでそこからダウンロードします。



% svn checkout http://svn.apache.org/repos/asf/httpd/mod_fcgid/trunk mod_fcgid
% cd mod_fcgid
% ./configure.apxs
% make
% sudo make install


flup をインストール



% wget http://www.saddi.com/software/flup/dist/flup-1.0.2.tar.gz
% tar zxvf flup-1.0.2.tar.gz
% cd flup-1.0.2
% python setup.py build
% sudo python setup.py install


Apache で mod_fcgid を使えるように設定


/etc/apache2/httpd.conf に


LoadModule fcgid_module libexec/apache2/mod_fcgid.so


を記述


Django のプロジェクトを移動


今回は /Library/WebServer 以下に置きました。


ディレクトリ名は django です。


fcgid.conf を設定


fcgid_module 用の設定を記述。場所は /etc/apache2/other/fcgid.conf です。



<IfModule fcgid_module>
AddHandler fcgid-script .fcgi
SocketPath /tmp/fcgidsock
SharememPath /tmp/fcgidshm
IPCCommTimeout 40
IPCConnectTimeout 10
</IfModule>


django.conf を設定


django 用の設定を記述。場所は同じく /etc/apache2/other/django.conf



Alias /django/ "/Library/WebServer/django/"
Alias /django "/Library/WebServer/django/"
<Directory /Library/WebServer/django/>
Options +ExecCGI +FollowSymLinks
AllowOverride all
Order allow,deny
Allow from all
</Directory>


.htaccess を設定


/Library/WebServer/django 内に .htaccess を用意します。



AddHandler fcgid-script .fcgi
RewriteEngine On
RewriteBase /django/
RewriteRule ^(media/.*)$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(dispatch\.fcgi/.*)$ - [L]
RewriteRule ^(.*)$ dispatch.fcgi [QSA,L]


dispatch.fcgi を用意


自分の場合は MacPorts でインストールした python を使うように設定してますが、


その辺りは適宜読み替えてください。



#!/opt/local/bin/python
import sys
import os
sys.path.insert(0, '/Library/WebServer')
os.environ['DJANGO_SETTINGS_MODULE'] = 'django.settings'
os.environ['PYTHON_EGG_CACHE'] = '/tmp'
os.environ['PYTHON_PATH'] = '/opt/local/lib/python2.6/site-packages'
from django.core.servers.fastcgi import runfastcgi
runfastcgi(method='threaded', daemonize='false')


以上の設定が終わった後にWebサーバを再起動して、


http://localhost/django/ で動いてるのを確認しました。


ちなみに、fcgid 入れた当初はアクセスするとなぜか apache が落ちるという症状が出てました。


調べてみて http://ktjx.blogspot.com/2008/02/mac-os-x-php5-apache2-modfcgid.html を参考に解決。





で、ここまで設定した後で settings.py で DEBUG = False にするのを忘れていました。


伴って必要な設定をもう一つ済ませておきます。


静的なファイル(テンプレート、CSS、画像など)の設定


Django はこれらのファイルを提供しないらしいです。 http://djangoproject.jp/doc/ja/1.0/howto/static-files.html


ただし、DEBUG = True の場合は例外です。よって、DEBUG = False にする場合はなにかしら設定をする


必要があります。


今回は、django/templates に静的なファイルをまとめてしまうことにしました。


で、/Library/WebServer/other/django.conf に一行書き加えます。


django 用の設定を記述



Alias /django/ "/Library/WebServer/django/"
Alias /django "/Library/WebServer/django/"
Alias /django/media "/Library/WebServer/django/templates" # <- 追加
<Directory /Library/WebServer/django/>
Options +ExecCGI +FollowSymLinks
AllowOverride all
Order allow,deny
Allow from all
</Directory>


これで DEBUG = True にしても問題なく動作しました。





2010年4月26日月曜日

launchctl を登録



launchctl を使って mediatomb を登録しようといろいろ試してたけど、上手くいかないので mediatomb を実行するシェルスクリプトを書いてそれを登録するようにした


startmb.sh



#!/bin/sh
ip=192.168.0.1
add=/Users/user/Movies
config=/Users/user/.mediatomb/config.xml
port=49152
/usr/bin/mediatomb --ip $ip --add $add --config $config --port $port --daemon


startmb.sh をパスが通ってるディレクトリ(今回は $HOME/bin)に置いておいて、launchctl に読み込ませるための startmb.plist を作成。



<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">;
<plist version="1.0">
<dict>
<key>Label</key>
<string>startmb</string>
<key>ProgramArguments</key>
<array>
<string>/Users/user/bin/startmb.sh</string>
</array>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>



これを ~/Library/LaunchAgents/startmb.plist に置く。


で、launchctl を実行



$ launchctl load -w ~/Library/LaunchAgents/startmb.plist
$ launchctl start startmb


これで mediatomb が動いた。


同様にして自作のWebアプリも登録しといた。





2010年4月22日木曜日

Python2.7のCounterを使ってみた



python2.7(2010年4月21日現在まだベータですが)で追加されるクラスの一つに Counter があります。


7.3. collections ? Container datatypes — Python v3.2rc2 documentation


その名の通り何かしらのデータをカウントするときに使えるクラスです。


例えば今までは



d = {}

d['foo'] = d.get('foo',0) + 1
d['bar'] = d.get('bar',0) + 1
d['foo'] = d.get('foo',0) + 1

for key,value in d.items():
print key,value


なんて書いていたのが



from collections import Counter

c = Counter()

c['foo'] += 1
c['bar'] += 1
c['foo'] += 1

for key,value in c.items():
print key,value


で済むようになります。


また、most_common()を使えば手軽にソートできます(上記リンクから参照)。



>>> # Find the ten most common words in Hamlet
>>> import re
>>> words = re.findall('\w+', open('hamlet.txt').read().lower())
>>> Counter(words).most_common(10)
[('the', 1143), ('and', 966), ('to', 762), ('of', 669), ('i', 631),
('you', 554), ('a', 546), ('my', 514), ('hamlet', 471), ('in', 451)]


今までのように辞書使ってると、一旦リストに変換して……とか面倒なステップを踏んでたのでこれはありがたいですね。


ちなみに、github に試しに作ったソースを載せました。


gist: 373850 - python2.7で追加されたCounterを試しに使ってみた。従来の辞書との使い方の比較。- GitHub





2010年2月13日土曜日

BLIP.fmを使ってみた


「音楽版Twitter」なんて言われているBLIP.fmに登録してみた。最初はよくわからなかったんだが、いろいろいじってるうちに何となく理解してきた。

  • 画面上部にある検索窓から自分が好きなアーティストや曲を検索
  • Blip ボタンを押す
  • 自分のタイムラインにその曲が追加される

一人でやってると何がなんだかって感じなのだが、Twitterのようにいろんな人をfollowしてるとだんだん楽しくなってくる。普段自分が聞かないような曲もなんとなく聞いてみようかって気になるし、そこからお気に入りの曲が見つかるかもしれないし。

で、他の人がpostした曲を気に入ったら「Reblip」なんてのもできる。TumblrでいうReblogね。

洋楽だけかと思ったら邦楽もそこそこあるようなので、しばらく利用するつもり。