pyramidでhello world(not light weight)

pyramidは、flaskのように、1ファイルで完結する1ファイルアプリケーションを書くことができます。
また、規模の大きな開発のために、複数のモジュールに切り分けて記述することも可能です。

今回は、pyramidアプリケーションでhello worldを表示するところまでを行います。
ただし、後々規模の大きな開発を行うことに備えてモジュールを分割した形で書いていくことにします。

agenda

今回作るのは単にhello worldと表示するだけのアプリケーションです。
動的な機能をまったく加えていないので、静的なhtmlを表示するのと何ら代わりがありません。

以下の手順に分けて説明します。

  • install
  • setup
  • coding

install

pip などを使いましょう。
(注意:詳細は後述しますが、現在pipでバージョン指定なしで入るpyramidのバージョンは1.3です。1.3と1.2では、デプロイまわりのコマンドのインターフェイスが異なっています。)

pip install pyramid # 1.3が入る

setup

1.3と1.2では、setupに利用するコマンドが異なります。ここでは、1.3の場合を例に書きます。
(1.2については末尾に補足として書きます)

for pyramid 1.3

pyramidをインストールすると以下のコマンドが使えるようになります。

ptweens
proutes
pshell
prequest
pviews
bfg2pyramid
pcreate
pserve

今回はこのうち,pcreate,pserveを使います。

pcreate,pserveは以下のような機能を持ったコマンドです。コマンドの機能は以下のようなかんじです。

pcreate scaffolding. 雛形の作成(アプリケーション開発の土台を作ります。)
pserve serverを起動
pshell プロジェクトの環境でインタラクティブシェル起動
proutes view関数のバインドの一覧表示
寄り道

提供されているコマンドを調べるには、インストールしたパッケージのinstalled-files.txtを見ると良いと思います。
例えば、今回は、virtualenvを使って構築した環境でこの記事を書いています。
ここで、以下のようなコマンドを実行すると、pyramidのインストールで使用可能になったコマンドを調べることができます。

$ cat ~/.virtualenvs/pyramid1.3/lib/python2.6/site-packages/pyramid-1.3a5-py2.6.egg-info/installed-files.txt | grep bin
../../../../bin/ptweens
../../../../bin/proutes

.. snip ..

寄り道です。

scaffolding

まずはじめにscaffoldingを行いましょう。helloというプロジェクトを作ることにします。pcreateを使います。

pyramidはいくつかの異なった種類のscaffoldingを行うことができます。
存在するscafoldingの一覧は以下のようにして調べることができます。

$ pcreate --list-templates
Available scaffolds:
  alchemy:  Pyramid SQLAlchemy project using url dispatch
  starter:  Pyramid starter project
  zodb:     Pyramid ZODB project using traversal

また、自分で好みのscaffoldを作成することもできます。
今回はデータの永続化などは行わないつもりなので、一番シンプルなstarterを使います。
pcreateにはこれから作るアプリケーションのプロジェクト名(e.g. hello)を渡してください

$ pcreate -t starter hello # -t starterを省略しても同様

以下のようなディレクトリ構成になりました

$ cd hello
$ tree
.
├── CHANGES.txt
├── MANIFEST.in
├── README.txt
├── development.ini
├── hello
│   ├── __init__.py
│   ├── static
│   │   ├── favicon.ico
│   │   ├── footerbg.png
│   │   ├── headerbg.png
│   │   ├── ie6.css
│   │   ├── middlebg.png
│   │   ├── pylons.css
│   │   ├── pyramid-small.png
│   │   ├── pyramid.png
│   │   └── transparent.gif
│   ├── templates
│   │   └── mytemplate.pt
│   ├── tests.py
│   └── views.py
├── production.ini
├── setup.cfg
└── setup.py

3 directories, 20 files
setup.pyを読み込み

作ったプロジェクトのsetup.pyを読み込みましょう。loadpathなどが設定されます。
また依存パッケージなどが新たに在ればインストールされます。

