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,一经查实,立即删除!

相关文章

速盾:免备案服务器?

速盾是一家提供网络安全服务的公司,其主要产品包括CDN加速、WEB防护、WAF、DDoS防护等。在网站建设过程中,选择一个合适的服务器是非常重要的一步。传统的服务器需要备案,涉及到较多的流程和审批时间,给网站运营带来了一定的麻烦。…

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) 以…

安全服务面试总结

154.mysql 安全要如何做? Mysql 账户权限安全 第 61 页 共 152 页 Mysql 数据的网络安全配置 密码策略安全 Mysql 日志 Mysql 数据库服务所在主机安全配置部署 SQL 注入检测、防御模块 mysqld 安全相关启动选项 mysql 备份策略 155.sqlserver public 权…

Python 循环跳出模式

Python 循环跳出模式 在 Python 编程中,循环是实现重复任务的重要工具。通常,我们会使用 for 或 while 循环来遍历序列或执行特定操作。然而,有时我们需要在特定条件下提前终止循环,这就是循环跳出的机制。Python 提供了几种方式…

IO模型介绍

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

jenkins配置eureka、nacos发布优雅上下线服务

eureka发布期间优雅上下线 1、编写eureka下线脚本 vim biz_out_of_service-eureka.pyimport sys import requests#服务名,脚本第一个参数 APP_NAMEsys.argv[1] # 需要置为OUT_OF_SERVICE的服务实例的ID,脚本第二个参数 INSTANCE_IDsys.argv[2]# Eureka…

维修保养记录接口-维修保养记录API-汽车接口

维修保养记录接口的使用主要涉及到API对接和在线查询两种方式。以下是详细的使用步骤和注意事项: 一、API对接 注册与申请: 首先,你需要在提供维修保养记录接口的平台(如挖数据平台、第三方数据服务商等)进行注册&…

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. 量化器(…

Go基础学习09-多协程资源竞争、sync.Mutex、sync.Cond、chan在多协程对共享变量的资源竞争中的使用

文章目录 Go中协程基础小记协程基础为什么需要多协程多协程面临的问题 代码演示存在共享变量的资源竞争Mutex解决资源竞争Mutex基本介绍代码演示 MutexCond解决资源竞争和CPU空转Cond条件变量讲解代码演示代码片段关于wait和for循环的解释说明条件变量Signal方法和Broadcast方法…

C++七种异常处理

在C++中,使用异常机制可以提高程序的健壮性和可维护性。异常是在程序运行时发生的一个事件,它会打断正在执行的程序的正常流程。C++异常处理机制可以使程序在出现异常时,进行异常处理,而不是退出程序。 基本的异常处理 #include <iostream> using namespace std;int …

IP 数据包分包组包

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

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

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

[论文笔记] LLaMA3.2

https://github.com/meta-llama/llama-stack [2407.21783] The Llama 3 Herd of Models Meta 部落格資訊:https://ai.meta.com/blog/llama-3-2-connect-2024-vision-edge-mobile-devices/HuggingFace:

【Kubernetes】常见面试题汇总(五十)

目录 112.考虑一个公司要向具有各种环境的客户提供所有必需的分发产品的方案。您如何看待他们如何动态地实现这一关键目标&#xff1f; 113.假设一家公司希望在从裸机到公共云的不同云基础架构上运行各种工作负载。在存在不同接口的情况下&#xff0c;公司将如何实现这一目标&…

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

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

Solidity智能合约中的事件和日志

1. Solidity 中的事件和日志概述 1.1 什么是事件&#xff1f; 在 Solidity 中&#xff0c;事件&#xff08;Event&#xff09;是一种允许智能合约与外部世界进行通信的机制。通过触发事件&#xff0c;可以记录合约执行中的关键操作&#xff0c;并将这些操作发送到链上。事件的…

魔改xjar支持springboot3,

jar包加密方案xjar, 不支持springboot3。这个发个魔改文章希望大家支持 最近公司需要将项目部署在第三方服务器&#xff0c;于是就有了jar包加密的需求&#xff0c;了解了下目前加密方案现况如下: 混淆方案&#xff0c;就是在代码中添加大量伪代码&#xff0c;以便隐藏业务代…

常见电脑品牌BIOS设置与进入启动项快捷键

常见电脑品牌BIOS与引导项快捷键速查表 | 电脑品牌 | BIOS快捷键 | 引导项快捷键 | 备注 ||------------|------------|--------------|------------------------------ || 联想 | F2/F1 | F12 | 笔记本通常为F2&#xff0c;台式机通常为F1 || IBM/ThinkPad | F1 | 未知 | ||…