7
$\begingroup$

I don't want to use /Application.../blender -P my_script.py but I want to tell a running Blender process to execute a script.

Is there an existing method to tell a running Blender process to execute a python script?

For example using http://localhost:123/run_script=myscript.py

$\endgroup$
  • 1
    $\begingroup$ I would like to create a vim shortcut, that's why I'm asking. $\endgroup$ – mipmip Nov 13 '15 at 15:44
11
$\begingroup$

This can be done with sockets, using the following examples you can run from the command line:

From the first terminal:

blender --python blender_server.py

From a second terminal:

python blender_client.py /path/to/myscript.py

This will execute /path/to/myscript.py in the first Blender instance.

You can send multiple scripts or run the client multiple times.

Note that this is a simple example, to get return codes in the client or make the port configurable... etc, this would have to be extended.

It could even be made to sent the entire script, or compressed Python byte-code over a network, none of this is especially hard. It just depends what you're after.


blender_server.py

# Script to run from blender:
#   blender --python blender_server.py

PORT = 8081
HOST = "localhost"
PATH_MAX = 4096


def execfile(filepath):
    import os
    global_namespace = {
        "__file__": filepath,
        "__name__": "__main__",
    }
    with open(filepath, 'rb') as file:
        exec(compile(file.read(), filepath, 'exec'), global_namespace)


def main():
    import socket

    serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    serversocket.bind((HOST, PORT))
    serversocket.listen(1)

    print("Listening on %s:%s" % (HOST, PORT))
    while True:
        connection, address = serversocket.accept()
        buf = connection.recv(PATH_MAX)

        for filepath in buf.split(b'\x00'):
            if filepath:
                print("Executing:", filepath)
                try:
                    execfile(filepath)
                except:
                    import traceback
                    traceback.print_exc()


if __name__ == "__main__":
    main()

blender_client.py

#!/usr/bin/env python
# Script to send paths to run in blender:
#   blender_client.py script1.py script2.py

PORT = 8081
HOST = "localhost"

def main():
    import sys
    import socket

    clientsocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    clientsocket.connect((HOST, PORT))

    for arg in sys.argv[1:]:
        clientsocket.sendall(arg.encode("utf-8") + b'\x00')


if __name__ == "__main__":
    main()
$\endgroup$
3
$\begingroup$

I think this is a simple solution and avoids dependencies entirely.

https://github.com/zeffii/bpy_externall

Blender (Server)

Here's a small modal operator addon that works like this:

enter image description here

  • Adds a panel to the TextEditor, with a start / end button
  • when Start is pressed it
    • reads a file located at /path/whatever.io every n seconds.
      • If the file is empty we do nothing,
      • If the file contains a filepath (for instance to a python file) then the filepath is executed with Blender's python (as if it was running from the TextEditor). Once completed the operator will erase the contents of the file to indicate that it executed the path.
    • When End is pressed the modal operator stops reading that file location.

External Text Editor (Client)

The add-on includes an example of a SublimeText3 plugin that acts as a Client. All this 'Sender' plugin needs to do is write the filepath of the python file you want Blender to execute to /path/whatever.io

$\endgroup$
  • $\begingroup$ Wow this looks great! $\endgroup$ – mipmip Nov 16 '15 at 11:28
  • 1
    $\begingroup$ This concept is fine! I've created a small pull-request. I'll start working on a vim-plugin rightaway. $\endgroup$ – mipmip Nov 16 '15 at 16:17
  • 1
    $\begingroup$ First vim plugin version is here $\endgroup$ – mipmip Nov 16 '15 at 21:30
  • $\begingroup$ I don't have a windows machine, but it should not be to hard to create working version for window too. I presume there are a lot of Blender users running Windows. $\endgroup$ – mipmip Nov 16 '15 at 21:41
  • $\begingroup$ ideasman42's answer using sockets is really cool, i'll need to study it :) $\endgroup$ – zeffii Nov 16 '15 at 21:43
2
$\begingroup$

I did ask a similar question, but as this one is way more popular so I guess that answer should be here. Question on command port

This usually is done with command port that listens for commands, but there's apparently no such thing in Blender. I've created an addon that implements this functionality. It can be found on github:

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.