<p>I am writing a little application to download files over http (as, for example, described <a href="https://stackoverflow.com/questions/22676/how-do-i-download-a-file-over-http-using-python#22776">here</a>).</p>

<p>I also want to include a little download progress indicator showing the percentage of the download progress.</p>

<p>Here is what I came up with:</p>

<pre>
    sys.stdout.write(rem_file + "...")    
    urllib.urlretrieve(rem_file, loc_file, reporthook=dlProgress)

    def dlProgress(count, blockSize, totalSize):
      percent = int(count*blockSize*100/totalSize)
      sys.stdout.write("%2d%%" % percent)
      sys.stdout.write("\b\b\b")
      sys.stdout.flush()
</pre>

<p>Output: MyFileName... 9%</p>

<p>Any other ideas or recommendations to do this? </p>

<p>One thing that's somewhat annoying is the blinking cursor in the terminal on the first digit of the percentage. Is there a way to prevent this? Is there a way to hide the cursor?</p>

<p><strong>EDIT:</strong></p>

<p>Here a better alternative using a global variable for the filename in dlProgress and the '\r' code:</p>

<pre>
    global rem_file # global variable to be used in dlProgress

    urllib.urlretrieve(rem_file, loc_file, reporthook=dlProgress)

    def dlProgress(count, blockSize, totalSize):
      percent = int(count*blockSize*100/totalSize)
      sys.stdout.write("\r" + rem_file + "...%d%%" % percent)
      sys.stdout.flush()
</pre>

<p>Output: MyFileName...9% </p>

<p>And the cursor shows up at the END of the line. Much better.</p>

