Take the 2-minute tour ×

Is there a good way to do the following?

I wrote a simple console app to upload and download files from an FTP server using the ftplib.

Each time some data chunks are downloaded, I want to update a text progress bar, even if it's just a number.

But I don't want to erase all the text that's been printed to the console. (Doing a "clear" and then printing the updated percentage.)

share|improve this question
you could also just use a GUI (which will save you more trouble in the end if you start doing anything advance in the app) it isn't 1960 anymore ;) –  L̲̳o̲̳̳n̲̳̳g̲̳̳p̲̳o̲̳̳k̲̳̳e̲̳̳ Jul 4 '10 at 0:55
Hmm, look like a duplicate of this question asked yesterday: stackoverflow.com/questions/3160699/python-progress-bar/3162864 So, you should use fish pypi.python.org/pypi/fish –  Etienne Jul 4 '10 at 2:33
add comment

15 Answers

up vote 80 down vote accepted

Writing '\r' will move the cursor back to the beginning of the line.

This displays a percentage counter:

>>> for i in range(100):
...    time.sleep(1)
...    sys.stdout.write("\r%d%%" %i)    # or print >> sys.stdout, "\r%d%%" %i,
...    sys.stdout.flush()
share|improve this answer
Pasted that and ran. It prints to a new line each time. I want the number to be updated on the same line. :) –  bobber205 Jul 4 '10 at 1:14
@bobber205 : I just tried it on two different OS's (mac & linux), two different versions of python. It prints on one line. :) Are you sure you added ',' at the end of the print statement? –  Stephen Jul 4 '10 at 1:31
I am using python 2.6 I tried in Aptana studio and on the command line. Prints on multiple lines. :( –  bobber205 Jul 4 '10 at 1:32
@bobber205 : Edited, try sys.stdout.write –  Stephen Jul 4 '10 at 1:34
This example also produces an OBOB it ends loading at 99% –  Glenn Dayton Sep 5 '12 at 22:26
show 7 more comments

Write a \r to the console. That is a "carriage return" which causes all text after it to be echoed at the beginning of the line. Something like:

def update_progress(progress):
    print '\r[{0}] {1}%'.format('#'*(progress/10), progress)

which will give you something like: [ ########## ] 100%

share|improve this answer
Do '\r' + myPercentage printout? –  bobber205 Jul 4 '10 at 0:37
Do \r and then write the whole line out again. Basically: print("\rProgress: [{0:50s}] {1:.1f}%".format('#' * int(amtDone * 50), amtDone * 100)), where amtDone is a float between 0 and 1. –  Mike DeSimone Jul 4 '10 at 0:46
Better to use sys.stdout.write than print. With print I got newlines. –  Gill Bates Dec 30 '12 at 22:55
append a comma , at the end of the print works for me. –  Chunliang Lyu Dec 31 '12 at 8:04
in python3 use print(...., end='') and you won't have any newlines –  Paladin Feb 21 '13 at 15:23
show 4 more comments

Check this library: clint

it has a lot of features including a progress bar:

from time import sleep  
from random import random  
from clint.textui import progress  
if __name__ == '__main__':
    for i in progress.bar(range(100)):
        sleep(random() * 0.2)

    for i in progress.dots(range(100)):
        sleep(random() * 0.2)

this link provides a quick overview of its features

share|improve this answer
add comment

Here's a nice example of a progressbar written in Python: http://nadiana.com/animated-terminal-progress-bar-in-python

But if you want to write it yourself. You could use the curses module to make things easier :)

[edit] Perhaps easier is not the word for curses. But if you want to create a full-blown cui than curses takes care of a lot of stuff for you.

[edit] Since the old link is dead I have put up my own version of a Python Progressbar, get it here: https://github.com/WoLpH/python-progressbar

share|improve this answer
curses? Easier? Hmmm.... –  aviraldg Jul 4 '10 at 0:45
An excellent article, I was going to give a link to it but couldn't find in my bookmarks :) –  Andy Mikhaylenko Jul 4 '10 at 0:46
@Aviral Dasgupta: fair enough, easier might not be the right word here. It can save you a lot of work though, but it really depends on what you're looking for. –  Wolph Jul 4 '10 at 0:54
Not looking for anything near this involved, but thanks anyway. :) –  bobber205 Jul 4 '10 at 1:10
add comment

Run this at the Python command line (not in any IDE or development environment):

>>> import threading
>>> for i in range(50+1):
...   threading._sleep(0.5)
...   print "\r%3d" % i, ('='*i)+('-'*(50-i)),

Works fine on my Windows system.

share|improve this answer
add comment

I realize I'm late to the game, but here's a slightly Yum-style (Red Hat) one I wrote (not going for 100% accuracy here, but if you're using a progress bar for that level of accuracy, then you're WRONG anyway):

import sys

def cli_progress_test(end_val, bar_length=20):
    for i in xrange(0, end_val):
        percent = float(i) / end_val
        hashes = '#' * int(round(percent * bar_length))
        spaces = ' ' * (bar_length - len(hashes))
        sys.stdout.write("\rPercent: [{0}] {1}%".format(hashes + spaces, int(round(percent * 100))))

Should produce something looking like this:

