Travis-CI を使ってみた

Travis-CI というサービスがあります。
継続的インテグレーションってやつです。
よくわかりません。
多分 Jenkins みたいなやつです。

とりあえず github に push したら指定したスクリプトを走らせてくれて、結果を通知してくれるサービスだと思っておきます。
で、これを使います。

環境

今回開発で使っている環境は以下の通り

  • Python2.7
    • Tornado 2.4
    • SQLAlchemy
    • zope.pageteplate
    • Pygments
  • MySQL

とかとか。
まあ普通ですね。

で、こいつのテストを Travis-CI で走らせます。

Travis-CI にログイン

Travis-CI のサイトに行って githubOpenID 認証をしたら終了なので特に書くことはありません。

で、 CI したいリポジトリの設定をポチっと切り替えるだけです。

.travis.yml を書く

リポジトリ直下に .travis.yml というファイルを作ります。
今回は以下の通り。

language: python
python:
  - "2.7"

before_script:
        - wget http://svn.zope.org/*checkout*/zc.buildout/trunk/bootstrap/bootstrap.py
        - python bootstrap.py -d
        - bin/buildout
script: ./test.sh

セットアップは全部 buildout 任せなのでまあこんなもんでしょうか。

Python の細かい設定の話は ドキュメント 見てください。
PyPy も使えるらしいっすよ素晴らしい!

MySQL は root@localhost でパスワード無しアクセスできるらしいです。
ドキュメント に書いてありました。
皆さん読みましょう。

この python: のところを書き換えるとバージョンも色々試せるみたいですよ。
複数バージョンでのテストも楽チン。

使ってみて

とりあえず楽で便利な Travis-CI なのですが、ちょっと気になるところも。

ビルドが再実行できない

PyPI が落ちていて buildout でコケてるとかそんなときでも再実行するという選択は取れない模様。
それが若干残念。

成果物とか作れない

Jenkins だとビルドした結果の成果物として色々とっておけたりするけれど、 Travis-CI だとそれもない。
なので Coverage を HTML 出力してもどうしようもない。

まとめ

若干残念とはいえ便利なので使いましょう。

あと、 BuildHive も気になってる。

zope.i18n の設定をするまで

なんか色々ハマったのでメモ。

やりたいこと

今作っている Web アプリで zope.pagetemplate を使おうとしているわけです。
で、時代はインターナショナルという事で i18n とか考えたい、と思うわけです。

zope.pagetemplate なので zope.i18n を使うわけなのですが、ここらへんが結構めんどくさいしドキュメントないしで泣けるのでメモっておくわけです。

基本的に http://collective-docs.takanory.net/i18n/localization.html を見ながらセットアップするといいよ。
あと How to internationalize your application も参考になるはず。

configure.zcml を書く

configure.zcml を書きます (ここではパッケージ直下)

pkg
 +- __init__.py
 +- configure.zcml

みたいな感じ。

で中身は

<!--*- mode:xml -*-->
<configure xmlns="http://namespaces.zope.org/zope"
           xmlns:i18n="http://namespaces.zope.org/i18n">
  <include package="zope.i18n" file="configure.zcml" />
  <include package="zope.i18n" file="meta.zcml" />
  <i18n:registerTranslations directory="locales" />
</configure>

こんなの。

i18n:registerTranslations の directory で指定した場所に pot とかが作られます。
gettext のキーワードとコンテンツとかですね。

で、パスはこの zcml からの相対で渡せるので、そのまま locales とすると zcml があるディレクトリに locales が掘られます。

buildout

buildout.cfg にこんなのを追加します。

[buildout]
parts = ... i18n

[i18n]
recipe = z3c.recipe.i18n:i18n
zcml = ${buildout:directory}/${buildout:pkgname}/configure.zcml
domain = trolle
output = ${buildout:directory}/${buildout:pkgname}/locales

そしておもむろに

$ bin/buildout

します。

すると bin の下にいくつかファイルができます。

$ ls bin/i18n*
bin/i18ncompile  bin/i18nextract  bin/i18nmergeall  bin/i18nstats

ここで bin/i18nextract を実行すると locales ディレクトリが作られるようです。

あとのコマンドはこれから先使うようですが、まだまだわからないのでそのうち。

PyCon JP 2012 で広報してきた #pyconjp

先日のことですが、 2012/09/15 〜 2012/09/17 にかけて PyCon JP 2012 が開催されました。
昨年の PyCon mini JP, PyCon JP 2011 に続いてスタッフとしての参加です。

議事録を見る限り第一回のミーティングは 2012/01/16 らしいので八ヶ月程度は関わってきたことになります。

広報のお仕事

今年も去年と同じく広報の主担当として各種メディア告知協力をお願いしたり、 pyfes で LT して参加者やスタッフを募集したり java-ja で LT してプロポーザルをリクエストしたりしました。
事前記事なんかもスタッフに書いてもらって載せてもらうということもしましたね。
あと初海外で PyCon TW で英語で告知するなんてこともしてなんとも貴重な経験をさせてもらいました。

