python webフレームワーク-初認識tornado

31442 ワード

Tornadoの概要
TornadoはFriendFeedが使用する拡張可能な非ブロックWebフレームワークとその関連ツールのオープンソースバージョンです.このWebフレームワークはwebのように見えます.pyまたはGoogleのwebappですが、非ブロックサーバ環境を有効に利用するために、このWebフレームワークにはいくつかの関連する有用なツールと最適化が含まれています.Tornadoと現在の主流のWebサーバフレームワーク(ほとんどのPythonのフレームワークを含む)には明らかな違いがあります.非ブロックサーバフレームワークであり、速度がかなり速いです.その非ブロック方式とepollの運用のため、Tornadoは毎秒数千の接続を処理することができ、これはリアルタイムのWebサービスにとってTornadoが理想的なWebフレームワークであることを意味する.このWebフレームワークを開発する主な目的は、FriendFeedのリアルタイム機能を処理することです.FriendFeedのアプリケーションでは、アクティブなユーザー一人一人がサーバ接続を維持しています(数千人のクライアントの接続を処理する方法については、C 10 Kの問題を参照してください).同時にTornadoは軽量級のWebフレームワークであり、主に性能の問題を解決しています.開発者が関連コンポーネントを柔軟に拡張できるようにします.
C 10 Kの問題は、Apacheのようなスレッドベースのサーバが、アクセス接続のためにオペレーティングシステムのスレッドプールを維持していることです.Apacheは、HTTP接続ごとにスレッドプール内のスレッドを割り当て、すべてのスレッドが占有され、メモリが使用可能である場合、新しいスレッドを生成します.OSによって設定が異なりますが、ほとんどのLinuxリリースではデフォルトのスレッドスタックサイズが8 MBです.Apacheのアーキテクチャは、大きな負荷で予測不可能になり、開いている接続ごとに大きなスレッドプールの待機データを維持することで、サーバのメモリリソースを迅速に消費しやすくなります.ほとんどのソーシャルネットワークアプリケーションでは、新しいメッセージ、ステータスの変化、およびユーザーの通知を通知するためのリアルタイム更新が表示されます.これにより、クライアントはサーバ側の応答を待つために開いた接続を維持する必要があります.これらの長い接続またはプッシュ要求は、Apacheの最大スレッドプールを急速に飽和させる.スレッドプールのリソースが消費されると、サーバは新しいリクエストに応答できません.このシーンでの非同期サーバの応用は比較的新しいが、スレッドベースのサーバの制限を軽減するために設計されている.負荷が増加すると、例えばNode.js,lighttpd,Tornodoのようなサーバは,コラボレーションしたマルチタスクを用いて優雅な拡張を行う.すなわち、現在の要求が他のリソースからのデータ(例えば、データベースクエリまたはHTTP要求)を待っている場合、非同期サーバは、要求を保留するように明確に制御することができる.非同期サーバが一時停止した操作を復元する一般的なモードの1つは、適切なデータが準備されているときにコールバック関数を呼び出すことです.
二Tornado使用入門
1インストール
pipインストールpip install tornadoソースコードインストールhttps://pypi.python.org/packages/source/t/tornado/tornado-4.3.tar.gz    python setup.py install
2 Tornado実行フロー
#!/usr/bin/env python
# -*- coding:utf-8 -*-
  
import tornado.ioloop
import tornado.web

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("Hello, world")
  
application = tornado.web.Application([
    (r"/index", MainHandler),
])
  
if __name__ == "__main__":
    application.listen(8888)
    tornado.ioloop.IOLoop.instance().start()

ステップ1:スクリプトを実行し、8888ポートをリスニングします.ステップ2:ブラウザクライアントアクセス/index-->http://127.0.0.1:8888/index;ステップ3:サーバは要求を受け入れ、対応するクラスにこの要求を処理する.ステップ4:クラスがリクエストを受信した後、リクエスト方式(post/get/delete...)に従っての異なる呼び出しを実行し、対応するメソッドを実行します.ステップ5:対応メソッドが返す文字列の内容をブラウザに送信します.
3ルーティングシステム
Tornadoでは,ルーティングシステムはurlとクラスの対応関係であるが,他のwebフレームワークではurlと関数の対応関係が多い.
#!/usr/bin/env python
# -*- coding:utf-8 -*-
  
