# Run a python script from Slicer

**URL:** <https://discourse.slicer.org/t/run-a-python-script-from-slicer/24016>\
**Category:** Development\
**Created:** [June 23, 2022, 11:48pm UTC](https://discourse.slicer.org/t/run-a-python-script-from-slicer/24016 "2022-06-23T23:48:45Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![koeglfryderyk](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/koeglfryderyk/32/14638_2.png) [@koeglfryderyk](https://discourse.slicer.org/u/koeglfryderyk)\
**Post date:** [June 23, 2022, 11:48pm UTC](https://discourse.slicer.org/t/run-a-python-script-from-slicer/24016/1 "2022-06-23T23:48:45Z")

</div>

I want to run a custom python script from slicer in a custom virtual environment.

I tried:

- `slicer.util.launchConsoleProcess()`, as suggested [here](https://discourse.slicer.org/t/run-a-python-script-as-subprocess-from-slicer/22668), but I couldn’t figure out how to specify my custom venv
- I tried using `subprocess.call(cmd, shell=True, executable='/bin/bash')`, where `cmd = "source path/to/venv/bin/activate; python3 path/to/script.py` (I tried this with `.` instead of source or without source but nothing worked)

I also tried a somewhat convoluted way that was the closest to working: `subprocess.run(command_line, env=slicer.util.startupEnvironment())`, where `command_line=["path/to/venv/bin/python3.7", "path/to/intermediate/script.py"]` and the intermediate python file contains an os.system call with the venv and ‘real’ script specified

- I wrote that it partially worked because I get a return code of 0, and the loading circle in slicer appears for a moment - so I’m guessing the ‘real’ script started but then closed after a moment  
(the script I want to run is a script that continuously sends data to Slicer, where my extension then uses this data to update markups)

It seemed to me like I tried all the options that If found here on Discourse, but maybe I missed something.

---

<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:** [June 24, 2022, 4:49am UTC](https://discourse.slicer.org/t/run-a-python-script-from-slicer/24016/2 "2022-06-24T04:49:15Z")

</div>

I would expect that `launchConsoleProcess` would work if you launch a wrapper bash script (that activates the virtual environment and launches your Python script). Maybe first start with a very simple script (e.g., that prints a short message or creates a new file).

Is there a particular reason you cannot run your script in Slicer’s virtual Python environment (using `PythonSlicer` executable)?

---

<div class="post-metadata">

**Author:** ![koeglfryderyk](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/koeglfryderyk/32/14638_2.png) [@koeglfryderyk](https://discourse.slicer.org/u/koeglfryderyk)\
**Post date:** [June 24, 2022, 2:12pm UTC](https://discourse.slicer.org/t/run-a-python-script-from-slicer/24016/3 "2022-06-24T14:12:43Z")

</div>

I just tried using a bash script but I also couldn’t make it work.

That’s my script (which I can execute on my mac) - the python file creates a dummy directory:

```auto
#! /usr/bin/env python
source /Users/fryderykkogl/Documents/university/master/thesis/code.nosync/venvs.nosync/mpipe/bin/activate
python3 /Users/fryderykkogl/Documents/university/master/thesis/code.nosync/x-nav/x.py

```

I run it with  
`slicer.util.launchConsoleProcess(["/Users/fryderykkogl/Documents/university/master/thesis/code.nosync/x-nav/wrapper.sh"])`

I first got a permission error which I fixed with chmod but now I get this error which I cannot get rid of:

```auto
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/Applications/Slicer_debug.app/Contents/bin/Python/slicer/util.py", line 3384, in launchConsoleProcess
    proc = subprocess.Popen(args, env=startupEnv, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True, cwd=cwd)
  File "/Applications/Slicer_debug.app/Contents/lib/Python/lib/python3.9/subprocess.py", line 951, in __init__
    self._execute_child(args, executable, preexec_fn, close_fds,
  File "/Applications/Slicer_debug.app/Contents/lib/Python/lib/python3.9/subprocess.py", line 1821, in _execute_child
    raise child_exception_type(errno_num, err_msg, err_filename)
OSError: [Errno 8] Exec format error: '/Users/fryderykkogl/Documents/university/master/thesis/code.nosync/x-nav/wrapper.sh'

```

I don’t think there is a reason, but I also can’t figure out how to use PythonSlicer from within Slicer. I can use PythonSlicer from my terminal, but I run into the same problems as with my venv when I do it in Slicer

A note on ‘the big picture’ - I want to have a button in my custom extension, which when pressed, executes this custom script

---

<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:** [June 24, 2022, 5:50pm UTC](https://discourse.slicer.org/t/run-a-python-script-from-slicer/24016/4 "2022-06-24T17:50:02Z")

</div>

You need to add `/bin/bash` as the first element of the list being passed to `launchConsoleProcess`.

---

<div class="post-metadata">

**Author:** ![koeglfryderyk](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/koeglfryderyk/32/14638_2.png) [@koeglfryderyk](https://discourse.slicer.org/u/koeglfryderyk)\
**Post date:** [June 24, 2022, 11:14pm UTC](https://discourse.slicer.org/t/run-a-python-script-from-slicer/24016/5 "2022-06-24T23:14:27Z")

</div>

That helped, thanks!!

However, my script now crashes at this line of code:  
`cap = cv2.VideoCapture(0)`

(again, it crashes only when I try to execute it through Slicer - it runs fine when executed through my terminal)

I accessed the results of `p = launchConsoleProcess()` with `p.communicate()` and this was the error:

```auto
OpenCV: not authorized to capture video (status 0), requesting...

```

Also, Python crashes and I get a report which, amongst other things, says:

> This app has crashed because it attempted to access privacy-sensitive data without a usage description. The app’s Info.plist must contain an com.apple.security.device.camera key with a string value explaining to the user how the app uses this data.

When I try to run `cap = cv2.VideoCapture(0)` in the Slicer Python console I get a similar error:

> This app has crashed because it attempted to access privacy-sensitive data without a usage description. The app’s Info.plist must contain an NSCameraUsageDescription key with a string value explaining to the user how the app uses this data.

I can’t figure out how to add this information to the Info.plist file

---

<div class="post-metadata">

**Author:** ![koeglfryderyk](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/koeglfryderyk/32/14638_2.png) [@koeglfryderyk](https://discourse.slicer.org/u/koeglfryderyk)\
**Post date:** [June 24, 2022, 11:42pm UTC](https://discourse.slicer.org/t/run-a-python-script-from-slicer/24016/6 "2022-06-24T23:42:25Z")

</div>

I added those two lines to the Info.plist file that I found in `/Applications/Slicer.app/Contents/Info.plist`

```auto
<key>com.apple.security.device.camera</key>
<string>used_to_track_your_hand</string>
<key>NSCameraUsageDescription</key>
<string>also_used_to_track_your_hand</string>

```

Now it seems that the code runs further (it doesn’t crash at `cap = cv2.VideoCapture(0)`), but `capcap.isOpened()` returns `False` and the it I get such a message:

```auto
'OpenCV: not authorized to capture video (status 0), requesting...\nOpenCV: camera failed to properly initialize!

```

---

<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:** [June 25, 2022, 4:29pm UTC](https://discourse.slicer.org/t/run-a-python-script-from-slicer/24016/7 "2022-06-25T16:29:46Z")

</div>

Those sound like permission issues with opencv and macOS at this point. Perhaps just run Slicer as root with sudo.

---

<div class="post-metadata">

**Author:** ![koeglfryderyk](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/koeglfryderyk/32/14638_2.png) [@koeglfryderyk](https://discourse.slicer.org/u/koeglfryderyk)\
**Post date:** [June 25, 2022, 5:49pm UTC](https://discourse.slicer.org/t/run-a-python-script-from-slicer/24016/8 "2022-06-25T17:49:05Z")

</div>

That unfortunately didn’t change anything.

I also tried adding `sudo` as an argument before `/bin/bash/` (and disabled the need for a password when using `sudo`), but this also didn’t change anything
