[Twisted-Python] Twisted Weekly News #10
![](https://secure.gravatar.com/avatar/6d06aa0eeb9d8486bc0886a206ec5a39.jpg?s=120&d=mm&r=g)
==================================================================== Twisted Weekly News #10 ==================================================================== .. contents:: There wasn't too much mail this week, so I merged the previous TWN with the current, as I was ill last week. If you have any new information, ideas, announcements for the next TWN, please write to me, <lior@gradstein.info>. TWN is also available as HTML formated ReST on http://gradstein.info/articles/ twisted_news/twisted_news/twn10 The Twisted Weekly News ------------------------- 9&10th Issue. Sunday, December 28, 2003 QOTW:: http://twistedmatrix.com/pipermail/twisted-python/2003-December/006789.html From a mail by Alan McIntyre: "I just wanted to thank the Twisted developers for making such a cool piece of software. [...] Thanks to Twisted and Python, I was able to start from scratch and put together a server to present some of this data via XML-RPC in about 2 or 3 hours (and that includes looking up a lot of stuff in the documentation)." Discussions ------------- * http://twistedmatrix.com/pipermail/ twisted-python/2003-December/006786.html Jonathan Simms asked for help on his new (new) ftp server code which is currently in sandbox. He asks for help to resolve some problems with authentication on the Windows side. * http://twistedmatrix.com/pipermail/ twisted-python/2003-December/006828.html More and more people are becoming interested in integrating Twisted stuff into their projects. Last week, RodrigB asked about The Circle. This week, Valentino Volonghi asks about the possibility (wish) to replace the pygame event loop with a Twisted reactor. * http://twistedmatrix.com/pipermail/ twisted-python/2003-December/006820.html Michal Pasternak made some tests on Twisted, and noticed some performance degradation after 40 simultaneous connections. Itamar replied there wasn't anything hardcoded that would change Twisted behaviour above 40 simultaneous connections. Cool Thing of the Week ----------------------- * **Treasure of code examples and tutorials for nevow** (http:// www.livejournal.com/users/fzzzy/) fzZzy updated his new blog on LiveJournal with a lot of code samples he wrote for people who asked questions on irc. The second lecture he gave on irc is also available (http://soundfarmer.com/content/logs/ NevowLecture2-121503.txt). With these docs and the previous more "in-depth" documentation from justinj (http://stewstuff.com/doc/nevow.xhtml) you do not any excuse for not learning nevow! * **SFTP support in Zope (using Twisted!)** (http://twistedmatrix.com/ pipermail/twisted-python/2003-December/006839.html) Fred L. Drake, Jr. wrote some support (http://cvs.zope.org/Packages/ SFTPGateway/) for the sftp protocol to be included in Zope. The result may be available as a separate product in a near future. * **Impacket** (http://oss.corest.com/projects/impacket.html) Not related to Twisted, but interesting anyway.Itamar recommended us to take a look at this python library which provides low-level programmatic access to network packets (tcp, udp, etc.). There is also a python pcap implementation on their web site. * **Reminder about the web forum** (http://twisted.banquise.org/) May I remind you that a web interface exists for those that prefer reading informations online? We're barely 8 now, but nobody posts anything which can be discussed :-( Current releases ----------------- * Twisted: 1.1.1 (released 2003-12-10) * Quotient: 0.8.8 (released 2003-12-12) * Twisted Java: 0.6.1 Ok, that's it for this week. Thanks for reading!
![](https://secure.gravatar.com/avatar/cdedd0f07d3d5976128eea43ea89c50b.jpg?s=120&d=mm&r=g)
in my resource's "render" method, I'm doing some things that require a fairly long time to accomplish, so each time through a loop, I want to render some intermediate results to the brower. Kinda like this: class myResource(resource.Resource): isLeaf = True def render(self, request): # Now I build up a string to render to the browser html = make_body() # And now I want to go into a loop for item in items: result = compute_some_item(item) # I just do something that returns some result request.write(result) # then send it to the browser return(server.NOT_DONE_YET) # Do I return now? If so, will I re-enter my "render" method again request.finish() # Now, do I just return the html I generated earlier return(html) what happens when I return with server.NOT_DONE_YET? will I get called again so I can do the request.write(something)? What is the sequence? According to the documentation, I quote: (from render.py) def render(self, request): """Render a given resource. This must be implemented in all subclasses of Resource. The return value of this method will be the rendered page, unless the return value is twisted.web.server.NOT_DONE_YET, in which case it is this class's responsibility to write the results to request.write(data), then call request.finish(). """ According to this, I return server.NOT_DONE_YET... but then it goes on to say it's my classes responsibility to write the results to request.write(data), to write the results, but how do i do that, because if i return server.NOT_DONE_YET then I've exited, and have no opportunity to call request.write(something). So when do I call it? Do I call it BEFORE I return? If so, then why doesn't the bloody document say that? And, in the using Web document, it says.... A Resource object may do various things to produce output which will be sent back to the browser: * Return a string * Call request.write("stuff") as many times as desired, then call request.finish() and return server.NOT_DONE_YET (This is deceptive, since you are in fact done with the request, but is the correct way to do this) * Request a Deferred, return server.NOT_DONE_YET, and call request.write("stuff") and request.finish() later, in a callback on the Deferred. This seems a little more reasonable, and my question, according to this is.... do I do it in this order? 1) call request.write(html) # from above Then for each interation of some loop: 1) call request.write(stuff) a bunch of times, which for each iteration of a loop, may take up to a minute. 2) call request.finish() 3) return server.NOT_DONE_YET Is this the right order for doing this? Should I try to use a Deferred? I have no clue how to do that, there appears to be a severe lack of examples similar to what I want to do. Lets say I want to defer ONE interation of a loop... Lets call this function... def do_iteration(item): # do the interation So, would I construct my loop like this: # In the render method. for item in items: # process some item # Then do something to add this deferred, which I still don't know how to do. # something like this? reactor.callLater(something, do_iteration) # But since I'm in the "render" method, how do I get a reference to "reactor"? # And what it the meaning of "something" in the first argument of "callLater"? John
![](https://secure.gravatar.com/avatar/e1554622707bedd9202884900430b838.jpg?s=120&d=mm&r=g)
On Dec 28, 2003, at 7:57 PM, JD wrote:
Is this the right order for doing this?
You can do it in any order. Basically, the rules are thus: - If you return a string, the framework will automatically call request.write(result); request.finish() for you when the method returns. - The request must be finish()ed or the page render will never complete in the browser. - If you return NOT_DONE_YET, nothing will happen automatically, and you can call request.write(...) at your leisure and request.finish() when you're done with it. This includes in a callback of a Deferred (the usual use case), in another form of network callback, synchronously before you return NOT_DONE_YET, or whenever. NOT_DONE_YET just means "Do not have the framework call write() and finish() on the request automatically.) The caveat is that you then MUST call finish(), or the page will hang forever in the browser.
![](https://secure.gravatar.com/avatar/495d63478c94ffedb51f7446f3a6be60.jpg?s=120&d=mm&r=g)
Hi, I call your attention to: This was quoted in the Docs on the TwistedMatrix web site. Persistent Data in the Factory Since the Protocol instance is recreated each time the connection is made, the client needs some way to keep track of data that should be persisted. In the case of ircLogBot.py: (LogBot.log() just logs the data to the file object stored in LogBot.file) it references a LogBot.log() call.... but I checked in ircLogBot.py and there is NO log() method, nor is there one in any of the other classes it inherits from. Would it be too much of a bother if I were to ask anyone about this descrepancy? John
![](https://secure.gravatar.com/avatar/56e4cc78ea7fcf3bb37888ebf23bc1f0.jpg?s=120&d=mm&r=g)
On Wed, Dec 31, 2003 at 01:29:59AM -0800, John Draper wrote:
Hi,
Hi. Your mail client has decided that you are responding to a message in a thread about Twisted Web. It probably did this because you had that message selected when you told it to compose mail, or because you selected reply rather than compose. Since your message is not actually about Twisted Web, this is confusing and undesirable. In the future, please pay more attention to what you are asking your mail client to do, so that it is easier to find and understand the question you are asking.
Not at all. It is true that the class has no log method, however, if you examine the connectionMade method: def connectionMade(self): irc.IRCClient.connectionMade(self) self.logger = MessageLogger(open(self.factory.filename, "a")) self.log = self.logger.log self.log("[connected at %s]" % time.asctime(time.localtime(time.time()))) you will see that instances of the class bind method from a *different* to that name, allowing users of the class to use the method as if it were defined by the LogBot class itself. Jp
![](https://secure.gravatar.com/avatar/cdedd0f07d3d5976128eea43ea89c50b.jpg?s=120&d=mm&r=g)
Below is a piece of code from ircLogBot.py in the examples section of the Twisted release. It makes reference to a "channel" - What is a channel. I assume that "sys.argv[1]" when passed into main() must be a "channel" Of course the person who wrote this module just had no inclination to actually tell anyone how to use it. I know the 2nd argument is a file name or path, but what is a "channel".... I know I probably am really lame for asking these kinds of questions, but i left my crystal ball on the planet venus, and can't read the mind of the person who wrote this module. class LogBotFactory(protocol.ClientFactory): """A factory for LogBots. A new protocol instance will be created each time we connect to the server. """ # the class of the protocol to build protocol = LogBot def __init__(self, channel, filename): self.channel = channel self.filename = filename def clientConnectionLost(self, connector, reason): """If we get disconnected, reconnect to server.""" connector.connect() def clientConnectionFailed(self, connector, reason): print "connection failed:", reason reactor.stop() if __name__ == '__main__': # create factory protocol and application import sys f = LogBotFactory(sys.argv[1], sys.argv[2]) # connect factory to this host and port reactor.connectTCP("irc.freenode.net", 6667, f) # run bot reactor.run()
![](https://secure.gravatar.com/avatar/cdedd0f07d3d5976128eea43ea89c50b.jpg?s=120&d=mm&r=g)
in my resource's "render" method, I'm doing some things that require a fairly long time to accomplish, so each time through a loop, I want to render some intermediate results to the brower. Kinda like this: class myResource(resource.Resource): isLeaf = True def render(self, request): # Now I build up a string to render to the browser html = make_body() # And now I want to go into a loop for item in items: result = compute_some_item(item) # I just do something that returns some result request.write(result) # then send it to the browser return(server.NOT_DONE_YET) # Do I return now? If so, will I re-enter my "render" method again request.finish() # Now, do I just return the html I generated earlier return(html) what happens when I return with server.NOT_DONE_YET? will I get called again so I can do the request.write(something)? What is the sequence? According to the documentation, I quote: (from render.py) def render(self, request): """Render a given resource. This must be implemented in all subclasses of Resource. The return value of this method will be the rendered page, unless the return value is twisted.web.server.NOT_DONE_YET, in which case it is this class's responsibility to write the results to request.write(data), then call request.finish(). """ According to this, I return server.NOT_DONE_YET... but then it goes on to say it's my classes responsibility to write the results to request.write(data), to write the results, but how do i do that, because if i return server.NOT_DONE_YET then I've exited, and have no opportunity to call request.write(something). So when do I call it? Do I call it BEFORE I return? If so, then why doesn't the bloody document say that? And, in the using Web document, it says.... A Resource object may do various things to produce output which will be sent back to the browser: * Return a string * Call request.write("stuff") as many times as desired, then call request.finish() and return server.NOT_DONE_YET (This is deceptive, since you are in fact done with the request, but is the correct way to do this) * Request a Deferred, return server.NOT_DONE_YET, and call request.write("stuff") and request.finish() later, in a callback on the Deferred. This seems a little more reasonable, and my question, according to this is.... do I do it in this order? 1) call request.write(html) # from above Then for each interation of some loop: 1) call request.write(stuff) a bunch of times, which for each iteration of a loop, may take up to a minute. 2) call request.finish() 3) return server.NOT_DONE_YET Is this the right order for doing this? Should I try to use a Deferred? I have no clue how to do that, there appears to be a severe lack of examples similar to what I want to do. Lets say I want to defer ONE interation of a loop... Lets call this function... def do_iteration(item): # do the interation So, would I construct my loop like this: # In the render method. for item in items: # process some item # Then do something to add this deferred, which I still don't know how to do. # something like this? reactor.callLater(something, do_iteration) # But since I'm in the "render" method, how do I get a reference to "reactor"? # And what it the meaning of "something" in the first argument of "callLater"? John
![](https://secure.gravatar.com/avatar/e1554622707bedd9202884900430b838.jpg?s=120&d=mm&r=g)
On Dec 28, 2003, at 7:57 PM, JD wrote:
Is this the right order for doing this?
You can do it in any order. Basically, the rules are thus: - If you return a string, the framework will automatically call request.write(result); request.finish() for you when the method returns. - The request must be finish()ed or the page render will never complete in the browser. - If you return NOT_DONE_YET, nothing will happen automatically, and you can call request.write(...) at your leisure and request.finish() when you're done with it. This includes in a callback of a Deferred (the usual use case), in another form of network callback, synchronously before you return NOT_DONE_YET, or whenever. NOT_DONE_YET just means "Do not have the framework call write() and finish() on the request automatically.) The caveat is that you then MUST call finish(), or the page will hang forever in the browser.
![](https://secure.gravatar.com/avatar/495d63478c94ffedb51f7446f3a6be60.jpg?s=120&d=mm&r=g)
Hi, I call your attention to: This was quoted in the Docs on the TwistedMatrix web site. Persistent Data in the Factory Since the Protocol instance is recreated each time the connection is made, the client needs some way to keep track of data that should be persisted. In the case of ircLogBot.py: (LogBot.log() just logs the data to the file object stored in LogBot.file) it references a LogBot.log() call.... but I checked in ircLogBot.py and there is NO log() method, nor is there one in any of the other classes it inherits from. Would it be too much of a bother if I were to ask anyone about this descrepancy? John
![](https://secure.gravatar.com/avatar/56e4cc78ea7fcf3bb37888ebf23bc1f0.jpg?s=120&d=mm&r=g)
On Wed, Dec 31, 2003 at 01:29:59AM -0800, John Draper wrote:
Hi,
Hi. Your mail client has decided that you are responding to a message in a thread about Twisted Web. It probably did this because you had that message selected when you told it to compose mail, or because you selected reply rather than compose. Since your message is not actually about Twisted Web, this is confusing and undesirable. In the future, please pay more attention to what you are asking your mail client to do, so that it is easier to find and understand the question you are asking.
Not at all. It is true that the class has no log method, however, if you examine the connectionMade method: def connectionMade(self): irc.IRCClient.connectionMade(self) self.logger = MessageLogger(open(self.factory.filename, "a")) self.log = self.logger.log self.log("[connected at %s]" % time.asctime(time.localtime(time.time()))) you will see that instances of the class bind method from a *different* to that name, allowing users of the class to use the method as if it were defined by the LogBot class itself. Jp
![](https://secure.gravatar.com/avatar/cdedd0f07d3d5976128eea43ea89c50b.jpg?s=120&d=mm&r=g)
Below is a piece of code from ircLogBot.py in the examples section of the Twisted release. It makes reference to a "channel" - What is a channel. I assume that "sys.argv[1]" when passed into main() must be a "channel" Of course the person who wrote this module just had no inclination to actually tell anyone how to use it. I know the 2nd argument is a file name or path, but what is a "channel".... I know I probably am really lame for asking these kinds of questions, but i left my crystal ball on the planet venus, and can't read the mind of the person who wrote this module. class LogBotFactory(protocol.ClientFactory): """A factory for LogBots. A new protocol instance will be created each time we connect to the server. """ # the class of the protocol to build protocol = LogBot def __init__(self, channel, filename): self.channel = channel self.filename = filename def clientConnectionLost(self, connector, reason): """If we get disconnected, reconnect to server.""" connector.connect() def clientConnectionFailed(self, connector, reason): print "connection failed:", reason reactor.stop() if __name__ == '__main__': # create factory protocol and application import sys f = LogBotFactory(sys.argv[1], sys.argv[2]) # connect factory to this host and port reactor.connectTCP("irc.freenode.net", 6667, f) # run bot reactor.run()
participants (6)
-
darryl
-
Glyph Lefkowitz
-
JD
-
John Draper
-
Jp Calderone
-
Luc Stepniewski