[{'answer_id': 51214, 'author': 'hazzen', 'author_id': 5066, 'author_profile': 'https://Stackoverflow.com/users/5066', 'pm_score': 2, 'selected': False, 'text': '<p>If you use the <code>curses</code>  package, you have much greater control of the console. It also comes at a higher cost in code complexity and is probably unnecessary unless you are developing a large console-based app.</p>\n\n<p>For a simple solution, you can always put the spinning wheel at the end of the status messge (the sequence of characters <code>|, \\, -, /</code> which actually looks nice under blinking cursor.</p>\n'}, {'answer_id': 51218, 'author': 'Commodore Jaeger', 'author_id': 4659, 'author_profile': 'https://Stackoverflow.com/users/4659', 'pm_score': 4, 'selected': False, 'text': '<p>You might also try:</p>\n\n<pre><code>sys.stdout.write("\\r%2d%%" % percent)\nsys.stdout.flush()\n</code></pre>\n\n<p>Using a single carriage return at the beginning of your string rather than several backspaces. Your cursor will still blink, but it\'ll blink after the percent sign rather than under the first digit, and with one control character instead of three you may get less flicker.</p>\n'}, {'answer_id': 51239, 'author': 'readonly', 'author_id': 4883, 'author_profile': 'https://Stackoverflow.com/users/4883', 'pm_score': 5, 'selected': True, 'text': '<p>There\'s a text progress bar library for python at  <a href="http://pypi.python.org/pypi/progressbar/2.2" rel="noreferrer">http://pypi.python.org/pypi/progressbar/2.2</a> that you might find useful:</p>\n<blockquote>\n<p>This library provides a text mode progressbar. This is tipically used to display the progress of a long running operation, providing a visual clue that processing is underway.</p>\n<p>The ProgressBar class manages the progress, and the format of the line is given by a number of widgets. A widget is an object that may display diferently depending on the state of the progress. There are three types of widget: - a string, which always shows itself; - a ProgressBarWidget, which may return a diferent value every time it\'s update method is called; and - a ProgressBarWidgetHFill, which is like ProgressBarWidget, except it expands to fill the remaining width of the line.</p>\n<p>The progressbar module is very easy to use, yet very powerful. And automatically supports features like auto-resizing when available.</p>\n</blockquote>\n'}, {'answer_id': 704865, 'author': 'Community', 'author_id': -1, 'author_profile': 'https://Stackoverflow.com/users/-1', 'pm_score': 0, 'selected': False, 'text': '<p>For small files you may need to had this lines in order to avoid crazy percentages:</p>\n\n<p>sys.stdout.write("\\r%2d%%" % percent)</p>\n\n<p>sys.stdout.flush()</p>\n\n<p>Cheers</p>\n'}, {'answer_id': 12880543, 'author': 'Arnaud Aliès', 'author_id': 1722117, 'author_profile': 'https://Stackoverflow.com/users/1722117', 'pm_score': 0, 'selected': False, 'text': '<p>Thats how I did this could help you:\n<a href="https://github.com/mouuff/MouDownloader/blob/master/api/download.py" rel="nofollow">https://github.com/mouuff/MouDownloader/blob/master/api/download.py</a></p>\n'}, {'answer_id': 14123416, 'author': 'MichaelvdNet', 'author_id': 1636835, 'author_profile': 'https://Stackoverflow.com/users/1636835', 'pm_score': 1, 'selected': False, 'text': '<p>I used this code:</p>\n\n<pre><code>url = (&lt;file location&gt;)\nfile_name = url.split(\'/\')[-1]\nu = urllib2.urlopen(url)\nf = open(file_name, \'wb\')\nmeta = u.info()\nfile_size = int(meta.getheaders("Content-Length")[0])\nprint "Downloading: %s Bytes: %s" % (file_name, file_size)\n\nfile_size_dl = 0\nblock_sz = 8192\nwhile True:\n    buffer = u.read(block_sz)\n    if not buffer:\n        break\n\n    file_size_dl += len(buffer)\n    f.write(buffer)\n    status = r"%10d [%3.2f%%]" % (file_size_dl, file_size_dl * 100. / file_size)\n    status = status + chr(8)*(len(status)+1)\n    print status,\n\nf.close()\n</code></pre>\n'}, {'answer_id': 28424236, 'author': 'mafrosis', 'author_id': 425050, 'author_profile': 'https://Stackoverflow.com/users/425050', 'pm_score': 0, 'selected': False, 'text': "<p>Late to the party, as usual. Here's an implementation that supports reporting progress, like the core <code>urlretrieve</code>:</p>\n\n<pre><code>import urllib2\n\ndef urlretrieve(urllib2_request, filepath, reporthook=None, chunk_size=4096):\n    req = urllib2.urlopen(urllib2_request)\n\n    if reporthook:\n        # ensure progress method is callable\n        if hasattr(reporthook, '__call__'):\n            reporthook = None\n\n        try:\n            # get response length\n            total_size = req.info().getheaders('Content-Length')[0]\n        except KeyError:\n            reporthook = None\n\n    data = ''\n    num_blocks = 0\n\n    with open(filepath, 'w') as f:\n        while True:\n            data = req.read(chunk_size)\n            num_blocks += 1\n            if reporthook:\n                # report progress\n                reporthook(num_blocks, chunk_size, total_size)\n            if not data:\n                break\n            f.write(data)\n\n    # return downloaded length\n    return len(data)\n</code></pre>\n"}, {'answer_id': 36022923, 'author': 'tstone2077', 'author_id': 1803741, 'author_profile': 'https://Stackoverflow.com/users/1803741', 'pm_score': 3, 'selected': False, 'text': '<p>For what it\'s worth, here\'s the code I used to get it working:</p>\n\n<pre><code>from urllib import urlretrieve\nfrom progressbar import ProgressBar, Percentage, Bar\n\nurl = "http://......."\nfileName = "file"\npbar = ProgressBar(widgets=[Percentage(), Bar()])\nurlretrieve(url, fileName, reporthook=dlProgress)\n\ndef dlProgress(count, blockSize, totalSize):\n    pbar.update( int(count * blockSize * 100 / totalSize) )\n</code></pre>\n'}, {'answer_id': 43475317, 'author': 'Paal Pedersen', 'author_id': 7048431, 'author_profile': 'https://Stackoverflow.com/users/7048431', 'pm_score': 1, 'selected': False, 'text': '<pre><code>def download_progress_hook(count, blockSize, totalSize):\n  """A hook to report the progress of a download. This is mostly intended for users with slow internet connections. Reports every 5% change in download progress.\n  """\n  global last_percent_reported\n  percent = int(count * blockSize * 100 / totalSize)\n\n  if last_percent_reported != percent:\n    if percent % 5 == 0:\n      sys.stdout.write("%s%%" % percent)\n      sys.stdout.flush()\n    else:\n      sys.stdout.write(".")\n      sys.stdout.flush()\n\n    last_percent_reported = percent\n\nurlretrieve(url, filename, reporthook=download_progress_hook)\n</code></pre>\n'}, {'answer_id': 70750636, 'author': 'Ashutosh Kumbhar', 'author_id': 13547109, 'author_profile': 'https://Stackoverflow.com/users/13547109', 'pm_score': 0, 'selected': False, 'text': '<p>To avoid progress values like 106% or similar, follow the below logic</p>\n<pre class="lang-py prettyprint-override"><code>percent = min(int(count * blockSize * 100 / totalSize), 100)\n</code></pre>\n'}]
['https://Stackoverflow.com/questions/51212', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/2386/']