これから開催後の運営レポートをスタッフに書いてもらうお仕事があったりまだまだ PyCon JP 2012 は終わりそうにありません。

当日

開催当日は撮影担当としてカメラを持って走り回っていました。

なんだか 1000 枚弱くらい撮っていたようですよ。
と言っても Sprint の写真は他の人にカメラを託していたので半分くらいしか撮っていませんが。

なのでセッションはほとんど楽しめていませんでした。
スタッフなのでしょうがないし、写真撮るのは撮るので楽しいですけどね。

PyCon JP 2012 の感想とか

感想と言ってもそもそも初日は基調講演の写真をサッと撮ってから受け付けあたりに入ってテンパる おしょー のサポートに回ったり代わりに受付仕切ったりメッセンジャーとして走りまわったり写真撮っていたりしたので感想と言ってもなあという感じ。

カメラ持って走りまわるのはセッションもそうですがパーティあたりが楽しいですね。

二日目は色々落ち着いて若干の余裕ができたのでセッションをちょっと見て回ったりカフェテリアでたむろっている人たちの話に混ざったりしてました。
二日目の基調講演はちょっと見ていて、 dankogai の Pythonista の炎上ポイントを心得ているのかなんなのか、と言った感じの内容とそれに反応する TL を見て「あー燃えてるわー楽しいわーこれ」とか思っていたりしました。

Sprint は pypy-ja で席を確保しつつレポートのアウトラインを考えたり作っているもののテスト書いていたりしたので pypy-ja らしいことは何もしていないですね。なんとも残念。

そんなこんなでカンファレンス終了。

皆様お疲れ様でしたー。

まとめ

広報として八ヶ月ほど PyCon JP 2012 に関わってきたわけなのですが…。
んーなんだろうなあ、実際楽しかったし、いろいろ経験できたのはそのとおりです。
否定のしようがありません。

しかしなんともモヤモヤしたものがあるのもまた事実。
広報は他の担当との関わり・連携が薄く、あまり運営内部に深々と入っていって何かをするという感じではないというのもあるのかもしれません。
中に居ながらにして外から中を見ている感じ。

もしかしたらカンファレンスにカンファレンスとして参加できなかったからかもしれないし、運営に直接関わった実感がないからかもしれませんがなんとも不完全燃焼感があります。

運営に関わるという事をやめるつもりはないのですが、なんともモヤっとした部分を解消したいと思ったりします。

ひとはずは来年こそは PyPy ネタで発表したいですね、ってことにしておきます。

tornado やってみたメモ

なんか作りたい人はこんなところを見ていないで ドキュメント 読めばわかるし読んでわからないなら諦めてください。

弄っているソースは ここらへん に置いてあるはず。

URL mapping

とりあえずこれですよ。

app = web.Application([
        ('/', serve.MainHandler),
        ('/websock', serve.OnWebsock),
        ('/yes/(.*)', serve.YesHandler),
        ('/print/(?P<aaa>.*)', serve.PrintHandler),
        ])

何となくこんな感じでやるらしい。

  • 正規表現で書く
  • グルーピングも使える
  • 名前付きグループと名前なしグループは混ぜられない

というところをおさえておけばいいっぽい。

リクエストの処理

まあなんとなくわかるよね。

class PrintHandler(web.RequestHandler):

    def get(self, *args, **argd):
        u'''
        :param *args: URL マッピング時の名前なしグルーピング
        :param **argd: URL マッピング時の名前付きグルーピング
        
        レスポンスボディは self.write で書き込んでやる。
        '''

        # レスポンスヘッダを弄る
        self.set_header('Content-Type', 'text/plain;charset=utf-8')

        print >> self, args, argd

        # URL パラメータから値を一個取る
        print >> self, self.get_argument('aaa')

        # URL パラメータから値を全部取る
        print >> self, self.get_arguments('aaa')

        # self.request がリクエストオブジェクト
        # リクエストオブジェクトの arguments にパラメータが辞書で入っている
        pprint.pprint(self.request.arguments, stream=self)

とりあえず今日はここまで。

supervisor を使ってみた

ちょっと tornado 使って WebSocket うひょーとかやりたくなったので色々調べていて、こいつプロセス立てて daemon にしなきゃいけないわけですよ。

んで、運用環境に行った後にプロセス管理とかめんどくせーなーなどと思っていた訳なのですが、 supervisor が結構よさそうということでメモ。

suervisor を入れる

ビルド管理はいつも通り buildout を使うので buildout.cfg に入れるだけ。

buildout で supervisor を使うには collective.recipe.supervisor っつーのを使えばいいらしい。

で、プログラムに管理したいプログラム(この場合は tornado で作ったアプリケーション)を追加してあげる。

programs = 
         10 tornado ${buildout:bin-directory}/ttest

という行がそれ。

で、この状態で buildout すると bin/supervisorctl, bin/supervisord という二つのファイルが作られる。

オプションはこれ以外にも色々あるけど詳しくは ここらへん を見た方がよい。

supervisor の起動と管理

で、作られた supervisor のアプリを使う。

$ bin/supervisord

