tornado

Tornado通过使用非阻塞网络I/O,可以扩展到数以万计的开放链接,非常适合 长时间轮询,WebSockets和其他需要与每个用户建立长期连接的应用程序。

特点

  • 注重性能优越,速度快
  • 解决高并发
  • 异步非阻塞
  • websockets 长连接
  • 内嵌了HTTP服务器
  • 单线程的异步网络程序,默认启动时根据CPU数量运行多个实例:利用CPU多核的优势

pip3 install tornado 

文档

 main.py

import tornado.web
import tornado.ioloop
from tornado.options import parse_command_line, options, defineclass HelloHandler(tornado.web.RequestHandler):def get(self, *args, **kwargs):self.write('hello tornado')def create_app():'''创建app, 注册路由与处理类'''app = tornado.web.Application(handlers=[(r'/', HelloHandler)],template_path='templates',   # 模板文件的目录static_path='static',    # 告诉tornado 静态目录static_url_prefix='/static/'   # 浏览器访问时的url)return appif __name__ == '__main__':# define, options, parse_command_line 三个配合使用解析命令行# 定义默认参数  这里定义默认启动端口,可通过命令行启动时修改port的值,改变端口define('port', default=8080, type=int)# 解析命令行parse_command_line()  # 获取命令行启动时 --xx  参数和值# 创建appapp = create_app()# 监听端口app.listen(options.port)# python main.py --port=8080  # options.port 的值为 8080# 服务监听tornado.ioloop.IOLoop.instance().start()

请求

get请求

# http://127.0.0.1:8080/?name=asd&name=qweclass HelloHandler(tornado.web.RequestHandler):def get(self):# 获取请求头信息user_agent = self.request.headers.get('User-Agent', 'Unknown')name = self.request.arguments.get('name')  # 当url有相同参数时,值为列表# ['asd', 'qwe']name = self.get_arguments('name')  # 当url有相同参数时,值为列表# ['asd', 'qwe']name = self.get_argument('name')name = self.get_query_argument('name')name = self.get_query_arguments('name')print(name)  # qweself.write('hello word')app = tornado.web.Application(handlers=[(r'/', HelloHandler)])
# http://127.0.0.1:8080/api/user/12class HelloHandler(tornado.web.RequestHandler):def get(self, uid):self.write(f'user id is: {uid}')app = tornado.web.Application(handlers=[(r'/api/user/(\d+)', HelloHandler)])

post请求

form-data请求的参数值在

  • self.request.arguments
  • self.request.body_arguments

json提交的数据再body中

  • self.request.body  # 需要json反序列化

urlencoded 请求的参数值在

  • self.request.arguments
  • self.request.body_arguments

class HelloHandler(tornado.web.RequestHandler):def post(self):# 获取form-data, urlencoded 参数name = self.request.arguments.get('name')name = self.get_argument('name')name = self.get_arguments('name')name = self.get_body_argument('name')name = self.get_body_arguments('name')# 获取json参数print(json.loads(self.request.body))self.write('post')

响应

write返回字符串

class HelloHandler(tornado.web.RequestHandler):def get(self, *args, **kwargs):self.write('hello tornado')

write返回json

  • 注意:自己手动序列化json方式 前端response headers 中的 Content_Type属性text/html,而采用write自动序列化方式,Content_Type属性为application/json
class HelloHandler(tornado.web.RequestHandler):def get(self, *args, **kwargs):data = {'name': 'alex','age': 20,'hobby': ['python', 'go', 'java', 'c++']}# 自动序列化self.write(data)  # {"name": "alex", "age": 20, "hobby": ["python", "go", "java", "c++"]}class HelloHandler(tornado.web.RequestHandler):def get(self, *args, **kwargs):data = {'name': 'alex','age': 20,'hobby': ['python', 'go', 'java', 'c++']}# 手动json序列化, 需设置header: Content_Type属性text/htmlself.write(json.dumps(data))

set_header设置响应头

还有 clear_header,add_header 方法

class HelloHandler(tornado.web.RequestHandler):def get(self, *args, **kwargs):data = {'name': 'alex','age': 20,'hobby': ['python', 'go', 'java', 'c++']}self.set_header("Content-Type","application/json;charset=UTF-8")self.set_header("token", "xxxxxxxxxxxx")self.write(data)

set_default_headers

规范默认修改响应的头的位置

  • 注意: 在http处理方法中再使用 self.set_headers() 方法 设置通用的name的值,会覆盖原先在set_default_headers() 中设置的值
class HelloHandler(tornado.web.RequestHandler):def set_default_headers(self):self.set_header("Content-Type","application/json;charset=UTF-8")self.set_header("token", "xxxxxxxxxxxx")def get(self, *args, **kwargs):data = {'name': 'alex','age': 20,'hobby': ['python', 'go', 'java', 'c++']}self.set_header("token", "aaaaaaaaaaaa")  # 替换set_default_headers中设置的 tokenself.write(data)

set_status设置响应状态码

参数:

  • status--状态码的值为 int类型
  • reason--对状态码的描述 str类型 如果reason值为None 则状态码的值必须为正常值
class HelloHandler(tornado.web.RequestHandler):def get(self, *args, **kwargs):self.set_status(404)self.write('error')

redirect重定向

class HelloHandler(tornado.web.RequestHandler):def get(self, *args, **kwargs):self.write('hello tornado')class UserHandler(tornado.web.RequestHandler):def get(self, *args, **kwargs):self.redirect('/')app = tornado.web.Application(handlers=[(r'/', HelloHandler),(r'/user', UserHandler)])

send_error

  • 作用:可以跑出http错误状态码,默认为500,跑出错误后tornado会调用write_error()方法处理,并返回给浏览器界面
  • 注意: 不执行send_error之后的内容
class HelloHandler(tornado.web.RequestHandler):def get(self, *args, **kwargs):self.send_error(500, reason="server error")# send_error 之后的代码不会执行self.write('hello tornado')

write_error(status_code,**kwargs)

  • 用来处理send_error跑出来的额信息,并返回给浏览器错误页面
class HelloHandler(tornado.web.RequestHandler):def write_error(self, status_code: int, **kwargs: Any):'''一般是返回自定义页面'''code = 200if status_code == 404:code = 404self.write('资源错误')elif status_code == 500:code = 500self.write('服务器错误')self.set_status(code)def get(self, *args, **kwargs):if self.get_argument('name') != 'alex':self.send_error(404)self.write('hello tornado')

finish

self.finish()RequestHandler 的一个方法,用于明确地结束 HTTP 请求处理。当你调用 self.finish() 时,Tornado 会立即发送响应给客户端,并关闭与该请求相关的所有资源。这意味着在 self.finish() 被调用之后,你不能再向响应中写入任何数据。

self.finish() 的主要用途包括:

  1. 提前终止响应:如果你在处理过程中发现不需要进一步处理或已经完成了所有的处理逻辑,可以调用 self.finish() 来立即发送响应并结束处理过程。

  2. 异步处理完成后的清理:在使用异步操作(如数据库查询、网络请求等)时,一旦操作完成,你可以调用 self.finish() 来结束请求处理。

  3. 防止意外的数据写入:通过显式调用 self.finish(),你可以确保不会在无意中向已发送的响应中添加额外的数据,这有助于避免产生不完整或损坏的响应。

文件上传下载


class UploadHandler(tornado.web.RequestHandler):def post(self):# 检查是否上传了文件if not self.request.files:self.write("No file uploaded")return# 获取文件对象file_info = self.request.files['file'][0]filename, content_type = file_info['filename'], file_info['content_type']body = file_info['body']# 定义保存路径upload_path = "files"if not os.path.exists(upload_path):os.makedirs(upload_path)# 保存文件with open(os.path.join(upload_path, filename), 'wb') as f:f.write(body)self.write(f"File {filename} has been uploaded successfully.")class DownloadHandler(tornado.web.RequestHandler):def get(self, filename):# 文件路径dir_path = "files/"file_path = os.path.join(dir_path, filename)# 检查文件是否存在if not os.path.exists(file_path):raise tornado.web.HTTPError(404, "File not found")# 设置响应头self.set_header('Content-Type', 'application/octet-stream')self.set_header('Content-Disposition', f'attachment; filename="{filename}"')# 读取并发送文件with open(file_path, 'rb') as f:while True:data = f.read(16384)  # 一次读取16KBif not data:breakself.write(data)self.finish()app = tornado.web.Application(handlers=[(r'/upload', UploadHandler),(r'/download/(.*)', DownloadHandler),])

返回图片

import os
import tornado.ioloop
import tornado.webclass MainHandler(tornado.web.RequestHandler):def get(self):# 显示包含图片链接的页面self.render("index.html")class ImageHandler(tornado.web.RequestHandler):def get(self, filename):# 图片路径image_path = os.path.join("static", "images", filename)# 检查图片是否存在if not os.path.exists(image_path):raise tornado.web.HTTPError(404, "Image not found")# 设置响应头self.set_header('Content-Type', 'image/jpeg')  # 根据图片类型设置 Content-Typewith open(image_path, 'rb') as f:while True:data = f.read(16384)  # 一次读取16KBif not data:breakself.write(data)self.finish()def make_app():return tornado.web.Application([(r"/", MainHandler),(r"/image/(.*)", ImageHandler),  # 匹配/image/后面的所有内容作为图片文件名(r"/static/(.*)", tornado.web.StaticFileHandler, {"path": "static"}),  # 静态文件服务], template_path=os.path.join(os.path.dirname(__file__), "templates"))if __name__ == "__main__":app = make_app()app.listen(8080)print("Server started on port 8080")tornado.ioloop.IOLoop.current().start()

web框架-tornado操作数据库 - 简书

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/55304.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

04 B-树

目录 常见的搜索结构B-树概念B-树的插入分析B-树的插入实现B树和B*树B-树的应用 1. 常见的搜索结构 种类数据格式时间复杂度顺序查找无要求O(N)二分查找有序O( l o g 2 N log_2N log2​N)二分搜索树无要求O(N)二叉平衡树无要求O( l o g 2 N log_2N log2​N)哈希无要求O(1) 以…

IO模型介绍

一、理解IO 网络通信的本质就是进程间通信,进程间通信本质就是IO TCP中的IO接口:read / write / send / recv,本质都是:等 拷贝 所以IO的本质就是:等 拷贝 那么如何高效的IO? 减少“等”在单位时间的…

CORDIC算法笔记整理

CORDIC算法有两种模式,分别为旋转模式和向量模式。而在数字硬件实现混频处理时,CORDIC算法是比较好的方法,使用的是CORDIC的旋转模式,只需通过移位操作和加法就可以实现频谱搬移的乘法操作。 1 CORDIC算法理解 1.1 单次旋转 对…

SpringCloud学习记录|day1

学习材料 2024最新SpringCloud微服务开发与实战,java黑马商城项目微服务实战开发(涵盖MybatisPlus、Docker、MQ、ES、Redis高级等) 学redis讲到微服务就停了,nginx也是。 所以嘛,我终于来到微服务了。 复习MyBatisP…

CMU 10423 Generative AI:lec14(Vision Language Model:CLIP、VQ-VAE)

文章目录 1 概述2 CLIP (Used in GPT-V)3 VQ-VAE (Used in Gemini)**VQ-VAE 详细笔记****VQ-VAE 的模块组成与数据流** **1. 输入数据****2. 编码器(Encoder)****2.1 编码器的作用****2.2 数据流与维度变化****2.3 编码器输出** **3. 量化器(…

IP 数据包分包组包

为什么要分包 由于数据链路层MTU的限制,对于较⼤的IP数据包要进⾏分包. 什么是MTU MTU相当于发快递时对包裹尺⼨的限制.这个限制是不同的数据链路对应的物理层,产⽣的限制. • 以太⽹帧中的数据⻓度规定最⼩46字节,最⼤1500字节,ARP数据包的⻓度不够46字节,要在后⾯补填 充…

云栖实录 | 开源大数据全面升级:Native 核心引擎、Serverless 化、湖仓架构引领云上大数据发展

本文根据2024云栖大会实录整理而成,演讲信息如下: 演讲人: 王 峰 | 阿里云智能集团研究员、开源大数据平台负责人 李 钰|阿里云智能集团资深技术专家 范 振|阿里云智能集团高级技术专家 李劲松|阿里云…

MongoDB聚合操作及索引底层原理

目录 链接:https://note.youdao.com/ynoteshare/index.html?id=50fdb657a9b06950fa255a82555b44a6&type=note&_time=1727951783296 本节课的内容: 聚合操作: 聚合管道操作: ​编辑 $match 进行文档筛选 ​编辑 将筛选和投影结合使用: ​编辑 多条件匹配: …

【AI】AIOT简介

随着技术的快速发展,人工智能AI和物联网IoT已经成为当今最热门的技术领域。AIOT是人工智能和物联网的结合,使物联网设备更加智能化,能够进行自主决策和学习的技术。 通过物联网产生、收集来自不同维度的、海量的数据存储于云端、边缘端&#…

数据治理006-数据标准的管理

元数据的分类和标准有哪些? 一、元数据的分类 元数据可以根据其描述的对象和属性不同,被分为不同的类型。以下是几种常见的元数据分类方法: 基于数据的类型:根据数据的类型,元数据可以被分为结构化元数据、非结构化元…

SQL连接Python

对于运营部门的Yoyo来说,她想要知道夜曲优选的订单都来自哪些省份,每个省份的总订单数以及总订单金额分别是多少。 这时小鹿就会通过SQL对连接的数据库进行查询,再将结果传递给Python处理,并帮助Yoyo生成可视化图表。 我们先来快…

拆解维修飞科剃须刀

原因 用了好几年的剃须刀,经过一次更换电池。后来上面的盖帽松动,无法合盖,经过把弹片矫正后修复。最近一次”大力出奇迹“的操作直接断送了这个老伤员最后的可能性。最终只能花了将近十块大洋买了一套盖着和中间座。简单更换了一下。 记录…

目前最好用的爬虫软件是那个?

作为一名数据工程师,三天两头要采集数据,用过十几种爬虫软件,也用过Python爬虫库,还是建议新手使用现成的软件比较方便。 这里推荐3款不错的自动化爬虫工具,八爪鱼、亮数据、Web Scraper 1. 八爪鱼爬虫 八爪鱼爬虫是一…

Linux:深入理解冯诺依曼结构与操作系统

目录 1. 冯诺依曼体系结构 1.1 结构分析 1.2 存储结构分布图 2. 操作系统 2.1 概念 2.2 如何管理 2.3 什么是系统调用和库函数 1. 冯诺依曼体系结构 1.1 结构分析 不管是何种计算机,如个人笔记本电脑,服务器,都是遵循冯诺依曼结构。…

可视化图表与源代码显示配置项及页面的动态调整功能分析

可视化图表与源代码显示配置项及页面的动态调整功能分析 文章目录 可视化图表与源代码显示配置项及页面的动态调整功能分析1.分析图表源代码2.分析源代码显示功能**完整代码参考:** 3.分析源代码显示及动态调整**完整代码参考:** 4.分析代码编辑器及运行…

华为云LTS日志上报至观测云最佳实践

华为云LTS简介 华为云云日志服务(Log Tank Service,简称 LTS),用于收集来自主机和云服务的日志数据,通过海量日志数据的分析与处理,可以将云服务和应用程序的可用性和性能最大化,为您提供实时、…

基于SSM的爱心慈善公益网站的设计与实现

文未可获取一份本项目的java源码和数据库参考。 选题意义 随着经济的不断进步,发展各种进行公益事业的渠道不断的出现,作为一个礼仪之邦,中华民族一直秉承先人的团结与友善精神,对社会和他人给予帮助关怀。但中国的公益事业相对…

【AIGC】2022-CVPR-利用潜在扩散模型进行高分辨率图像合成

2022-CVPR-High-Resolution Image Synthesis with Latent Diffusion Models 利用潜在扩散模型进行高分辨率图像合成摘要1. 引言2. 相关工作3. 方法3.1. 感知图像压缩3.2. 潜在扩散模型3.3. 调节机制 4. 实验4.1. 关于感知压缩权衡4.2. 利用潜在扩散生成图像4.3. 条件潜在扩散4.…

防sql注入的网站登录系统设计与实现

课程名称 网络安全 大作业名称 防sql注入的网站登录系统设计与实现 姓名 学号 班级 大 作 业 要 求 结合mysql数据库设计一个web登录页面密码需密文存放(可以采用hash方式,建议用sha1或md5加盐)采用服务器端的验证码&#…

基于Hive和Hadoop的招聘分析系统

本项目是一个基于大数据技术的招聘分析系统,旨在为用户提供全面的招聘信息和深入的职位市场分析。系统采用 Hadoop 平台进行大规模数据存储和处理,利用 MapReduce 进行数据分析和处理,通过 Sqoop 实现数据的导入导出,以 Spark 为核…