Displaying Progress Bar for Series Download (REST API, Dio + Flutter)

Hi everyone,

I’m developing a Flutter app that utilizes the Orthanc REST API to download series in ZIP format. While the download functionality works well, I’d like to implement a progress bar to enhance the user experience.

The current challenge is that the /series/<seriesId>/archive endpoint doesn’t provide the total file size. This makes it difficult to calculate the exact download progress.

I’m reaching out to the community to see if anyone has encountered a similar issue and might have solutions or workarounds.

Here are some details that might be helpful:

  • I’m using Dio for making the API call in my Flutter app.
  • I’ve considered the onProgress callback in Dio’s get method to track downloaded bytes, but this doesn’t provide the total size for accurate progress calculation.

If anyone has insights or suggestions on achieving a progress bar in this scenario with Dio, I’d be very grateful!


The /series/<seriesId>/statistics contains the total series disk size as well as the uncompressed size. Together with some heuristics, this could give you a starting point?

http :8742/series/2cce7fcb-fd98bbdc-4eaaf0a8-4ea23228-f5423908/statistics | jq '.DiskSizeMB'    


Hey thanks a lot of response, really appreciate it. I have tried your solution but the problem is that the zip that I am downloading is 59mb but the statistics gives 112 mb which is the uncompressed size. What could be done in this case?


Actually, Orthanc does not know the size of the zip when it starts returning it because it is being built at the same time.

However, if you set this option to false, you’ll get the “Content-Length” in the response but you’ll have to wait until the zip is fully built before receiving the first byte:

  // Whether Orthanc streams ZIP archive/media to the HTTP
  // client. Setting this option to "false" corresponds to the
  // behavior of Orthanc <= 1.9.3: The ZIP is first entirely written
  // to a temporary file, then sent to the client (which necessitates
  // disk space and might lead to HTTP timeouts on large archives). If
  // set to "true", the chunks of the ZIP file are progressively sent
  // as soon as one DICOM file gets compressed (new in Orthanc 1.9.4)
  "SynchronousZipStream" : true,

You may also create an asynchronous ArchiveJob; that will basically have the same asynchronous behavior

Hey thanks a lot of response, really appreciate it.

You’re welcome!

I have tried your solution but the problem is that the zip that I am downloading is 59mb but the statistics gives 112 mb

Yes, that is what I meant by “together with some heuristics”. My reasoning was that, since a progress bar does not need to be accurate, you could just assume that the compressed size is 40% of the uncompressed size, and work from that.

Of course, this only works if you are storing mostly similar instances, for instance, uncompressed MR slices.

If you request a zip archive of a resource that is already compressed at the pixel level, then the compression ratio will be more like 98% :smile:

If your download speed is slow and the time Orthanc takes to prepare the zip is significantly bigger than the total download time, then Alain’s suggestion could help.

You could for instance compute heuristics for the time it takes for Orthanc to create the zip and the time it takes to download it and assume, at the beginning of the process, that this is the total time.

Then, sometime along the way, the archive is created and you can retrieve the Content-Length and refine your estimation (that’s the moment when the transfer starts)

Lucky for you if you can afford to spend time on such niceties :joy: This is a fun issue.

Hope this helps.