Tornado简介

Tornado是一个具有强大异步功能的Python Web框架.

Hello World

使用pip安装tornado:

pip install tornado

编写控制器:

import tornado.httpserver
import tornado.ioloop
import tornado.options
from tornado.web import RequestHandler

from tornado.options import define, options
define("port", default=8000, help="run on the given port", type=int)


class IndexHandler(RequestHandler):
    def get(self):
        self.write('Hello World!')

if __name__ == "__main__":
    tornado.options.parse_command_line()
    app = tornado.web.Application(handlers=[(r"/", IndexHandler)])
    http_server = tornado.httpserver.HTTPServer(app)
    http_server.listen(options.port)
    tornado.ioloop.IOLoop.instance().start()

在命令行中运行:

python hello.py --port=8000

在浏览器中访问http://localhost:8000, 可以看到来自服务器的Hello World.

Web.Application

每一个torndao服务端程序均使用Application封装:

define("port", default=8000, help="run on the given port", type=int)
if __name__ == "__main__":
        tornado.options.parse_command_line()
        app = tornado.web.Application(handlers=[(r"/", IndexHandler)])
        http_server = tornado.httpserver.HTTPServer(app)
        http_server.listen(options.port)
        tornado.ioloop.IOLoop.instance().start()

常量定义:

define("port", default=8000, help="run on the given port", type=int)

解析命令行参数并进行配置options:

tornado.options.parse_command_line()

Web.Application的handler关键字参数是一个列表,列表中的元素是(地址正则表达式,handler类)二元组

handlers=[(r"/", IndexHandler)]

初始化httpserver:

http_server = tornado.httpserver.HTTPServer(app)

绑定服务器监听的端口:

http_server.listen(options.port)

启动IO循环来接收请求并处理:

tornado.ioloop.IOLoop.instance().start()

RequestHandler

Tornado开发的核心是继承RequestHandler类,并重写get, post等方法实现对相应HTTP请求的响应。

返回响应

一般情况下不需要get或post方法返回任何值, 使用self.write(chunk)可以直接将块写入缓冲区, chunk参数可以是str或dict对象.

若chunk是一个dict对象, tornado会将其序列化JSON字符串同时会把响应头设置为application/json.

RequestHandler.render(template_name, **kwargs)会渲染模板并将结果返回客户端:

class PageHandler(RequestHandler):
    def get(self):
        self.render('./templates/index.html')

若要对渲染结果进行处理则可以使用RequestHandler.render_string(template_name, **kwargs)获得渲染结果字符串, 并在处理后手动写入缓冲区.

RequestHandler.redirect(url, permanent=False, status=None)方法可以将请求重定向到其它url.

如果指定了status参数, 这个值将作为HTTP状态码; 否则,将通过 permanent 参数选择301 (永久) 或者 302 (临时). 默认是 302 (临时重定向).

RequestHandler.set_status(status_code, reason=None)方法可以设置响应的状态码, reason参数用人类可读的原因短语来描述状态码. 如果reason是None, 会自动使用httplib.responses 的reason.

RequestHandler.set_header(name, value)add_header(name, value)可以设置或添加响应头中的参数.

RequestHandler.flush(callback=None)刷新缓冲区然后执行回调.

RequestHandler.finish(chunk=None)将返回response并断开连接, 一般在响应方法退出时自动执行.

获得请求参数

get和post方法默认只有一个self参数, 而url中被匹配的字符串会被作为位置参数传入:

handlers = [("user/([0-9]+)", UserInfoHandler)]

class UserInfoHandler(Requesthandler):
	def get(self, uid):
    	self.write(str(uid))

RequestHandler.get_body_argument(name)可以返回请求body部分中的参数,比如post方法提交的参数,.

RequestHandler.get_query_argument(name)可以获得包含url中的参数, 一般为get方法提交的参数.

RequestHandler.get_argument(name)则可以获得body或query参数.

class LoginHandler(RequestHandler):
	def post(self):
    	username = self.get_argument('username')
        password = self.get_argument('password')
        result = do_login(username, password)
        self.write(result)

RequestHandler.request 对象封装HTTP请求的信息, request.arguments以字典的形式包含了所有body和query参数.

request.headers.get(name, default=None)则可以用来获得在请求头中的参数.

request.files可以获得上传文件的信息, 先编写上传表单:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Upload</title>
</head>
<body>
    <form action="/do-upload/" method="post" enctype="multipart/form-data">
        <input type="file" name="filename">
        <input type="submit" value="submit">
    </form>
</body>
</html>

实现handler:

class UploadFileHandler(RequestHandler):
    def post(self):
        upload_path = os.path.join(os.path.dirname(__file__),'files')
        filemeta = self.request.files['filename'][0]
        filename = filemeta['filename']
        path = os.path.join(upload_path, filename)
        with open(filepath,'wb') as fw:
        	fw.write(meta['body'])
        self.write('upload success')

RequestHandler.cookies 存储cookie的字典, 等同于self.request.cookies.

RequestHandler.get_cookie(name, default=None) 获取给定name的cookie值, 如果未获取到则返回默认值.

RequestHandler.set_cookie(name, value)设置给定的cookie 名称/值还有其他给定的选项.

RequestHandler.clear_cookie(name, path='/', domain=None)删除给定名称的cookie.受cookie协议的限制,必须传递path和domain来清除这个cookie.

RequestHandler.clear_all_cookies(path='/', domain=None)删除用户在本次请求中所有携带的cookie.

tornado的cookie系统同样提供了含有数字签名的时间戳的secure_cookie系统.其操作与普通cookie类似:

class AuthHandler(RequestHandler):
	def get(self, redirect_uri):
    	uid = self.get_secure_cookie('uid')
        token = make_token(uid)
        self.set_secure_cookie('token', token)
        self.redirect("/" + redirect_uri)

参考资料:


原文地址:https://www.cnblogs.com/Finley/p/5509326.html