$ pwd # hello
$ pip install -e .
pserveでサーバ起動

モジュールを分けたタイプのpyramidの開発では、「開発環境用の設定ファイル」と「デプロイ用の設定ファイル」を分けます。
(このあたりは他のweb application frameworkと同様ですね)

それぞれの設定ファイルの用途は以下のようになっています。

development.ini 開発環境用設定ファイル
production.ini デプロイ用設定ファイル

試しにサーバを起動させてみましょう。もうひとつのコマンドpserveを使います。
pserveには上に上げた設定ファイルを渡します。port 6543でサーバが立ち上がります。

$ pserve development.ini
Starting server in PID 25164.
serving on http://0.0.0.0:6543

coding

ここから実際の開発に移ります。

development.ini,production.iniの設定

本来であれば、データの永続化を行う場合などDBの設定を設定ファイルに追加しますが、今回は使わないので省略

view(view callable)の定義

hello/views.pyを開いてください*1
はじめからmy_viewという関数が定義されてます。このとおりにview(view callable)を定義していってくださいということです。

同様にして、hello_viewを定義してみましょう。

from pyramid.view import view_config
from pyramid.response import Response

@view_config(route_name='home', renderer='templates/mytemplate.pt')
def my_view(request):
    return {'project':'hello'}

@view_config(route_name="hello")
def hello_view(request):
    return Response("hello anytone")

(察しのとおり、テンプレートの設定はview_configのrendererで行います。が、今回の記事の内容の範囲外なので省略します)

viewのバインド

定義したviewは何ともバインドされてません(localhost/? どのようなパスを指定するとhello_view関数にたどり着くのでしょう?)。
hello/__init__.pyを開いてください。my_viewを真似て、add_routeを追加してください。

from pyramid.config import Configurator

def main(global_config, **settings):
    """ This function returns a Pyramid WSGI application.
    """
    config = Configurator(settings=settings)
    config.add_static_view('static', 'static', cache_max_age=3600)
    config.add_route('home', '/')
    config.add_route("hello", "/hello") # this!
    config.scan()
    return config.make_wsgi_app()

簡単に説明します。Configuratorのインスタンスは設定の情報を持つオブジェクトです。
(コンストラクタを呼び出しただけでは、情報を持つだけで、まだアプリケーションに設定を適用するというわけではないことに注意してください)

config.add_route()で、定義したviewをバインドしていきます。先ほど定義したhello_viewは"/hello"にバインドすることにしました。

設定が有効になるのは、その後のconfig.scan()が呼ばれた時です。注意してください。

次は定義したviewが有効に動作するか確認を行います。
(本来は、テストなどを書くべきかもしれませんが、今回の記事では省略します。
そのかわりに、直接コマンドを実行してみて、動作しているか確認します。)

パスにバインドされているviewの確認(using proutes)

proutesはバインドされているviewを確認する際に便利なコマンドです。ついでに紹介しておきましょう。
proutesも設定ファイルを引数にとります。

