# Thread for uploading data

**URL:** <https://discourse.slicer.org/t/thread-for-uploading-data/10185>\
**Category:** Support\
**Created:** [February 10, 2020, 3:30pm UTC](https://discourse.slicer.org/t/thread-for-uploading-data/10185 "2020-02-10T15:30:37Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![tbuikr](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/tbuikr/32/3899_2.png) [@tbuikr](https://discourse.slicer.org/u/tbuikr)\
**Post date:** [February 10, 2020, 3:30pm UTC](https://discourse.slicer.org/t/thread-for-uploading-data/10185/1 "2020-02-10T15:30:37Z")

</div>

Thanks for great SDK and python support.

I am using python and Slicer to upload dicom file to my server using `requests.post`. My dicom size about 20MB and it takes 1 mins to upload it to server.

During uploading process, the application only runs one thread, so I cannot do other tasks (GUI blocked). Could we create another thread for data uploading and run it on other thread, instead of main thread (GUI)? Do we have any example for the task? Thanks

---

<div class="post-metadata">

**Author:** ![pieper](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/pieper/32/8_2.png) [@pieper](https://discourse.slicer.org/u/pieper)\
**Post date:** [February 10, 2020, 3:48pm UTC](https://discourse.slicer.org/t/thread-for-uploading-data/10185/2 "2020-02-10T15:48:57Z")

</div>

Probably the easiest is to save the data to a file and then use `subprocess.run` or `QProcess` to execute a little script that does the upload (you can execute it with `PythonSlicer` which will be in your path and can run the same python scripts (non-gui) as you would inside slicer).

Are you connecting to a dicomweb server using dicomweb\_client or directly via requests?

---

<div class="post-metadata">

**Author:** ![tbuikr](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/tbuikr/32/3899_2.png) [@tbuikr](https://discourse.slicer.org/u/tbuikr)\
**Post date:** [February 10, 2020, 4:00pm UTC](https://discourse.slicer.org/t/thread-for-uploading-data/10185/3 "2020-02-10T16:00:12Z")

</div>

> [@pieper](#):
>
> subprocess.run

I just directly use request function in python. My data is dump to file and write to buffer to send to a web-service.

My function such as

```auto
def send_data():
   with open(path_to_dcm, 'rb') as file:
        file_read = file.read()
        base64_encode = base64.encodebytes(file_read)         
        multipart_form_data = {
              'file': (path_to_dcm, base64_encode, 'dicom')
          }
        try:
            json_results = requests.post(my_url,
                                    files=multipart_form_data)
            return json_results.json()
        except:
            pass

```

The `send_data ` is called when I click the `Send` button such as

```auto
       self.sendButton = qt.QPushButton("Send")
       self.sendButton.connect("clicked()", self.onSend)

def onSend(self):
    send_data()

```

Could you give an example how to do `subprocess.run` or `QProcess`?

---

<div class="post-metadata">

**Author:** ![pieper](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/pieper/32/8_2.png) [@pieper](https://discourse.slicer.org/u/pieper)\
**Post date:** [February 10, 2020, 7:48pm UTC](https://discourse.slicer.org/t/thread-for-uploading-data/10185/4 "2020-02-10T19:48:32Z")

</div>

Here’s an example with subprocess to run a job:

> <https://github.com/Slicer/Slicer/blob/91acb6167cdda31bfdc18bd752a85c6420462885/Modules/Scripted/ScreenCapture/ScreenCapture.py#L1281>

Also, coincidentally, I’m working on another example for the SlicerMorph project that maybe be closer to your use case. I hope to publish it soon.

---

<div class="post-metadata">

**Author:** ![pieper](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/pieper/32/8_2.png) [@pieper](https://discourse.slicer.org/u/pieper)\
**Post date:** [February 10, 2020, 8:38pm UTC](https://discourse.slicer.org/t/thread-for-uploading-data/10185/5 "2020-02-10T20:38:47Z")

</div>

Here’s a more elaborate set of code for doing this sort of thing (new, so use with care). It you look at the self test you can see what the interface looks like.

> **[pieper/SlicerProcesses](https://github.com/pieper/SlicerProcesses)**
>
> Slicer modules for running subprocesses to operate on data in parallel - pieper/SlicerProcesses

---

<div class="post-metadata">

**Author:** ![Manh\_Nguyen](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/manh_nguyen/32/6327_2.png) [@Manh\_Nguyen](https://discourse.slicer.org/u/Manh_Nguyen)\
**Post date:** [March 22, 2020, 12:25pm UTC](https://discourse.slicer.org/t/thread-for-uploading-data/10185/6 "2020-03-22T12:25:11Z")

</div>

Hi Steven, I’ve been looking into your project and have some questions:

How can a process modify the GUI written in ScriptedLoadableModuleWidget inherited class ?  
If I put a time.sleep(4) in your processing Input code, the GUI is freeze and unable to access or click.

In case I want to use multi-threading to handle the send to server, I got unexpected issue like when I click in the button and the send to server thread does not working at all. Is there any modules with multi-threading code that I can learn from ?

Thanks you very much

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [March 22, 2020, 1:43pm UTC](https://discourse.slicer.org/t/thread-for-uploading-data/10185/7 "2020-03-22T13:43:46Z")

</div>

If you want to give a chance for GUI updates while you are doing processing then you need to call slicer.app.processEvents(), not just a sleep.

As you probably know, due to the global interpreter lock, there is no parallel execution of Python code within one interpreter, even if you start multiple threads. For IO operations, asynchronous IO might help, but I don’t know if anyone has figured out how to use that in Slicer.

A simpler solution is to start a separate process for background operations. Fortunately, Slicer already has a very simple solution for this: scripted CLI modules, which are Python scripts that are executed in the background, in a new Python interpreter. If you have a Python script that uploads an input image to a server then all you need to run it in the background in Slicer is to create a simple XML file that describes inputs and outputs of your script - see a complete example [here](https://github.com/lassoan/SlicerPythonCLIExample). The XML file allows Slicer to recognize the script as a CLI module, and [CLI modules are run in the background by default](https://www.slicer.org/wiki/Documentation/Nightly/Developers/Python_scripting#Running_a_CLI_from_Python).

If you start multiple CLI modules in parallel then Slicer puts them in a queue and runs them one after the other.

---

<div class="post-metadata">

**Author:** ![Manh\_Nguyen](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/manh_nguyen/32/6327_2.png) [@Manh\_Nguyen](https://discourse.slicer.org/u/Manh_Nguyen)\
**Post date:** [March 22, 2020, 1:52pm UTC](https://discourse.slicer.org/t/thread-for-uploading-data/10185/8 "2020-03-22T13:52:56Z")

</div>

Thanks you very much for your answers.  
The example link you provided above seems not working to me  
Anyway, I found some useful reference in this github [link](https://github.com/Radiomics/SlicerRadiomics/tree/master/SlicerRadiomicsCLI)

However, how can I add this CLI modules to my Slicer

 ![Screenshot from 2020-03-22 20-50-39](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/d/3/d3b3f9e2d461d0c2173b360a11677f30ebf61078.png)  
 ![Screenshot from 2020-03-22 20-50-45](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/e/c/ec6557b24fc1c61d01909ff0dabaa39ada5e89a7.png)  
This seems not working at all ? Seems like I missed some steps ? Can you show me some instruction into this ?  
Again, thank you very much for your help.

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [March 22, 2020, 2:04pm UTC](https://discourse.slicer.org/t/thread-for-uploading-data/10185/9 "2020-03-22T14:04:44Z")

</div>

I confirm that the module that I linked works well with recent Slicer-4.11 versions. If you have any problems running it then describe what steps you performed, what you expected to happen, and what happened instead.

---

<div class="post-metadata">

**Author:** ![Manh\_Nguyen](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/manh_nguyen/32/6327_2.png) [@Manh\_Nguyen](https://discourse.slicer.org/u/Manh_Nguyen)\
**Post date:** [March 22, 2020, 2:25pm UTC](https://discourse.slicer.org/t/thread-for-uploading-data/10185/10 "2020-03-22T14:25:28Z")

</div>

So these are steps that I followed:

- Clone the git project from [here](https://github.com/Radiomics/SlicerRadiomics)
- Add the modules inside Slicer: Application Settings → Modules → Add → **SlicerRadiomicsCLI**
- Run some experiment code:

> parameters = {}  
> res = slicer.cli.runSync(slicer.modules.SlicerRadiomicsCLI, None, parameters)  
> print(res)  
> pass

So are there anything need to be additionally performed ? The version I used is Slicer 4.11 (I think my Slicer is not nightly version since I downloaded the binary in the main page)

The way I want it to work is I’m able to access slicer.modules.SlicerRadiomicsCLI CLI from the scripted code python that I wrote.

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [March 22, 2020, 3:58pm UTC](https://discourse.slicer.org/t/thread-for-uploading-data/10185/11 "2020-03-22T15:58:18Z")

</div>

OK, what you do will work, just use the example that I provided above: [https://github.com/lassoan/SlicerPythonCLIExample](https://github.com/lassoan/SlicerPythonCLIExample)

---

<div class="post-metadata">

**Author:** ![Manh\_Nguyen](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/manh_nguyen/32/6327_2.png) [@Manh\_Nguyen](https://discourse.slicer.org/u/Manh_Nguyen)\
**Post date:** [March 27, 2020, 9:10am UTC](https://discourse.slicer.org/t/thread-for-uploading-data/10185/12 "2020-03-27T09:10:22Z")

</div>

Sorry for the late response. Do I need to runSync CLI modules in separated file ? The BlurImage CLI seems still frozen GUI when I add time.sleep(5) into BlurImage.py

Btw, the SlicerProcesses works pretty well. However, is there any way to monitor the progress of the process run in background ?

Many thanks for yours support

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [March 27, 2020, 12:08pm UTC](https://discourse.slicer.org/t/thread-for-uploading-data/10185/13 "2020-03-27T12:08:20Z")

</div>

RunSync blocks the main thread until the execution completes, so don’t use it of you want to process in the background.

---

<div class="post-metadata">

**Author:** ![pieper](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/pieper/32/8_2.png) [@pieper](https://discourse.slicer.org/u/pieper)\
**Post date:** [March 27, 2020, 12:35pm UTC](https://discourse.slicer.org/t/thread-for-uploading-data/10185/14 "2020-03-27T12:35:11Z")

</div>

> [@Manh\_Nguyen](#):
>
> Btw, the SlicerProcesses works pretty well. However, is there any way to monitor the progress of the process run in background ?

The current SlicerProcesses code isn’t set up for progress reporting. There could be lots of ways to do it, Slicer CLI modules use a convention of embedding xml snippets in the output that triggers automatic progress updates in the GUI. Another option would be to set up a connection like OpenIGTLink to pass data. Or one could create a custom network protocol.
