Chapter 1: はじめに

はじめに

web2py [web2py] Vは、セキュアなデータベース駆動型のWebアプリケーションをアジャイルで開発するための、フリーでオープンなWebフレームワークです。フレームワーク自身が Python[python] で書かれており、Pythonでプログラムする事ができます。web2pyはフルスタックフレームワークです、つまり完全なWebアプリケーションの開発に必要な全てのコンポーネントを含んでいます。

web2pyは、Web開発者をソフトウェア開発の良いプラクティス、いわゆるモデル/ビュー/コントローラ(MVC)パターンに導くためのガイドとなるよう、デザインされています。web2pyは、 データの構造の表現(モデル)を、データの見せ方の表現(ビュー)やアプリケーションのロジックやワークフロー(コントローラ)から分離します。web2pyは 開発者を助けるために、それら3つの構成に対して、それぞれ、設計、実装、テストできるようなライブラリを提供し、協調して動作させることができます。

web2pyは、セキュリティを考慮して構築されています。つまり、確立された手法に沿った形で、セキュリティの脆弱性につながるような問題を解決しています。例えばこのフレームワークでは、全ての入力をバリデーションし(インジェクションを防ぐため)、全ての出力をエスケープし(クロスサイトスクリプティングを防ぐため)、アップロードしたファイル名を変更します(ディレクトリトラバーサルを防ぐため)。web2pyはアプリケーション開発者に対して、セキュリティを考慮した実装をせざるをえないようにします。

web2pyには、開発者がSQLを記述しなくてもよいようにするために、SQL[sql-w] を動的に作成するデータベース抽象化レイヤ(DAL)が含まれています。DALは、SQLite[sqlite]、MySQL[mysql]、PostgreSQL[postgres]、MSSQL[mssql]、Firebird[firebird]、Oracle[oracle]、IBM DB2[db2]、Informix[informix]、そして Ingres[ingresdb] について、それぞれのデータベースに依存しない透過的なSQLを生成することができます。さらに、Google App Engine(GAE)[gae] 上で動いている時は、Googleデータストアに対する関数呼び出しも生成することができます。実験的にはさらに多くのデータベースに対応しています。最近のアダプタの情報を知るために、web2pyのサイトやメーリングリストをチェックしてください。一旦、データベースのテーブルを定義すると、データベースとテーブルにアクセスできる十分な機能を持ったWebベースのデータベース管理インターフェースが生成されます。

web2pyは、Webはコンピュータである、というWeb2.0のパラダイムを完全に取り入れるための最適なフレームワークという点で、他のWebフレームワークとは異なります。実際、web2pyはインストールや設定は要求しません。Pythonが実行できる任意のアーキテクチャ(Windows、Windows CE、Mac OS X、iOS、Unix/Linux)で動作します。そして開発、デプロイ、メンテナンスといったアプリケーション開発の各フェーズに対して、ローカルやリモートから操作のできるWebのインターフェイスを提供しています。web2pyはCPython(Cによる実装)およびPyPy(Pythonによる実装Python)、Pythonのバージョン2.5、2.6および2.7で、動作します。

web2pyは、チケットシステムを提供しています。エラーが発生した場合、チケットが発行され、エラーが管理者用に記録されます。

web2pyはオープンソースであり、LGPL 3ライセンスの下に公開されています。

web2pyのもう1つの特徴は、将来のバージョンにおいて後方互換性を維持することを誓っていることです。web2pyは2007年10月に初めて公開されました。新機能が追加されてバグも修正されていますが、しかしweb2py 1.0で動いているプログラムは、最新版でも動きます。

さてここで、web2pyの記述の強力さとシンプルさを示す幾つかの例を示します。次のコードをみてください:

db.define_table('person', Field('name'), Field('image', 'upload'))

このコードは、"name" という文字列、"image" というアップロードが必要なもの(実際の画像)、という二つのフィールドを持つ "person" というテーブルを、データベースに作成します。テーブルがすでに存在しているが定義と一致しない場合には、適切に修正されます。

上記のテーブル定義されている場合、次のコードを見てください:

form = SQLFORM(db.person).process()

このコードは、画像もアップロードすることのできるpersonテーブル用の登録フォームを作成します。このコードはまた、送信されたフォームをバリデーションし、アップロードされた画像を安全な方法でリネームし、画像をファイルに保存し、対応するレコードをデータベースに挿入し、二重投稿を防ぎます。もし最終的に送信されたデータがバリデーションをパスしない場合には、エラーメッセージをフォームに加えます。

このコードはタグ、検索、タグクラウド、アクセス権、画像の添付、オブジェクトの埋め込みを完全にサポートしているwikiを埋め込みます:

def index(): return auth.wiki()

代わりに、次のコード:

@auth.requires_permission('read','person')
def f(): ....

このコードは、訪問者が "person" テーブルのレコードを "read" できる権限を持つグループのメンバーでない限り、関数 f へアクセスを拒否します。もし訪問者がログインをしていない場合、ログインページ(web2pyのデフォルトとして提供されている)にリダイレクトされます。

web2pyはコンポーネントをサポートしています。例えばページ全体を再読み込みしないで、Ajaxで訪問者とコンテンツのやりとりを行える、ビューをロードするアクションがあります。これは LOAD ヘルパによって実現され、よりモジュール的なデザインのアプリケーションを作ることができます。第3章でwikiについて、幾つか詳細について最終章でも説明しています。

第5版の本書はweb2py2.4.1以降のバージョンを元に書かれています。

原則

Pythonのプログラミングは、主として、以下の基本原則に従います:

  • 同じことを繰り返さない(DRY)
  • あることを実現する方法は一通りだけである
  • 暗黙的よりも明示的を良しとする

web2pyは、最初の2つの原則は十分に取り入れています。コードの重複を抑制する健全なソフトウェアエンジニアリングのプラクティスの使用を促しています。また、Webアプリケーションの開発に共通するほぼ全てのタスク(フォームの作成や操作、セッション管理、クッキー、エラーなど)について指針を示します。

