# 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.

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