# Embedding Python inside an experiment

**URL:** <https://mworks.discourse.group/t/embedding-python-inside-an-experiment/517>\
**Category:** Support\
**Created:** [June 23, 2015, 3:09pm UTC](https://mworks.discourse.group/t/embedding-python-inside-an-experiment/517 "2015-06-23T15:09:06Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![cstawarz](https://yyz1.discourse-cdn.com/flex031/user_avatar/mworks.discourse.group/cstawarz/32/3_2.png) [@cstawarz](https://mworks.discourse.group/u/cstawarz)\
**Post date:** [June 23, 2015, 3:09pm UTC](https://mworks.discourse.group/t/embedding-python-inside-an-experiment/517/1 "2015-06-23T15:09:06Z")

</div>

Hi Mark,

As we have [previously discussed](https://mworks.discourse.group/discussions/questions/418/page/1#comment_31983250), I’ve implemented a mechanism for running Python code _inside_ an MWorks experiment (i.e. within the MWServer process).

MWorks now supports two Python-related actions: `run_python_file`, which takes the path to a Python source file and executes it, and `run_python_string`, which executes a string of Python code. In both cases, the code is executed within Python’s ` __main__ ` module, so any variables, functions, classes, etc. defined by one Python action are available to subsequent ones. My thinking is that you’ll want to set things up inside a Python source file, which gets executed once at the beginning of your protocol via `run_python_file`, and then call functions and methods as needed with `run_python_string`.

To enable interaction with the rest of your experiment, Python code has access to two MWorks-specific functions: `getvar`, which takes the name of an MWorks variable and returns its current value, and `setvar`, which takes the name of a variable and a value and stores the value in the variable. I’ve attached a very simple example experiment and associated Python script that demonstrates how this all works.

A few things worth noting:

- Both Python actions are synchronous, meaning no subsequent actions will run until your Python code finishes executing. (You are, of course, free to create new threads from Python, and those threads will run concurrently with the main experiment thread, subject to the limitations imposed by Python’s GIL.)

- The new actions use the system-provided Python (version 2.7 on all currently-supported OS X versions). If you want to install third-party packages, you should do so with `/usr/bin/easy_install` or install directly in to `/Library/Python/2.7/site-packages`.

- Python state is _not_ reset when a new experiment is loaded. This is because the Python interpreter itself can’t really be reset within a running process. If your Python code needs to run in a “clean slate” environment, then it’ll have to reset things itself.

- The file used by `run_python_file` is copied from client to server, just like an image or sound file. However, files _imported_ by that file are not. If your script imports any modules or packages that aren’t in the Python standard library, then you’ll need to install them on the server machine.

The Python actions are available in the current nightly build. When you have a chance, please try them out and let me know what you think.

Cheers,  
Chris

---

<div class="post-metadata">

**Author:** ![cstawarz](https://yyz1.discourse-cdn.com/flex031/user_avatar/mworks.discourse.group/cstawarz/32/3_2.png) [@cstawarz](https://mworks.discourse.group/u/cstawarz)\
**Post date:** [June 23, 2015, 3:09pm UTC](https://mworks.discourse.group/t/embedding-python-inside-an-experiment/517/2 "2015-06-23T15:09:06Z")

</div>

Attachment: [python\_actions\_example.zip](https://mworks.discourse.group/uploads/short-url/zGw9TlsnC9yN5QjBZhptWOybUcy.zip) (1.7 KB)

---

<div class="post-metadata">

**Author:** ![cstawarz](https://yyz1.discourse-cdn.com/flex031/user_avatar/mworks.discourse.group/cstawarz/32/3_2.png) [@cstawarz](https://mworks.discourse.group/u/cstawarz)\
**Post date:** [June 23, 2015, 4:07pm UTC](https://mworks.discourse.group/t/embedding-python-inside-an-experiment/517/3 "2015-06-23T16:07:30Z")

</div>

Wow. I am really glad you have implemented this, Chris.  
We are in the process of upgrading to a new nightly. When that is done I  
will take a look and test this. Thanks!!!

---

<div class="post-metadata">

**Author:** ![cstawarz](https://yyz1.discourse-cdn.com/flex031/user_avatar/mworks.discourse.group/cstawarz/32/3_2.png) [@cstawarz](https://mworks.discourse.group/u/cstawarz)\
**Post date:** [July 19, 2022, 10:39pm UTC](https://mworks.discourse.group/t/embedding-python-inside-an-experiment/517/4 "2022-07-19T22:39:54Z")

</div>