request

web2pyが他のフレームワークと異なるのは、3つ目の原則に関してです。これは最初の2つの原則と時々相反する事があります。特に、web2pyはユーザーアプリケーションをインポートするのではなく、事前定義されたコンテキストの上でそれらを実行します。このコンテキストは、web2pyのキーワードだけでなく、Pythonのキーワードも公開しています。

これらの機能は魔法のように見えるかもしれませんが、そうではありません。簡単に言うと、実際には、いくつかのモジュールはすでにインポートされ、あなたは何かをする必要がありません。他のフレームワークの面倒な特性である、全てのモデルやコントローラの先頭に同じモジュールをインポートすることを強いることを避けるようにしています。

web2pyは、独自のモジュールをインポートすることにより、時間を節約し、ミスを防ぎます。このことは、"おなじ事を繰り返さない"、"あることを実現する方法は一通りだけである" という精神に基づいています。

他のPythonモジュールやサードパーティ製のモジュールを使用したい場合は、他のPythonプログラムと同様に、それらのモジュールを明示的にインポートしなければなりません。

Webフレームワーク

PHP
ASP
JSP

最も基本的なレベルでは、Webアプリケーションは、対応するURLに訪問があった時に、実行されるプログラム(または関数)のセットで構成されます。プログラムの出力は訪問者に返され、ブラウザによりレンダリングされます。

Webフレームワークの目的は、新しいアプリケーションを、迅速かつ、容易に、ミスなく構築できるようにすることです。これは、APIやツールを提供することによって行われます。それにより、必要とされるコードの量が減り、単純化されます。

Webアプリケーションの開発には2つの古典的なアプローチがあります:

  • HTML[html-w] [html-o] をプログラムで生成する
  • HTMLページにコードを埋め込む

第1のモデルは、例えば初期のCGIスクリプトが従ったモデルです。第2のモデルは、PHP[php] (コードはC言語に似たPHP)、ASP(コードはVisual Basic)、JSP(コードはJava)などです。

これは、実行時にデータベースからデータを取得し、選択したレコードを表示するHTMLページを返すPHPプログラムの例です:

<html><body><h1>Records</h1><?
  mysql_connect(localhost,username,password);
  @mysql_select_db(database) or die( "Unable to select database");
  $query="SELECT * FROM contacts";
  $result=mysql_query($query);
  mysql_close();
  $i=0;
  while ($i < mysql_numrows($result)) {
    $name=mysql_result($result,$i,"name");
    $phone=mysql_result($result,$i,"phone");
    echo "<b>$name</b><br>Phone:$phone<br /><br /><hr /><br />";
    $i++;
  }
?></body></html>

このアプローチの問題は、HTMLにコードが埋め込まれる際に非常に似たコードが、追加のHTML生成とデータベースクエリでのSQL文生成で、必要になることです。それにより、アプリケーションの複数のレイヤーが絡み合って可読性や保守性が困難になります。この状況はAjaxアプリケーションにおいて、より悪化します。さらに、アプリケーションを構成するページ(ファイル)の数とともに複雑さが増加します。

上記した例の機能は、web2pyを使うと2行のPythonコードで表現できます:

def index():
    return HTML(BODY(H1('Records'), db().select(db.contacts.ALL)))

この単純な例では、HTMLページの構造が、HTMLBODYH1 オブジェクトによってプログラム的に表現されています。データベース dbselect コマンドによって問い合わせ、最終的に全てHTMLにシリアライズされます。なお、db はキーワードではなく、ユーザー定義変数です。本書では混乱を避けるため、データベース接続を参照するために、一貫してこの名前を使用します。

Webフレームワークは典型的に2つのタイプに分類されます: 一つは、いくつかのサードパーティのコンポーネントを組み立てて(接合して)構築された "グルー(接着)" フレームワークです。もう一つは、緊密に組み合わせされて協調して動作するように特別に設計されたコンポーネントを組み合わせて構築された "フルスタック" フレームワークです。

web2pyはフルスタックフレームワークです。ほぼ全てのコンポーネントは、スクラッチで構築され一体となって動作するように設計されています。ただしそれらは、完全なweb2pyフレームワークの枠組みの外でも同様に機能します。例えば、データベース抽象化レイヤ(DAL)や言語テンプレートは、Pythonアプリケーションに gluon.dalgluon.template をインポートすることによって、web2pyフレームワークとは独立して使用することができます。gluon はweb2pyのモジュール名で、システムライブラリを含んでいます。いくつかのweb2pyのライブラリ、例えばデータベースのテーブルからフォームを構築し処理する機能などは、別のweb2pyの一部に依存しています。web2pyはまた、他のテンプレート言語やDALなどのサードパーティー製のPythonのライブラリと、共に動作させることも可能です。しかしながらそれらは、オリジナルのコンポーネントほどには緊密に連携することはないでしょう。

モデル、ビュー、コントローラ

Model-View-Controller

web2pyでは、データ表現(モデル)、データの表示(ビュー)、アプリケーションの作業手順(コントローラ)を分離することを奨励しています。web2pyのアプリケーションが、この点でどのように構築されるのか、前の例を再度考えてみましょう。web2pyのMVCを編集するインターフェイスの例です:

image

次図は、web2pyのリクエストに対する典型的な実行順序を示したものです:

image

