Manhole, The Twisted Interaction Client

Manhole is a client that you can use to connect to the twisted.manhole service. It lets you execute arbitrary code on the server, thus it is a great administration and debugging tool.

Starting the twisted.manhole service

Execute the command mktap manhole -u [username] -w [password]. This will create a twisted application (.tap) file that has a twisted.manhole service which will listen on port 8787. Execute the command 'twistd -f manhole.tap' to actually start the server.

Using manhole

You can execute the command manhole to start the GTK+ manhole client. This will give you a window asking for your username, password, hostname, service, perspective, and port #. Type in the username and password you selected above, the hostname that the twisted.manhole service was started on (localhost is the default), leave the Service the same ('twisted.manhole'), leave Perspective blank, and leave Port # as the default of 8787. Click the "Log In" button and you will be greeted with a short message in a window with an output area and an input area. You can type arbitrary python code into the input area and get the results in the output area.

Special Commands

There are a few special commands so far that make debugging Twisted objects really nice. These are /browse and /watch. You can /browse any type of object, and it will give you some nice information about that object. /watch-ing an object adds hooks to the object, allowing you to watch modifications to it in real time. For example:

/browse ["hello", "there"]

  <ObjectLink of ["hello", "there"] type list>:
  ['hello',
   'there',]


class A:
    def foo(self):
        self.x = 1
x = A()
/browse x

<ObjectLink of x type instance>:
  {members: {}
   class: 'A'
   methods: {}}


/watch x

    <ObjectLink of x type instance>:
  {members: {}
   class: 'A'
   methods: {}}


x.foo()


<ObjectLink of x type instance>:
  {members: {x: 1}
   class: 'twisted.python.explorer.WatchingA8195574'
   methods:
     {foo:
        <ObjectLink of x.foo type instance_method>:
          {class: 'twisted.python.explorer.WatchingA8195574'
           self: '<twisted.python.explorer.WatchingA8195574 instance at 0x8195574>'
           doc:
             Pretend to be the method I replaced, and ring the bell.
                     
           line: 651
           signature:
             [{name: instance},
              {name: a
               list: 1},
              {name: kw
               keywords: 1},]
           file: /home/punck/cvs/Twisted/twisted/python/explorer.py
           name: __call__}
        }}

<ObjectLink of x type instance>:
  {members: {x: 1}
   class: 'twisted.python.explorer.WatchingA8195574'
   methods:
     {foo:
        <ObjectLink of x.foo type instance_method>:
          {class: 'twisted.python.explorer.WatchingA8195574'
           self: '<twisted.python.explorer.WatchingA8195574 instance at 0x8195574>'
           doc:
             Pretend to be the method I replaced, and ring the bell.
                     
           line: 651
           signature:
             [{name: instance},
              {name: a
               list: 1},
              {name: kw
               keywords: 1},]
           file: /home/punck/cvs/Twisted/twisted/python/explorer.py
           name: __call__}
        }}

    

As you can see, /watch really gives you a lot of power (and a lot of output, too -- hopefully we'll have a nice GUI display for this in the future). The /browse and /watch functionality is brought to you by the twisted.python.explorer module, which was written largely by Kevin Turner.


Chris Armstrong
Last modified: Tue Mar 12 22:32:48 EST 2002