$ proutes development.ini 
Name            Pattern                        View                     
----            -------                        ----                     
___debug_toolbar/static/ /_debug_toolbar/static/*subpath <function <pyramid.static.static_view object at 0x2ddac90> at 0x2eb8758>
debugtoolbar.source /_debug_toolbar/source         <function ExceptionDebugView at 0x2ec2500>
debugtoolbar.execute /_debug_toolbar/execute        <function ExceptionDebugView at 0x2ec27d0>
debugtoolbar.console /_debug_toolbar/console        <function ExceptionDebugView at 0x2ec2aa0>
debugtoolbar.exception /_debug_toolbar/exception      <function ExceptionDebugView at 0x2ec2230>
debugtoolbar.sql_select /_debug_toolbar/sqlalchemy/sql_select <function SQLAlchemyViews at 0x2ec2d70>
debugtoolbar.sql_explain /_debug_toolbar/sqlalchemy/sql_explain <function SQLAlchemyViews at 0x2ec40c8>
__static/       /static/*subpath               <function <pyramid.static.static_view object at 0x2de9490> at 0x2ec42a8>
home            /                              <function my_view at 0x2ec4758>
hello           /hello                         <function hello_view at 0x2ec45f0>

homeにmy_viewが、helloにhello_viewがバインドされてますね。

view関数が動いているか確認(using pshell)

実際に定義したview関数が動いているか確認してみましょう。
pshellコマンドを使います。pshellは、作られたアプリのパッケージの環境でpythonインタラクティブシェルを立ち上げるコマンドです。
pshellもpserveと同様に設定ファイルを引数にとります。

$ pshell development.ini
Python 2.6.6 (r266:84292, Sep 15 2010, 16:22:56) 
[GCC 4.4.5] on linux2
Type "help" for more information.

Environment:
  app          The WSGI application.
  registry     Active Pyramid registry.
  request      Active request object.
  root         Root of the default resource tree.
  root_factory Default root factory used to create `root`.

>>> from hello.views import hello_view
>>> hello_view(None)
<Response at 0x249c950 200 OK>
>>> hello_view(None).text
u'hello anytone'
>>> 

動いていますね。

サーバの起動とブラウザで閲覧(using pserve)

開発用のサーバを立ち上げ、ブラウザで見てみましょう。
開発用のサーバは同梱されているので、新しくインストール設定する必要は在りません(もちろん、実際のデプロイの際にはそうはいきませんが)。

開発ようのサーバを立ち上げるにはpserveを使います。
pserveも引数に設定ファイルをとります。

$ pserve development.ini &
Starting server in PID 26321.
serving on http://0.0.0.0:6543

$ curl localhost:6543/hello
hello anyone

面倒なのでcurlで確認してしまいましたが、pserveでサーバを立ち上げたら、ブラウザで閲覧できるようになります。
hello anyoneと表示されてますね。hello_viewが動作しています。

next

この記事には以下の内容が含まれていません。

  • viewのテストの書き方
  • templateの使い方(e.g. Chameleon,mako,jinja2, ... etc.)

公式pyramidの公式ドキュメントにもチュートリアルがあります。参照してください。
http://docs.pylonsproject.org/projects/pyramid/en/1.3-branch/index.html#tutorials

また日本語のチュートリアルもあります(こちらは1.2.xでの説明です)
http://pyramid_tutorial_pylonprojectjp.readthedocs.org/en/latest/index.html

補足(pyramid1.2.xのコマンドについて)

繰り返しになりますが、pyramidの1.2と1.3でコマンドの実行形式が異なります。
1.3ではpcreate,pserveなど直接提供する機能に紐づくコマンドが用意されていましたが、1.2.xでは異なります。

1.2.x では同様の機能を提供するpasterコマンドが用意されています。

Usage: paster [paster_options] COMMAND [command_options]

Options:
  --version         show program's version number and exit
  --plugin=PLUGINS  Add a plugin to the list of commands (plugins are Egg
                    specs; will also require() the Egg)
  -h, --help        Show this help message

Commands:
  create       Create the file layout for a Python distribution
  help         Display help
  make-config  Install a package and create a fresh config file/directory
  points       Show information about entry points
  post         Run a request for the described application
  proutes      Print all URL dispatch routes related to a Pyramid application
  pshell       Open an interactive shell with a Pyramid application loaded
  ptweens      Print all tweens related to a Pyramid application
  pviews       Print all views in an application that might match a URL
  request      Run a request for the described application
  serve        Serve the described application
  setup-app    Setup an application, given a config file

例えば、
1.3での以下のコマンドは

$ pserve development.ini

1.2.xでは以下のようになります。

paster serve development.ini

1.2.xのバージョンのpyramidを使う場合には適宜読み替えてください。

*1:helloはアプリ名