この図で:

  • Server はweb2py内蔵のWebサーバー、もしくはApacheなどのサードパーティ製のサーバーにすることができます。Serverはマルチスレッドで処理します。
  • "main" はメインのWSGIアプリケーションです。これは全ての共通タスクを実行し、ユーザアプリケーションを制御します。クッキー、セッション、トランザクション、URLのルーティングと逆ルーティング、ディスパッチ処理を扱います。Webサーバー側でまだ処理されていない場合、静的ファイルを送信することもできます。
  • モデル、ビュー、コントローラのコンポーネントは、ユーザーアプリケーションを構成します。
  • 複数のアプリケーションは、同じweb2pyのインスタンスでホストすることができます。
  • 破線の矢印は、(単一/複数の)データベースエンジンとの通信を表しています。データベースへの問い合わせは、SQLで直接(非推奨)、もしくは、web2pyのデータベース抽象化レイヤーを利用(推奨)して記述することができます。後者の場合、web2pyのアプリケーションコードは特定のデータベースエンジンに依存しないものとなります。
  • ディスパッチャーは、リクエストされたURLをコントローラの関数呼び出しにマッピングします。関数の実行結果は、文字列もしくは複数のシンボルからなる辞書(ハッシュテーブル)として返すことができます。辞書内のデータはビューによって表示されます。HTMLページをリクエストした場合(デフォルトの挙動)、辞書はHTMLページ中でレンダリングされます。同じページをXMLとしてリクエストした場合、web2pyは辞書をXMLとして表示することができるビューを探します。開発者はすでにサポートされるプロトコル(HTML、XML、JSON、RSS、CSV、RTF)や、追加のカスタムプロトコルで、ページを表示するビューを作成することができます。
  • 全ての呼び出しはトランザクション内で操作され、キャッチされない例外が発生した場合はいつも、トランザクションがロールバックされます。リクエストが成功した場合は、トランザクションがコミットされます。
  • web2pyはまた、セッションとセッションのクッキーを自動的に処理し、トランザクションがコミットされる時に特に指定がない場合、セッションも同時に保存されます。
  • (cronによる)定期タスクを登録し、予定された時刻に、または/かつ、特定のアクションが完了した後に実行することができます。この方法により、時間のかかるタスクやコンピュータ負荷の高いタスクを、操作性を落とすことなくバックグラウンドで実行することが可能になります。

次に示すのは、最小限かつ完結したMVCアプリケーションです。3つのファイルから構成されています:

"db.py" はモデルです:

db = DAL('sqlite://storage.sqlite')
db.define_table('contact',
   Field('name'),
   Field('phone'))

ここでは、データベース(この例では storage.sqlite ファイルに保存されるSQLite)に接続し、contact というテーブルを定義しています。テーブルが存在しない場合は、web2pyが作成します。そして透過的にバックグラウンドで使用する特定のデータベースエンジンに対して、適切な方言でSQLコードを生成します。開発者は生成されたSQLを参照することができますが、バックエンドのデータベースをデフォルトのSQLiteから、MySQLや、PostgreSQL、MSSQL、Firebird、Oracle、DB2、Informix、Interbase、Ingress、さらに、Google App Engine(SQLとNoSQLのいずれも)に置き換えたとしても、コードを変更する必要はありません。

一旦、テーブルが定義され作成されると、appadmin と呼ばれるデータベースやテーブルにアクセスするために十分な機能を持つ、Webベースのデータベース管理インターフェイスが利用できます。

"default.py" はコントローラです:

def contacts():
    grid=SQLFORM.grid(db.contact, user_signature=False)
    return locals()

web2pyにおいてURLは、Pythonモジュールと関数呼び出しにマッピングされます。この例では、コントローラーが contacts という単一の関数(もしくは "アクション")を持っています。アクションは文字列(返されるWebページ)かPythonの辞書(key:value のペアのセット)、あるいはローカル変数(このサンプルのように)を返すことになります。 もし関数が辞書を返す場合は、コントローラ/関数と同じ名前のビューに渡され、結果的にページがレンダリングされます。 この例では、contacts 関数は、db.contact テーブルの select/search/create/update/delete のグリッドを作成します。そしてグリッドをビューに返します。

"default/contacts.html" はビューです:

{{extend 'layout.html'}}
<h1>Manage My Contacts</h1>
{{=grid}}

このビューは、関連するコントローラの関数(アクション)が実行された後に、web2pyによって自動的に呼び出されます。このビューの目的は、返された辞書内の変数(今回は grid)をHTMLにレンダリングすることです。ビューのファイルはHTMLで書かれますが、{{}} の特殊文字で区切られたPythonコードを埋め込みます。これは、PHPコードのサンプルとは大きく異なります。なぜなら、HTMLに埋め込まれているコードは "プレゼンテーション層" のコードだけだからです。ビューの先頭で参照されている "layout.html" ファイルは、web2pyによって提供されたもので、全てのweb2pyアプリケーションのための基本的なレイアウトを定めます。レイアウトファイルは簡単に修正したり置き換えたりすることができます。

なぜweb2pyか

web2pyは数あるWebアプリケーションフレームワークの1つですが、魅力的でユニークな特徴を持っています。 web2pyは、元々、次のような主要な目的のために教育用ツールとして開発されました。

  • サーバサイドのWeb開発を機能の妥協なしに、簡単に学ぶことができます。この理由から、web2pyはインストールと設定を必要とせず、依存性がなく(ただし、配布したソースコードはPython2.5とその標準ライブラリを必要とします)、大抵の機能はWebブラウザのインターフェースを介して利用することができます。
  • web2pyは当初から安定してます。なぜなら、トップダウンの設計に従っているからです。つまり、APIは実装前に設計されました。新しい機能が追加されても、web2pyは後方互換性を破りませんでしたし、これから機能追加しても破ることはないでしょう。
  • web2pyは最も重要なセキュリティの問題に積極的に取り組んでいます。それらは現在ある多くのWebアプリケーションを悩ませるもので、後述する OWASP[owasp] によって定められています。
  • web2pyは軽量です。コアライブラリは、データベース抽象化レイヤ、テンプレート言語、全てのヘルパーを含んで、合計1.4MBです。全てのソースコードは、サンプルアプリケーションや画像を含んでも、合計10.4MBです。
  • web2pyは必要なメモリ量が小さく、非常に高速に動作します。Timothy Farrellによって開発された Rocket[rocket] WSGI Webサーバーを使用しています。これは、mod_wsgiを利用したApacheとほぼ同等の速度で動作しSSLとIPv6をサポートします。
  • web2pyは、モデル、コントローラ、ビューを実装するためにPythonの構文を使用していますが、(他の全てのPythonのフレームワークがしているように)モデルやコントローラをインポートはしません。その代わりに、それらを実行します。これはアプリケーションのインストール、アンインストール、そして修正を、Webサーバー(本番機であっても)を再起動せず行なえることを意味します。また複数のアプリケーションのモジュールが、互いに干渉することなく共存できることも意味します。
  • web2pyは、オブジェクト・リレーショナル・マッパ(ORM)の代わりに、データベース抽象化レイヤ(DAL)を使用します。概念的には、データベースのテーブルはそれぞれ Table クラスのインスタンスにマッピングされ、異なるクラスにはマッピングされません。そしてレコードは Row クラスのインスタンスにマッピングされ、対応するテーブルクラスのインスタンスにはマッピングされません。実用性からみると、これはSQLの構文がDALの構文にほぼ1対1に対応することを意味します。そして、仕組みを隠蔽化する一般的なORMを使う時のような、メタクラスを使ったプログラミングの複雑さはありません。

