在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专用方法与迭代机制实例分析
Sep 15 Python
Python中多线程的创建及基本调用方法
Jul 08 Python
python 设置文件编码格式的实现方法
Dec 21 Python
pycharm的console输入实现换行的方法
Jan 16 Python
详解小白之KMP算法及python实现
Apr 04 Python
Python 分享10个PyCharm技巧
Jul 13 Python
Python 实现Numpy中找出array中最大值所对应的行和列
Nov 26 Python
如何使用python写截屏小工具
Sep 29 Python
Sentry错误日志监控使用方法解析
Nov 12 Python
分享一枚pycharm激活码适用所有pycharm版本我的pycharm2020.2.3激活成功
Nov 20 Python
如何用用Python将地址标记在地图上
Feb 07 Python
Pytorch使用shuffle打乱数据的操作
May 20 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读取IMAP邮件
2006/10/09 PHP
php UTF-8、Unicode和BOM问题
2010/05/18 PHP
深入理解PHP之数组(遍历顺序)  Laruence原创
2012/06/13 PHP
PHP中HTML标签过滤技巧
2014/01/07 PHP
ThinkPHP3.2.2的插件控制器功能
2015/03/05 PHP
PHP基于单例模式编写PDO类的方法
2016/09/13 PHP
CI框架实现框架前后端分离的方法详解
2016/12/30 PHP
Laravel 5.4.36中session没有保存成功问题的解决
2018/02/19 PHP
基于JQuery的访问WebService的代码(可访问Java[Xfire])
2010/11/19 Javascript
JQuery中对服务器控件 DropdownList, RadioButtonList, CheckboxList的操作总结
2011/06/28 Javascript
js 实现在离开页面时提醒未保存的信息(减少用户重复操作)
2013/01/16 Javascript
当json键为数字时的取值方法解析
2013/11/15 Javascript
jQuery事件的绑定、触发、及监听方法简单说明
2016/05/10 Javascript
Bootstrap开关(switch)控件学习笔记分享
2016/05/30 Javascript
Centos7 中 Node.js安装简单方法
2016/11/02 Javascript
JavaScript编程设计模式之观察者模式(Observer Pattern)实例详解
2017/10/25 Javascript
js 原生判断内容区域是否滚动到底部的实例代码
2017/11/15 Javascript
vue项目中引入noVNC远程桌面的方法
2018/03/05 Javascript
微信小程序实现搜索指定景点周边美食、酒店
2019/05/18 Javascript
[00:59]DOTA2荣耀之路1:Doom is back!weapon X!
2018/05/22 DOTA
Python中声明只包含一个元素的元组数据方法
2014/08/25 Python
python排序方法实例分析
2015/04/30 Python
Python中反射和描述器总结
2018/09/23 Python
如何使用Python实现自动化水军评论
2019/06/26 Python
Mytheresa中国官网:德国时尚奢侈品商城
2017/08/04 全球购物
彪马加拿大官网:PUMA加拿大
2018/10/04 全球购物
生产总经理岗位职责
2013/12/19 职场文书
英语专业学生个人求职信范文
2014/01/06 职场文书
幼儿园毕业典礼主持词
2014/03/21 职场文书
向国旗敬礼活动小结
2014/09/27 职场文书
学习党的群众路线剖析材料
2014/10/09 职场文书
超搞笑婚前保证书
2015/05/08 职场文书
MySQL中order by的使用详情
2021/11/17 MySQL
Go语言安装并操作redis的go-redis库
2022/04/14 Golang
Golang MatrixOne使用介绍和汇编语法
2022/04/19 Golang
python数字图像处理之图像自动阈值分割示例
2022/06/28 Python