Как отправлять асинхронные HTTP-запросы от Django и ждать результатов в python2.7? - PullRequest
0 голосов
/ 11 февраля 2019

У меня есть несколько API в качестве источников данных, например - сообщения в блоге.То, чего я пытаюсь добиться, - это отправлять запросы к этому API параллельно из представления Django и получать результаты.Нет необходимости хранить результаты в БД, мне нужно передать их в мой ответ просмотра.Мой проект написан на Python 2.7, поэтому я не могу использовать asyncio.Я ищу совет по наилучшей практике для ее решения (сельдерей, торнадо, что-то еще?) С примерами того, как этого добиться, потому что я только начинаю свой путь в асинхронном режиме.Спасибо.

Ответы [ 2 ]

0 голосов
/ 19 февраля 2019

Я нашел решение, используя concurrent.futures ThreadPoolExecutor из futures lib .

import concurrent.futures
import urllib.request

URLS = ['http://www.foxnews.com/',
        'http://www.cnn.com/',
        'http://europe.wsj.com/',
        'http://www.bbc.co.uk/',
        'http://some-made-up-domain.com/']

# Retrieve a single page and report the URL and contents
def load_url(url, timeout):
    with urllib.request.urlopen(url, timeout=timeout) as conn:
        return conn.read()

# We can use a with statement to ensure threads are cleaned up promptly
with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
    # Start the load operations and mark each future with its URL
    future_to_url = {executor.submit(load_url, url, 60): url for url in URLS}
    for future in concurrent.futures.as_completed(future_to_url):
        url = future_to_url[future]
        try:
            data = future.result()
        except Exception as exc:
            print('%r generated an exception: %s' % (url, exc))
        else:
            print('%r page is %d bytes' % (url, len(data)))

Вы также можете проверить оставшуюся часть документа concurrent.futures .

Важно! Класс ProcessPoolExecutor обнаружил (нефиксированные) проблемы в Python 2 и не должен использоваться для критически важной работы.

0 голосов
/ 11 февраля 2019

Решением является использование Celery и передача аргументов вашего запроса на это, а спереди - AJAX.

Пример:

def my_def (request):
    do_something_in_celery.delay()
    return Response(something)    

Для контроля выполнения задачи в Celery,Вы можете поместить возвращение Celery в переменную:

task_run = do_something_in_celery.delay()

В task_run есть свойство .id.Это .id вы возвращаетесь на свой фронт и используете его для мониторинга состояния задачи.

И ваша функция, выполняемая в Celery, должна иметь de decorator @ task

@task
do_something_in_celery(*args, **kwargs):

Вам понадобитсяуправлять задачами, как Redis или RabbitMQ.

Посмотрите эти URL:

http://masnun.com/2014/08/02/django-celery-easy-async-task-processing.html

https://buildwithdjango.com/blog/post/celery-progress-bars/

http://docs.celeryproject.org/en/latest/index.html

...