WSGI [wsgi-w] [wsgi-o] (Web Server Gateway Interface)は、WebサーバーとPythonアプリケーション間の通信のための新たなPythonの標準です。

これは、メインとなるweb2pyの admin インターフェースのスクリーンショットです:

image

セキュリティ

security

The Open Web Application Security Project [owasp] (OWASP)は、アプリケーションソフトウェアのセキュリティを向上させることに焦点を置いた、自由で開かれた世界的なコミュニティです。

OWASPでは、Webアプリケーションのリスクとなるセキュリティ問題のトップ10を挙げています。ここではこのリストを、web2pyがどのようにこれらの問題を解決しているかという説明とともに、再掲します:

  • cross site scripting
    "クロスサイト・スクリプティング(Cross Site Scripting, XSS): アプリケーションがユーザからデータを受信して、そのデータに対してバリデーションやエンコードを行わずにブラウザに送信した時に、常にXSSの脆弱性が発生します。XSSは、セッションのハイジャック、Webサイトの改ざん、ワーム侵入の許可を可能にするなど、被害を受けるブラウザで動作するスクリプトを、攻撃者に対して実行可能にします。" web2pyはデフォルトで、ビューに表示される全ての変数をエスケープすることでXSSを防ぎます。
  • injection flaws
    "インジェクション・フロー(Injection Flaws): インジェクション・フロー、特にSQLインジェクションは、Webアプリケーションで一般的なものです。インジェクションは、ユーザーが入力したデータがコマンドまたはクエリの一部としてインタプリタに送信される時に発生します。攻撃者の不正なデータはインタプリタに対して意図しないコマンドを実行したり、データを変更します。" web2pyには、データベース抽象化レイヤが含まれており、それがSQLインジェクションを防ぎます。開発者によりSQL文は、通常書かれません。代わりにSQLはDALによって動的に生成され、全ての挿入データが適切にエスケープされるようにします。
  • malicious file execution
    "悪意のあるファイルの実行: 脆弱なコードによるリモートファイルのインクルード(Remote File Inclusion, RFI)は、悪意のあるコードやデータを持ち込ませることを許し、サーバー全体を危険にさらすような破壊的な攻撃につながります。" web2pyは公開するコードのみ実行を許可し、悪意のあるファイルの実行を防止します。インポートされた関数は決して公開されません。つまり、アクションのみが公開されます。Webベースの管理インターフェースを用いると、何が公開されているのか、いないのかを把握するのが容易になります。
  • insecure object reference
    "安全でないダイレクト・オブジェクト参照: ダイレク・トオブジェクト参照とは、開発者が内部実装のオブジェクト、例えば、ファイル、ディレクトリ、データベースのレコード、キーなどへの参照を、URLやフォームのパラメータとして公開したときに起こるものです。攻撃者は、認証なしに他のオブジェクトにアクセスし、それらの参照を操作できます。" web2pyはいかなる内部オブジェクトも公開しません。さらに、全てのURLを検証し、ディレクトリ走査の攻撃を防ぎます。web2pyはまた、全ての入力値を自動的にバリデーションする、フォームを作成するメカニズムを提供します。
  • CSRF
    "クロスサイト・リクエスト・フォージェリ(Cross Site Request Forgery, CSRF): CSRF攻撃は、被害を受けるログオンしたブラウザに、脆弱なWebアプリケーションへの事前認証リクエストを送信します。これにより、被害を受けるブラウザは、攻撃者の利益となる悪意のある行為を実行させられます。CSRFは、攻撃を行うWebアプリケーションと同じくらい強力です。" web2pyはCSRFと共に、偶発によるフォームの二重投稿も防ぎます。これは、一度きりのランダムトークンを各フォームに対して割り当てることで実現しています。さらに、web2pyはUUIDをセッションCookieとして使用します。
  • information leakage
    improper error handling
    "情報漏洩と不適切なエラー処理: アプリケーションは、設定や内部資料などの情報を意図せず漏洩したり、さまざまなアプリケーションの問題によりプライバシーの侵害を起こす恐れがあります。攻撃者はこの弱点を利用して機密データを盗み、より深刻な攻撃を実施します。" web2pyはチケットシステムを持っています。どんなエラーでも、コードがユーザーにさらされることはありません。全てのエラーはログに記録され、エラーの追跡を可能するためのチケットがユーザーに発行されます。けれども、エラーとソースコードは管理者のみがアクセスを許されます。
  • "不適切な認証やセッション管理: アカウントの認証情報やセッションのトークンは、しばしば適切に保護されません。攻撃者はパスワード、キー、認証トークンなどを侵害し、他のユーザーに成りすまします。" web2pyでは、管理者認証のための組み込み機構を提供します。そこでは、アプリケーション毎にセッションが独立に管理されます。管理インターフェイスは、"localhost" からではないクライアントからの接続には、セキュアなセッションクッキーの使用を強制します。アプリケーションに対しては、強力なロールベースのアクセスコントロールAPIを用意しています。
  • cryptographic store
    "安全でない暗号保存: Webアプリケーションにおいて、データや認証情報を保護するための暗号化関数を適切に利用しているものはほとんどありません。攻撃者は、弱く保護されたデータから、身元情報の盗難や、クレジットカード詐欺などのその他犯罪を行います。" web2pyでは、保存したパスワードを保護するために、MD5やHMAC+SHA-512のハッシュアルゴリズムを使用しています。他のアルゴリズムも利用可能です。
  • secure communications
    "安全でない通信: アプリケーションは、機密扱いの通信を保護することが必要な時、ネットワークトラフィックの暗号化にしばしば失敗することがあります。" web2pyは、SSL[ssl] が有効なRocket WSGI サーバーを用意していますが、SSLの暗号化通信を提供するApacheやLigthttpdとmod_sslを用いることもできます。
  • access restriction
    "URLアクセス制限の失敗: よく見かけるのは、重要な機能を非認証ユーザーに対して、リンクやURLの表示を防ぐだけで保護しているものです。攻撃者はこの弱点を利用することができ、URLを直接叩くことで、認証されていない操作にアクセスし実行します。" web2pyはURLリクエストをPythonのモジュールと関数へ対応付けします。そして、どの関数が公開され、どれが認証や権限が必要かを宣言するメカニズムを用意しています。組み込みのロールベース・アクセスコントロールAPIは、任意の関数へのアクセスを、ログインやグループメンバーシップ、グループベースの権限に基づいて制限することを可能にします。その権限は、とても細かい粒度で行われ、そして許可をデータベースフィルタと組み合わせて使用することができます。例えば、特定のテーブル、かつ/または、レコードへのアクセス権限を与えることができます。web2pyは、デジタル署名されたURLを可能にし、Ajaxコールバックにデジタル署名するためのAPIを提供します。

