Асинхронная среда Python

задняя часть Python

написать впереди

С тех пор, как python3 представил новый синтаксис для асинхронного программирования, асинхронные веб-фреймворки росли как грибы после дождя, и производительность асинхронных фреймворков становилась все более интенсивной. Сегодня я организую асинхронные фреймворки про python.

текст начинается

asyncio — это стандартная библиотека, представленная в Python 3.4, со встроенной прямой поддержкой асинхронного ввода-вывода.

asyncio поддерживает очередь EventLoop в одном потоке, а затем добавляет задачи, которые должны выполнять асинхронный ввод-вывод, в очередь EventLoop.Что касается завершения задач, последующие задачи реализуются с помощью логики обратного вызова. Если у вас есть базовые знания JavaScript, понять асинхронность Python очень просто, ключевые слова, синтаксис и принципы реализации очень похожи.

import asyncio

async def main():
    print('Hello ...')
    await asyncio.sleep(1)
    print('... World!')

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

1. Tornado

Tornado — это веб-фреймворк Python и библиотека асинхронных сетей, первоначально разработанная FriendFeed.Используя неблокирующий сетевой ввод-вывод, Tornado может поддерживать десятки тысяч соединений, обрабатывать постоянные соединения, WebSockets и другие потребности для поддержания постоянных соединений с каждым пользователем. Приложения.

Вставьте официальную демо ниже:

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, поддерживает websocket, не требует обратной записи кода, имеет богатую экологию, среднюю цену и т. д., сервер и клиент «из коробки».

Вставьте официальную демо ниже:

# 客服端代码
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-sessionОбеспечьте поддержку сеансов для службы aiohttp и поддержите базу данных сохраняемости данных.
  • aiohttp-debugtoolbarПредоставляет инструменты отладки для aiohttp (регистрация информации о стеке для исключений asyncio).
  • aiohttp-securityПредоставляет подключаемые модули, связанные с аутентификацией и разрешениями, для aiohttp.
  • aiohttp-devtoolsИнструмент разработки aiohttp, обеспечивающий развертывание среды разработки и прокси статических ресурсов.
  • aiohttp-corsПоддержка междоменной аутентификации CORS.
  • aiohttp-sseПоддержка событий на стороне сервера (служба push-сообщений на стороне сервера).
  • pytest-aiohttpподдержка среды тестирования pytest.
  • aiohttp-makoПоддержка рендеринга шаблонов Mako на стороне сервера.
  • aiohttp-jinja2Поддержка рендеринга шаблонов на стороне сервера Jinja2 (знаменитый движок рендеринга фляг).
  • aiozipkinОтслеживание сервисов в распределенных системах обеспечивает поддержку данных для проблем с задержкой в ​​микросервисах.

База данных aiohttp поддерживает:

  • aiopgПоддержка асинхронности PostgreSQL.
  • aiomysqlАсинхронная поддержка MySql.
  • aioredisАсинхронная поддержка Redis.
  • asyncpgДругой — асинхронная поддержка PostgreSQL, которая более эффективна, чем aiopg, но API не является универсальным.

3.Sanic

Sanic — это асинхронный веб-сервер и веб-фреймворк для Python 3.7+. Цель — предоставить простой способ запуска и запуска простого в сборке, расширении и максимальной производительности HTTP-сервера. веб-фреймворк.

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.

Официальная демонстрация:

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, основанная на Python 3.6+ и поддерживающая стандартные подсказки типов Python. Также один из самых быстрых веб-фреймворков Python, наравне с 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 и быстро получать данные страницы.

Официальная демонстрация:

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, Tornado постепенно упал с алтаря. Но неважно, кто самый быстрый, важна экология, и важно не изобретать велосипед.

PS:

  1. Я помню, что когда я узнал о Sanic раньше, это был веб-фреймворк, разработанный на основе aiohttp, сейчас большая часть кода была рефакторинг, а основные компоненты были реализованы сами по себе.

  2. Хотя у tornado устаревший синтаксис, он должен быть самой зрелой, ранней и наиболее задокументированной асинхронной структурой.

  3. При использовании торнадо раньше нужно было строить колесо для асинхронных операций, но сейчас экология становится все совершеннее.

Наконец, если вы хотите использовать асинхронный фреймворк, помните, что все операции ввода-вывода должны быть реализованы асинхронно, иначе производительность сильно пострадает.(Например, сторонние СМС-сервисы не могут напрямую использовать sdk кода синхронизации)

использованная литература

Aiohttp docs

саник на китайском

Uvloop

торнадо на китайском