Skip to content
Advertisement

Is there a way to stop or cancel a urlretrieve in python?

So I basically have written a program in python using tkinter and urllib.request which is supposed to work as a downloader, but each downloader has to have a pause or cancel button but I can’t seem to find anyway to do this! Recently I bumped into the same question in stackoverflow( the link: Is it possible to stop (cancel) urlretrieve process?) and it seems like that I have to use threads or multi-processing but I don’t have a single idea how to do this! By the way how is threading or multi-processing going to help with the canceling pausing the download? Can someone explain to me what should I do? Is there anyway to do this without threading or multi-processing? If there is not, can you explain how to use threading or multi-processing in this program because I don’t have a single clue what to do! Please help me out on this. My code:

JavaScript

Advertisement

Answer

When running a function like urlretrieve in a single thread or process, there is no way to stop it because there is only one thread or process.

In this case, you are calling urlretrieve from a tkinter callback. Those are called by tkinter from the mainloop, effectively interrupting the mainloop.

This might not be a problem for a small download from a host on a fast connection. But if the download takes second or minutes then you have a problem. Because while urlretrieve is in progress, your GUI is unresponsive because the mainloop is waiting for your callback to finish.

So even if you were to have a “Cancel” button, it would not respond als long as urlretrieve is running.

Read the urlretrieve function from the file urllib/request.py in your Python directory. It’s not a big function and should be relatively easy to follow. Internally, urlretrieve contains a loop that reads from a URL and writes to a file. By defaults, such reads wait until there is anything to read. The thing is; there is no way to interrupt this loop.

So one way or another, you will have to re-write urlretrieve. In this re-written version you should check in every iteration of the inner loop if you should continue.

You basically have two options;

  1. Work the functionality of urlretrieve into the event loop.
  2. Work the functionality of urlretrieve into a different thread.

Each has their pros and cons. If you are using Python 3, starting a threading.Thread is probably the easiest thing to do because tkinter in Python 3 is thread-safe.

For an example of the first approach, see unlock-excel.pyw from my scripts repo on github. In this application, a long operation is divided into several small steps that are called from the tkinter eventloop via the after method.

I don’t have an example handy for the method with using a thread. Basically you have to rewrite urlretrieve to check a variable (e.g. a threading.Event) that signals if it should stop in the inner while loop.

User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement