0

I'm trying to run a program and feed the program a script as such:

subprocess.Popen(['X:\\apps\\Nuke6.1v5\\Nuke6.1.exe', '-t', 'X:\\apps\\Scripts\NUKE\\nukeExternalControl\\server.py'])

My problem is that it takes the program a few seconds to finish launching. So while its starting up the program Popen runs the next command and of course because the program is not up and running is errors out. So my question is how do I tell Popen to wait for the first application to run THEN execute the next part of Popen.. any takers??

UPDATE

    import nukeExternalControl.client

    np = subprocess.Popen(['X:\\apps\\Nuke6.1v5\\Nuke6.1.exe', '-t', 'X:\\apps\\Scripts\NUKE\\nukeExternalControl\\server.py'])


    print "Starting Nuke Server"

    conn = nukeExternalControl.client.NukeConnection()
    nuke = conn.nuke

    print "execute commands"

    nuke.root().knob('first_frame').setValue(1)
    nuke.root().knob('last_frame').setValue(10)

    read = nuke.createNode('CheckerBoard2')
    textFrame = nuke.createNode('Text')
    textShotName = nuke.createNode('Text')
    reformat = nuke.createNode('Reformat')
    write = nuke.createNode('Write')

SOLUTION

So! Thanks to jdi the problem has been sovled! Props to him as he has stuck this problem out with me for quite some time... thanks so much!

ANSWER:

I needed to use time.sleep() after the Popen command because my server was not waiting for nuke to start before communicating to it.

user1159817
  • 29
  • 1
  • 6
  • Maybe you find an answer here: http://stackoverflow.com/questions/8377391/running-subsequent-commands-within-python ... Something along those lines: from subprocess import Popen, PIPE p1 = Popen([script1, input1], stdout=PIPE) p2 = Popen([script2], stdin=p1.stdout, stdout=PIPE) p1.stdout.close() Sorry, I can't test it right now. – Simon Steinberger Feb 28 '12 at 22:28
  • The problem with calling the program is that it opens the program in the shell and from that point on it expects user input. But I don't want to give it user input.. I want the program to take a list of commands later down the python script. Thats what the second part of the Popen is for. – user1159817 Feb 28 '12 at 22:38
  • If you're going to be giving it commands later why don't you just include them in your `call` call :-). Or is there some reason why you **have** to use `Popen`? – Ben Feb 28 '12 at 22:43
  • I have tried that too.. same problem.. second command starts before the first is finished. And if I can I would like to stick to Popen :) – user1159817 Feb 28 '12 at 22:45
  • where's that next command or next part? could you clarify what's going on? – Karoly Horvath Feb 28 '12 at 23:10
  • For sure, So the first part is the "subprocess.Popen(['X:\\apps\\Nuke6.1v5\\Nuke6.1.exe', '-t'" This starts the program. The second part "'X:\\apps\\Scripts\NUKE\\nukeExternalControl\\server.py'])" this starts the server.py script which is looking for the running program that I am calling.. But because the program takes a little bit of time to start, the server.py can't find it right away and therefore errors out.. :( Hence the reason why I am trying to find a way to make Popen wait for the program to start before running the server.py – user1159817 Feb 28 '12 at 23:18
  • just as I thought.. check my answer – Karoly Horvath Feb 28 '12 at 23:21
  • What you are currently doing though looks to be right. You are calling nuke -t which means start the nuke python interp and by passing it your script its going to start that python script with the nuke interp. Its the same idea as saying `python myscript.py` – jdi Feb 28 '12 at 23:41
  • @user1159817 - Please explain in more detail the exact functionality you are trying to configuring. Do you want the server and client both running in the same script for some reason? Or are you trying to write two scripts, one that starts a server and another that connects to it? – jdi Feb 29 '12 at 00:13

2 Answers2

1

After glancing over the readme for this nuke module, I get the sense that you might be confused about what is actually required to use it.

subprocess.Popen(['X:\\apps\\Nuke6.1v5\\Nuke6.1.exe', '-t', 'X:\\apps\\Scripts\NUKE\\nukeExternalControl\\server.py'])

... This line (which I assume you are actually assigning to a variable and either blocking on it, or checking its status), is what is required to start a non-gui based server with Nuke. Nuke being a python interpreter can run a python script via nuke -t <script.py>, hence you are using it to start your server process. This will block, and wait for you to use your client class to communicate.

What seems to be missing from your question is more context about how you are exactly trying to run this server/client configuration. If you are attempting to do both parts in the same script, then you would need to start the server process as you are doing, then maybe sleep for a second (the server process starts pretty quickly), and then run the client code that makes the connection.

Update

Realistically there are two ways to start your server process, as very plainly outlined in the readme:

To start a command sever whenever Nuke is launched, add the following lines
to your Nuke menu.py:
---------------------------
import nukeExternalControl.server
nukeExternalControl.server.nuke_command_server()
---------------------------

This is something you would put in your nuke menu.py file, or manually start this with a running Nuke application. Your application will now be running a server process and allow clients to connect.

If you dont want to have to use a GUI license and keep it running to server connections, then you use the other method from the command line X:\apps\Nuke6.1v5\Nuke6.1.exe -t X:\apps\Scripts\NUKE\nukeExternalControl\server.py , which starts a terminal-based server. There is NO reason I can think of that you need to be using subprocess to start the server in your script when they give you a method for starting it already.

Solution

