Pyblish QML xml-rpc error

hey guys,

I’m trying to connect the pyblish QML to maya in linux. because we are running centos 6.5 and only have python 2.6 support I’m building a virtual env like setup where i can run pyblish-qml with python 2.7 and pyqt5. this seems to work.

I can launch pyblish-qml using the pyblish-tray and open the QML widget.

however when i then load the maya widget it initial speak with it but then gives me the following error on validate or publish. (error at the bottom)

it seems to run my first validator as i’m seeing some print statements from it in maya.

Thanks Lars, I’ll take a look at this asap.

If possible, could you post some more specifics about the environment in which you run pyblish-qml? I’ll try and recreate it at home to hopefully reproduce the error. Starting from a blank CentOS 6 dist, what else do I need?

Hey Marcus,

that might be a bit difficult as it’s built ontop a lot of inhouse stuff but here is the gist.

I’ve created a env with the following packages

gcc-4.8.2
libzlib-1.2.5
pyblish-1.3.1
pyblish_qml-0.4.0
pyblish_rpc-0.2.0
pyblish_tray-0.1.0
pyqt-5.5.1
python-2.7.5
qt-5.5.1   
sip-4.17

i launch it using

python -m pyblish_tray

if i try and use:

python -m pyblish_qml

it always hangs and doesnt open the UI.

ones open I can see the UI. from maya I hit the publish menu option. it connects and shows me the menu as show.
when I then click validate or publish it runs the first validator and i get the error message below.

Perfect, that’s really useful.

pyblish-tray runs pyblish-qml, so this step isn’t necessary. I would expect it to cause trouble, as the second copy would try and use the same port.

Either run pyblish-tray or pyblish-qml.

To test pyblish-qml in the terminal, without a host, you can try this.

$ python -m pyblish_qml --debug

I’ve narrowed it down to the following call in my validator

self.log.info('Units (time): {0} FPS'.format(fps))

this print the following in maya

pyblish.validate_fps.ValidateUnitsFps : Units (time): 25 FPS # 

yet afterwards thows that error message and stops execution.

Can you make sure you aren’t actually having 2 pyblish-qml running on your machine? They would both be listening and sending requests to Maya, which might throw it off. The processes can be a little tricky to identify, but one would be running under pyblish-tray, and will close when you quit it.

deffinitly only 1 qml running

$ ps ax | grep qml
30051 pts/3    Sl     1:58 python -u -m pyblish_qml

which way around should it start? should i start maya first? is that the rpc server?
or should i start qml first?

They can be started in any order.

pyblish-rpc is normally started through pyblish-maya.

import pyblish_maya
pyblish_maya.setup()

If pyblish-qml is up and running, that’s the only command you should need for the GUI and Maya to do their dance.

Ok, so I’m having a look at trying to recreate your environment, but as it has it, 6.5 is too old to even have a Docker image. :smiley:

So let’s approach it from the ground up. Putting aside Python 2.7 and PyQt5, your environment must be capable of IPC, so have a look to see if this example works for you.

In 2 terminals, run this in one…

server.py

from SimpleXMLRPCServer import SimpleXMLRPCServer

def hello():
  print("server.py says hello..")
  return "Hello!"

server = SimpleXMLRPCServer(("127.0.0.1", 9999))
server.register_function(hello)

print("Listening on 127.0.0.1:9999")
server.serve_forever()

And this in the other…

client.py

import xmlrpclib
proxy = xmlrpclib.ServerProxy("http://127.0.0.1:9999")
print(proxy.hello())

The server terminal should say server.py says hello.. and the client terminal should say Hello!.

Let me know how this goes and we’ll take it from there!

that works

server.py says hello..
localhost.localdomain - - [02/Mar/2016 22:51:45] "POST /RPC2 HTTP/1.0" 200

Excellent, now let’s try talking with Maya.

Once you’ve launched Maya and run pyblish_maya.setup(), try this in a new terminal…

import xmlrpclib
proxy = xmlrpclib.ServerProxy("http://127.0.0.1:9001/pyblish")
proxy.discover()

This should print out JSON representations of all currently discoverable plug-ins from the host you connected with. If port number 9001 isn’t found, you can query it from inside Maya via PYBLISH_CLIENT_PORT.

# From inside Maya
import os
print(os.environ["PYBLISH_CLIENT_PORT"])

I’ve updated the Developer Guide with this information too.

Let me know how it goes!

that works. I’m getting the list.