で supervisor の管理プロセスが立ち上がる。
こいつはコマンドを打つだけで daemon になってしまうので、デバッグ時などは

$ bin/supervisord -n

してあげるとコンソールに残ってくれる。

この状態で http://localhost:9001 (ポートはデフォルト) にアクセスすると管理画面が現れて、設定したプログラムごとに起動・停止・再起動などができる。

Web からでなくコンソールからも操作できる。

$ bin/supervisorctl start tornado # tornado の開始
$ bin/supervisorctl stop tornado # tornado の終了
$ bin/supervisorctl start all # 全てのプロセスの開始
$ bin/supervisorctl stop all # 全てのプロセスの終了

こいつを使えば色々と管理が楽そうなのでこれでとりあえずがんばってみようそうしよう。

fabric を使ってみた

最近 githubSphinx で作った s6 スライドのソースを置いて、それを自分の VPS にアップロードするということが結構ある。

その時に

  • github に push
  • サーバに ssh
    • git clone
    • buildout
    • make html
    • sudo して /var/www なりなんなりにコピー

という手順をこなさないといけない。

大した手順ではないけれど、正直めんどい。
一回だけならいいけれど、更新掛けたり何度も書き換えるようなときは手間なのでなんとか自動化したい。

というわけで fabric を使ってみた。

fabric とは

Fabric is a Python (2.5 or higher) library and command-line tool for streamlining the use of SSH for application deployment or systems administration tasks.

http://docs.fabfile.org/en/1.4.3/index.html

適当に訳すと fabric とは Python2.5 以降で動く SSH を使ったアプリケーションデプロイやサーバ管理を行うためのツールである、ということらしい。

fabric の使い方

fabric は以下のようにして使う。

  • easy_install/pip で fabric を入れる
    • pycrypto が古かったので更新した記憶あり
  • fabfile.py を書く
  • fab コマンドを実行

で、問題なのは fabfile.py を書くところ。

今回書いたのは以下のようなスクリプト

#-*- coding:utf-8 -*-

import sys
import os
import subprocess

from fabric import api

api.env.hosts = ['vps_hostname']

python = '/usr/local/python2.6/bin/python'

m = lambda *seq: subprocess.list2cmdline(seq)

def make_docs(n):

    target = os.path.join('/path/to/apache/public/dir', n)

    with api.cd(n):
        api.run(m(python, '/path/to/bootstrap.py', '-d', 'init'))
        api.run(m('bin/buildout', '-N'))
        api.run(m('bin/make-docs'))
        api.run(m('sudo', 'rm', '-rf', target))
        api.run(m('sudo', 'cp', '-r', '_build/html', target))



def deploy():

    with api.cd('linuxsyscall'):
        api.run('git pull')

        make_docs('01')

で、こんなものを用意して、

$ fab deploy

ってやると api.env.hosts に設定したホストに ssh して勝手に処理してくれる。
sudo したらパスワードの入力を求めてくれるので非常に楽。

やー楽だわー。めっちゃ楽だわー

Python から Java を使ってみる

Python から Java を弄りたいと思ったので何となくやってみる。
PyPI でモジュールを探したら javabridge と javaclass がでてきた。

javaclass

で、 javaclass を試してみたらダメだったという。

Mercurial のリポジトリ(証明書エラー出るので自己責任) に runclass.py というサンプルがあるので中を見てみると、

import javaclass.classhook
import java.lang

となっている。

これは javaclass.classhook を読み込んだ時点で Python の import hook が仕掛けられるのだろうけども、どうやらこれがうまくいっていない。

調べるのも面倒なのでこっちはスルー。

javabridge

もう一つのモジュール javabridge を使ってみる。

$ pip install javabridge

してみたらこけた。
JAVA_HOME がないっぽかったので jdk 落としてきて

$ JAVA_HOME=$HOME/local/jdk1.7.0_05 pip install javabridge

とか指定してあげた。
でもだめ。

gcc -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions build/temp.linux-i686-2.6/javabridge/javabridge.o -L/home/shoma/local/jdk1.7.0_05/jre/lib/amd64/server -ljvm -o build/lib.linux-i686-2.6/javabridge/javabridge.so

/usr/bin/ld: cannot find -ljvm

collect2: ld returned 1 exit status

とか言われてしまう。
このメッセージをよく見ると、

-L/home/shoma/local/jdk1.7.0_05/jre/lib/amd64/server

とか書いてあっておかしい。
そもそもこのビルドを行っているマシンは 32bit OS なのでこんな指定は変だなあと。

まあ直接指定すればいいので

$ export CFLAGS="-L/home/shoma/local/jdk1.7.0_05/jre/lib/i386/server"

とか指定してあげて再度ビルドしてインストール成功。

使ってみる

とりあえず普通に import すればいいようなので

from java import lang

lang.System.out.println("Hello, Java")

とかやってあげたら動いた。
良かったね。

これで Python から Java のリフレクション実験しまくれるね。
Java 書いて実験するっていう選択肢は Java がかったるいので存在しません。
Jython でもいいんだけどね。