How do I send input from python cmd to autobahn websocket client running in the same interpreter?

I’m trying to take input from an interactive prompt via python’s cmd library and pass the input to an autobahn websocket client to send up to a websocket server. The cmd loop and the autobahn websocket client loop are running in the same interpreter. I’m trying to use crochet to make that work. The websocket client connects to the server successfully but when I enter something at the cmd prompt to invoke sendMessage, I get the exception shown at the bottom of this post. Any guidance on where I may have messed up would be much appreciated. If there’s a better approach to accomplish what I’m trying to do, I’m all ears.

These are the relevant imports and setup:

from cmd import Cmd
from crochet import setup, run_in_reactor, wait_for, retrieve_result, TimeoutError

# Setup crochet before importing twisted

from twisted.internet import reactor, ssl
from twisted.python import log
from autobahn.twisted.websocket import WebSocketClientFactory, \
    WebSocketClientProtocol, \

This is the websocket client protocol class:

class MyClientProtocol(WebSocketClientProtocol):

    def __init__(self, *args, **kwargs):
        super(MyClientProtocol, self).__init__(*args, **kwargs)

    def onConnect(self, response):

    def onMessage(self, payload, isBinary):
        if not isBinary:
            print('Message received: {}'.format(payload.decode('utf8')))

    def sendTask(self, payload):
        payload = json.dumps(payload, ensure_ascii = False).encode('utf8')

This is the websocket client factory class:

class MyClientFactory(WebSocketClientFactory):

    def __init__(self, *args, **kwargs):
        super(MyClientFactory, self).__init__(*args, **kwargs)

    def buildFactory(self, uri, headers):
        factory = WebSocketClientFactory(uri, headers=headers)
        factory.protocol = MyClientProtocol
        return factory

This is the cmd class that sends input to the websocket client:

class mycmd(Cmd):
    def do_send(self, inp):
        payload = {'task': inp}
        m = MyClientProtocol()
        reactor.callFromThread(m.sendTask, payload)

This is how I’m calling the websocket client and cmd loop:

if __name__ == '__main__':

    def start_connectWS():
        headers = {'header1': 'value1'}
        f = MyClientFactory()
        connectStatement = f.buildFactory(uri, headers)
        if connectStatement.isSecure:
            contextFactory = ssl.ClientContextFactory()
            contextFactory = None
        connectWS(connectStatement, contextFactory)


This is the exception:

Unhandled Error
Traceback (most recent call last):
  File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.7/lib/python3.7/", line 865, in run
    self._target(*self._args, **self._kwargs)
  File "/Users/tomd/project/lib/python3.7/site-packages/crochet/", line 412, in <lambda>
  File "/Users/tomd/project/lib/python3.7/site-packages/twisted/internet/", line 1283, in run
  File "/Users/tomd/project/lib/python3.7/site-packages/twisted/internet/", line 1292, in mainLoop
--- <exception caught here> ---
  File "/Users/tomd/project/lib/python3.7/site-packages/twisted/internet/", line 886, in runUntilCurrent
    f(*a, **kw)
  File "./", line 62, in sendTask
  File "/Users/tomd/project/lib/python3.7/site-packages/autobahn/websocket/", line 2215, in sendMessage
    if self.state != WebSocketProtocol.STATE_OPEN:
builtins.AttributeError: 'MyClientProtocol' object has no attribute 'state'