In order to create a manhole server, use a command like
mktap manhole -u [username] -w [password]
.
If you've already got a TAP
for a server, you can use the argument
--append [tapname]
to
mktap
to add a manhole service to that
TAP
.
The second service offered by twisted.manhole is a Perspective Broker
-based server. This gives the client a remote reference to a
twisted.manhole.service.Service object, which offers remotely-callable
methods to evaluate Python code. With the rich remote-method-invocation
facilities provided by PB, however, much more is possible: the client can
ask to watch
certain objects, and then will receive messages every time
that python object is changed. (this takes advantage of some twisted.python
code that hooks
some functions, like .setattr). These features are
described in detail below.
With this in place and running, you're ready to connect with the manhole
client. This is a Gtk+-based GUI application named manhole
that
gets installed along with the rest of twisted. Execute the command manhole
to start the client, and it will bring up a
dialog that asks for hostname, port number, Service name, username, and
password (and also Perspective
but don't worry about that for now). Use
the default host/port of localhost/8787 to indicate where the
twisted.manhole
service is listening, and use boss/sekrit for the
username and password. Use the default Service name twisted.manhole
, and
leave the Perspective blank.
Click the Log In
button to establish the connection, and you will be
greeted with a short message in a window with an output area in the top, and
an input area at the bottom. This is just like the python interpreter
accessed through the telnet shell, but with a different GUI. You can type
arbitrary python code into the input area and get the results in the output
area. Note that multi-line sequences are all sent together, so if you define
a function (or anything else that uses indentation to tell the interpreter
that you aren't finished yet), you'll need to type one additional Return to
tell the client to send off the code.
At this point, you can get access to the main Application
object just like you did
before with the telnet-based shell. You can use that to obtain the Service
objects inside it, or
references to the Factory
objects that are listening
on TCP or UDP ports, by doing:
from twisted.internet import app a = app.theApplication service = a.getServiceNamed("manhole") (port, factory, backlog, interface) = a.tcpPorts[0]
After that, you can do anything you want with those objects.
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 in the Spelunking
window that pops up
when manhole
establishes a connection to the manhole
Service. /watch
-ing an object adds hooks to the object,
allowing you to watch modifications to it in real time. Try the following in
the manhole
window and watch what happens in the Spelunking
box (word wrapped for clarity):
/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__} }}
TODO: /watch
might be broken right now.
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.manhole.explorer
module, which was written largely by Kevin Turner.
TODO: Add an example using twisted.python.rebuild.rebuild
. This lets you tell your
application (remotely) to reload its classes, allowing you to upgrade a
running server without missing a beat.
Have fun!