目录
  • 1. tornado
  • 2. aiohttp
  • 3.sanic
  • 4. fastapi
  • 5. ruia

正文开始

asyncio 是 python 3.4版本引入的标准库,直接内置了对异步io的支持。

asyncio 在单线程内部维护了 eventloop 队列,然后把需要执行异步io的任务添加到 eventloop 队列中,至于任务的完成通过类似回调的逻辑是实现后续的任务。如果你有 javascript的基础那么理解python的 asyncio 很简单,关键字、语法以及实现的原理都极其类似。

import asyncio

async def main():
    print('hello ...')
    await asyncio.sleep(1)
    print('... world!')

# python 3.7+
asyncio.run(main())

1. tornado

tornado 是一个python web框架和异步网络库,起初由 friendfeed 开发. 通过使用非阻塞网络i/o, tornado可以支撑上万级的连接,处理 长连接, websockets ,和其他需要与每个用户保持长久连接的应用。

下面贴上官方 demo :

import tornado.ioloop
import tornado.web

class mainhandler(tornado.web.requesthandler):
    def get(self):
        self.write("hello, world")

def make_app():
    return tornado.web.application([
        (r"/", mainhandler),
    ])

if __name__ == "__main__":
    app = make_app()
    app.listen(8888)
    tornado.ioloop.ioloop.current().start()

2. aiohttp

一个基于 asyncio 异步的web框架,支持 websocket,不需要写回掉的代码、有着丰富的生态、中间价等、开箱即用的服务端与客户端。

下面贴上官方 demo :

# 客服端代码
import aiohttp
import asyncio

async def main():

    async with aiohttp.clientsession() as session:
        async with session.get('http://python.org') as response:

            print("status:", response.status)
            print("content-type:", response.headers['content-type'])

            html = await response.text()
            print("body:", html[:15], "...")

loop = asyncio.get_event_loop()
loop.run_until_complete(main())
# 服务端代码
from aiohttp import web

async def handle(request):
    name = request.match_info.get('name', "anonymous")
    text = "hello, " + name
    return web.response(text=text)

async def wshandle(request):
    ws = web.websocketresponse()
    await ws.prepare(request)

    async for msg in ws:
        if msg.type == web.wsmsgtype.text:
            await ws.send_str("hello, {}".format(msg.data))
        elif msg.type == web.wsmsgtype.binary:
            await ws.send_bytes(msg.data)
        elif msg.type == web.wsmsgtype.close:
            break

    return ws


app = web.application()
app.add_routes([web.get('/', handle),
                web.get('/echo', wshandle),
                web.get('/{name}', handle)])

if __name__ == '__main__':
    web.run_app(app)

aiohttp的生态:

  • 为 aiohttp 服务提供 sessions支持,同时支持数据持久化数据库。
  • 为 aiohttp 提供调试的工具(记录 asyncio 异常的堆栈信息)。
  • 为aiohttp提供认证以及权限相关的插件。
  • aiohttp开发工具,提供开发环境的部署、静态资源的代理。
  • cors 跨域认证支持。
  • 服务端事件的支持(一种服务端推送消息的服务)。
  • pytest 测试框架的支持。
  • mako 服务端模板渲染的支持。
  • jinja2 服务端模板渲染的支持(大名鼎鼎的flask的渲染引擎)。
  • 分布式系统中对服务追踪,为微服务中延时问题提供数据支持。

aiohttp数据库支持:

postgresql异步支持。
mysql 异步支持。
redis 异步支持。
asyncpg 另外一个对 postgresql 异步支持,比 aiopg 效率高,但是 api 不通用。

3.sanic

sanic 是一个 python 3.7+ 的基于 asyncio 的 web 服务器和web框架,目标是提供一种简单的方法来启动和运行一个易于构建、扩展和终极性能http服务器,是一个比较类似 falsk 的异步web框架。

to provide a simple way to get up and running a highly performant http server that is easy to build, to expand, and ultimately to scale.

官方demo:

from sanic import sanic
from sanic.response import json

app = sanic("my hello, world app")

@app.route('/')
async def test(request):
    return json({'hello': 'world'})

if __name__ == '__main__':
    app.run()

4. fastapi

fastapi 是一个用于构建api的高性能web框架,基于python3.6+并支持标准的 python 类型提示。同时是最快的 python web框架之一,可与 nodejs 和 go 比肩(主要归功于 starlette 和 pydantic)。

from typing import optional

from fastapi import fastapi

app = fastapi()


@app.get("/")
def read_root():
    return {"hello": "world"}


@app.get("/items/{item_id}")
def read_item(item_id: int, q: optional[str] = none):
    return {"item_id": item_id, "q": q}

# 启动 uvicorn main:app --reload
# pip install uvicorn[standard]

5. ruia

一个基于asyncio和aiohttp的异步爬虫框架,目标在于让开发者编写爬虫尽可能地方便快速。国人开发中文文档的支持,方便快速的构建爬虫项目,自定义html解析工具,快速获取页面数据。

官方demo:

import asyncio

from ruia import item, textfield, attrfield


class hackernewsitem(item):
    target_item = textfield(css_select='tr.athing')
    title = textfield(css_select='a.storylink')
    url = attrfield(css_select='a.storylink', attr='href')


async def test_item():
    url = 'https://news.ycombinator.com/news?p=1'
    async for item in hackernewsitem.get_items(url=url):
        print('{}: {}'.format(item.title, item.url))


if __name__ == '__main__':
    # python 3.7 required.
    asyncio.run(test_item()) 

    # for python 3.6
    # loop = asyncio.get_event_loop()
    # loop.run_until_complete(test_item())

总结

随着 python 社区对异步支持的愈发友好,异步框架的生态也愈发完善。tornado 是我第一个接触到的一步框架,现如今伴随着最快 python web 框架之争,tornado也渐渐跌落神坛。但是至于谁是最快的并不重要,重要的是生态,避免重复造轮子才是重要的。

ps:

  1. 我记得之前了解 sanic 的时候它还是基于 aiohttp 开发的 web 框架,现如今已经重构了大部分代码,核心组件也都自己实现。
  2. tornado 虽然语法过时了,但是应该是最成熟、最早以及文档最多的一个异步框架。
  3. 之前用tornado的时候还需要造关于异步操作的轮子,现如今生态日趋完善。

最后如果你想使用异步的框架,那么记得所有的io操作均需要异步操作实现,否则会大大影响性能。 (比如第三方的短信服务不能直接使用同步代码的sdk )

参考资料

aiohttp docs

sanic 中文

uvloop

tornado 中文

以上就是python 常用的异步框架汇总整理的详细内容,更多关于python异步框架汇总的资料请关注www.887551.com其它相关文章!