Forum Moderators: Lobo3433, Staff Forum Coordinators: Anim8dtoon
Poser Python Scripting F.A.Q (Last Updated: 2026 Mar 26 2:31 pm)
I made the server TCP (not UDP) because it is simpler to deal with large data packages. Such as required to exchange data between Poser and other apps (for me C4D at the moment).
And it is possible to connect to the server with standard apps. Even telnet :)
A basic connection written in Python can look like this:
from __future__ import print_function
import sys
import socket
import time
import threading
import thread
HOST = "192.168.1.215"
PORT = 55555
stopflag = threading.Event()
_tcpsocket = None
def incoming(connection, outstream):
assert isinstance(connection, socket.socket)
# We need a timeout to be able to watch stopflag.
connection.settimeout(0.5)
while not stopflag.is_set():
data = None
try:
data = connection.recv(1024 * 4)
except socket.timeout:
continue # timeout is fine
except socket.error as e:
print(e)
stopflag.set()
else:
if data:
print("nIN >>> ", data, file=outstream)
try:
connection.close()
except socket.error as e:
print(e)
print("IN >>> STOPPED.")
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
s.connect((HOST, PORT))
except socket.error as e:
raise IOError("Can't connect to server %s an port %s" % (HOST, PORT))
thread.start_new_thread(incoming, (s, sys.stdout))
while True:
try:
print("n(Ctl-D or Ctl-Z+Return to stop)")
cmd = raw_input("Cmd to send: ")
except EOFError:
break
else:
s.sendall(cmd)
stopflag.set()
s.shutdown(socket.SHUT_RDWR)
This site uses cookies to deliver the best experience. Our own cookies make user accounts and other features possible. Third-party cookies are used to display relevant ads and to analyze how Renderosity is used. By using our site, you acknowledge that you have read and understood our Terms of Service, including our Cookie Policy and our Privacy Policy.
(Download from my website as ZIP packet, contains all files needed for import)
First version of a working command server: "PoserTalkr".
Efforts to use the Python standard libraries under Poser-Python have failed across the board. Too many peculiarities to be considered a) for the intended use and b) for Poser in general.
How the TCP server works:
The whole thing is based on threads and "queues". First of all there is the "dispatcher" task, which is started immediately after the script is called. Its main task is to wait for incoming connections, then start a thread for the client connection and wake up the "Poser interpreter".
Each started client thread handles incoming and outgoing data for the respective client. Incoming data is stored in the "input_queue" as it comes in. No checks, no preformatting. If there is no incoming data, the client thread checks if there is data in the "output_queue". If there is, it will be sent.
The main task of the client thread is to maintain a stable connection between server and client.
The "queues" in which incoming and outgoing data is stored are based on Python's "deque". They are also thread save, similar to the "real" Python queues. But Python's deques are more similar to lists. This is more suitable for this purpose, since each client has its own queue(s) anyway - one for input and one for output, based on IP addresses (but this also means: If several connections to the server are started from one machine - i.e. one IP address - they are treated as one client - I'll explain the consequences in a moment).
Parallel to the client threads, there is exactly one thread that has contact to Poser. This thread processes all inbound queues (incoming data from all clients) and stores results in the respective outbound queue (belonging to the client that created the result).
The first character of each entry in the input-queue is taken into account and interpreted if necessary. At the moment these are the characters:
"=" : Subsequent data processed with "eval".
"%": Subsequent data processed with "object_from_path".
For the interpreted input data, the result is sent back to the client.
"=4+5" ### Returns 9, result of 4+5.
" =SCENE.CurrentActor().Name() ### Returns the name of the current actor.
and so on.
Other incoming data packets are executed with "exec". If the data packet contains a "\n" at any position, "compile" is called first. This makes it possible to send complete scripts and have them interpreted.
The Poser interpreter puts all results into the outbound queue, from where the client thread can fetch and send it if necessary. Provided "exec" returns any result (error messages for example).
Since each client has its own workspace ("globals" and "locals"), different clients do not get in each other's way. So if client A sends: "MyPrivVar = SCENE.CurrentActor()", client B cannot access "MyPrivVar".
The work areas (more precisely: the client data) are stored beyond the lifetime of a connection. If said client A breaks the connection and reconnects later, the client can access "MyPrivVar" again (as mentioned: IP == Client).
At this point it should be mentioned that this version does not take any security precautions. It does not check whether a connection is allowed. Whoever can connect to the server is accepted.
Who has more questions about the script: Bring it on. Also suggestions for improvements and/or extensions are welcome. And of course: Hints about the probably existing errors...
Translated with www.DeepL.com/Translator (free version)