在Django的View中使用asyncio的方法


Posted in Python onJuly 12, 2019

起步

Django 是个同步框架,本文并不是 让 Django 变成异步框架。而是对于在一个 view 中需要请求多次 http api 的场景。

一个简单的例子

例子来源于 https://stackoverflow.com/questions/44667242/python-asyncio-in-django-view :

def djangoview(request, language1, language2):
 async def main(language1, language2):
  loop = asyncio.get_event_loop()
  r = sr.Recognizer()
  with sr.AudioFile(path.join(os.getcwd(), "audio.wav")) as source:
   audio = r.record(source)
  def reco_ibm(lang):
   return(r.recognize_ibm(audio, key, secret language=lang, show_all=True))
  future1 = loop.run_in_executor(None, reco_ibm, str(language1))
  future2 = loop.run_in_executor(None, reco_ibm, str(language2))
  response1 = await future1
  response2 = await future2
 loop = asyncio.new_event_loop()
 asyncio.set_event_loop(loop)
 loop = asyncio.get_event_loop()
 loop.run_until_complete(main(language1, language2))
 loop.close()
 return(HttpResponse)

这个例子中,把两个任务放到 asyncio 的 loop 运行,等到两个任务都完成了再返回 HttpResponse 。

在 Django 的 View 中使用 asyncio

现在可以对于上面的例子做一个扩充,让它能更合理被使用。

对于使用 asyncio ,我们通常会创建个子线程专门处理异步任务。

在 wsgi.py 中创建一个单独线程并运行事件循环:

import asyncio
import threading

...
application = get_wsgi_application()

# 创建子线程并等待
thread_loop = asyncio.new_event_loop()
def start_loop(loop):
 asyncio.set_event_loop(loop)
 loop.run_forever()

t = threading.Thread(target=start_loop, args=(thread_loop,), daemon=True)
t.start()

然后就是在 view 中动态向里面添加任务了:

async def fetch(url):
  async with aiohttp.ClientSession() as session:
   async with session.get(url) as response:
    text = await response.text()
    return text

def hello(request):
 from yeezy_bot.wsgi import thread_loop

 fut1 = asyncio.run_coroutine_threadsafe(fetch(url1), thread_loop)
 fut2 = asyncio.run_coroutine_threadsafe(fetch(url2), thread_loop)

 ret1 = fut1.result()
 ret2 = fut2.result()
 return HttpResponse('')

asyncio.run_coroutine_threadsafe() 返回是 Future 对象,因此可以通过 fut.result() 获得任务的运行结果。 这个方式也可以处理API请求中的数据依赖的先后顺序。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python THREADING模块中的JOIN()方法深入理解
Feb 18 Python
Python 爬虫模拟登陆知乎
Sep 23 Python
python利用拉链法实现字典方法示例
Mar 25 Python
python的pdb调试命令的命令整理及实例
Jul 12 Python
python实现弹跳小球
May 13 Python
使用 Python 合并多个格式一致的 Excel 文件(推荐)
Dec 09 Python
利用 PyCharm 实现本地代码和远端的实时同步功能
Mar 23 Python
如何实现更换Jupyter Notebook内核Python版本
May 18 Python
无需压缩软件,用python帮你操作压缩包
Aug 17 Python
python修改微信和支付宝步数的示例代码
Oct 12 Python
python字符串拼接.join()和拆分.split()详解
Nov 23 Python
Django框架中模型的用法
Jun 10 Python
检测python爬虫时是否代理ip伪装成功的方法
Jul 12 #Python
在PyCharm中控制台输出日志分层级分颜色显示的方法
Jul 11 #Python
基于sklearn实现Bagging算法(python)
Jul 11 #Python
Python的log日志功能及设置方法
Jul 11 #Python
python使用装饰器作日志处理的方法
Jul 11 #Python
Python日志无延迟实时写入的示例
Jul 11 #Python
深入了解Python iter() 方法的用法
Jul 11 #Python
You might like
php 的加密函数 md5,crypt,base64_encode 等使用介绍
2012/04/09 PHP
两种php去除二维数组的重复项方法
2015/11/04 PHP
javascript 学习之旅 (2)
2009/02/05 Javascript
javascript通过navigator.userAgent识别各种浏览器
2013/10/25 Javascript
多种方法实现360浏览器下禁止自动填写用户名密码
2014/06/16 Javascript
jQuery中DOM树操作之使用反向插入方法实例分析
2015/01/23 Javascript
微信小程序开发探究
2016/12/27 Javascript
JavaScript字符串对象(string)基本用法示例
2017/01/18 Javascript
javascript自执行函数
2017/02/10 Javascript
Angular2入门--架构总览
2017/03/29 Javascript
微信小程序 页面滑动事件的实例详解
2017/10/12 Javascript
分析javascript原型及原型链
2018/03/18 Javascript
bootstrap与pagehelper实现分页效果
2018/12/29 Javascript
详解Python中__str__和__repr__方法的区别
2015/04/17 Python
使用py2exe在Windows下将Python程序转为exe文件
2016/03/04 Python
Python Requests安装与简单运用
2016/04/07 Python
Python判断某个用户对某个文件的权限
2016/10/13 Python
Django如何配置mysql数据库
2018/05/04 Python
python删除列表元素的三种方法(remove,pop,del)
2019/07/22 Python
flask框架jinja2模板与模板继承实例分析
2019/08/01 Python
Python shutil模块用法实例分析
2019/10/02 Python
Windows下python3安装tkinter的问题及解决方法
2020/01/06 Python
如何在windows下安装Pycham2020软件(方法步骤详解)
2020/05/03 Python
让IE9以下版本的浏览器兼容HTML5的方法
2014/03/12 HTML / CSS
英国最大的美妆产品在线零售商之一:Beauty Bay
2017/09/29 全球购物
自荐信的五个重要部分
2013/10/29 职场文书
探亲邀请信范文
2014/01/30 职场文书
学生请假条格式
2014/04/11 职场文书
小学生常见病防治方案
2014/06/06 职场文书
陕西导游词
2015/02/04 职场文书
大学生暑期实践报告
2015/07/13 职场文书
谢师宴家长答谢词
2015/09/30 职场文书
百年校庆宣传标语口号
2015/12/26 职场文书
怎样写好工作计划
2019/04/10 职场文书
SQL实现LeetCode(180.连续的数字)
2021/08/04 MySQL
使用Redis做预定库存缓存功能
2022/04/02 Redis