Я реализовал конечную точку для запуска фоновой задачи.Когда вы нажимаете post
, конечная точка возвращает идентификатор задания.Затем вы можете нажать конечную точку get
с идентификатором задачи задания и получить результат или in progress
, если задание все еще выполняется.
Я не использовал celery
для выполнения этой задачи,но django-q , который я нашел легче, чем сельдерей, и более того, django-q использует все батареи, которые уже есть у django.Вот пример API View, который я реализовал с помощью django-q.
from django.urls import reverse
from django_q.models import Task, OrmQ
from django_q.tasks import async, result
from rest_framework.exceptions import NotFound
from rest_framework.response import Response
from rest_framework.views import APIView
def the_function_to_run():
# do something here
pass
class YourTaskApiView(APIView):
def get(self):
# you mustr construct the get url to take the id
task_id = self.kwargs.get('task_id')
try:
task = Task.objects.get(id=task_id)
except Task.DoesNotExist:
task = None
# here the task is on processing
if task:
return Response({
'id': task_id,
'result': result(task_id),
'started': task.started,
'stopped': task.stopped,
'status': 'DONE' if task.stopped else 'RUNNING',
'success': task.success,
})
else:
# here you find the task in the query (not even processed, but waiting for the cluster to process it)
for q in OrmQ.objects.all():
if q.task_id() == task_id:
task = q.task()
return Response({
'id': task['id'],
'started': task['started'],
'status': 'WAITING', # or ON QUEUE
'stopped': None,
'success': None,
})
return NotFound()
def post(self, request):
# run the task as async
task_id = async(the_function_to_run)
# create the reverse for the get so the client already has the link to query for
# the task status
link = reverse('yourapp:yournamespace:yourview', kwargs={'task_id': task_id}, request=request)
return Response(data={'task_id': task_id, 'link': link})