Python中的异步请求

今天,我们将学习异步请求;这个讨论将引出代码实例,看看我们如何在Python中编写异步请求。

Python中的异步请求

异步请求是我们系统的核心。我们可以把它们想成如下:

当用户加载我们的网站(网站或网络应用)时,用户立即开始看到内容。但它还没有完全准备好。所以我们在用户继续与页面互动时,在后台异步加载内容。

这些请求在等待响应时不会阻止后续代码的执行。这意味着,在处理请求的同时,其他代码可以继续运行。

在处理外部资源时,如API调用,可能需要一些时间来响应,这可能是有帮助的。它还可以使你的代码更有响应性,因为在处理请求的同时,用户界面可以继续更新。

在Python中使用异步请求的重要性

异步请求是提高Python应用程序性能的一个好方法。当发出请求时,Python解释器可以在处理请求的同时继续执行其他代码。

它可以导致速度的显著提高,特别是对于那些提出大量请求的应用程序。然而,在使用异步请求时,以下是几个必须记住的要点。

  1. 首先,我们必须避免同时发出太多的请求。如果我们发出太多的请求,解释器会被淹没,速度会变慢。
  2. 第二,我们需要准备好处理错误。如果一个请求失败,解释器就不能继续执行代码。

总的来说,异步请求是一个很好的工具,可以提高我们的Python应用程序的性能。但是,要小心使用;它们可以帮助我们的应用程序运行得更快、更顺畅。

在Python中编写异步请求的最简单方法

使用asyncio 模块可以轻松地进行异步请求。此外,python的asyncio 库提供了编写异步代码的工具。例如,我们可以使用asyncio.sleep() 来暂停一个 coroutine,使用asyncio.wait() 来等待一个 coroutine 完成。

要写一个异步请求,我们需要首先创建一个coroutine。我们可以使用asyncio.ensure_future() 函数来完成。一旦我们有了一个循环程序,我们可以使用asyncio.sleep() 函数来暂停它,使用asyncio.wait() 函数来等待它完成。

在Python中处理异步请求

首先,如果我们想在Python中运行异步请求,那么你应该通过使用以下命令安装aiohttp 的python库。

pip install aiohttp

我们可以使用异步请求来提高Python应用程序的性能。通过并行请求,我们可以极大地加快程序的速度。

在Python中,有一些不同的方法来处理异步请求。最流行的是asyncio 库。这个库提供了强大的工具来处理async 请求。

另一个流行的选择是grequests 库。这个库的使用比asyncio 要简单一些,但它也同样有效。

我们选择哪个选项将取决于我们的具体需求。但无论我们选择哪一种,通过使我们的请求async ,我们肯定会看到一个显著的性能提升。

import grequests
urls = [
    'http://www.heroku.com',
    'http://tablib.org',
    'http://httpbin.org',
    'http://python-requests.org',
    'http://kennethreitz.com'
]
rs = (grequests.get(u) for u in urls)
grequests.map(rs)

异步请求所需的Python库

我们可以使用许多Python库来进行异步请求。最流行的是aiohttpasyncio

aiohttp 异步请求库

aiohttp 是一个使我们能够进行异步 HTTP 请求的库。它建立在 的基础上,提供了一个简单的接口来进行 HTTP 请求。asyncio

asyncio 异步请求库

asyncio 是一个支持 Python 异步编程的库。它使我们能够编写异步代码,并使我们能够轻松使用支持 的库。asyncio

aiohttpasyncio 都可以在PyPI 上找到,可以用 pip 安装。

import asyncio
import aiohttp
import json
from text_api_config import apikey

异步请求与常规请求

我们可以向服务器发出两种类型的请求:异步和常规。异步请求是在后台进行的,而用户仍然在与页面进行交互。典型的请求是在页面加载时进行的。

异步请求通常比常规请求更快、更有效,因为它们不会阻止页面的加载。然而,它们的实现可能更加复杂,而且所有的浏览器并不总是支持它们。

代码示例:

import requests
import time
start_time = time.time()
for number in range(1, 151):
    url = f'https://pokeapi.co/api/v2/pokemon/{number}'
    resp = requests.get(url)
    pokemon = resp.json()
    print(pokemon['name'])
print("--- %s seconds ---" % (time.time() - start_time))

输出:

bulbasaur
ivysaur
venusaur
....
dragonair
dragonite
mewtwo
--- 68.17992424964905 seconds

Python中的theasyncio 模块

asyncio 是一个用于Python中并发编程的模块。它提供了一个管理并发线程、任务和事件的框架。 ,用于编写可以并发执行多个任务的程序。asyncio

asyncio 是基于coroutines的概念。coroutine是一个可以暂停其执行并将控制权交还给调用者的函数。它允许多个coroutine同时运行。

asyncio 它提供了管理程序的工具,包括一个事件循环、任务调度器和并发数据结构。

asyncio 是编写并发程序的一种有效方式。它易于使用,可以扩展到大型程序。对于需要多个任务并发的程序, 是一个很好的选择。asyncio

代码示例:

import asyncio
import aiohttp
import json
from text_api_config import apikey
async def gather_with_concurrency(n, *tasks):
    semaphore = asyncio.Semaphore(n)
    async def sem_task(task):
        async with semaphore:
            return await task
    return await asyncio.gather(*(sem_task(task) for task in tasks))

Python中的theaiohttp 模块

aiohttp 模块是一个用于 Python 的异步 HTTP 客户端/服务器。它建立在asyncio 上,提供了一个简单的 API 来处理 HTTP。

aiohttp 模块使在 Python 中使用 HTTP 更加容易。它提供了一个简单的 API,使发送和接收 HTTP 请求和响应变得容易。

aiohttp 模块还提供了一种运行异步 HTTP 服务器的方法。

import asyncio
import aiohttp
import json
from text_api_config import apikey
async def main():
    conn = aiohttp.TCPConnector(limit=None, ttl_dns_cache=300)
    session = aiohttp.ClientSession(connector=conn)
    urls = [summarize_url, ner_url, mcp_url]
    conc_req = 3

Async Python中的请求

代码示例:

import queue
def task1(name, s_queue):
    if s_queue.empty():
        print(f'Task {name} has nothing to do')
    else:
        while not s_queue.empty():
            cnt = s_queue.get()
            total = 0
            for x in range(cnt):
                print(f'Task {name} is working now.')
                total += 1
            print(f'Task {name} is working with a total of: {total}')
def s_async():
    s_queue = queue.Queue()
    for work in [2, 5, 10, 15, 20]:
        s_queue.put(work)
    tasks = [
        (task1, 'Async1', s_queue),
        (task1, 'Async2', s_queue),
        (task1, 'Async3', s_queue)
    ]
    for t, n, q in tasks:
        t(n, q)
if __name__ == '__main__':
    s_async()

输出:

Task Async1 is running now.
Task Async1 is running with a total of: 2
Task Async1 is running now
...
Task Async1 is running now.
Task Async1 is running with a total of: 5
Task Async1 is running now
...
Task Async1 is running now.
Task Async1 is running with a total of: 10
Task Async1 is running now
...
Task Async1 is running now.
Task Async1 is running with a total of: 15
Task Async1 is running now
...
Task Async1 is running now.
Task Async1 is running with a total of: 20
Task Async3 has nothing to do