so I'm currently writing a Flask application and I am new to flask.
There is some processing going on, which I outsourced to a separate function.
As this processing takes some time, I wanted to give the user a progress update on how many iterations have passed. No problem so far.
However, as soon I call the render template, the function ends and I cannot update that variable anymore.
I was imagining an if loop. if that variable changes, render template with the new variable as input.
But after the first iteration, the if loop will brake.
Currently, the render template renders an html function, which just displays the variable it receives. I want to update that variable as soon as it changes.
Do you guys have any suggestion, on how I could achieve this "background update"?
Cheers and thanks!
You need some kind of ongoing request/response cycle.
As soon as your app sends the response with the rendered template back to the browser, this connection is closed and there's no way to send any more data.
There's a few things that need to happen in order to accomplish what you want:
The long running function needs to run in the background so it doesn't block execution of the rest of the application
There has to be a way to get a status update from the long running function
The client (ie browser) needs a way to receive the status updates
1 and 2 can be solved using celery. It allows you to run tasks in the background and the task to send information via a side channel to be consumed elsewhere.
The easiest way to achieve 3 would be to set up a route in your flask application that returns information about the task, and request it periodically from the browser using some JavaScript. The more favorable method in my opinion would be to use websockets to actively send out the information to the client, but this is a bit more complicated.
This is just a rough outline, but there's a tutorial by Miguel Grinberg about how to set this up using celery and polling from JS.
Related
I am trying to build a browser-based debugging tool for Python but I am having trouble combining the Python inner workings with user interactions. My setup looks like this (jsfiddle link). Essentially I am using sys.settrace to inspect a function one opcode at a time. My goal is for the user to be able to manually step forward each instruction by pressing the Step button.
The problems I am having is that the tracer function cannot be asynchronous because Python does not like that, and if it is synchronous there is no real way to stop and wait for input/interaction. If I make just an infinite while loop it freezes the browsers main thread so the page becomes unresponsive.
Does anyone have advice on how I can structure this to allow interaction between the UI and the tracer function?
I managed to get a work-around working based on a service worker. I used an example implementation from here. It utilizes the fact that you can make a synchronous thread wait for an HTTP request, so we intercept that request using a service worker and make it last for as long as we need, and when we're done we can even send data back with the request.
What I'm trying to accomplish:
I have a sensor that is constantly reading in data. I need to print this data to a UI whenever data appears. While the aforementioned task is taking place, the user should be able to write data to the sensor. Ideally, both these tasks would / could happen at the same time. Currently, I have the program written using flask; but if django would be better suited (or a third party) I would be willing to make the switch. Note: this website will never be deployed so no need to worry about that. Only user will be me, running program from my laptop.
I have spent a lot of time researching flask async functions and coroutines; however I have not seen any clear indications if something like this would be possible.
Not looking for a line by line solution. Rather, a way (async, threading etc) to set up the code such that the aforementioned tasks are possible. All help is appreciated, thanks.
I'm a Django guy, so I'll throw out what I think could be possible
Django has a decorator #start_new_thread which can be put on any function and it will run in a thread.
You could make a view, POST to it with Javascript/Ajax and start a thread for communication with the sensor using the data POSTed.
You could also make a threading function that will read from the sensor
Could be a management command or a 'start' btn that POSTs to a view that then starts the thread
Note: You need to do Locks or some other logic so the two threads don't conflict when reading/writing
Maybe it's a single thread that reads/writes to the sensor and each loop it checks if there's anything to write (existence + contents of a file? Maybe db entry?
Per the UI, lets say a webpage. You're best best would be Websockets, but because you're the only one that will ever use it you could just write up some Javascript/Ajax that would Ping a view every x seconds and display the new data on the webpage
Note: that's essentially what websockets do, ping every x seconds
Now the common thread is Javascript/Ajax, this is so the page doesn't need to refresh and you can constantly see the data coming in without the page being refreshed.
You can probably do all of this in Flask if you find a similar threading ability and just add some javascript to the frontend
Hopefully you find some of this useful, and idk why stackoverflow hates these types of questions... They're literally fine
I'm building what might end up being a web-app / game for a fun side-project. In the app the user has the ability to kick off a server-side function that will do a few processes on the back end. At times this could take a few minutes, so I'm try to work out how to return text from Django to the front end without doing a full 'return' from backend to front. Is there a good way of doing this? I experimented with StreamingHttpResponse, but couldn't figure it out, and am not even sure if it's the right solution. Below is a sample for what my flow looks like.
Current state
User hits button on website and there is an Ajax post call to a
Django function
This Django function calls ~4 sub-functions, each doing certain
processing
After the completion of all sub-functions (~2 minutes of a static
front-end), Django returns HTTPResponse of success and triggers a
refresh of the front end page
Desired State
User hits button on website and there is an Ajax post call to a Django function
This Django function calls ~4 sub-functions, each doing certain processing
After the completion of sub-function 1 (~30 seconds), a message is returned to the front-end saying 'X process done, 25% complete for this period'
After the completion of sub-function 2 (~30 seconds), a message is returned to the front-end saying 'Y process done, 50% complete for this period'... etc for other functions
After the completion of all sub-functions, Django returns HTTPResponse of success and triggers a refresh of the front end page
Thanks!
Actually, you are trying to make a full-duplex client-server communication. There are many strategies to make that possible :
WebSockets, chat protocols, IoT protocols, and more.
In Django, there is a nice package called channels to implement that : https://channels.readthedocs.io/en/latest/
Answer Lazy URI ressources
A strategy may be to immediately answer a
HTTPResponse with a URI that will serve the resource when it will be available (with a security token). And you can expose another endpoint the Front End can call whenever it wants to know the processing progress, giving its token.
Asynchronous workloads
What I understand is that you made the processing synchronously, blocking the HTTP answer during all the processing tasks. Actually, with timeout policies, it could be problematic.
And finally, if you think to scale your app, you would probably like to split purely answering HTTP requests, and long-processing workloads.
For that, you may need asynchronous processing, for which celery is python natural candidate.
I have build an application outside of Django which i would like to interact with Django. So within a view in Django i would like to start and stop this application. While the application is running it will return a JSON string which has to be pushed back to the view and processed client-side with JavaScript. The application is pretty much blocking as it is a while-loop running until it has been killed.
It is very important to stress that this is an experimental project and wont be used in production, so it has to work and nothing more than that as i intend to use this for one demonstration.
So to sum it up, i want to (1) start the application from the view, (2) the application runs and returns JSON values to the view and (3) at any given time i should be able to kill the application (while-loop in this case).
Another option is to use for example Tornado, but it seems very comprehensive for such a simple test..
Have you tried django-celery?
I have a python code which starts running on a button click. This function takes some time to complete. In my django code, the result page is displayed after this function has completed execution.
But what I want is some sort of queue based mechanism using which my currently running function can pass the partial results (list of links) as it computes it, to the views and the result page contents are updated dynamically according to data in the queue so that the user won't have to wait for the whole function to finish exception and can see partial results on the result page.
I am new to django and web development. How can this be done in django? Is there any library for doing this?
Thank you in advance
You can't do the partial computation in a function synchronous way. You can try to consider this library celery to do the asynchronous execution.
OR ELSE
You have to go with intermediate middleware where Python and Javascript can be communicated in thread safe way like redis queue, zmq etc..
Ajax would be more appropriate to do this kind of "real time" updates. It allows you to send asynchronous (the A of AJAX) requests/datas.
Put a script in your web page that will update the render everytime your server send new datas.
You can find more on this here : http://api.jquery.com/jquery.ajax/