9

How to implement asynchronous tasks in Django rest framework? After python3.7 async.io became part of the python language and coroutines are embedded in the language .

But I can’t make use out of it i had to use celery and a redis server for such async behavior.


Update

class ReportViewSet(viewsets.ModelViewSet):

    queryset = Report.objects.all()
    serializer_class = ReportSerializer
    filter_class = ReportFilter

    def create(self, request):

        serializer = ReportSerializer(data=request.data)

        if serializer.is_valid(raise_exception=True):
            report_obj = serializer.save()
            #Start multiple tools asynchronously but we need to return the next statement without waiting for those tools to finish
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

I tried to modify the create an async function that runs the tools, but i get the error that you can't run this function in an executor that's not a co-routine. When i tried to make the create function async, it returns a co-routine instead of an HTTP response. So the django-rest-framework itself needs to modify its internals to be of co-routine types. Any suggesstions or thoughts on how to do what i mentioned in a good way without using any MQ or caching techniques.

6
  • 1
    What's the problem that you're facing? And can you show the code that you have come up till yet? Commented Dec 24, 2018 at 9:36
  • 1
    You should look into django-channels Commented Dec 24, 2018 at 14:12
  • @saad check my updates Commented Dec 24, 2018 at 21:49
  • 1
    You shouldn't be turning create into an async function. You should have a loop within the create that runs all your logic asynchronously. Commented Dec 25, 2018 at 10:44
  • Can you try to run it on your side? I tried this as well but you have to make the create function async still! Commented Dec 25, 2018 at 10:54

2 Answers 2

2

You shouldn't be turning create into an async function. You should have a loop within the create that runs all your logic asynchronously but even that won't free up the worker process to serve other requests while your async tasks run. The best you can do here is offload the tasks to celery and then poll through another API to check for their status or result.

Django's a synchronous framework and it won't support what you're trying to do here. If you want to have long-polling with overlapping requests then I'd suggest looking into tornado

Sign up to request clarification or add additional context in comments.

Comments

2

You can do it with Async Django REST framework (adrf)

requirements: Python 3.8+, Django 4.1+

Install using pip:

pip install adrf

Add adrf to your INSTALLED_APPS setting:

INSTALLED_APPS = [
    ...
    'adrf',
]

Now in serializers.py:

from adrf.serializers import ModelSerializer


class AsyncReportSerializer(ModelSerializer):

    class Meta:
        model = Report

In views.py:

from adrf.viewsets import ViewSet

from .serializers import AsyncReportSerializer


class AsyncReportViewSet(ViewSet):

    async def post(self, request):

        serializer = AsyncReportSerializer(data=request.data)

        if serializer.is_valid(raise_exception=True):
            await serializer.asave()
    
            return Response(await serializer.adata, status=status.HTTP_201_CREATED)
       

1 Comment

in ModelSerializer I'm using SerializerMethodField from drf, and I've to override to_representation as well. but I get this error: 'SerializerMethodField' object has no attribute 'ato_representation'

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.