Hello,
I'm trying to play a little bit with Twisted to discover how it works
and I thought it was a nice exercise with the following case.
I have a list of IP addresses that I want to get the reverse DNS value.
I'm using the answer provided by JP at
http://twistedmatrix.com/pipermail/twisted-python/2004-September/008715.html
to perform the lookup and it's all good.
I'm putting all the results of client.lookupPointer() into a
DeferredList to display the result in order when everything is donew,
which is also working fine. The code looks like this so far:
def resolve(ip):
ptr = '.'.join(ip.split('.')[::-1]) + '.in-addr.arpa'
return client.lookupPointer(ptr)
def display_results(result):
for (succeeded, value) in result:
if not succeeded:
print "unknown"
else:
(ans, auth, add) = value
name = ans[0].payload.name
print name
d = DeferredList([resolve(ip) for ip in IPS],
consumeErrors=True).addCallback(display_results)
Now, I would like to have access both to the result of the lookup but
also the original IP address, so that I can print, especially, the
addresses which failed to be resolved.
At first, I added a callback to lookupPointer() like this:
client.lookupPointer(ptr).addCallback(lambda r: (ip, r))
and it does the job: in display_results(), I now have the IP address and
the result of the lookup.
However, I'm stuck how to do this for the failures: I tried to add an
errback the same way as I added the callback to lookupPointer(), but
then, it seems that DeferredList() sees the result of the errback() as a
ssuccess, so `succeeded` is True and I hav to ressort to a isinstance()
call to compare to see if my item is a Failure exception or not, like
this:
def display_results(result):
for (succeeded, value) in result:
ip, answer = result
if isinstance(answer, twisted.python.failure.Failure):
succeeded = False
...
My question is: is there a simpler way to pass values along the
callbacks?
Side question: why the reactor is not stopped in the final example
below?
Thanks!
Jonathan
ps: my final try looks like this:
from twisted.internet import reactor
from twisted.internet.defer import DeferredList
from twisted.names import client
import twisted.python.failure
IPS = open('ips.txt').read().split()[0:10]
def display_results(result):
for (succeeded, value) in result:
ip, answer = value
if isinstance(answer, twisted.python.failure.Failure):
succeeded = False
if not succeeded:
name = "(unknown)"
else:
(ans, auth, add) = answer
name = str(ans[0].payload.name)
print "%16s: %s" % (ip, name)
def resolve(ip):
ptr = '.'.join(ip.split('.')[::-1]) + '.in-addr.arpa'
return client.lookupPointer(ptr).\
addCallback(lambda x: (ip, x)).\
addErrback(lambda x: (ip, x))
l = [resolve(ip) for ip in IPS]
d = DeferredList( l, consumeErrors=True).\
addCallback(display_results).\
addCallback(lambda x: reactor.stop)
reactor.run()