有什么最简单的方法可以异步运行大量的python请求吗



有一个APIlocalhost:8000/api/postdatetime/,负责更改驱动程序的联机状态。每次驱动程序访问API时,如果返回响应,则驱动程序状态将为联机,否则驱动程序状态为脱机。

Drivers need to give the response within every 10 seconds.如果驾驶员没有响应,则他/她将自动标记为离线。

目前我正在做的是获取所有已登录的驱动程序,并一次一个驱动程序地调用上述API。

为了进行模拟,我填充了数千个驱动程序。使用我的方法保持数千名司机的在线离线将使几乎许多司机离线。

我的方法代码如下所述:

online-offline.py

import requests
import random
import math
from rest_framework.authtoken.models import Token
from ** import get_logged_in_driver_ids
from ** import Driver

def post_date_time():
url = 'localhost:8000/api/postdatetime/'
while True:
# getting all logged in driver ids 
logged_in_driver_ids = get_logged_in_driver_ids() 
# filtering the driver who are logged in and storing their user id in the driver_query variable
driver_query = Driver.objects.only('id', 'user_id').filter(id__in=logged_in_driver_ids).values('user_id')
# storing the user id of driver in list
driver_user_ids = [driver['user_id'] for driver in driver_query]
# getting number of drivers who are supposed to hit the API
drivers_subset_count = math.ceil(len(driver_user_ids)*(random.randint(75, 85)/100))
# shuffle the driver ids list to randomize the driver id order
random.shuffle(driver_user_ids)
# getting the driver list of length drivers_subset_count
required_drivers = driver_user_ids[:drivers_subset_count]
for driver in required_drivers:
token = Token.objects.only('key', 'user_id').get(user_id=driver)
req_headers = {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': 'Token' + ' ' + str(token)
}
response = requests.post(url=url, headers=req_headers)
print(response.text)

if __name == '__main__':
post_date_time()

有没有什么想法可以异步发布请求localhost:8000/api/postdatetime/API,并且可以在10秒内处理大约2-3000个驱动程序?

我对实现异步代码真的很陌生。我读过一些关于aiohttp库的文章,但在实现它时感到困惑

online-offline.py将在整个模拟过程中运行。

如有任何帮助,我们将不胜感激。谢谢:(

在非本地API的情况下,asyncio可以帮助您。要异步发出请求,您必须:

  • 使用特殊语法(async defawait-请阅读此处了解详细信息(
  • 以非阻塞方式发出请求(这样您就可以等待它们(
  • 使用类似方式的asyncio.gather((使多个请求并行">
  • 启动事件循环

虽然可以使用线程使requests库与asyncio协同工作,但使用像aiohttp这样已经异步兼容的库会更容易、更好。

看看这里的代码片段*:它们包含了发出多个并发请求的示例。用同样的方式重写代码,它看起来像:

import asyncio

async def driver_request(driver):
# ...
# use aiohttp to make request with custom headers:
# https://docs.aiohttp.org/en/stable/client_advanced.html#custom-request-headers

async def post_date_time():
# ...
await asyncio.gather(*[
driver_request(driver) 
for driver 
in required_drivers
])

asyncio.run(post_date_time())

在本地,默认情况下你不会看到任何效果,所以要在本地测试它,你必须让localhost发送延迟响应,以模拟真实的网络延迟。


*在最新的Python版本中,事件循环只需使用asyncio.run((即可运行

最新更新