What Makes Pyramid
      Unique!
  Django & Pylons Con 2012
           aodag
お前誰よ

Atsushi Odagiri

株式会社ビープラウド

http://twitter.com/aodag
http://facebook.com/aodag
Pyramid 仕事で使ってます
機能追加のパッチを投げました
Pythonは1.5から。
Pyramidは、repoze.bfg1.2のころから。
今日のお話

Pyramidって何?
どんな特徴が?
実際どんな開発の仕方?
Pyramidとは?

Pylonsプロジェクトの
Webアプリケーションフレームワーク

Simple, Fast, Tested, Documented

No ORM, No Template Engine.
Pyramidができるまで

  WSGI                Zope




  Pylons             Repoze


           Pyramid
Zopeから受け継いだもの

Zope Component Architecture
URLトラバーサル
コンテキストベースのセキュリティ機構
Pylonsから受け継いだもの

WebOb, BeakerなどのWSGIコンポーネント
URLパターンでのディスパッチ
PasteScript
(ただしPython3対応のために独自コマンドとして取
り込まれた)
Pyramidの設計方針

仕組みをたくさん提供する
ポリシーを押し付けない
コンポーネント指向を直接見せない
ことさらマイクロフレームワークを意識しない
特徴的なしくみ

デコレータベースの設定
さまざまなフック
例外ビュー
デコレータベースの設定

 ユニットテスト中に
副作用のあるデコレータ
  が実行されると、
うっとおしいですよね?
デコレータベースの設定

デコレータでビューなどを登録できる

ただし、いきなり登録するのではなく
Configurator.scan()をトリガーとして、初めて登録
される。
さまざまなフック

フレームワークの途中に処理を
   割り込ませたいこと、
  たくさんありますよね?
さまざまなフック

NewRequest
Tween
BeforeRender
など
例外ビュー

 処理を打ち切って、
    さっさと
レスポンスを返したいこ
     と、
たくさんありますよね?
例外ビュー

例外クラスごとにそれぞれビューを設定可能
view predicate

       同じ処理だけど、
       Ajaxリクエストと
      ブラウザリクエストで
       テンプレートとか
       変更したいよね?
view predicate
name             xhr
context          accept
route_name       header
request_type     path_info
request_method   custom_predicate
request_param
match_param
view predicate
@view_config(.... xhr=True, renderer="json")
@view_config(... xhr=False, renderer="index.
html")
def get_something(request):
  ....
  return dict(items=items)
その他いろいろ

シングルトンは存在しない
継承を多様しない
開発を助けるコマンド群

pcreate
pserve

pshell
prequest

proutes
pviews
ptweens
pcreate
プロジェクトテンプレート(Scaffold)を展開する
開発開始時の土台を作成するツール

ユーザー定義のプロジェクトテンプレートも作成で
きる
pserve
Webアプリケーションを実行する
--reloadオプションで、ファイル更新を検地してリ
ロードしてくれる

daemon化やモニタリングしてリスタートさせること
も可能
pshell
Webアプリケーション実行時の環境を擬似的に作
成して、Pythonシェルを起動する
prequest
Webアプリケーションをオフラインで実行して結果
を確認できる
proutes, pviews, ptweens
アプリケーション構成を確認できる。

例えば:
● URLパターンが実際にどのViewにマッチするの
  か
● 具体的なURLに対応するViewはどれか
● Tweenの実行順序はどのようになっているのか
よく使うライブラリ、ツール

ZODB3             distribute
SQLAlchemy        zc.buildout
zope.sqlalchemy   nose
deform/colander   alembic
WebHelpers
cliff
有力なアドオン

pyramid_tm
pyramid_deform
pyramid_debugtoolbar
pyramid_exclog
pyramid_zodbconn
Pyramidベースのフレームワーク

SubstanceD
Kotti
Cornice

GroundHog
MetaTG
Pyramidでの開発

2つのベースアーキテクチャ

ZODB + トラバーサル
SQLAlchemy + URLディスパッチ
ZODB + トラバーサル

URLパターンとかいらない!
URL -> オブジェクトツリー
URLでオブジェクト取得

例:
URL : /great/bucho/show
トラバーサル : root['great']['bucho'].
   showがない?
showという名前のViewを呼ぶ
Pyramidでの開発 環境構築

mkvirtualenv pycon2012
easy_install pyramid
pcreate -s zodb pycon2012
cd pycon2012
python setup.py develop
Pyramidでの開発

追加のライブラリなど

pyramid_deform
deform_bootstrap
colander
pillow
repoze.filesafe
repoze.folder
setup.pyに依存ライブラリを追加する

install_requires = [
...
"pyramid_deform",
"deform_bootstrap",
"colander",
"pillow",
"repoze.filesafe",
"repoze.folder",
iniファイルにアドオンを追加する

pyramid.includes =
  ....
  pyramid_deform
  deform_bootstrap
Pyramidでの開発

モデルを書く

class Document(Persistent):
   def __init__(self, name, contents):
     super(Document, self).__init__()
     self.__name__ = name
     self.contents = contents
Pyramidでの開発

ビューを書く

@view_config(context=Document,
  renderer='templates/document.pt')
def document_view(request):
  return dict()
テンプレートを書く

<html>
<body>
<h1>${context.__name__}</h1>
<div>
${structure:context.contents}
</div>
</body>
</html>
pshellでモデルデータを登録

$ pshell development.ini
>>> from pyconjp2012.models import
Document
>>> doc = Document('test-document', 'this-is-
document')
>>> root[doc.__name__] = doc
>>> doc.__parent__ = root
>>> import transaction
>>> transaction.commit()
prequestで試してみよう

$ prequest development.ini /test-document
<html>
<body>
<h1>test-document</h1>
<div>
this-is-document
</div>
</body>
</html>
pserveでWebアプリケーションを実行

pserve development.ini --reload
ユーザー入力フォーム

スキーマ定義

class AddDocumentSchema(c.Schema):
   name = c.SchemaNode(c.String())
   contents = c.SchemaNode(c.String(),
     widget=w.RichTextWidget())
ユーザー入力(実装)

class AddDocumentView(FormView):
   schema = AddDocumentSchema()
   buttons = ('save',)

  def save_success(self, params):
    doc = Document(**params)
    self.request.context[doc.__name__] = doc
    doc.__parent__ = self.request.context
    return HTTPFound(self.request.
resource_url(doc))
pyramid_deform (表示)

${structure:form}
Chameleonのテンプレートマクロ(定義)

<html metal:define-macro="html">
<head>
<!-- いろんなヘッダ -->
</head>
<body metal:define-slot="main">
</body>
</html>
Chameleonのテンプレートマクロ(利用)

<html metal:use-macro="base.macros.html">
<body metal:fill-slot="main">
${form}
</body>
</html>
まとめ

使う場合
言われるほど面倒ではない
難しいこともない

使い切る場合
手をいれれられる箇所が多いので、相対的に難し
く感じるかも?
(´  > ω < )こわくないよー
Pyramidの今後

Pyramidベースのフレームワークが発展していく
Python3対応?ああ、去年やってましたね。
テンプレートの標準サポートをなくす方針
Pyramidの今後

管理アプリが欲しい!
今世界中のPylonsどもが実装している。
参考URL

The Pylons Project Documentation http://docs.
pylonsproject.org/en/latest/index.html

Pyramid Documentation http://docs.
pylonsproject.org/en/latest/docs/pyramid.html

Defending Pyramid's Design http://docs.
pylonsproject.
org/projects/pyramid/en/master/designdefense.
html

What makes pyramid unique