[Django]-How to use async function based views in DRF?

11๐Ÿ‘

As of now, DRF doesnโ€™t support async "api views". Here is an open issue (#7260) in the DRF community and it is still in the discussion stage.

But, Django providing a decorator/wrapper which allow us to convert our sync views/function to async using sync_to_async(...) wrapper.

Example,

@sync_to_async
@api_view(["GET"])
def sample_view(request):
    data = get_data()
    return Response(data)

Note that, here, sample_view(...) and get_data(...) are sync functions.

๐Ÿ‘คJPG

5๐Ÿ‘

You can do it with adrf:

pip install adrf

then add it to INSTALLED_APPS

INSTALLED_APPS = [
    ...
    'adrf',
]


import asyncio
from asgiref.sync import sync_to_async

@sync_to_async  
def do_a_network_call(some_input):  
    expensive_result = do_expensive_network_call(some_input)
    return expensive_result
    
# Class Based Views:
from adrf.views import APIView

class AsyncView(APIView):
    async def get(self, request):
        result = await asyncio.gather(do_a_network_call("some_input"))  
        return Response({"result": result})


# Function Based Views:
from adrf.decorators import api_view

@api_view(['GET'])
async def async_view(request):
    result = await asyncio.gather(do_a_network_call("some_input"))
    return Response({"result": result})

0๐Ÿ‘

I think you can Use this decorator in DRF

import asyncio
from functools import wraps


def to_async(blocking):
    @wraps(blocking)
    def run_wrapper(*args, **kwargs):
        return asyncio.run(blocking(*args, **kwargs))

    return run_wrapper

Example of usage

@to_async
@api_view(["GET"])
async def sample_view(request):
    ...

Leave a comment