How can I redirect the output from a function that calls `ProgressMeter` to an `Observable` variable?

I have a function that uses ProgressMeter. I need the output from @showprogress that is called inside that function to be redirected to an Observable. Something like the following (except that the following code doesn’t work):

using ProgressMeter
using Observables

function my_func()
    @showprogress 1 "Computing..." for i in 1:50
        sleep(0.1)
    end
end

progress = Observable("")

redirect_stdio(my_func, stdout=progress[])

I know I can’t pass an observable to redirect_stdio, but is there a way of doing what I want somehow?

There’s an (long standing) open issue to support using IOBuffer directly, but as far as I can tell, it does not yet support it.

The Progress type supports specifying an output, but given it expects an IOStream, I think it will run into the same issue.

Thankfully, there’s a package that provides with a good workaround, courtesy of the discussion here

using ProgressMeter
using Observables
using Suppressor


function my_func()
    @showprogress 1 "Computing..." for i in 1:50
        sleep(0.1)
    end
end

x = Observable("")

x[] = @capture_err begin
    my_func()
end

println(x[])
# Computing... 100%|███████████████████████████████████████| Time: 0:00:05

The captured output may not be “clean” (I’m not sure what happens if outputs span multiple lines for example), so that needs to be handled somehow if it’s an issue.

1 Like