This module intends to replace several other, older modules and functions, such as: os.system os.spawn. os.popen. popen2. commands. Information about how the subprocess module can be used to replace these modules and functions can be found in the following sections.
Both hosts are running CentOS 7 and Python 3.6.8
Doing a little more investigation, I was able to replicate the problem on the first host by running
pip3 install subprocess.run. I then ran
pip3 uninstall subprocess.runon both hosts and was able to get things working again.
I was unaware that Python includes the subprocess.run module, but apparently the version installed with Pip is faulty? Can someone explain what happened here?
At the TouchDesigner Summit in Montreal we’ll be taking some time to talk about working with external Python Modules in TouchDesigner. While we’ll have time to cover lots of information about how to incorporate external modules in Touch, we won’t have a lot of time to talk through the wobbles that you might run into when working with operations that might be slow, or otherwise unwieldy to run in Touch.
“What do you mean Matt?”
The types of pieces that usually fall into this category are blocking operations. For example, let’s say that you want to upload an image to the web somewhere. Many of the libraries that you might find will have an approach that’s probably blocking – as in it will appear as if TouchDesigner has frozen while the whole operation completes. While this is fine outside of Touch, we don’t typically like it when our applications appear to freeze – especially in installations or live performances. You might be able to move that process to another thread, though that might be a little more hassle that you really want it to be in the long run.
Enter the Python Subprocess module.
The subprocess module allows you to run a python script as a parallel execution that doesn’t touch your TouchDesigner application. You could use this for all sorts of interesting an powerful applications – from starting media syncing between machines, running a process that talks to the internet, or any number of solutions that execute outside of TouchDesigner. In the past I’ve used this for things like sending emails, or uploading images to Instagram – there’s lots you can do with this approach, it’s just a matter of wrangling python and the subprocess module.
What exactly is happening when we use the subprocess module?! Well, we can think of this as a situation where we write a python script in a text file, and then ask your operating system to run that file. There are great ways to pass in arguments into those situations, and if you really need data there are ways to get a response before the process quits. This can be a very flexible solution for a number of situations, and worth looking into if you want something that’s non-blocking and can be run outside of TouchDesigner.
Subprocess calls can be infuriating if you’re not familiar with them, so let’s look at some simple anatomy of making this work from Touch.
Yamaha Piano Serial Number Search. Input your Serial # to determine whether the piano was made for the US market. (Please enter the entire serial # including letters and leading zeros.) (Note: This is for Acoustic Pianos only- please do not enter a digital piano Serial Number.). Yamaha U3A Upright Piano 1986. Sign up to our newsletter to receive no more than a monthly email with news and offers for our new and secondhand pianos and as well as our piano services. You can unsubscribe from it at any time. Yamaha Piano Serial Number Search. Input your Serial # to determine whether the piano was made for the US market. (Please enter the entire serial # including letters and leading zeros.) (Note: This is for Acoustic Pianos only- please do not enter a digital piano Serial Number.) Where are my Serial# and Model# located? Yamaha piano serial number search europe.
Scenario 1 – Execute this Script
Let’s start with the most basic of scenarios. Here we have some Python script that normally takes a long time to run, that we just want to kick off from TouchDesigner. For this example let’s just look at something that will print to a shell – nothing fancy, just a place to get our bearings. Our python script might look something like this:
This works just the way that we might expect if we run it in our OS. But how can we run this script from TouchDesigner?
In TouchDesigner we’d add a DAT that has the following contents. Here we assume that the script above has been saved in a folder called
scripts that’s in the same folder as our project file, and the name of the script is
This is great, but this will actually execute with the version of Python that’s packaged with TouchDesigner. In some cases that’s exactly what we want… in other’s we might want to use a different version of python that’s installed on our OS. How can we do that?
Scenario 2 – Execute this Script with a Specific Python
This is very similar to our first situation, but here we want to run the python that’s installed on our OS, not the python that’s packaged with Touch. In this case we can use the exact same python script we saw above.
Our real changes come when we’re issuing the subprocess call in TouchDesigner.
Again, we add a DAT that has the following contents. Here we assume that the script above has been saved in a folder called
scripts that’s in the same folder as our project file, and the name of the script is
cmd_line_python.py. The additional wrinkle this time, is that we also need to specify which
python.exe we want to use for this process.
If we look closely at the example above, we can see that we’ve been very specific about where our
python_exe lives. This approach runs the same script, only this time with the
python.exe that we’ve specifically pointed to.
Scenario 3 – Passing Over Args
There are several ways to approach this challenge. One that will line up with the format of many pure pythonic approaches here would be to use the
argparse library. We find this in lots of stand-alone scripts, and it allows us the flexibility of setting default arguments, and creating some relatively clean inputs when calling a script form the command line. In this approach we set up a function that we’ll call, and pass arguments into – in the example below that’s our
My_python_method(). By using
ArgumentParser we can pass in command line arguments that we can in turn pass through to our function. Notice the syntax at the bottom to see how this works.
ArgumentParser returns keyword arguments, which is why we use
kwargs as the mechanism for sending args into our simple for loop.
Where this becomes more interesting is when we look at what’s happening on the TouchDesigner side of this equation.
A DAT in TouchDesigner needs to follow the same rules we established so far – we need to know what executable we’re using, which file we’re running, and finally we now need to send along some arguments that will be passed to that file. In Touch, our script this time should look something like this:
Scenario 4 – I Want a Message Back
Like all things Touch, and all things Python there are LOTS of ways to accomplish this task. One way we might want to consider, however, is using UDP messages. Touch happens to have a handy
UDPIn DAT that’s ready to accept messages, and the other benefit here is that we could potentially target another machine on our network as the target for these messages. For this first exploration let’s imagine that we’re only sending a message locally, and that all of our variables are defined in the python script we’re running. We’ll need to use the
socket library to help with the communication elements, and you’ll notice that we import that at the top of our script. This silly example just creates a UDP connection, and sends messages at a regular interval. Funkcje zespolone leja pdf free.
For this simple execution in TouchDesigner we only need to worry about kicking off the script. That looks almost exactly like the other pieces we’ve set up so far.
Our catch this time is that we need to use a
UDPIn DAT to receive those messages. Let’s also make sure the
Row/Callback Format parameter is set to
One Per Message. With this all set up we should see something like this when we kick off the script.
Scenario 5 – Messages, I can has args?!
That all seems mighty fine… but, what happens when I want to combine what we’ve done with passing along arguments, and messages? I’m so glad you asked. With a little extra work we can make exactly that happen. We do need to do a little more heavy lifting on the python front, but that work gives us some extra flexibility. You’ll notice below that we’re now passing along which port we want to use, how many iterations of our for loop, and the interval between repetitions.
Over in TouchDesigner, our subprocess script looks very similar to what we’ve done so far with just a few modifications.
Here the resulting messages look very similar, only we’ve not gotten to specify all the qualities about the for loop from our script.
What does this Matter?
Well, there are lots of things you might do with this, but especially interesting might be considering how you can use otherwise very costly and slow operations in Python with this approach. For example, a recent set of Style Transfer experiments I was working on used this style of approach to essentially create a TouchDesigner front end / UI for a
pytorch style transfer backend. This let me pass along arguments from the UI over to a pure python execution that didn’t block or freeze touch while it was running. There are lots of ways you might get into mischief with this kind of work, and it’s worth pointing out that while all this is focused on python, there’s no reason you couldn’t instead think of other applications you want to run with a particular file and a set of command line arguments.
What to follow along? Download the sample code from github