import tornado.ioloop
import tornado.web
  
class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("Hello, world")
  
class StoryHandler(tornado.web.RequestHandler):
    def get(self, story_id):
        self.write("You requested the story " + story_id)
  
class BuyHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("buy.wupeiqi.com/index")
  
application = tornado.web.Application([
    (r"/index", MainHandler),
    (r"/story/([0-9]+)", StoryHandler),
])
  
application.add_handlers('buy.wupeiqi.com$', [
    (r'/index',BuyHandler),
])
  
if __name__ == "__main__":
    application.listen(80)
    tornado.ioloop.IOLoop.instance().start()

4テンプレート
Tornadoのテンプレート言語はdjangoと同様で、テンプレートエンジンはまずテンプレートファイルをメモリにロードし、その後テンプレートファイルとデータを混合し、最終的に完全な文字列を取得し、最後に要求者に文字列を返します.Tornadoのテンプレート言語では、{%if len(items)>2%}などの{%if len(items)>2%}を使用してパッケージされた制御文と表現文がサポートされています.表現文は{xx}}で囲まれています.例えば{items[0]}}です.制御文と対応するPython文のフォーマットはほぼ同じです.if、for、while、tryをサポートします.これらの文の論理が終了する場所は{%end%}でマークする必要があります.テンプレートの継承はextends文とblock文によっても実現されます.これらはtemplateモジュールのコードドキュメントに詳細に説明されています.
tornadoプログラムプライマリファイル
#!/usr/bin/env python
# -*- coding:utf-8 -*-

import tornado.ioloop
import tornado.web

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.render('index.html')

settings = {
    'template_path': 'template',
    'static_path': 'static',
    'static_url_prefix': '/static/',
}

application = tornado.web.Application([
    (r"/index", MainHandler),
], **settings)


if __name__ == "__main__":
    application.listen(8888)
    tornado.ioloop.IOLoop.instance().start()

    layout.htmlファイル(マザーボード)
DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Testtitle>
    {% block css%}

    {% end %}
head>
<body> <div><h1>TESTh1>div> {% block htmlbody %}{% end %} <script src="{{static_url('js/jquery-1.8.2.min.js')}}">script> {% block JavaScript %}{% end %} body> html>

   index.htmlファイル(サブボード)
{% extends 'layout.html' %}

{% block css %}
    <link href="{{static_url('css/index.css')}}" rel="stylesheet" />
{% end %}

{% block htmlbody %}
    <h1 id="test_id" class="tim">Tornado  .h1>
{% end %}

{% block JavaScript %}

{% end %}

テンプレート内のforループの構文
{% extends 'layout.html'%}
{% block CSS %}
    <link href="{{static_url("css/index.css")}}" rel="stylesheet" />
{% end %}

{% block RenderBody %}
    <h1>Indexh1>

    <ul>
    {%  for item in li %}
        <li>{{ item }}li>
    {% end %}
    ul>

{% end %}

{% block JavaScript %}
    
{% end %}

テンプレートのデフォルトでは、テンプレートで使用する関数、フィールド、クラスがいくつか用意されています.escape:tornado.escape.xhtml_escapeの別名xhtml_escape: tornado.escape.xhtml_escapeの別名url_escape: tornado.escape.url_escapeの別名json_encode: tornado.escape.json_encodeの別名squeeze:tornado.escape.squeezeの別名linkify:tornado.escape.linkifyの別名datetime:Pythonのdatetimeモジュールhandler:現在のRequestHandlerオブジェクトrequest:handler.requestの別名current_user: handler.current_userの別名locale:handler.localeの別名_:handler.locale.translateの別名static_url: for handler.static_urlの別名xsrf_form_html: handler.xsrf_form_htmlの別名
Tornadoがデフォルトで提供しているこれらの機能は本質的にUImethodとUImoduleであり、Djangoのようなsimple_を実現するためにカスタマイズすることもできます.tagの機能:(1)定義
# uimethods.py 
def tab(self):
    return 'UIMethod'
#uimodule.py

#!/usr/bin/env python
# -*- coding:utf-8 -*-
from tornado.web import UIModule
from tornado import escape

