Python 3.7 非阻塞请求?
Python 3.7 Non-Blocking Request?
我想在 Python 3.7 中执行非阻塞 http 请求。 this SO post 中对我尝试做的事情进行了很好的描述,但目前还没有公认的答案。
到目前为止,这是我的代码:
import asyncio
from aiohttp import ClientSession
[.....]
async def call_endpoint_async(endpoint, data):
async with ClientSession() as session, session.post(url=endpoint, data=data) as result:
response = await result.read()
print(response)
return response
class CreateTestScores(APIView):
permission_classes = (IsAuthenticated,)
def post(self, request):
[.....]
asyncio.run(call_endpoint_async(url, data))
print('cp #1') # <== `async.io` BLOCKS -- PRINT STATEMENT DOESN'T RUN UNTIL `asyncio.run` RETURNS
在 Python 中执行 Ajax 样式的非阻塞 http 请求的正确方法是什么?
如果您的程序 运行 在 asyncio 中,Asyncio 可以轻松发出非阻塞请求 。例如:
async def doit():
task = asyncio.create_task(call_endpoint_async(url, data))
print('cp #1')
await asyncio.sleep(1)
print('is it done?', task.done())
await task
print('now it is done')
但这要求 "caller" 也是异步的。在您的情况下,您希望整个 asyncio 事件循环在后台 运行 ,这样。这可以通过 运行 在单独的线程中实现,例如:
pool = concurrent.futures.ThreadPoolExecutor()
# ...
def post(self, request):
fut = pool.submit(asyncio.run, call_endpoint_async(url, data))
print('cp #1')
但是,在那种情况下,您无法通过使用 asyncio 获得任何东西。由于无论如何您都在使用线程,因此您也可以先调用 requests.get()
等同步函数。
我想在 Python 3.7 中执行非阻塞 http 请求。 this SO post 中对我尝试做的事情进行了很好的描述,但目前还没有公认的答案。
到目前为止,这是我的代码:
import asyncio
from aiohttp import ClientSession
[.....]
async def call_endpoint_async(endpoint, data):
async with ClientSession() as session, session.post(url=endpoint, data=data) as result:
response = await result.read()
print(response)
return response
class CreateTestScores(APIView):
permission_classes = (IsAuthenticated,)
def post(self, request):
[.....]
asyncio.run(call_endpoint_async(url, data))
print('cp #1') # <== `async.io` BLOCKS -- PRINT STATEMENT DOESN'T RUN UNTIL `asyncio.run` RETURNS
在 Python 中执行 Ajax 样式的非阻塞 http 请求的正确方法是什么?
如果您的程序 运行 在 asyncio 中,Asyncio 可以轻松发出非阻塞请求 。例如:
async def doit():
task = asyncio.create_task(call_endpoint_async(url, data))
print('cp #1')
await asyncio.sleep(1)
print('is it done?', task.done())
await task
print('now it is done')
但这要求 "caller" 也是异步的。在您的情况下,您希望整个 asyncio 事件循环在后台 运行 ,这样。这可以通过 运行 在单独的线程中实现,例如:
pool = concurrent.futures.ThreadPoolExecutor()
# ...
def post(self, request):
fut = pool.submit(asyncio.run, call_endpoint_async(url, data))
print('cp #1')
但是,在那种情况下,您无法通过使用 asyncio 获得任何东西。由于无论如何您都在使用线程,因此您也可以先调用 requests.get()
等同步函数。