After a lengthy conversation with the OP, it turns out that what he wanted to do was what the first part of my answer suggested. He has a standalone script that wants to do something using Nuke's python interpreter (completely headless without the Nuke GUI app). Using this 3rd party module, he wants to start the script in a subprocess that will act as a server to the nuke terminal. He will then proceed in his code to communicate with it using the client class (he is self hosting a server process and sorta round-robin communicating with it.

The solution to his problem was that he needed to time.sleep(2) right after the Popen that starts his server.py. Waiting a few seconds for the server to completely start allowed the client to successfully connect.

And yes, he owes me a beer now.

jdi
  • 90,542
  • 19
  • 167
  • 203
  • I think I know what you mean.. originally I set it up as such: 'np = subprocess.Popen(['X:\\apps\\Nuke6.1v5\\Nuke6.1.exe','-t',` `'X:\\apps\\Scripts\NUKE\\nukeExternalControl\\server.py'])` `np.communicate()` But this has not worked for me.. do you mean something? Can you give me an example code? – user1159817 Feb 28 '12 at 23:57
  • First can you please explain how you intend to set up your script? Is your goal to simply make it start the server and block? – jdi Feb 29 '12 at 00:02
  • To be honest I'm not really sure. I've been doing python within Nuke for a while and know that no problem but python outside.. I'm pretty new to still. As far as I understand .communicate() blocks.. or rather it can block. I'm not sure what you mean by set up my script.. if you mean start it, then I have a command in my right-click menu that runs this python script which brings up a pyGui.. then after user input runs nuke and feeds it some nuke commands.. which is where I'm stuck. I've got the server to work with nukes gui open.. just not without it open – user1159817 Feb 29 '12 at 00:14
  • See my update. I think you might really be confused on what this tool does and how its set up properly. – jdi Feb 29 '12 at 00:25
  • Ok soooo.. either I am awfully confused.. or miss communicating.. This is part of the script I am executing after user input to the gui.. when I run this part of the script once.. I get an error that the server cannot connect to nuke.. but if I run this script again right after the error, the server connects to nuke and runs the nuke commands and renders out a small test sequence.. thats what I want it to do.. and that what I thought this server.py was meant for. lol so am I confused and this is not what its for or am I just being confusing.. check above for updated script – user1159817 Feb 29 '12 at 00:50
  • Ok, so now that I can actually see your script, I'm still confused as to why you are starting the server using subprocess as opposed to `import nukeExternalControl.server; nukeExternalControl.server.nuke_command_server()`? Swap that line out. – jdi Feb 29 '12 at 00:55
  • `import nukeExternalControl.server` and `nukeExternalControl.server.nuke_command_server()` are supposed to be in the menu.py, which is where they are currently. Are you saying put both those lines of code in where the \server.py is in the Popen? Because if I do Popen tries to find a file named that :P. I'm really sorry if I'm frustrating to work with. – user1159817 Feb 29 '12 at 01:08
  • What I am saying is that if you have already put that in the menu.py, then your server is running and you have NO NEED to be starting another server process again before connecting with your client. Its already running when Nuke GUI started. – jdi Feb 29 '12 at 01:17
  • Ok.. it may be running but the thing is, if I take out the server.py from the Popen, the python shell becomes a command line for me to type in commands and create stuff in nuke, but requires user input. The python script I created does not continue after it starts nuke.. it just sits there. Where as if I leave the the server.py, it errors the first time and then works the way I want the second time.. sigh.. I will not ask you for anymore help.. thank you very VERY much for your time.. if your ever in Vancouver I will buy you a beer.. a few haha. – user1159817 Feb 29 '12 at 01:26
  • Yea you still aren't understanding what Im saying though. This might be impossible to communicate over comments, without a chat and you dont have enough SO points to chat. If you want to AIM chat me, contact me at `VFXjustin`. Whatever we resolve, I will update my answer. – jdi Feb 29 '12 at 01:34
  • If you really want to suffer more by my account then alright.. can we do that tomorrow? Its end of the day.. need to go pick up my fiance. – user1159817 Feb 29 '12 at 01:55
  • Thats fine. Contact me tomorrow. – jdi Feb 29 '12 at 01:59
0

If the thing you're reffering to when you say "next command/thing" is 'X:\\apps\\Scripts\NUKE\\nukeExternalControl\\server.py', then you're quite confused. That's an command line argument passed to nuke.exe (the same way as C:\ is passed when you execute dir C:\).

There's simply no way to control what nuke.exe does from the python side... you have to check in your server.py that the exe is finished "booting".

Karoly Horvath
  • 94,607
  • 11
  • 117
  • 176
  • Yes I am trying to pass the `server.py` to the nuke.exe. Bummer though.. I'm slightly confuzzled as to what to do now.. I can't pass the server.py after nuke.exe has been called because now nuke python commands work in the shell from that point.. any ideas how to pass the server to nuke? – user1159817 Feb 28 '12 at 23:30
  • Hmm well here is a link to the thing I am trying to get working https://github.com/Nvizible/NukeExternalControl about half way down is what I am trying to do: "Nuke -t /nukeExternalControl/server.py" – user1159817 Feb 28 '12 at 23:37
  • @yi_H - Just to help clarify for the OP... Nuke uses a python interpreter and can be started from a command line like he is doing. I assume he is start up the interpreter with a custom script that will then allow him to actively send commands to Nuke – jdi Feb 28 '12 at 23:37