Python3で
Webアプリケーション
      aodag
   PyConJP2012
お前誰よ

Atsushi ODAGiri
aodag

@aodag


株式会社ビープラウド
Python3!
Python3.2.3
Python3.3rc2
来週(9/22)に3.3finalの予定
Python3での重要な変更

標準ライブラリが整理された
str,unicodeがbytes,strに。ユニコードと生データと
の違いが明確に。
相対importの扱いが変更された。相対モジュール
をインポートするときは、 "from . "が必要に。
Python3の情報
PYPI Python3Packages

http://pypi.python.org/pypi?:
action=browse&c=533&show=all
Python3の情報 Wall Of Shame

http://python3wos.appspot.com/
すでにPython3対応している
フレームワーク

Pyramid
Bottle
Bobo
CherryPy
Tornado
Python3での課題

PEP333(WSGI 1.0) であいまいな点が多い
特に文字コード、ユニコード関連

Python3では bytesとstrの違いが明確になった。

WSGIでも明確に! -> PEP3333(WSGI 1.0.1)
WSGIで行こう

def hello(environ, start_response):
  start_response(['200 OK',
     ('Content-type', 'text/plain')])
  return [b"Hello"]

from wsgiref.simple_server import make_server
httpd = make_server('', 8080, hello)
httpd.serve_forever()
(´・ω・`)
めんどくさいですねぇ
とりあえず必要だと思うもの

リクエストオブジェクト
ルーティング
HTMLテンプレート
WSGIサーバー
WebObで行こう

from webob.dec import wsgify

@wsgify
def hello(request):
  return "Hello"

from wsgiref.simple_server import make_server
httpd = make_server('', 8080, hello)
httpd.serve_forever()
WSGIサーバー

cherrypy
waitress
tornado
URLディスパッチ

WebDispatch

WSGIアプリの様々なディスパッチをサポート

URLパターン
リクエストメソッド
WebDispatch
dispatcher = URLDispatcher()
dispatcher.add_url('top', '/', index)
dispatcher.add_url('hello', '/hello/{name}', hello)
dispatcher.add_url('top', '/good-by', bye)
urlvars
urlパターン:/hello/{name}
実際のurl: /hello/aodag
urlvars: {'name': 'aodag'}

@wsgify
def hello(request):
  name = request.urlvars.get('name', 'world')
  return "Hello, {0}".format(name)
テンプレートエンジン

Jinja2
Mako
Chameleon
Tempita
...
(`・ω・) 意外と充実!
jinja2
loader=PackageLoader(__name__, 'templates')

env = Environment(loader=loader)
jinja2
@wsgify
def hello(req):
  name = req.urlvars.get('name', 'world')
  tmpl = env.get_template('index.html')
  return tmpl.render(name=name)
(`・ω・) これで
**MVC**
  できるね!
CSSとか
画像とか
どうするの
NGINXでやれよ!
と、思いますが、
開発中にNginx使うのも萎えるので。
スタティックファイルを扱う

webob.static.FileApp
webob.static.DiectoryApp
static_resource = pkg_resources.resource_file
(__name__, 'static')

static_app = DirectoryApp(static_resource)

application.add_url('static', '/static/*', static_app)
(´・ω・`) データはどうしよう
データベースアクセス

ドライバ: psycopg2
ORM: SQLAlchemy
マイグレーション: alembic
(`・ω・) 予想以上に
  ちゃんと動くぞ!
セッション

Beaker

Beaker自体は動く
バックエンドは Memory, Fileは問題なし
その他のバックエンドは依存ライブラリが対応して
いるか未確認
認証

repoze.who (trunk)

多分 2.1 でリリース

使いたければ setup.py の dependency_links に以
下を追加

https://github.com/repoze/repoze.
who/zipball/master#egg=repoze.who-2.1dev
フォームライブラリ

deform
colander

問題なく利用可能。
っていうか僕が対応しました(・∀・)
画像処理

pillow はよ
(´・ω・`) PILとかは
  非公式パッチで
動くらしいですねぇ
       |
   \  __  /
   _ (m) _ピコーン
      |ミ|
    /  `´  \
     ('A`)
     ノヽノヽ
       くく
画像処理

PyQtにQImageがあるじゃないか!
PyQt
説明しよう!PyQtとは!
UNIX系のデスクトップ環境KDEで採用されている
ことで有名なGUIツールキットQtのPythonバイン
ディングである!
つまり!
画像をリサイズするためだけに、GUIツールキット
を使おうとしているのである!
(゚д゚ )
( ゚д゚ )
QImageを使うために

QImageがQtGUIモジュールにあるため、ヘッドレ
ス不可能
LinuxだったらX11が必要になります
Qtをインストール
PyQtをインストール
ファイルアップロードからの
サムネイル保存

data = validated['image']['fp'].read()
image = QtGui.QImage.fromData(data)
thumbnail = image.scaled(128, 128,
  aspectRatioMode=Qt.KeepAspectRatio)
thumbnail.save(thumbnail_filename)
まとめ

画像処理だけ難あり?
他は結構でそろっている

が、実際にはフレームワークを使うことになるでしょ
う。
つまり、Django待ち
参考

● Wall of Shame http://python3wos.appspot.
  com/
● PyPI Python3 Packages http://pypi.python.
  org/pypi?:action=browse&c=533&show=all
● Python Web Server Gateway Interface v1.0
● http://www.python.org/dev/peps/pep-333/
● Python Web Server Gateway Interface v1.
  0.1 http://www.python.org/dev/peps/pep-
  3333/

Python3でwebアプリ