# SyntaxError Using subprocess in MorphoSourceImportV2 Module

**URL:** <https://discourse.slicer.org/t/syntaxerror-using-subprocess-in-morphosourceimportv2-module/32866>\
**Category:** Development\
**Tags:** extensions-manager, python\
**Created:** [November 16, 2023, 6:21pm UTC](https://discourse.slicer.org/t/syntaxerror-using-subprocess-in-morphosourceimportv2-module/32866 "2023-11-16T18:21:32Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![othomas2](https://avatars.discourse-cdn.com/v4/letter/o/848f3c/32.png) [@othomas2](https://discourse.slicer.org/u/othomas2)\
**Post date:** [November 16, 2023, 6:21pm UTC](https://discourse.slicer.org/t/syntaxerror-using-subprocess-in-morphosourceimportv2-module/32866/1 "2023-11-16T18:21:32Z")

</div>

Hello Slicer Community,

I’m developing a module, `MorphoSourceImportV2`, for 3D Slicer to download media from MorphoSource in the background. However, I’ve encountered a `SyntaxError` when trying to use the `subprocess` module within Slicer.

File “/Applications/Slicer.app/Contents/bin/…/lib/Python/lib/python3.9/site.py”, line 178  
file=sys.stderr)  
^  
SyntaxError: invalid syntax

This error arises when I attempt to run a subprocess for downloading media files.

**Module Repository** : The module’s code is available in my forked repository: [MorphoSourceImportV2 on GitHub](https://github.com/oothomas/SlicerMorph/tree/master/MorphoSourceImportV2).

I would greatly appreciate any insights or suggestions you might have on resolving this issue. If anyone has experience with using `subprocess` in Slicer or has encountered similar problems, your guidance would be invaluable.

Thank you in advance for your help!

---

<div class="post-metadata">

**Author:** ![muratmaga](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/muratmaga/32/3622_2.png) [@muratmaga](https://discourse.slicer.org/u/muratmaga)\
**Post date:** [November 16, 2023, 7:00pm UTC](https://discourse.slicer.org/t/syntaxerror-using-subprocess-in-morphosourceimportv2-module/32866/2 "2023-11-16T19:00:05Z")

</div>

I bit more context to this question:

These downloads are long (multiple GBs per file), and can be multiple dataset. We do not want the Slicer UI to be non-responsive during downloads, which should happen in the background.

Any suggestions to do this would be appreciated.

---

<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:** [November 16, 2023, 8:04pm UTC](https://discourse.slicer.org/t/syntaxerror-using-subprocess-in-morphosourceimportv2-module/32866/3 "2023-11-16T20:04:45Z")

</div>

Doing the downloads in a subprocess makes sense. You could look at how the [DICOMProcess code handles this](https://github.com/Slicer/Slicer/blob/main/Modules/Scripted/DICOMLib/DICOMProcesses.py). Basically a `QProcess` is started as the process downloads data the main Slicer process gets signals that tell it when to read the results. The [ParallelProcessing](https://github.com/pieper/SlicerParallelProcessing) extension code works the same way and might be easier to read.

---

<div class="post-metadata">

**Author:** ![othomas2](https://avatars.discourse-cdn.com/v4/letter/o/848f3c/32.png) [@othomas2](https://discourse.slicer.org/u/othomas2)\
**Post date:** [November 16, 2023, 9:17pm UTC](https://discourse.slicer.org/t/syntaxerror-using-subprocess-in-morphosourceimportv2-module/32866/4 "2023-11-16T21:17:23Z")

</div>

Thank you, Steve! I’ll try these approaches.

---

<div class="post-metadata">

**Author:** ![othomas2](https://avatars.discourse-cdn.com/v4/letter/o/848f3c/32.png) [@othomas2](https://discourse.slicer.org/u/othomas2)\
**Post date:** [November 16, 2023, 10:24pm UTC](https://discourse.slicer.org/t/syntaxerror-using-subprocess-in-morphosourceimportv2-module/32866/5 "2023-11-16T22:24:41Z")

</div>

I’ve successfully used `subprocess.Popen` to run an external Python script (`download_script.py`) from within a Slicer module, and it’s working great for downloading data. However, I have a couple of questions regarding best practices for script placement and specifying the Python interpreter in Slicer:

1. **Script Location:** Currently, `download_script.py` is located in the same folder as the module file. I’ve specified its file path explicitly in the code. Is this the recommended location for such scripts, or should they be placed elsewhere? Additionally, is there a way to reference the script’s location relative to the module file, to make the module more portable?
2. **Python Interpreter Path:** For the Python interpreter, I’ve used a hard-coded path to Slicer’s Python (`/Applications/Slicer.app/Contents/bin/PythonSlicer`). However, I’m wondering if there’s a more dynamic way to reference the interpreter, perhaps using `sys.executable` or a similar approach. This would be particularly useful for ensuring the module’s compatibility across different systems and Slicer installations.

Steve, thanks again for your help! I look forward to your response. It would be helpful not only for refining my current module but also for guiding best practices for the Slicer developer community.

 ![Screen Shot 2023-11-16 at 2.19.29 PM](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/5/c/5cfc199878944394bba32a133e6eeea95bb5c4b6.png)

---

<div class="post-metadata">

**Author:** ![muratmaga](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/muratmaga/32/3622_2.png) [@muratmaga](https://discourse.slicer.org/u/muratmaga)\
**Post date:** [November 17, 2023, 2:33am UTC](https://discourse.slicer.org/t/syntaxerror-using-subprocess-in-morphosourceimportv2-module/32866/6 "2023-11-17T02:33:40Z")

</div>

> [@othomas2](#):
>
> Is this the recommended location for such scripts, or should they be placed elsewhere?

I think supplementary files for modules go under Resources/ folder of the module hierarchy.

> [@othomas2](#):
>
> script’s location relative to the module file, to make the module more portable?

`slicer.util.modulePath('MorphoSourceImportV2')`  
returns the path of python script for your module. If you put the `download_script.py` within the Resources folder then you can paste these together to form the correct path that will be portable

> [@othomas2](#):
>
> owever, I’m wondering if there’s a more dynamic way to reference the interpreter,

`os.getcwd()`  
returns the path of where slicer install tree is (i.e., working directory for the python console)  
` 'C:\\Users\\amaga\\AppData\\Local\\slicer.org\\Slicer 5.4.0'`

so, the path of the Python interpreter is **bin/PythonSlicer** under this tree.

```auto
os.path.exists("bin/PythonSlicer.exe")
True

```

---

<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:** [November 17, 2023, 2:06pm UTC](https://discourse.slicer.org/t/syntaxerror-using-subprocess-in-morphosourceimportv2-module/32866/7 "2023-11-17T14:06:44Z")

</div>

@othomas2 I suggest you change from using subprocess.Popen and instead use QProcess for use within Slicer. The reason is that QProcess integrates with the Qt event loop for the application, so that instead of relying on. timer, you can be notified of events from the process as they happen. This is a cleaner approach and in general it is more efficient and provides a smoother user experience.

I agree with @muratmaga 's suggestions about using the Resources directory and locating it relative to the module path for consistency across os platforms. Do avoid using `.exe` as that is windows specific.