web2pyはセキュリティに対するレビューを受けています。その評価は参照 [pythonsecurity] で参照することができます。

内部構造

web2pyは公式サイトからダウンロードすることができます:

http://www.web2py.com

web2pyは、以下のコンポーネントで構成されています:

  • ライブラリ: web2pyのコア機能を提供し、プログラムからアクセスできます。
  • Webサーバー: Rocket WSGI Webサーバー。
  • adminアプリケーション: 他のweb2pyアプリケーションを作成、設計、管理するために利用します。admin はweb2pyアプリケーションを構築するための、完結的なWebベースの統合開発環境(IDE)を提供します。また、WebベースのテストやWebベースのシェルなどの他の機能も用意されています。
  • examples アプリケーション: ドキュメントとインタラクティブなサンプルがあります。examples はweb2py.comの公式サイトの複製でepydocを含んでいます。
  • welcome アプリケーション: その他全てのアプリケーションのための、基本的なひな形となるテンプレートです。デフォルトで、純粋なCSSによるカスケードメニューとユーザー認証(第9章で解説)が含まれます。

web2pyはソースコード版のほか、Microsoft Windows用や、Mac OS X用のバイナリ形式で公開されています。

配布されたソースコードは、Pythonが動くプラットフォームならどこでも利用可能で、また、上記のコンポーネントを含んでいます。ソースコードを実行するには、Python2.5、2.6または2.7があらかじめシステムにインストールされている必要があります。また、サポートされているデータベースエンジンがインストールされている必要があります。テスト目的や軽めの要望のアプリケーションには、Python 2.7に含まれているSQLiteデータベースを使用するのもいいでしょう。

バイナリ版のweb2py(Windows用およびMac OS X 用)には、Python 2.7インタプリタとSQLiteデータベースが含まれます。技術的には、これら2つはweb2pyのコンポーネントではありません。これらをバイナリ配布に含めることで、web2pyを難しい設定などなしに、すぐに実行することが可能になります。

次の図は、全体的なweb2pyの構造を描いたものです:

image

一番下にPythonインタプリタがあり、その上にwebサーバー(rocket)、ライブラリ、アプリケーションと続きます。それぞれのアプリケーションは独自のMVC設計(モデル、コントローラ、ビュー、モジュール、言語、データベース、静的ファイル)からできています。また独自のデータベース管理コード(appadmin)を持ちます。全てのweb2pyインスタンスは、welcome(アプリのひな形)、admin(webベースのIDE)、examples(公式サイトの複製とサンプル)を含みます。

本書について