Ok, in that case, Maya was your server, and the terminal was your client.

Now let’s try it the other way, and let Maya be your client, and Pyblish QML be your server.

Terminal

python -m pyblish_qml --debug

You should be seeing the QML GUI with a number of plug-ins and instances, if not, don’t bother with the next step. If all is well, you can click the X on the GUI, but leave the process running in the terminal.

In Maya

import xmlrpclib
proxy = xmlrpclib.ServerProxy("http://127.0.0.1:9090")
proxy.show()

This should bring back the GUI, this time almost empty, apart from a few default collectors.

gives me this error

# Fault: <Fault 1: "<type 'exceptions.TypeError'>:show() takes at least 2 arguments (1 given)"> # 

i tried it with:

proxy.show("")

it crashes QML with

Traceback (most recent call last):
  File "/users/lars/packages/pyblish_qml/0.4.0/python/pyblish_qml/app.py", line 179, in show
    self.controller.reset()
  File "/users/lars/packages/pyblish_qml/0.4.0/python/pyblish_qml/control.py", line 597, in reset
    stats = {"requestCount": self.host.stats()["totalRequestCount"]}
  File "/software/rez/packages/centos_6/python/2.7.5/platform-linux/arch-x86_64/lib/python2.7/xmlrpclib.py", line 1224, in __call__
    return self.__send(self.__name, args)
  File "/software/rez/packages/centos_6/python/2.7.5/platform-linux/arch-x86_64/lib/python2.7/xmlrpclib.py", line 1578, in __request
    verbose=self.__verbose
  File "/software/rez/packages/centos_6/python/2.7.5/platform-linux/arch-x86_64/lib/python2.7/xmlrpclib.py", line 1264, in request
    return self.single_request(host, handler, request_body, verbose)
  File "/software/rez/packages/centos_6/python/2.7.5/platform-linux/arch-x86_64/lib/python2.7/xmlrpclib.py", line 1292, in single_request
    self.send_content(h, request_body)
  File "/software/rez/packages/centos_6/python/2.7.5/platform-linux/arch-x86_64/lib/python2.7/xmlrpclib.py", line 1439, in send_content
    connection.endheaders(request_body)
  File "/software/rez/packages/centos_6/python/2.7.5/platform-linux/arch-x86_64/lib/python2.7/httplib.py", line 969, in endheaders
    self._send_output(message_body)
  File "/software/rez/packages/centos_6/python/2.7.5/platform-linux/arch-x86_64/lib/python2.7/httplib.py", line 829, in _send_output
    self.send(msg)
  File "/software/rez/packages/centos_6/python/2.7.5/platform-linux/arch-x86_64/lib/python2.7/httplib.py", line 791, in send
    self.connect()
  File "/software/rez/packages/centos_6/python/2.7.5/platform-linux/arch-x86_64/lib/python2.7/httplib.py", line 772, in connect
    self.timeout, self.source_address)
  File "/software/rez/packages/centos_6/python/2.7.5/platform-linux/arch-x86_64/lib/python2.7/socket.py", line 571, in create_connection
    raise err
socket.error: [Errno 111] Connection refused

Sorry, it should have been.

proxy.show(9001)

Where 9001 is the PYBLISH_CLIENT_PORT.

that worked

import xmlrpclib
proxy = xmlrpclib.ServerProxy("http://127.0.0.1:9090")
proxy.show(9001)
# Warning: pyblish.collect_maya_cameras.CollectMayaCameras : no _layout_camera set found #

At this point, you have a fully functional Pyblish QML and Maya integration.

You should be able to publish from here. If you can, then the only remaining component is the Publish menu item in Maya, which calls a function similar to the one you just ran.

the issue still remains that self.log inside of any of the plugins causes the error message.

I guess I can do without it for now but how are log messages sent back over rpc? can you point me to where in the code this logic happens so i can try and debug ?

Ah, interesting. So it’s strictly log messages that is causing trouble. That is quite odd, as they are just strings sent across, maybe something with unicode?

Log messages are converted from the native Python LogRecord object here, put into a result dictionary and sent across here.

You can try and create a few LogRecords by hand, format them with format_record(), and send them over plain RPC like above. It should produce the same error. Even in two plain terminals, but between two Maya’s should probably be more accurate, as it sounds like something in Maya’s Python.

ok so i’ve found the culprate

the “thread” value in the LogRecord causes this issues. when I put

record.pop('thread')

the errors go away.