tornado

Tornado通过使用非阻塞网络1/0,可以扩展到数以万计的开放链接,非常适合 长时间轮询,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.xdnf.cn/news/147149.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

十一、 JDK17 新特性梳理

文章目录 为什么是JDK17语法层面新特性1、文本块2 、Switch 表达式增强3、instanceof的模式匹配4、var 局部变量推导 模块化及类封装1、记录类 record2 、隐藏类 Hidden Classes3 、密封类 Sealed Classes4、模块化 Module System1 、什么是模块化2、声明一个module3 、require…

“智能密钥管家”IKE

IKE的出现 上一篇通过IPSec实现了BJ到CS的业务互通,但是是通过手工方式把加密和验证密钥手动配置,为了保障安全性,就需要经常去修改这些密钥,小型场景还好,来来回回就这2个点, 修改起来不算麻烦&#xff…

[Redis] 渐进式遍历+使用jedis操作Redis+使用Spring操作Redis

🌸个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 🏵️热门专栏: 🧊 Java基本语法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12615970.html?spm1001.2014.3001.5482 🍕 Collection与…

解决SVN蓝色问号的问题

桌面或文件夹右键,选择TortoiseSVN->Settings打开设置对话框,选择Icon Overlays->Overlay Handlers->取消钩选Unversioned。确定,重启系统即可

CodeGeeX4:程序员的高效助手,多语言代码生成神器!

你是否曾在编写代码时,为复杂的语法、逻辑错误而绞尽脑汁?或是在面对多个编程语言的切换时,感觉脑子快要爆炸?别担心!一款全新的多语言代码生成神器——CodeGeeX4,正悄然成为程序员们的“救命稻草”。它不仅…

【工具变量】地市环保法庭试点城市DID数据集(2005-2023年)

数据简介:环保法庭是中国司法体系中专门处理环境资源案件的审判机构,其主要职责包括审理涉及自然环境污染、矿产资源保护、自然资源环境开发等环境资源民事纠纷案件,对不服下级人民法院生效裁判的环境资源民事案件进行审查,以及对…

如何在Chrome最新浏览器中调用ActiveX控件?

小编最近登陆工商银行网上银行,发现工商银行的个人网银网页,由于使用了ActiveX安全控件,导致不能用高版本Chrome浏览器打开,目前只有使用IE或基于IE内核的浏览器才能正常登录网上银行,而IE已经彻底停止更新了&#xff…

C++:类和对象OJ题

目录 一、求123...n 二、计算日期到天数的转换 三、日期差值 四、打印日期 一、求123...n 这里先把题目链接放在这里求123.....n 描述: 求123...n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C…

介绍 2款 Oracle 开发工具

准备工作 Oracle SQL Developer 下载(免费) Oracle 的官方网站下载 Oracle SQL Developer。以下是下载的步骤: 访问 Oracle SQL Developer 官方下载页面。点击页面上的“下载”链接。选择适合你操作系统的版本(Windows、macO…

第十五章:使用html、css、js编程制作一个网页版的下雪场景动画

背景:这是一个充满诗意的下雪场景代码。打开网页时,雪花轻轻飘落,覆盖住你的屏幕,仿佛置身于冬日的夜空下。背景音乐《我期待的不是雪》缓缓响起,伴随着雪花的飘动,仿佛心中的那份爱与温柔悄然绽放。 雪花的飘落是梦境般的存在,每一片雪花都是轻盈的告白,旋转着从天际…

百度营销转化追踪(网页JS布码)

引言:使用百度营销api配置网站上各个模块组件的转化追踪,统计网站上的各组件模块点击等信息。 一、选择接入方式(本文选择的是网页JS布码) 参考文档:百度营销-商业开发者中心百度开发者中心是一个面向开发者的知识分享…

『功能项目』QFrameWork制作背包界面UGUI【72】

本章项目成果展示 我们打开上一篇71QFrameWork更新道具图片UGUI的项目, 本章要做的事情是制作背包UI界面,实现道具栏与背包道具的互通 首先将以下资源图片放进Art文件夹 将UICanvas的UISlot对象复制一份放在Image下 创建Scrollbar View 设置Scrollbar V…

Resolving and Binding

1 Semantic Analysis中的变量绑定解析 背景:当一个变量在一个循环里赋值100次。那么这个变量会被赋值100次。当右侧是函数时,这非常没必要。这个可以通过静态的分析来避免这个问题。这个分析就是Sematic Analysis中的一个例子。 具体做的事情叫 2 把定…

10.解析解方法推导线性回归——不容小觑的线性回归算法

引言 线性回归是许多复杂机器学习模型的基础。作为一种基本的机器学习方法,线性回归提供了清晰的思路和工具,通过理解其推导过程,可以更好地掌握机器学习的基本原理和模型设计。 通过阅读本篇博客,你可以: 1.学会如…

对抗攻击的详细解析:原理、方法与挑战

对抗攻击的详细解析:原理、方法与挑战 对抗攻击(Adversarial Attack)是现代机器学习模型,尤其是深度学习模型中的一个关键安全问题。其本质在于,通过对输入数据添加精微的扰动,人类难以察觉这些扰动&#…

Cyber Weekly #25

赛博新闻 1、阿里云Qwen2.5发布!再登开源大模型王座,Qwen-Max性能逼近GPT-4o 阿里云在云栖大会上宣布通义千问发布新一代开源模型Qwen2.5,开源旗舰模型Qwen2.5-72B性能超越Llama3.1-405B,再次登上全球开源大模型的王座&#xff…

【优选算法之二分查找】No.5--- 经典二分查找算法

文章目录 前言一、二分查找模板:1.1 朴素二分查找模板1.2 查找区间左端点模板1.3 查找区间右端点模板 二、二分查找示例:2.1 ⼆分查找2.2 在排序数组中查找元素的第⼀个和最后⼀个位置2.3 搜索插⼊位置2.4 x 的平⽅根2.5 ⼭脉数组的峰顶索引2.6 寻找峰值…

鸿蒙开发(NEXT/API 12)【跨设备互通NDK开发】协同服务

跨设备互通提供跨设备的相机、扫描、图库访问能力,平板或2in1设备可以调用手机的相机、扫描、图库等功能。 说明 本章节以拍照为例展开介绍,扫描、图库功能的使用与拍照类似。 用户在平板或2in1设备上使用富文本类编辑应用(如:…

深入理解 flex-grow、flex-shrink、flex-basis

目录 1. Flex布局 2. flex-grow 计算方式 3. flex-shrink 计算公式 4. flex-basis 5. 应用场景 6. 总结 1. Flex布局 Flex 是 Flexible Box 的缩写,意为"弹性布局",用来为盒状模型提供最大的灵活性 flex属性是flex-grow, flex-shrink 和…

vscode安装ESLint与Vetur插件后自动修复代码不生效

vscode安装ESLint与Vetur插件后自动修复代码不生效 1、安装ESLint 和 Vuter 2、运行结果 2.1、代码保存时代码中的分号;能被检测出来,但是不会自动修复 2.2、手动运行ESLint 修复命令(在终端中执行 npx eslint . --fix)可以修复问题 3、解决办法 在.vscode目录下setti…