alive-progress icon indicating copy to clipboard operation
alive-progress copied to clipboard

support writing to stderr

Open aerickson opened this issue 1 year ago • 6 comments

I think that stderr is the preferred destination for progress bars (and errors in command line tools). When the bar is written to stderr, users can still see the progress bar for commands that are redirecting or piping output and can avoid getting the bar in the captured output.

  • Please support specifying a file (stdout or stderr) to write the progress bar to.
  • Please consider (in a major version change) defaulting to stderr.

I'm happy to work on this if you can provide some guidance on how you'd like it implemented. As a proof of concept, changing alive_progress/utils/terminal/tty.py to sys.stderr had the desired effect.

I'm replacing a simple spinner with alive_progress and writing to stderr is one thing that alive_progress is missing.

tqdm writes to stderr by default. See 'file' at https://github.com/tqdm/tqdm#parameters.

aerickson avatar Jul 06 '22 23:07 aerickson

When the bar is written to stderr, users can still see the progress bar for commands that are redirecting or piping output and can avoid getting the bar in the captured output.

If I remember correctly, the bar always uses stdout even if it's redirected. Cf. #171

TheTechRobo avatar Jul 07 '22 14:07 TheTechRobo

Correct. Yeah, that statement was regarding other progress bars that write to stderr.

I've got a branch that writes to stderr by default (https://github.com/rsalmei/alive-progress/compare/main...aerickson:alive-progress:write_to_stderr).

aerickson avatar Jul 07 '22 16:07 aerickson

Hey @aerickson, you're right, perhaps the stderr would be a better default. I wonder how no one has ever asked about this... I have a new version almost ready, I'll try to take a look at this before releasing it.

rsalmei avatar Jul 07 '22 22:07 rsalmei

It is interesting that it hasn't been brought up. I guess it's a bit of an obscure feature... most apps with progress bars aren't used as input to other commands (they're end-user UIs)?

Awesome. :) Thank you.

aerickson avatar Jul 08 '22 02:07 aerickson

You're welcome. Perhaps you've nailed it, that's because they're end-user UIs... Although my alive-progress do work when used as input to other commands, since I disable the refresh, and only output the final receipt.

rsalmei avatar Jul 08 '22 22:07 rsalmei

Hey @aerickson, it's done!!

It was hard work to accomplish it, but the refactoring was worth it.

Look how cool the effect is: Untitled

The code:

import sys
import time

from alive_progress import alive_bar


def run(f):
    with alive_bar(100, file=f) as bar:
        for _ in range(100):
            time.sleep(.02)
            bar()


run(sys.stdout)
run(sys.stderr)

Next release man! 👍

rsalmei avatar Jul 16 '22 04:07 rsalmei

When will this be released? Thanks! :)

aerickson avatar Nov 02 '22 17:11 aerickson

This does not seem to be working on this branch: https://github.com/aerickson/alive-progress/tree/file_as_argument

import time

from alive_progress import alive_bar

def run():
    text_object = "foo"
    with alive_bar(100, file=text_object) as bar:
        for _ in range(100):
            time.sleep(0.02)
            bar()
            # print(text_object)

run()

I would expect that when the line print(text_object) is commented, no bar will show, but the bar is still showing up when I run it.

Instead of using a string literal as the file argument, I also tried a file object and nothing was written there either.

jacobian91 avatar Nov 03 '22 05:11 jacobian91

Sorry, I was wrong. I never finished the feature. :(

I'm not sure how @rsalmei is doing it in his implementation.

aerickson avatar Nov 03 '22 08:11 aerickson

Hey yeah, I have to try and find time to commit this... It's done for four months now, and still only on my machine. Since I work with Rust now, all my free time lately goes to studying Rust...

I'll try to get to it next weekend.

rsalmei avatar Nov 03 '22 16:11 rsalmei