Django/Python Downloading a file with progressbar - python

Ok i decided to post the question here because i really don't know what to do or even if its possible. You might tell me it's a repost or so but i aready read similar posts about it and it didn't helped me out.
Here is the deal. I have an admin interface with django and want to download a file from an external site on my server with a progressbar showing the percentage of the download.
I can't do anything while it's downloading. I tried to run a command with call_command within a view but it's the same.
Is it because Django server is single threaded? So, is it even possible do achieve what i want to do ?
Thanks in advance,

It's possible but takes some jumps though the metaphorical hoops. My answer isn't Django specific, you'll need to translate it to your framework.
Start a thread that does the actual download. While it downloads, it must update some data structure in the user's session (total size of the download, etc).
In the browser, start a timer which does AJAX requests to a "download status URL"
Create a handler for this URL which takes the status from the session and turns that into JSON or a piece of HTML which you send to the browser.
In the AJAX handler's success method, take the JSON/HTML and put it into the current page. Unless the download is complete (this part is more simple with JSON), restart the timer.

Related

Send api request every x minutes and update context with status

I am trying to make a website, where user can start a task on a button click, which will send an api request every x seconds/minutes. Api request gets a list of offers as a response and the task will check if the api request is the same as before.
If it is then then i want to show status on my page as: "No offers were found, still searching" and if the api response is different the status changes to: "I found an offer"
I wanted to make that process in the background and without need to refresh the page by user. I want the context["status"] to be automatically updated when new offer is found.
I tried to achieve this with threading but the page keep on loading as a task is working.
Every idea is appreciated.
Thanks!
Although you can use Ajax, I prefer to use websocket and, therefore, channels. Have a look to this tutorial: https://realpython.com/getting-started-with-django-channels/ or https://blog.logrocket.com/django-channels-and-websockets/. There are lots of tutorials on the web and also book like Django 3 by example (disclosed: I am not the author). Besides, channels is an official Django project and, it will be part of Django in the coming release.
create a custom result view in django, set a timer on your page and then use jQuery.load()
var l_timer = setInterval(function(){
$( "#result" ).load( "/my_periodic_view", function() {
alert( "Load was performed." );
});
},1000) //1000ms loop
you will require jquery. The better approach is to use ajax calls and rest api(or a socket depending on particular case), but both require additional setup on the server, and if your application does not need more realtime updates, going for the load approach is cheap easy and straightforward.

Python long running process

I have a Python web application in which one function that can take up to 30 seconds to complete.
I have been kicking off the process with a cURL request (inc. parameters) from PHP but I don't want the user staring at a blank screen the whole time the Python function is working.
Is there a way to have it process the data 'in the background', e.g. close the http socket and allow the user to do other things while it continues to process the data?
Thank you.
You should use an asynchronous data approach to transfer data from a PHP script - or directly from the Python script, to an already rendered HTML page on the user side.
Check a javascript framework for the way that is easier for you to do that (for example, jquery). Then return an html page minus results to the user, with the javascript code to show a "calculating" animation, and fetch the reslts, in xml or json from the proper URL when they are done.

What’s the correct way to run a long-running task in Django whilst returning a page to the user immediately?

I’m writing a tiny Django website that’s going to provide users with a way to delete all their contacts on Flickr.
It’s mainly an exercise to learn about Selenium, rather than something actually useful — because the Flickr API doesn’t provide a way to delete contacts, I’m using Selenium to make an actual web browser do the actual deleting of contacts.
Because this might take a while, I’d like to present the user with a message saying that the deleting is being done, and then notify them when it’s finished.
In Django, what’s the correct way to return a web page to the user immediately, whilst performing a task on the server that continues after the page is returned?
Would my Django view function use the Python threading module to make the deleting code run in another thread whilst it returns a page to the user?
Consider using some task queues - one of the most liked by Django community solution is to use Celery with RabbitMQ.
Once I needed this, I set up another Python process, that would communicate with Django via xmlrpc - this other process would take care of the long requests, and be able to answer the status of each. The Django views would call that other process (via xmlrpc) to queue jobs, and query job status. I made a couple proper json views in django to query the xmlrpc process - and would update the html page using javascript asynchronous calls to those views (aka Ajax)

How to properly redirect to another site without breaking the browser back button?

I am trying to make a redirection from a python app to another site. I am currently doing it in the controller which works just fine but breaks the back browser button.
I know that a redirection with meta refresh or js, will allow me to add a delay so the user will have time to go back but I read everywhere that these techniques are deprecated and better be avoided.
Any thoughts or ideas?
Thanks
The correct way is sending HTTP status code 302 instead of 200 and adding Location: <url> to response headers. How to do this depends on the WEB framework you are running your Python app on.

How to return a website and automatically redirect to another side which takes long to load

I ask the user to input some data, after that I redirect him to a 'result' website which takes several seconds to load.
I don't like this, because there is no user feedback telling him, that the server has not crashed and that his result is coming. So I was thinking about showing the user a 'loading' website stating 'please wait' and then automatically redirect him to the 'result' page. The user would see the "please-wait"-website the whole time the other one is loading, as Flask does not serve the site before it is finished with the calculations.
[Attempt to clarify]
One of the pages takes so long, because it waits for a file upload. The other side takes so long because its functions wait for data from a third party api.
How would I do that in Flask?
I was going to suggest Celery for this, but someone just posted this on the Flask mailing list, and this might be a more simpler solution: Hello-Redis-Tasks. If you still want to use Celery though, this is what you should check out: Custom states in celery
Flask's documentation for file uploads includes a section on implementing progress bars for file uploads. Choose one of the many client-side solutions to display the progress of the upload and then redirect once the upload is complete.
For the long-running server side process you have several options:
Pre-fetch (and cache) the data from the slow-to-respond API.
Hijack your link's action with JavaScript and make an ajax request for the data - update the DOM with a status message to let the user know that everything is still working.
Have a three step process. Page #1 has a link to the "Please wait ... " page (Page #2). Page #2 has a meta refresh tag pointing at Page #3 (<meta http-equiv="refresh" content="0; url=/path/to/page3">)

Categories