Python 3.7 Запрос на блокировку? - PullRequest
0 голосов
/ 08 ноября 2019

Я хотел бы сделать неблокирующий http-запрос в Python 3.7. То, что я пытаюсь сделать, хорошо описано в этом SO сообщении , но на него еще нет принятого ответа.

Вот мой код:

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

Как правильно выполнить неблокирующий http-запрос в стиле Ajax в Python?

1 Ответ

2 голосов
/ 08 ноября 2019

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')

Но для этого необходимо, чтобы "вызывающий" также был асинхронным. В вашем случае вы хотите, чтобы весь цикл событий 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().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...