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