views.py 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. from django.http import HttpResponse, Http404
  2. from anyjson import serialize as JSON_dump
  3. from billiard.utils.functional import wraps
  4. from celery.utils import get_full_cls_name
  5. from celery.result import AsyncResult
  6. from celery.registry import tasks
  7. from celery.backends import default_backend
  8. def task_view(task):
  9. """Decorator turning any task into a view that applies the task
  10. asynchronously.
  11. :returns: a JSON dictionary containing the keys ``ok``, and
  12. ``task_id``.
  13. """
  14. def _applier(request, **options):
  15. kwargs = request.method == "POST" and \
  16. request.POST.copy() or request.GET.copy()
  17. kwargs = dict((key.encode("utf-8"), value)
  18. for key, value in kwargs.items())
  19. result = task.apply_async(kwargs=kwargs)
  20. response_data = {"ok": "true", "task_id": result.task_id}
  21. return HttpResponse(JSON_dump(response_data),
  22. mimetype="application/json")
  23. return _applier
  24. def apply(request, task_name):
  25. """View applying a task.
  26. Example:
  27. http://e.com/celery/apply/task_name/arg1/arg2//?kwarg1=a&kwarg2=b
  28. **NOTE** Use with caution, preferably not make this publicly accessible
  29. without ensuring your code is safe!
  30. """
  31. try:
  32. task = tasks[task_name]
  33. except KeyError:
  34. raise Http404("apply: no such task")
  35. return task_view(task)(request)
  36. def is_task_successful(request, task_id):
  37. """Returns task execute status in JSON format."""
  38. response_data = {"task": {"id": task_id,
  39. "executed": AsyncResult(task_id).successful()}}
  40. return HttpResponse(JSON_dump(response_data), mimetype="application/json")
  41. is_task_done = is_task_successful # Backward compatible
  42. def task_status(request, task_id):
  43. """Returns task status and result in JSON format."""
  44. status = default_backend.get_status(task_id)
  45. res = default_backend.get_result(task_id)
  46. response_data = dict(id=task_id, status=status, result=res)
  47. if status in default_backend.EXCEPTION_STATES:
  48. traceback = default_backend.get_traceback(task_id)
  49. response_data.update({"result": str(res.args[0]),
  50. "exc": get_full_cls_name(res.__class__),
  51. "traceback": traceback})
  52. return HttpResponse(JSON_dump({"task": response_data}),
  53. mimetype="application/json")
  54. def task_webhook(fun):
  55. """Decorator turning a function into a task webhook.
  56. If an exception is raised within the function, the decorated
  57. function catches this and returns an error JSON response, otherwise
  58. it returns the result as a JSON response.
  59. Example:
  60. @task_webhook
  61. def add(request):
  62. x = int(request.GET["x"])
  63. y = int(request.GET["y"])
  64. return x + y
  65. >>> response = add(request)
  66. >>> response.content
  67. '{"status": "success", "retval": 100}'
  68. """
  69. @wraps(fun)
  70. def _inner(*args, **kwargs):
  71. try:
  72. retval = fun(*args, **kwargs)
  73. except Exception, exc:
  74. response = {"status": "failure", "reason": str(exc)}
  75. else:
  76. response = {"status": "success", "retval": retval}
  77. return HttpResponse(JSON_dump(response), mimetype="application/json")
  78. return _inner