この本はこの序章に加えて、次の章から成ります。

  • 第2章はPythonの最小限の入門です。ここでは、手続き型とオブジェクト指向プログラミングの両方のコンセプト、例えば、ループや条件、関数呼び出しやクラスといった知識を前提に、基本的なPythonの構文を説明します。また、本書を通じて使用されるPythonモジュールの例を説明します。Pythonについてすでに知っている場合は、第2章は飛ばしてもかまいません。
  • 第3章では、web2pyを開始する方法を示し、管理インターフェースについて説明し、少しずつ複雑にしていきながら、さまざまな例を通して読者を案内します。文字列を返すアプリケーションから、数を数えるアプリケーション、画像付きブログ、そして、画像アップロードやコメントを可能にし、認証、権限、Webサービス、RSSフィードを提供する本格的なwikiアプリケーションまで例示します。この章を読む時は、一般的なPythonの構文については第2章を、利用されている機能のより詳細なレファレンスは後続の章を参照する必要があるかもしれません。
  • 第4章では、より体系的に中核となる構造とライブラリについて説明します。URLのマッピング、リクエスト、レスポンス、セッション、キャッシュ、クーロン、国際化、一般的なワークフローについて説明します。
  • 第5章は、ビューを構築するために用いられるテンプレート言語のレファレンスです。ここでは、PythonコードをどのようにHTMLに埋め込むのか、またヘルパー(HTMLを生成できるオブジェクト)を使用したデモを紹介します。
  • 第6章では、データベース抽象化レイヤ、すなわちDALを説明します。 DALの構文は、一連の例によって示されます。
  • 第7章では、フォーム、フォームの検証、フォームの処理について説明します。FORMは、フォームを構築するための低レベルのヘルパーです。SQLFORMは、高レベルのフォームビルダーです。第7章ではまた、Create/Read/Update/Delete (CRUD) APIについて論じます。
  • 第8章では、emailやSMSを用いた送受信によるコミュニケーションを扱います。
  • 第9章では、web2pで使用可能な、認証、権限、拡張可能なロールベースのアクセス制御機構を扱います。メールの設定やCAPTCHAについても、認証でよく使われるので、ここで議論します。本の第3版では、サードパーティー製の認証機構、例えば、OpenID、OAuth、Google、Facebook、LinkedInなどとの統合に関する広範囲な説明も加えました。
  • 第10章は、web2pyにおいてWebサービスを作成する方法についてです。Google Web ToolkitをPyjamasから使う例や、Adobe FlashをPyAMFから使う例を示します。
  • 第11章は、web2pyとjQueryのレシピについてです。web2pyは、主にサーバサイドのプログラミングとして設計されていますが、jQueryを内包しています。なぜならそれが、エフェクトやAjaxのために利用可能なベストなオープンソースのJavaScriptライブラリだと分かったからです。この章では、web2pyとともにjQueryを効果的に使用する方法を説明します。
  • 第12章では、モジュール化されたアプリケーションを作成する方法として、web2pyのコンポーネントやプラグインを説明します。ここではよく使われる機能として、チャート、コメント、タグ、そしてwikiなどを実装したプラグインのサンプルを提供します。
  • 第13章は、web2pyアプリケーションの本番デプロイについてです。 主に3つの可能性のある本番シナリオに取り組みます: LinuxのWebサーバーまたはサーバセットにデプロイし(主要となるデプロイの選択肢であると思います)、Microsoft Windows環境上にサービスとして動かし、Google Applications Engine(訳注:GAE)上にデプロイします。この章ではまた、セキュリティやスケーラビリティの問題について論じます。
  • 第14章は、特定のタスクを解決するさまざまなレシピを掲載します。アップグレードや、ジオコーディング、ページ処理、Twitter APIなどです。

この本では、web2pyの基本的機能とweb2pyとともに公開されるAPIしかカバーしません。 web2pyのアプライアンス(すなわち、既製アプリケーション)については説明しません。

web2pyのアプライアンスは、対応するWebサイト [appliances] からダウンロードできます。

追加トピックに関しては、ユーザーグループ[usergroup] や古いweb2pyブログとFAQの AlterEgo[alterego] で議論されています。

MARKMIN
この本はmarkminを使用して書かれていて、自動的にHTMLやLaTeX、PDFに変換されます。

サポート

主要なサポートの場所は ユーザーグループ[usergroup] です。毎日何十もの投稿がされています。誰もが優しく教えてくれるので初めての人でも気軽に質問してください。正式な問題管理システムには https://github.com/web2py/web2py/issues からアクセスできます。最後になりますが有料のサポートも受けることができます(詳細は公式サイトを参照してください)。

貢献