class custom(UIModule):
    def render(self, *args, **kwargs):
        return escape.xhtml_escape('

wupeiqi

')

(2)登録
#!/usr/bin/env python
# -*- coding:utf-8 -*-

import tornado.ioloop
import tornado.web
from tornado.escape import linkify
import uimodules as md
import uimethods as mt

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.render('index.html')

settings = {
    'template_path': 'template',
    'static_path': 'static',
    'static_url_prefix': '/static/',
    'ui_methods': mt,
    'ui_modules': md,
}

application = tornado.web.Application([
    (r"/index", MainHandler),
], **settings)


if __name__ == "__main__":
    application.listen(8009)
    tornado.ioloop.IOLoop.instance().start()

(3)使用
DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>title>
    <link href="{{static_url("commons.css")}}" rel="stylesheet" />
head>
<body>
    <h1>helloh1>
    {% module custom(123) %}
    {{ tab() }}
body>

5実用機能
(1)静的ファイル
#!/usr/bin/env python
# -*- coding:utf-8 -*-

import tornado.ioloop
import tornado.web

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.render('index.html')

settings = {
    'template_path': 'template',
    'static_path': 'static',
    'static_url_prefix': '/static/',
}

application = tornado.web.Application([
    (r"/index", MainHandler),
], **settings)

if __name__ == "__main__":
    application.listen(8888)
    tornado.ioloop.IOLoop.instance().start()

静的ファイルの場合、静的ファイルのディレクトリと前段の使用時の接頭辞を構成できます.また、Tornaodoでは静的ファイルキャッシュもサポートされます.
DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>title>
    <link href="{{static_url("commons.css")}}" rel="stylesheet" />
head>
<body>
    <h1>helloh1>
body>
html>

静的ファイルの構成:
静的ファイルの構成ここのパスは変数staticと書きます.urlの形式は、静的ファイルを維持するパスを変更しやすい点でDjangoと一致し、Tornadoにはキャッシュの役割を果たすもう一つの機能があります.キャッシュの役割の解釈:静的ファイル/static/commons.js、フロントエンドがstatic_を使用する場合urlがパスを構成すると、urlの後ろに文字列、すなわち/static/commonsが追加されたようになります.js?v=asdf 123であると、ブラウザがアクセスするとこの特殊な文字列が携帯され、クライアントキャッシュの静的ファイルが変化していないことが判明した場合、フロントエンドページを直接レンダリングすればよいので、サービス側に行ってページを再ロードする必要がなく、アクセスを高速化することができる.
Tornado静的ファイルキャッシュを実現するコード
def get_content_version(cls, abspath):
        """Returns a version string for the resource at the given path.

        This class method may be overridden by subclasses.  The
        default implementation is a hash of the file's contents.

        .. versionadded:: 3.1
        """
        data = cls.get_content(abspath)
        hasher = hashlib.md5()
        if isinstance(data, bytes):
            hasher.update(data)
        else:
            for chunk in data:
                hasher.update(chunk)
        return hasher.hexdigest()

   (2)CSRF
Tornadoにおけるクロスステーション要求偽造はDjangoにおけるものと類似しており、クロスステーション要求偽造(Cross-site request forgery).
pythonコードの構成
settings = {
    "xsrf_cookies": True,
}
application = tornado.web.Application([
    (r"/", MainHandler),
    (r"/login", LoginHandler),
], **settings)

formフォームのコミット
<form action="/new_message" method="post">
  {{ xsrf_form_html() }}
  <input type="text" name="message"/>
  <input type="submit" value="Post"/>
form>

Ajax操作
function getCookie(name) {
    var r = document.cookie.match("\\b" + name + "=([^;]*)\\b");
    return r ? r[1] : undefined;
}

jQuery.postJSON = function(url, args, callback) {
    args._xsrf = getCookie("_xsrf");
    $.ajax({url: url, data: $.param(args), dataType: "text", type: "POST",
        success: function(response) {
        callback(eval("(" + response + ")"));
    }});
};

注:Ajaxを使用する場合、本質的にはローカルのクッキーを取得し、クッキーを携帯してリクエストを送信します
 
参考資料:
    http://www.cnblogs.com/wupeiqi/articles/5341480.html
 
転載先:https://www.cnblogs.com/maociping/p/5350275.html