Percent: [##############      ] 69%

... where the brackets stay stationary and only the hashes increase.

This might work better as a decorator. For another day...

share|improve this answer
add comment

based on the above answers and other similar questions about CLI progress bar, I think I got a general common answer to all of them. Check it at http://stackoverflow.com/a/15860757/2254146

In summary, the code is this:

import time, sys

# update_progress() : Displays or updates a console progress bar
## Accepts a float between 0 and 1. Any int will be converted to a float.
## A value under 0 represents a 'halt'.
## A value at 1 or bigger represents 100%
def update_progress(progress):
    barLength = 10 # Modify this to change the length of the progress bar
    status = ""
    if isinstance(progress, int):
        progress = float(progress)
    if not isinstance(progress, float):
        progress = 0
        status = "error: progress var must be float\r\n"
    if progress < 0:
        progress = 0
        status = "Halt...\r\n"
    if progress >= 1:
        progress = 1
        status = "Done...\r\n"
    block = int(round(barLength*progress))
    text = "\rPercent: [{0}] {1}% {2}".format( "#"*block + "-"*(barLength-block), progress*100, status)

Looks like

Percent: [##########] 99.0%

share|improve this answer
add comment
import sys
def progresssbar():
         for i in range(100):
            sys.stdout.write("%i\r" % i)


NOTE: if you run this in interactive interepter you get extra numbers printed out

share|improve this answer
add comment

lol i just wrote a whole thingy for this heres the code keep in mind you cant use unicode when doing block ascii i use cp437

import os
import time
def load(left_side, right_side, length, time):
    x = 0
    y = ""
    print "\r"
    while x < length:
        space = length - len(y)
        space = " " * space
        z = left + y + space + right
        print "\r", z,
        y += "█"
        x += 1

and you call it like so

print "loading something awesome"
load("|", "|", 10, .01)

so it looks like this

loading something awesome
|█████     |
share|improve this answer
add comment

With the great advices above I work out the progress bar.

However I would like to point out some shortcomings

  1. Every time the progress bar is flushed, it will start on a new line

    print('\r[{0}]{1}%'.format('#' * progress* 10, progress))  

    like this:
    [] 0%

2.The square bracket ']' and the percent number on the right side shift right as the '###' get longer.
3. An error will occur if the expression 'progress / 10' can not return an integer.

And the following code will fix the problem above.

def update_progress(progress, total):  
    print('\r[{0:10}]{1:>2}%'.format('#' * int(progress * 10 /total), progress), end='')
share|improve this answer
add comment

I am using this one from reddit. I like it because it can print progress for every item in one line, and it shouldn't erase printouts from the program.

share|improve this answer
add comment

and, just to add to the pile, here's an object you can use

import sys

class ProgressBar():
    DEFAULT_BAR_LENGTH = float(65)

    def __init__(self, end, start=0):
        self.end    = end
        self.start  = start
        self._barLength = ProgressBar.DEFAULT_BAR_LENGTH

        self._plotted = False

    def setLevel(self, level, initial=False):
        self._level = level
        if level < self.start:  self._level = self.start
        if level > self.end:    self._level = self.end

        self._ratio = float(self._level - self.start) / float(self.end - self.start)
        self._levelChars = int(self._ratio * self._barLength)

    def plotProgress(self):
        sys.stdout.write("\r  %3i%% [%s%s]" %(
            int(self._ratio * 100.0),
            '=' * int(self._levelChars),
            ' ' * int(self._barLength - self._levelChars),
        self._plotted = True

    def setAndPlot(self, level):
        oldChars = self._levelChars
        if (not self._plotted) or (oldChars != self._levelChars):

    def __del__(self):

if __name__ == "__main__":
    import time
    count = 5
    print "starting things:"

    pb = ProgressBar(count)

    curProgress = 0
    while curProgress <= count:
        curProgress += 1
    del pb

    print "done"

results in:

starting things:

This would most commonly be considered to be "over the top", but it's handy when you're using it a lot

share|improve this answer
add comment

Well here is code that works and I tested it before posting:

import sys
def prg(prog, fillchar, emptchar):
    fillt = 0
    emptt = 20
    if prog < 100 and prog > 0:
        prog2 = prog/5
        fillt = fillt + prog2
        emptt = emptt - prog2
        sys.stdout.write("\r[" + str(fillchar)*fillt + str(emptchar)*emptt + "]" + str(prog) + "%")
    elif prog >= 100:
        prog = 100
        prog2 = prog/5
        fillt = fillt + prog2
        emptt = emptt - prog2
        sys.stdout.write("\r[" + str(fillchar)*fillt + str(emptchar)*emptt + "]" + str(prog) + "%" + "\nDone!")
    elif prog < 0:
        prog = 0
        prog2 = prog/5
        fillt = fillt + prog2
        emptt = emptt - prog2


  • 20 character bar (1 character for every 5 (number wise))
  • Custom fill characters
  • Custom empty characters
  • Halt (any number below 0)
  • Done (100 and any number above 100)
  • Progress count (0-100 (below and above used for special functions))
  • Percentage number next to bar, and it's a single line


  • Supports integers only (It can be modified to support them though, by making the division an integer division, so just change prog2 = prog/5 to prog2 = int(prog/5))
share|improve this answer
add comment

Here's my Python 3 solution:

import time
for i in range(100):
    s = "{}% Complete".format(i)
    print(s,end=len(s) * '\b')

'\b' is a backslash, for each character in your string. This does not work within the Windows cmd window.

share|improve this answer
add comment

Your Answer


