Tornado
跳转到导航
跳转到搜索
使用
HTTP 错误处理
覆盖 RequestHandler 的 write_error(self, status_code, **kwargs) 方法即可,如:
class ErrorHandlerMixin:
'''nicer error page'''
error_page = '''\
<!DOCTYPE html>
<meta charset="utf-8" />
<title>%(code)s %(message)s</title>
<style type="text/css">
body { font-family: serif; }
</style>
<h1>%(code)s %(message)s</h1>
<p>%(err)s</p>
<hr/>
'''
def write_error(self, status_code, **kwargs):
if self.settings.get("debug") and "exc_info" in kwargs:
# in debug mode, try to send a traceback
self.set_header('Content-Type', 'text/plain')
for line in traceback.format_exception(*kwargs["exc_info"]):
self.write(line)
self.finish()
else:
err_exc = kwargs.get('exc_info', ' ')[1]
if err_exc in (None, ' '):
err_msg = ''
else:
if isinstance(err_exc, HTTPError):
err_msg = str(err_exc.log_message) + '.'
else:
err_msg = str(err_exc) + '.'
self.finish(self.error_page % {
"code": status_code,
"message": httpclient.responses[status_code],
"err": err_msg,
})
@classmethod
def patchHandler(cls, RequestHandler):
'''patch a RequestHandler without subclassing
In this way we can change all ``tornado.web.RequestHandler``. Simply
subclassing and replacing won't work due to the Python 2-style ``super()``
call in its ``__init__`` method.
'''
RequestHandler.write_error = cls.write_error
RequestHandler.error_page = cls.error_page
注意
tornado.web.StaticFileHandler会将整个文件读取到内存中再发送tornado.autoreload在重新执行时会丢失传给 Python 的参数,如-uRequestHandler.redirect默认重定向地址不带域名。可手动加上:
import urllib.urlparse as urlparse
new_url = urlparse.urljoin(self.request.full_url(), new_url)
模板
默认 tornado.web.RequestHandler 的 render 方法会压缩 .html 或者 .js 文件中的空白。如果不想这样做,可以更改模板文件的后缀,或者使用自定义的 tornado.template.Loader :[1]
from tornado.template import Loader, Template
class MyLoader(Loader):
def _create_template(self, name):
path = os.path.join(self.root, name)
f = open(path, "rb")
template = Template(f.read(), name=name, loader=self,
compress_whitespace=False) # <--- 直接传入这个参数
f.close()
return template
template_path = './template'
tornado.web.Application(Handlers,
template_path=template_path,
template_loader = MyLoader(template_path),
)
配置
启用 debug 模式
Application 初始化时传递 debug=True 。
启用 gzip
Application 初始化时传递 gzip=True 。如需要修改使用 gzip 的文件类型,可修改 GZipContentEncoding 的属性 CONTENT_TYPES :
tornado.web.GZipContentEncoding.CONTENT_TYPES.update(['application/javascript'])
在请求处理类中使用 self.settings.get("gzip") 来判断是否启用了 gzip。注意:如果设置了内容长度 Content-Length ,gzip 将会被禁用。
使用 HTTPS
设置必要的选项即可:[2]
app = Application()
http_server = tornado.httpserver.HTTPServer(
app,
ssl_options = {
"certfile": os.path.expanduser("~/etc/key/server.crt"),
"keyfile": os.path.expanduser("~/etc/key/server.key"),
},
)
http_server.listen(options.port)
tornado.ioloop.IOLoop.instance().start()
虚拟主机
使用 Application.add_handlers 方法时可指定主机名模式。此模式将从头匹配到尾(不含端口号)。
application.add_handlers(r'updl\.lilydjwg\.cjb\.net', [
(r'/dl(?:/(.*)|$)', handlers.Download, {'dl_path': dl_path}),
(r'/upload$', handlers.Upload, {
'static_dir': static_dir,
'upload_dir': upload_dir,
}),
(r'/static/(.*)', handlers.Upload, {'static_dir': static_dir}),
])
文档修改
修改 build/html/_static/default.css:126 ,设置已访问链接的颜色为 #551a8b。
参见
外部链接
- 官方网站,tornado@github
- [1] Links of many resources
- python_Tornado文档翻译 » 进出自由才是游戏者的生存之道
- Josh Inkenbrandt - Tornado's Templates
- 用Tornado打造WebSocket与Ajax Long-Polling自适应聊天室
- AceFantasyVI - 在Tornado中使用Django的ORM注意事项
- python - Wrapping a tornado.gen.engine-wrapped function with another function - Stack Overflow, 包含使用
tornado.gen.coroutine的示例。
数据库
- Making MySQL Queries Asynchronous in Tornado | Chart.io
- tornado-redis, for Redis
- Motor: Asynchronous Python driver for Tornado and MongoDB