如何从 Django 发送异步 HTTP 请求并在 python2.7 中等待结果?
How to send asynchronous HTTP requests from Django and wait for results in python2.7?
我有几个 API 作为数据源,例如 - 博客文章。我想要实现的是从 Django 视图并行向此 API 发送请求并获得结果。无需将结果存储在数据库中,我需要将它们传递给我的视图响应。我的项目是在python2.7上写的,所以不能用asyncio。我正在寻找有关解决它的最佳实践的建议(芹菜,龙卷风,其他东西?)以及如何实现该目标的示例,因为我只是开始异步。谢谢
一个解决方案是使用 Celery 并将您的请求参数传递给它,并在前面使用 AJAX.
示例:
def my_def (request):
do_something_in_celery.delay()
return Response(something)
要控制一个任务是否在 Celery 中完成,你可以将 Celery 的 return 放在一个变量中:
task_run = do_something_in_celery.delay()
在 task_run 中有一个 属性 .id。
这个 .id 你 return 到你的前面并用它来监视任务的状态。
并且你在 Celery 中执行的函数必须有 de decorator @task
@task
do_something_in_celery(*args, **kwargs):
您需要控制任务,例如 Redis 或 RabbitMQ。
看这个网址:
http://masnun.com/2014/08/02/django-celery-easy-async-task-processing.html
我使用 futures lib 中的 concurrent.futures ThreadPoolExecutor 找到了解决方案。
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)))
您还可以查看 rest of the concurrent.futures doc。
重要!
ProcessPoolExecutor class 在 Python 2 上存在已知(无法修复)问题,不应依赖它来完成关键任务工作。
我有几个 API 作为数据源,例如 - 博客文章。我想要实现的是从 Django 视图并行向此 API 发送请求并获得结果。无需将结果存储在数据库中,我需要将它们传递给我的视图响应。我的项目是在python2.7上写的,所以不能用asyncio。我正在寻找有关解决它的最佳实践的建议(芹菜,龙卷风,其他东西?)以及如何实现该目标的示例,因为我只是开始异步。谢谢
一个解决方案是使用 Celery 并将您的请求参数传递给它,并在前面使用 AJAX.
示例:
def my_def (request):
do_something_in_celery.delay()
return Response(something)
要控制一个任务是否在 Celery 中完成,你可以将 Celery 的 return 放在一个变量中:
task_run = do_something_in_celery.delay()
在 task_run 中有一个 属性 .id。 这个 .id 你 return 到你的前面并用它来监视任务的状态。
并且你在 Celery 中执行的函数必须有 de decorator @task
@task
do_something_in_celery(*args, **kwargs):
您需要控制任务,例如 Redis 或 RabbitMQ。
看这个网址:
http://masnun.com/2014/08/02/django-celery-easy-async-task-processing.html
我使用 futures lib 中的 concurrent.futures ThreadPoolExecutor 找到了解决方案。
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)))
您还可以查看 rest of the concurrent.futures doc。
重要! ProcessPoolExecutor class 在 Python 2 上存在已知(无法修复)问题,不应依赖它来完成关键任务工作。