How to reproduce a wget-like speed interface on a linux terminal?
Question: Wget prints out speed information to stdout in a very clear manner, where the
speed is shown and refreshed whilst the file is downloaded, and a bar scrolls
across the screen. I'd like to replicate this sort of output, in a Python
program. How is this possible?

I thought the [curses](http://docs.python.org/library/curses.html) library
should be able to do this; this is what I came up with:-

    
    
    import curses, time
    
    class Speeder( object ):
        """Show and refresh time and download speed in a curses interface."""
        t1 = 0. # start time
        t  = 0. # current time
        tf = 0. # end time
        def start(self, filename=None ):
            """Start timer"""
            self.t1 = self.t = time.time()
            curses.use_env(True)
            curses.initscr()
            self.win = curses.newwin(4, 0)
            if filename is not None:
                self.win.addnstr(filename, 50 )
                self.win.refresh()
    
        def update(self, rbytes):
            """Refresh speed."""
            t = time.time()
            td = t - self.t
            self.t = t
            speed = rbytes / td 
            self.win.addstr(0,54,str('{0:.02f} B/s'.format(speed)))
            self.win.refresh()
    
        def end(self):
            """End timer"""
            self.tf = time.time() 
            curses.endwin()
    
    
    try:
        speed = Speeder()
        speed.start(filename='foo.bar')
        for i in xrange(10):
            time.sleep(0.5)
            speed.update(200)
    finally:
        speed.end()
    

The problem is that it takes up an entire window, and I only really need a
line at a time. I'd rather not push all the command line history back above
the terminal window. Please correct me if I'm wrong, but I currently think
curses apps always take up the entire terminal window.

So I had a look at the [tty](http://docs.python.org/library/tty.html) and
[termios](http://docs.python.org/library/termios.html#module-termios) modules,
but I can't find any examples doing what I want to do.

Finally, I came across [a blog
post](http://www.mutaku.com/wp/index.php/2011/06/python-dynamically-printing-
to-single-line-of-stdout/) which does it by simply writing some special
characters to sys.stdout. Applying his code to my Speeder class, I came up
with this:-

    
    
    import sys
    class Speeder( object ):
        """Show and refresh time and download speed."""
        t1 = 0. # start time
        t  = 0. # current time
        tf = 0. # end time
        def start(self, filename=None ):
            """Start timer"""
            self.t1 = self.t = time.time()
            if filename is not None:
                sys.stdout.write( '\r\x1b[K' + filename.ljust(50) )
                sys.stdout.flush()
    
        def update(self, rbytes):
            """Refresh speed."""
            t = time.time()
            td = t - self.t
            self.t = t
            speed = '{0} B/s'.format( rbytes / td )
            sys.stdout.write( "\r\x1b[K" + speed.rjust(65) )
            sys.stdout.flush()
    
        def end(self):
            """End timer"""
            self.tf = time.time()
            sys.stdout.write('\n')
    

This has fewer lines of code, which I like, but tbh I don't have a clue what's
going on, or how to modify it to only update part of the line, similar to the
curses.addstr function. Currently, the filename is overwritten with white-
space. I could of course modify the class to construct the entire line each
time from python, but I'd like to understand this in order to tailor it to my
own needs.

The author says this is possible only on VT100 terminals. So I guess this
would only work on Unix terminals then? That's fine, but are there any Unix
terminals that this would not work on?

Is there better documentation on the subject, or more complicated examples
(e.g. updating multiple lines, one line of many, or single characters on a
line), preferably for Python? This doesn't seem like a feature of Python, but
the tty, which is why I guess I've failed to find anything. Is there a man
page or something I should read?


Answer: The code above is using ANSI escape codes:
<https://en.wikipedia.org/wiki/ANSI_escape_code>. I think that's the
documentation you are looking for when trying to grok the code you found.

