Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any way to make an asynchronous function call from Python [Django]?

I am creating a Django application that does various long computations with uploaded files. I don't want to make the user wait for the file to be handled - I just want to show the user a page reading something like 'file is being parsed'.

How can I make an asynchronous function call from a view?

Something that may look like that:

def view(request):
    ...
    if form.is_valid():
        form.save()
        async_call(handle_file)
    return render_to_response(...)
like image 265
DataGreed Avatar asked Aug 29 '09 23:08

DataGreed


People also ask

How do you use asynchronous call in Django?

Django has support for writing asynchronous (“async”) views, along with an entirely async-enabled request stack if you are running under ASGI. Async views will still work under WSGI, but with performance penalties, and without the ability to have efficient long-running requests.

How do I call a function asynchronously in Python?

To run an async function (coroutine) you have to call it using an Event Loop. Event Loops: You can think of Event Loop as functions to run asynchronous tasks and callbacks, perform network IO operations, and run subprocesses. Example 1: Event Loop example to run async Function to run a single async function: Python3.

What are asynchronous tasks in Django?

An async view function in Django is detected by the annotation async def , which then runs the async view in a thread within its own event loop. This gives the benefit of being able to do and run tasks concurrently inside the async views.

Is Django REST asynchronous?

Django REST framework is built on Django, which is a synchronous framework for web applications. If you're already using a synchronous framework like Django, having a synchronous API is less of an issue.


2 Answers

Rather than trying to manage this via subprocesses or threads, I recommend you separate it out completely. There are two approaches: the first is to set a flag in a database table somewhere, and have a cron job running regularly that checks the flag and performs the required operation.

The second option is to use a message queue. Your file upload process sends a message on the queue, and a separate listener receives the message and does what's needed. I've used RabbitMQ for this sort of thing, but others are available.

Either way, your user doesn't have to wait for the process to finish, and you don't have to worry about managing subprocesses.

like image 152
Daniel Roseman Avatar answered Oct 11 '22 16:10

Daniel Roseman


I have tried to do the same and failed after multiple attempt due of the nature of django and other asynchronous call.

The solution I have come up which could be a bit over the top for you is to have another asynchronous server in the background processing messages queues from the web request and throwing some chunked javascript which get parsed directly from the browser in an asynchronous way (ie: ajax).

Everything is made transparent for the end user via mod_proxy setting.

like image 22
Chmouel Boudjnah Avatar answered Oct 11 '22 16:10

Chmouel Boudjnah