どのようなヘルプでも歓迎です。ユーザーグループで他の仲間を助けたり、プログラムの修整パッチを投稿(GitHubサイト: https://github.com/web2py/web2py)したりしてみてください。本書に誤植があった場合や追加内容があった場合には本自体に修整パッチを適用することもできます(ソースフォルダのレポジトリ:https://github.com/mdipierro/web2py-book)。

要素のスタイル

PEP8[style] は、Pythonでプログラミングをする時の良いスタイルのプラクティスが含まれています。web2pyはこれらのプラクティスに全て従ってるわけではないことに気づくでしょう。これは省略や手抜きのためではありません。web2pの利用者はこれらのルールに従うべきであると信じていますし、それを奨励していますが、我々は、これらのルールの内いくつかに従わないことを選択しました。それはweb2pyのヘルパーオブジェクトがユーザー定義オブジェクトに対して名前競合を起こす確率を最小限にしようとして定義されたからです。

例えば、<div> を表現するクラスは DIV ですが、Pythonのスタイルレファレンスによれば、Div とするべきです。我々は、この特定の例については、全て大文字の "DIV" を使用するほうがより自然な選択だと考えています。さらに、このアプローチでは、必要とあればプログラマーが "Div" クラスを自由に作ることができます。これらの構文はほとんどのブラウザのDOM表記法に自然にマッピングされます(例えばFirefoxなどを含みます)。

Pythonのスタイルガイドによると、全て大文字の文字列は、変数ではなく定数として使用するべきとあります。先の例を続けると、DIV がクラスであることを考慮しても、それは二度と修正されるべきない特別なクラスになります。そうでないと、他のweb2pyアプリケーションが動かなくなるからです。このことから DIV クラスは定数のように扱われるべきものとして適格であり、我々はこの表記の選択が正当化されると信じています。

要約すると、次のような慣例に従います:

  • HTMLヘルパーとバリデータは、上記の議論の通り全て大文字です(例えば、DIV, A, FORM, URL)。
  • 翻訳オブジェクトの T は、クラス自身ではなくクラスのインスタンスであるという事実にもかかわらず、大文字で表されます。論理的に、翻訳オブジェクトは、HTMLヘルパーと似た動作を行い、プレゼンテーションの一部の表示に影響します。また、T はコード内で確認しやすい必要があり、短かい名前を持つ必要があります。
  • DALのクラスは、Pythonのスタイルガイド(先頭文字を大文字にする)に従います。例えば、TableFieldQueryRowRows などがあります。

他の全てのケースでは、我々は、可能な限りPythonのスタイルガイド(PEP8)に従ってきたと信じています。 例えば、全てのインスタンスオブジェクトは小文字(request、response、session、cache)であり、全ての内部クラスは大文字で始まっています。

この本の全ての例において、web2pyのキーワードは太字で、文字列やコメントはイタリック体で記載されています。

ライセンス

license

web2pyはLGPLのバージョン3でライセンスされています。ライセンスの全文は、参照 [lgpl3] に用意されています。

(訳注:この節に関しては、原文をリンクしておきます。)

LGPLに従うならば、あなたは次の項目に当てはまる場合に:

  • あなたのアプリケーションと共に、web2py(公式のweb2pyのバイナリバージョン含む)を再配布する場合
  • 公式のweb2pyライブラリを使うアプリケーションをあなたの望む任意のライセンスで公開する場合

次の項目に従う必要があります:

  • あなたのアプリケーションがweb2pyを使っていることを明確に文書化する
  • LGPL v3ライセンスで、web2pyライブラリの修正個所を公開する

ライセンスには、通常の免責条項が含まれています。 (訳注:訳は http://sourceforge.jp/magazine/07/09/02/130237 より引用)

『プログラム』には、適用可能な法で許可されている範囲において何の保証もない。書面で述べられていない限り、『コピーライト』保有者やその他の当事者は『プログラム』を「あるがまま(as is)」で、明示的、暗示的を問わず、いかなる種類の保証もなく提供する。この保証には、商用可能性や特定 目的への適合性の暗黙的保証が含まれるが、これらに限定されない。『プログラム』の質や性能に関するリスクは全てあなたに帰属する。『プログラム』に問題があると判明した場合、あなたは必要な全ての対応、補修、修正にかかる費用を負うものとする。

適用可能な法において義務づけられるか、書面による同意がない限り、『コピーライト』保有者あるいはその他『プログラム』を上記で許可された通りに改変あるいは伝達する当事者は、例えそうした保有者や他の当事者が損害が発生する可能性について事前に通知されていたとしても、あなたに対して 損害賠償責任を有することはない。ここでいう損害には、『プログラム』の利用あるいは利用できないことから発生した一般的、特殊的、偶然的、必然的な 損害の全てが含まれる(データの消失やデータの不正確な解釈、あなたや第三者によって被った、あるいは『プログラム』が他のプログラムといっしょにうまく動作しなかったために引き起こされた損害などが含まれるが、これらに限定されない)。

過去のバージョン

過去のバージョンのweb2py(1.0.*~1.90.*)は、GPL2ライセンスに加えて、現在のLGPLv3によく似た、実用的な目的のための、例外的な商用ライセンスで公開されていました。

web2pyとともに配布されるサードパーティー製のソフトウェア

フォルダに含まれるさまざまなJavaScript、CSSファイルなどのサードパーティー製のソフトウェアが含まれています。 これらのファイルは、それらのファイルに記載されているように、それらのオリジナルなライセンスの下でweb2pyと一緒に配布されています。

謝辞

web2pyは、Massimo Di Pierroによって元々作成され、著作権が取得されています。最初のバージョン(1.0)は2007年10月にリリースされました。それ以来多くのユーザーに受け入れられ、その中の幾人かは、バグレポート、テスト、デバッグ、パッチやこの本の校正に貢献してきました。

主な貢献者を、アルファベット順で紹介します:

Adam Bryzak, Adam Gojdas, Adrian Klaver, Alain Boulch, Alan Etkin, Alec Taylor, Alexandre Andrade, Alexey Nezhdanov, Alvaro Justen, Anand Vaidya, Anatoly Belyakov, Ander Arbelaiz, Anders Roos, Andrew Replogle, Andrew Willimott, Angelo Compagnucci, Angelo and Villas, Annet Vermeer, Anthony Bastardi, Anton Muecki, Antonio Ramos, Arun Rajeevan, Attila Csipa, Ben Goosman, Ben Reinhart, Benjamin, Bernd Rothert, Bill Ferret, Blomqvist, Boris Manojlovic, Branko Vukelic, Brent Zeiben, Brian Cottingham, Brian Harrison, Brian Meredyk, Bruno Rocha, CJ Lazell, Caleb Hattingh, Carlos Galindo, Carlos Hanson, Carsten Haese, Cedric Meyer, Charles Law, Charles Winebrinner, Chris Clark, Chris May, Chris Sanders, Christian Foster Howes, Christopher Smiga, Christopher Steel, Clavin Sim, Cliff Kachinske, Corne Dickens, Craig Younkins, Dan McGee, Dan Ragubba, Dane Wright, Danny Morgan, Daniel Gonz, Daniel Haag, Daniel Lin, Dave Stoll, David Adley, David Harrison, David Lin, David Marko, David Wagner, Denes Lengyel, Diaz Luis, Dirk Krause, Dominic Koenig, Doug Warren, Douglas Philips, Douglas Soares de Andrade, Douglas and Alan, Dustin Bensing, Elcio Ferreira, Eric Vicenti, Erwin Olario, Falko Krause, Farsheed Ashouri, Felipe Meirelles, Flavien Scheurer, Fran Boon, Francisco Gama, Fred Yanowski, Friedrich Weber, Gabriele Alberti, Gergely Kontra, Gergely Peli, Gerley Kontra, Gilson Filho, Glenn Caltech, Graham Dumpleton, Gregory Benjamin, Gustavo Di Pietro, Gyuris Szabolcs, Hamdy Abdel-Badeea, Hans C. v. Stockhausen, Hans Donner, Hans Murx, Huaiyu Wang, Ian Reinhart Geiser, Iceberg, Igor Gassko, Ismael Serratos, Jan Beilicke, Jay Kelkar, Jeff Bauer, Jesus Matrinez, Jim Karsten, Joachim Breitsprecher, Joakim Eriksson, Joe Barnhart, Joel Carrier, Joel Samuelsson, John Heenan, Jon Romero, Jonas Rundberg, Jonathan Benn, Jonathan Lundell, Jose Jachuf, Joseph Piron, Josh Goldfoot, Josh Jaques, Jose Vicente de Sousa, Jurgis Pralgauskis, Keith Yang, Kenji Hosoda, Kenneth Lundstr, Kirill Spitsin, Kyle Smith, Larry Weinberg, Limodou, Loren McGinnis, Louis DaPrato, Luca De Alfaro, Luca Zachetti, Lucas D'Avila, Madhukar R Pai, Manuele Presenti, Marc Abramowitz, Marcel Hellkamp, Marcel Leuthi, Marcello Della Longa, Margaret Greaney, Maria Mitica, Mariano Reingart, Marin Prajic, Marin Pranji, Marius van Niekerk, Mark Kirkwood, Mark Larsen, Mark Moore, Markus Gritsch, Mart Senecal, Martin Hufsky, Martin Mulone, Martin Weissenboeck, Mateusz Banach, Mathew Grabau, Mathieu Clabaut, Matt Doiron, Matthew Norris, Michael Fig, Michael Herman, Michael Howden, Michael Jursa, Michael Toomim, Michael Willis, Michele Comitini, Miguel Goncalves, Miguel Lopez, Mike Amy, Mike Dickun, Mike Ellis, Mike Pechkin, Milan Melena, Muhammet Aydin, Napoleon Moreno, Nathan Freeze, Niall Sweeny, Niccolo Polo, Nick Groenke, Nick Vargish, Nico de Groot, Nico Zanferrari, Nicolas Bruxer, Nik Klever, Olaf Ferger, Oliver Dain, Olivier Roch Vilato, Omi Chiba, Ondrej Such, Ont Rif, Oscar Benjamin, Osman Masood, Ovidio Marinho Falcao Neto, Pai, Panos Jee, Paolo Betti, Paolo Caruccio, Paolo Gasparello, Paolo Valleri, Patrick Breitenbach, Pearu Peterson, Peli Gergely, Pete Hunt, Peter Kirchner, Phyo Arkar Lwin, Pierre Thibault, Pieter Muller, Piotr Banasziewicz, Ramjee Ganti, Richard Gordon, Richard Ree, Robert Kooij, Robert Valentak, Roberto Perdomo, Robin Bhattacharyya, Roman Bataev, Ron McOuat, Ross Peoples, Ruijun Luo, Running Calm, Ryan Seto, Salomon Derossi, Sam Sheftel, Scott Roberts, Sebastian Ortiz, Sergey Podlesnyi, Sharriff Aina, Simone Bizzotto, Sriram Durbha, Sterling Hankins, Stuart Rackham, Telman Yusupov, Thadeus Burgess, Thomas Dallagnese, Tim Farrell, Tim Michelsen, Tim Richardson, Timothy Farrell, Tito Garrido, Tyrone Hattingh, Vasile Ermicioi, Vidul Nikolaev Petrov, Vidul Petrov, Vinicius Assef, Vladimir Donnikov, Vladyslav Kozlovsky, Vladyslav Kozlovskyy, Wang Huaiyu, Wen Gong, Wes James, Will Stevens, Yair Eshel, Yarko Tymciurak, Yoshiyuki Nakamura, Younghyun Jo, Zahariash.

載せ忘れている貢献者方がいると思いますので、それについては謝罪します。

私は特に、Anthony, Jonathan, Mariano, Bruno, Vladyslav, Martin, Nathan, Simone, Thadeus, Tim, Iceberg, Denes, Hans, Christian, Fran そして Patrick といったweb2pyの主だった貢献者、 Anthony, Alvaro, Brian, Bruno, Denes, Dane Denny, Erwin, Felipe, Graham, Jonathan, Hans, Kyle, Mark, Margaret, Michele, Nico, Richard, Roberto, Robin, Roman, Scott, Shane, Sharriff, Sriram, Sterling, Stuart, Thadeus, Wen、そしてその他の多くの方々が、この本のさまざまなバージョンを校正してくれたことに感謝します。彼らの貢献は非常に貴重でした。この本の中にある全ての間違いについては、その責任は全て私にあります。おそらく最後の編集によって混入されたのでしょう。また、この本の初版の発行を助けてくれた、Wiley Custom Learning Solutions の Ryan Steffen に感謝します。

web2pyは次の作者によるコードを含んでいます。彼らに感謝します:

Guido van Rossum for Python[python], Peter Hunt, Richard Gordon, Timothy Farrell for the Rocket[rocket] web server, Christopher Dolivet for EditArea[editarea], Bob Ippolito for simplejson[simplejson], Simon Cusack and Grant Edwards for pyRTF[pyrtf], Dalke Scientific Software for pyRSS2Gen[pyrss2gen], Mark Pilgrim for feedparser[feedparser], Trent Mick for markdown2[markdown2], Allan Saddi for fcgi.py, Evan Martin for the Python memcache module[memcache], John Resig for jQuery[jquery].

Helmut Epp(DePaul Universityの学長)、David Miller(the College of Computing and Digital Media of DePaul Universityの学部長)、Estia Eichten(MetaCryption LLCの会員)、彼らの継続的な信頼と支持に感謝します。

最後に、私が多くの時間をweb2pyの開発、ユーザーや協力者とのメールの交換、そしてこの本の執筆に費やしていることに忍耐強く我慢してくれている、妻のClaudiaと息子のMarcoに感謝しています。この本は彼らに捧げます。

第3版 - 翻訳: 中垣健志 レビュー: Omi Chiba
第4版 - 翻訳: 中垣健志 レビュー: Mitsuhiro Tsuda
第5版 - 翻訳: Omi Chiba レビュー: Hitoshi Kato
 top