<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title>A Twisted Mind</title>
  <link href="http://dreid.org/atom.xml" rel="self"/>
  <link href="http://dreid.org"/>
  <updated>2013-03-23T21:51:54-07:00</updated>
  <id>http://dreid.org</id>
  <author>
    <name>David Reid</name>
    <email>dreid@dreid.org</email>
  </author>
  
  <entry>
    <title>The Talks I Saw At Pycon</title>
    <link href="http://dreid.org"/>
    <updated>2013-03-22T00:00:00-07:00</updated>
    <id>http://dreid.org/2013/03/22/the-talks-i-saw-at-pycon</id>
    <content type="html">&lt;p&gt;PyCon 2013 was amazing. Here are video links to the talks I saw whose videos are currently available. I liked them all.&lt;/p&gt;

&lt;p&gt;In no particular order:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href='http://pyvideo.org/video/1736/worry-free-parsers-with-parsley'&gt;Worry-Free Parsers with Parsley&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://pyvideo.org/video/1778/crypto-101'&gt;Crypto 101&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://pyvideo.org/video/1698/death-by-a-thousand-leaks-what-statically-analys'&gt;Death by a thousand leaks: what statically-analysing 370 Python extensions looks&amp;#8230;&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://pyvideo.org/video/1681/so-easy-you-can-even-do-it-in-javascript-event-d'&gt;So Easy You Can Even Do It in JavaScript: Event-Driven Architecture for Regular &amp;#8230;&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://pyvideo.org/video/1727/solid-python-application-deployments-for-everybod'&gt;Solid Python Application Deployments For Everybody&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://pyvideo.org/video/1668/keynote-2'&gt;Keynote - Eben Upton&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://pyvideo.org/video/1848/opening-statements'&gt;Opening Statements&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://pyvideo.org/video/1740/twisted-logic-endpoints-and-why-you-shouldnt-be'&gt;Twisted Logic: Endpoints and Why You Shouldn&amp;#8217;t Be Scared of Twisted&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://pyvideo.org/video/1677/how-the-internet-works'&gt;How the Internet works&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://pyvideo.org/video/1667/keynote-1'&gt;Guido van Rossum&amp;#8217;s Keynote&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://pyvideo.org/video/1694/so-you-want-to-write-an-interpreter'&gt;So you want to write an interpreter?&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://pyvideo.org/video/1684/the-end-of-object-inheritance-the-beginning-of'&gt;The End Of Object Inheritance &amp;amp; The Beginning Of A New Modularity&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Of course, these are just a few of the talks at the conference, you can find more at &lt;a href='http://pyvideo.org/category/33/pycon-us-2013'&gt;pyvideo.org&lt;/a&gt;.&lt;/p&gt;</content>
  </entry>
  
  <entry>
    <title>Deferreds Are A Dataflow Abstraction</title>
    <link href="http://dreid.org"/>
    <updated>2012-03-30T00:00:00-07:00</updated>
    <id>http://dreid.org/2012/03/30/deferreds-are-a-dataflow-abstraction</id>
    <content type="html">&lt;p&gt;This was originally concieved as a response to &lt;a href='http://oubiwann.blogspot.com/2012/03/conversation-with-guido-about-callbacks.html'&gt;A Conversation with Guido about Callbacks&lt;/a&gt; over at Duncan McGreggor&amp;#8217;s blog.&lt;/p&gt;

&lt;p&gt;First, a jQuery-ish example of using some callbacks:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='python'&gt;&lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;handleResponse&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;resp&lt;/span&gt;&lt;span class='p'&gt;):&lt;/span&gt;
    &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;handleParsed&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;xmlObj&lt;/span&gt;&lt;span class='p'&gt;):&lt;/span&gt;
          &lt;span class='n'&gt;firstStyle&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;xmlObj&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;xpath&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s'&gt;&amp;#39;//link[rel=&amp;quot;stylesheet&amp;quot;]&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;)[&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt;

        &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;handleAnotherResponse&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;anotherResp&lt;/span&gt;&lt;span class='p'&gt;):&lt;/span&gt;
              &lt;span class='k'&gt;print&lt;/span&gt; &lt;span class='n'&gt;anotherResp&lt;/span&gt;

        &lt;span class='n'&gt;getPage&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;firstStyle&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='s'&gt;&amp;#39;href&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;],&lt;/span&gt; &lt;span class='n'&gt;handleAnotherResponse&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;

    &lt;span class='n'&gt;asyncParser&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;resp&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;body&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;onComplete&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;

&lt;span class='n'&gt;getPage&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;http://example.com&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;handleResponse&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now this is an absurd example of callback soup. Or is it? I&amp;#8217;ve read a lot of JavaScript, and it isn&amp;#8217;t really uncommon to see multiple levels of calls which take a callback. The JavaScript actually usually looks cleaner and is easier to read than our contrived Python because JavaScript has multi-statement anonymous functions that can be used to inline the callback definition into the function call. (That feature has other readability side-effects though, such as the pattern of defining a single argument anonymous function to invoke a single, single argument function.)&lt;/p&gt;

&lt;p&gt;Now, when you write callbacks like this, it&amp;#8217;s no wonder people tend to dislike them. Especially when contrasted with the more straightforward non-callback example.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='python'&gt;&lt;span class='n'&gt;resp&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;getPage&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s'&gt;&amp;#39;http://example.com&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='n'&gt;xmlObj&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;parser&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;resp&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;body&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='n'&gt;firstStyle&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;xmlObj&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;xpath&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s'&gt;&amp;#39;…&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;)[&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt;
&lt;span class='k'&gt;print&lt;/span&gt; &lt;span class='n'&gt;getPage&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;firstStyle&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='s'&gt;&amp;#39;href&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;4 lines of code vs 8 lines of code (11 including almost mandatory blank lines.) Is it any wonder that Guido prefers this approach? No, absolutely not. That first example is an absolutely terrible but perfectly normal piece of callback using code. Let&amp;#8217;s enumerate some of the ways in which it is bad.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Everything is out of order.&lt;/li&gt;

&lt;li&gt;Excessive indentation. Flat is better than nested, but close is better than far, so nested wins.&lt;/li&gt;

&lt;li&gt;The desire for locality causes function definitions to be scattered among statements.&lt;/li&gt;

&lt;li&gt;You&amp;#8217;re defining a lot of non-reusable, non-testable functions.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I&amp;#8217;m sure you&amp;#8217;ve come up with plenty more of complaints (including non-PEP8 camelCase names) but these are the 4 big points I&amp;#8217;d like to discuss further.&lt;/p&gt;

&lt;h3 id='order_matters'&gt;Order matters.&lt;/h3&gt;

&lt;p&gt;Most of us read left to right and top to bottom. Even if your primary language doesn&amp;#8217;t read left to right and top to bottom your primary programming language almost certainly does. When we make todo lists we give them an order, items at the top are more important. Shopping lists are sometimes ordered starting with vegetables and moving towards more time fragile things like ice cream, because that&amp;#8217;s the way the stores are laid out. Computer programs are written line by line in the order we want instructions executed, because that is how computers work.&lt;/p&gt;

&lt;p&gt;Order matters. On first encounters with code order matters a lot.&lt;/p&gt;

&lt;h3 id='related_statements_should_be_close'&gt;Related statements should be close.&lt;/h3&gt;

&lt;p&gt;Locality is the topic of both issues 2 &amp;amp; 3. And it can best be summed up as, related things should be close. It&amp;#8217;s the most basic element of organization for everything from kitchens to code.&lt;/p&gt;

&lt;p&gt;Anytime you&amp;#8217;re reading anything you&amp;#8217;ll find yourself glancing back to reread a few lines, or sentences, or even words as soon as you&amp;#8217;ve encountered something that you don&amp;#8217;t understand or doesn&amp;#8217;t quite make sense. The further you have to look the longer it&amp;#8217;s going to take to get your answer.&lt;/p&gt;

&lt;h3 id='reduce_reuse_retest'&gt;Reduce, Reuse, Retest.&lt;/h3&gt;

&lt;p&gt;We write functions to enhance the readability, and testability of our code. We reduce the size of large functions by breaking them up into higher level discrete steps and creating functions to encapsulate those actions. We reuse common code by creating more functions. We retest, ok well retest doesn&amp;#8217;t make much sense, but we inc&lt;b&gt;re&lt;/b&gt;ase &lt;b&gt;test&lt;/b&gt;ability by concentrating functionality into smaller more well defined units.&lt;/p&gt;

&lt;p&gt;You would never inline all the socket calls necessary to make an HTTP request. Maintainable software is built out of well defined reusable and testable abstractions, and there is no reason that callbacks should not also be reusable and testable as much as possible.&lt;/p&gt;

&lt;h1 id='there_is_a_better_way'&gt;There is a better way.&lt;/h1&gt;

&lt;p&gt;I&amp;#8217;ll admit, I have a love/hate relationship with callbacks. I view them as a necessary evil to do event-driven programming. There is of course a better way to think about callbacks and you may have already guessed it. &lt;a href='http://twistedmatrix.com/documents/current/core/howto/defer.html'&gt;Deferreds&lt;/a&gt; and &lt;a href='https://en.wikipedia.org/wiki/Dataflow_programming'&gt;Dataflow programming&lt;/a&gt;. A lot of people use deferreds for the first time much the same way they use plain callbacks.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='python'&gt;&lt;span class='n'&gt;d&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;getPage&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;url&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;handleResponse&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;resp&lt;/span&gt;&lt;span class='p'&gt;):&lt;/span&gt;
    &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;handleParsed&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;xmlObj&lt;/span&gt;&lt;span class='p'&gt;):&lt;/span&gt;
        &lt;span class='n'&gt;firstStyle&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;xmlObj&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;xpath&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;pattern&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
        &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;handleOtherResponse&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;otherResponse&lt;/span&gt;&lt;span class='p'&gt;):&lt;/span&gt;
              &lt;span class='k'&gt;print&lt;/span&gt; &lt;span class='n'&gt;otherResponse&lt;/span&gt;

        &lt;span class='n'&gt;d3&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;getPage&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;firstStyle&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='s'&gt;&amp;#39;href&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;])&lt;/span&gt;
        &lt;span class='n'&gt;d3&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;addCallback&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;handleOtherResponse&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;

    &lt;span class='n'&gt;d2&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;asyncParser&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;resp&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;body&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='n'&gt;d2&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;addCallback&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;handleParsed&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;

&lt;span class='n'&gt;d&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;addCallback&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;handleResponse&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now, this example, though still contrived is not unrealistic, it is in fact perfectly functional and probably exists in more than a few Twisted using code bases. Of course it&amp;#8217;s terrible for all the same reasons our plain callback example was terrible.&lt;/p&gt;

&lt;p&gt;So clearly it is not the better way. So what is?&lt;/p&gt;

&lt;h2 id='deferreds_as_a_dataflow_abstraction'&gt;Deferreds as a dataflow abstraction.&lt;/h2&gt;

&lt;p&gt;&lt;a href='http://twistedmatrix.com/documents/current/core/howto/defer.html#auto3'&gt;&lt;img src='/images/deferred-process.png' alt='A Visual Explanation of Deferreds' /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here you have a acyclic directed graph of data through the callback chain. The individual operations being performed is less important than the flow of information through the structure. An event causes a result to be available, it is put into the deferred and moves along the directed graph through the callback chain until an error is encountered. Then we move to the errback chain will proceed until the error has been handled at which point we can go back to the callback chain, or until we run out of errbacks.&lt;/p&gt;

&lt;p&gt;The result from one operation flows directly into the next.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='python'&gt;&lt;span class='n'&gt;getPage&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;getFirstStyle&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;parse&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;getPage&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;http://example.com&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;)))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The above is a dataflow program. Our imperative example from earlier is not, because the grouping of operations is a side effect of style, any number of operations could be interspersed which may or may not have side effects that influence future operations.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='python'&gt;&lt;span class='n'&gt;d&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;getPage&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;http://example.com&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='n'&gt;d&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;addCallback&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;parse&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='n'&gt;d&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;addCallback&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;getFirstStyle&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='n'&gt;d&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;addCallback&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;getPage&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='n'&gt;d&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;addCallback&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;printResult&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now, everything is order, related operations are close, and the structure of higher level operation is broken up into discrete and independently testable units.&lt;/p&gt;

&lt;p&gt;By this point I hope I have made it obvious about why &amp;#8220;thinking in Deferreds&amp;#8221; is better than &amp;#8220;thinking in callbacks&amp;#8221; but if I have not imagine this example from a &lt;a href='http://twistedmatrix.com/trac/ticket/1956'&gt;fictional streaming API&lt;/a&gt; and maybe you&amp;#8217;ll understand why &amp;#8220;thinking in dataflows&amp;#8221; is a good thing.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='python'&gt;&lt;span class='n'&gt;urls&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;flowTo&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;getPage&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;flowTo&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;parse&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;flowTo&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;getFirstStyle&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;flowTo&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;getPage&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;flowTo&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;stdout&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;

&lt;span class='n'&gt;urls&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;put&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;http://example.com&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='n'&gt;urls&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;put&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;http://google.com&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now we have encapsulated not only how we handle one result, but rather a potentially infinite number of events. Now we have the potential for building some &lt;b&gt;realtime&lt;/b&gt; distributed systems.&lt;/p&gt;

&lt;h2 id='that_is_all'&gt;That is all.&lt;/h2&gt;

&lt;p&gt;Go read about &lt;a href='https://github.com/nathanmarz/storm/wiki/Tutorial'&gt;Storm&lt;/a&gt; and &lt;a href='http://orc.csres.utexas.edu/'&gt;Orc&lt;/a&gt;&lt;/p&gt;</content>
  </entry>
  
  <entry>
    <title>Klein A Twisted.web Microframework</title>
    <link href="http://dreid.org"/>
    <updated>2012-03-28T00:00:00-07:00</updated>
    <id>http://dreid.org/programming/2012/03/28/klein-a-twisted.web-microframework</id>
    <content type="html">&lt;h2 id='what_is_klein'&gt;What is Klein?&lt;/h2&gt;

&lt;p&gt;&lt;a href='https://github.com/twisted/klein/'&gt;klein&lt;/a&gt; is a micro-framework built out of widely used components that aims to be production ready out of the box.&lt;/p&gt;

&lt;p&gt;Inspired by frameworks such as &lt;a href='http://flask.pocoo.org/'&gt;flask&lt;/a&gt; and &lt;a href='http://bottlepy.org'&gt;bottle&lt;/a&gt; it features:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A minimalist API.&lt;/li&gt;

&lt;li&gt;A fast, event-driven, production-ready web server.&lt;/li&gt;

&lt;li&gt;Complete support for a wide range of asynchronous client APIs.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It&amp;#8217;s routing is provided by &lt;a href='http://werkzeug.pocoo.org'&gt;werkzeug&lt;/a&gt; and it&amp;#8217;s webserver &amp;amp; event-loop by &lt;a href='http://twistedmatrix.com/trac/'&gt;Twisted&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id='an_example'&gt;An Example&lt;/h3&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='python'&gt;&lt;span class='kn'&gt;from&lt;/span&gt; &lt;span class='nn'&gt;klein&lt;/span&gt; &lt;span class='kn'&gt;import&lt;/span&gt; &lt;span class='n'&gt;run&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;route&lt;/span&gt;

&lt;span class='nd'&gt;@route&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s'&gt;&amp;#39;/&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;hello&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;request&lt;/span&gt;&lt;span class='p'&gt;):&lt;/span&gt;
    &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='s'&gt;&amp;#39;Hello, world!&amp;#39;&lt;/span&gt;

&lt;span class='n'&gt;run&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s'&gt;&amp;#39;localhost&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;8080&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is the most simple example possible. It&amp;#8217;s actually simpler than the first bottle example. This is the example you want to use in the &amp;#8220;how fast can I serve a hard coded static string&amp;#8221; benchmark you post to Hacker News&lt;/p&gt;

&lt;p&gt;This post will not contain one of those benchmarks. Lets break it down.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='python'&gt;&lt;span class='kn'&gt;from&lt;/span&gt; &lt;span class='nn'&gt;klein&lt;/span&gt; &lt;span class='kn'&gt;import&lt;/span&gt; &lt;span class='n'&gt;run&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;route&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;run&lt;/code&gt; and &lt;code&gt;route&lt;/code&gt; are the most basic APIs and it should be pretty clear what they are for. In this example we&amp;#8217;ve imported the top-level functions which actually operate on a global instance of a the class &lt;code&gt;klein.Klein&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This class may be used directly to facilitate a more flask-like usage. For example:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='python'&gt;&lt;span class='kn'&gt;from&lt;/span&gt; &lt;span class='nn'&gt;klein&lt;/span&gt; &lt;span class='kn'&gt;import&lt;/span&gt; &lt;span class='n'&gt;Klein&lt;/span&gt;

&lt;span class='n'&gt;app&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;Klein&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt;

&lt;span class='nd'&gt;@app.route&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s'&gt;&amp;#39;/&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;hello&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;request&lt;/span&gt;&lt;span class='p'&gt;):&lt;/span&gt;
    &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='s'&gt;&amp;#39;Hello, world!&amp;#39;&lt;/span&gt;

&lt;span class='n'&gt;app&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;run&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s'&gt;&amp;#39;localhost&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;8080&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Next we have the actual handler definition:&lt;/p&gt;

&lt;p&gt;&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='python'&gt;&lt;span class='nd'&gt;@route&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s'&gt;&amp;#39;/&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;hello&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;request&lt;/span&gt;&lt;span class='p'&gt;):&lt;/span&gt;
    &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='s'&gt;&amp;#39;Hello, world!&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;route&lt;/code&gt; decorator is built on top of &lt;a href='http://werkzeug.pocoo.org'&gt;Werkzeug&lt;/a&gt; and passes all unknown arguments directly to &lt;code&gt;werkzeug.routing.Rule&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You may have noticed that unlike both flask and bottle handler functions in klein take an explicit request argument, which is an &lt;a href='http://twistedmatrix.com/documents/current/api/twisted.web.iweb.IRequest.html'&gt;IRequest&lt;/a&gt; provider. This is primarily because &amp;#8220;Explicit is better than Implicit&amp;#8221;, but also because anything else would greatly complicate the implementation.&lt;/p&gt;

&lt;p&gt;At this point we have our feet firmly planted in the world of Twisted. Though our example does not do anything asynchronous, or Twisted specific the full power of Twisted is available to us. You may return a &lt;code&gt;str&lt;/code&gt;, &lt;code&gt;unicode&lt;/code&gt;, &lt;code&gt;twisted.web.template.Element&lt;/code&gt;, or &lt;code&gt;twisted.web.resource.IResource&lt;/code&gt;, and klein will handle all of them for you. You may of course also return a &lt;code&gt;twisted.internet.defer.Deferred&lt;/code&gt; which fires with any of the above as it&amp;#8217;s result and we will handle that as well. The &lt;a href='https://github.com/twisted/klein/blob/master/README.rst'&gt;README&lt;/a&gt; of course has examples covering the full range of return values.&lt;/p&gt;

&lt;p&gt;Finally we are ready to run the server.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='python'&gt;&lt;span class='n'&gt;run&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s'&gt;&amp;#39;localhost&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;8080&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This starts up a twisted web server listening on port 8080 and only accessible to localhost. You can listen any specific IP address, or &amp;#8216;0.0.0.0&amp;#8217; for all IP addresses. As a bonus logging to stdout is set up for you.&lt;/p&gt;

&lt;h3 id='work_in_progress'&gt;Work in Progress&lt;/h3&gt;

&lt;p&gt;klein is of course not complete, as no software is ever complete. It does however have a comprehensive test suite and builds on Twisted&amp;#8217;s own heroicly extensive tests. We have lots of ideas about how to improve it and don&amp;#8217;t plan to stop developing it. It is not currently used in production anywhere but it&amp;#8217;s only a matter of time.&lt;/p&gt;

&lt;p&gt;If you try it give us feedback in #twisted.web on freenode. And of course &lt;a href='https://github.com/twisted/klein/'&gt;fork it on github&lt;/a&gt;.&lt;/p&gt;</content>
  </entry>
  
  <entry>
    <title>Why I still trust Tor, WikiLeaks, and Jacob Appelbaum.</title>
    <link href="http://dreid.org"/>
    <updated>2010-12-29T00:00:00-08:00</updated>
    <id>http://dreid.org/2010/12/why-i-still-trust-tor-wikileaks-and-jacob-applebaum</id>
    <content type="html">&lt;p&gt;I feel compelled to comment on Zed Shaw&amp;#8217;s recent &amp;#8220;analysis&amp;#8221; of an apparent conflict of interest concerning Tor developer and WikiLeaks supporter Jacob Appelbaum.&lt;br /&gt;&lt;br /&gt;If you don&amp;#8217;t know what I&amp;#8217;m talking about you should start by reading &lt;a href='http://sheddingbikes.com/posts/1293530004.html'&gt;Why
I Don't Use Tor&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I&amp;#8217;m going to try to not be too &amp;#8220;logical&amp;#8221; in my argument because apparently that will cause my argument to be inherently flawed. So instead I&amp;#8217;m going to try to mix emotion with logic in what I hope will not be too volatile a cocktail for this blog post to contain.&lt;br /&gt;&lt;br /&gt;I&amp;#8217;ve met Jacob Appelbaum multiple times, mostly through our mutual friend Zooko of &amp;#8220;Zooko&amp;#8217;s Triangle&amp;#8221; and Tahoe-LAFS fame. He seems like a great guy, nice, smart, funny, and passionate about personal privacy. It was his demo of Tor on Android over cheap Korean BBQ which convinced me to give up my iPhone.&lt;br /&gt;&lt;br /&gt;I&amp;#8217;ve also met Zed Shaw. He was abrasive, and seemed offended that I did not recognize him as &amp;#8220;Zed &amp;#8216;Mother-Fucking&amp;#8217; Shaw&amp;#8221; but who knows, maybe that was just his schtick.&lt;br /&gt;&lt;br /&gt;The above linked post is not what I would consider a classic example of trolling. I believe that Zed Shaw probably believes the things he&amp;#8217;s written there and that&amp;#8217;s fine. I&amp;#8217;m not one to judge people&amp;#8217;s other personal beliefs, however his argument seems flawed not only because he bases partly on a well known-rumor that has been repeatedly denied while no evidence has ever been offered for it. But also because it makes certain assumptions which I&amp;#8217;m not convinced are valid. 3 to be exact.&lt;br /&gt;&lt;br /&gt; 1) Jacob Appelbaum is in a position to drastically impact the security of Tor.&lt;br /&gt;&lt;br /&gt; Yes, and no. He is certainly qualified, and what little I know of the project&amp;#8217;s organization he seems to be in a position where he could make decisions which could impact Tor&amp;#8217;s security. However Tor is an open code base, freely available for anyone to audit and not the work of one lone programmer. This does not mean that everyone is qualified to audit the code, I&amp;#8217;m certainly not, however I think enough people care about personal privacy and anonymity that qualified individuals are looking at it.&lt;br /&gt;&lt;br /&gt; 2) WikiLeaks&amp;#8217; job would be easier if an insecure Tor were in widespread use.&lt;br /&gt;&lt;br /&gt;I don&amp;#8217;t think it would be. As far as I know, there is no evidence to suggest that information obtained by WikiLeaks has ever come from a source other than a conventional whistleblower. A person with some level of access to certain information decides that it is right, just, or worth 15 minutes of fame to leak some information. If Bradley Manning leaked those diplomatic cables, and that collateral murder video he probably didn&amp;#8217;t have legitimate access to that information, but he also didn&amp;#8217;t obtain it by setting up a rogue Tor exit node. He had legitimate access to military networks. &lt;br /&gt;&lt;br /&gt;On a second point, in a future where Tor usage is widespread, I would also expect that you would see Tor Hidden Services also be widespread and any organization hoping to insure anonymity and privacy to their users would be better off running one of those than a normal website that users could access by Tor.&lt;br /&gt;&lt;br /&gt; 3) WikiLeaks&amp;#8217; job would be harder if a secure Tor were in widespread use.&lt;br /&gt;&lt;br /&gt;I hope so, but probably not sufficiently so that it would be worth risking both Tor and WikiLeaks&amp;#8217; reputations to do so. On the off chance that an oppressive regime or a major corporation used Tor for all their most dirty little secrets it&amp;#8217;s still more likely that the heavily bearded sysadmin in Reeboks and a Fedora would take that information and leak it than some hacker or even enemy government or corporation would steal it.&lt;br /&gt;&lt;br /&gt;Of course, these 3 points only matter if you&amp;#8217;re willing to completely ignore the fact that Tor and WikiLeaks&amp;#8217; interests do not actually conflict. WikiLeaks does not appear to be interested in posting the latest celebrity sex tape or pictures from Miley Cyrus&amp;#8217; Facebook page.&lt;br /&gt;&lt;br /&gt;In conclusion I think it&amp;#8217;s far more likely that Zed Shaw wanted to get some hackernews juice by blogging about WikiLeaks than it is that Jacob Appelbaum and Julian Assange want to read your email.&lt;/p&gt;</content>
  </entry>
  
  <entry>
    <title>Mimicing source virtualenv/bin/activate in Emacs.</title>
    <link href="http://dreid.org"/>
    <updated>2010-02-03T00:00:00-08:00</updated>
    <id>http://dreid.org/2010/02/mimicing-source-virtualenv-bin-activate-in-emacs</id>
    <content type="html">&lt;p&gt;For a while now I&amp;#8217;ve had a problem where at work we rely heavily on virtualenv and I occasionally want to do things like run pyflakes or run trial from the Twisted installed in that virtualenv. This following activate-virtualenv function appears to be all that is necessary to mimic source virtualenv/bin/activate for Emacs.&lt;/p&gt;

&lt;p&gt;Enjoy.&lt;/p&gt;
&lt;script src='https://gist.github.com/779324.js'&gt; &lt;/script&gt;</content>
  </entry>
  
  <entry>
    <title>Twisted + Django + Pinax: Hey, yeah that works.</title>
    <link href="http://dreid.org"/>
    <updated>2009-03-30T18:44:00-07:00</updated>
    <id>http://dreid.org/2009/03/twisted+pinax</id>
    <content type="html">&lt;p&gt;Ok, so yeah. As of about 2 hours ago &lt;a href='http://pinaxproject.com/'&gt;Pinax&lt;/a&gt; runs on top of Twisted trunk. These seems to indicate that Twisted is a pretty capable and correct WSGI implementation. I suggest you start serving stuff. It&amp;#8217;s great! Here is a screenshot.&lt;br /&gt;&lt;br /&gt;&lt;img class='reflect' title='' src='http://farm4.static.flickr.com/3585/3399714325_f51ef3ba47.jpg?v=0' onload='show_notes_initially();' height='347' alt='Picture 3 by you.' width='500' /&gt;&lt;/p&gt;</content>
  </entry>
  
  <entry>
    <title>Twisted + Django: It won't burn down your house.</title>
    <link href="http://dreid.org"/>
    <updated>2009-03-30T09:34:00-07:00</updated>
    <id>http://dreid.org/2009/03/twisted+django</id>
    <content type="html">&lt;p&gt;It&amp;#8217;s actually really easy to make these two things work together. Since ~8.2.0 Twisted has had a WSGI container runnable from the command line. So here is how you run Django on a supported version of Twisted.web.&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;easy_install Twisted&lt;/li&gt;&lt;li&gt;easy_install Django&lt;/li&gt;&lt;li&gt;Profit!&lt;br /&gt;&lt;/li&gt;&lt;li&gt;django-admin.py startproject foo&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Create a myapp.py
with the following code:&lt;pre&gt;&lt;br /&gt;from django.core.handlers.wsgi import
WSGIHandler&lt;br /&gt;&lt;br /&gt;application = WSGIHandler()&lt;br /&gt;&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;export
DJANGO_SETTINGS_MODULE=foo.settings&lt;/li&gt;&lt;li&gt;twistd -no web
--wsgi=myapp.application&lt;/li&gt;&lt;/ol&gt;And there you have it. There are probably a few compatibility problems but this mostly seems to work just fine. I&amp;#8217;ll be working with some Django weenies to figure out what, if anything is broken.&lt;br /&gt;&lt;br /&gt;So look, this is really AWESOME.&lt;br /&gt;&lt;br /&gt;Updated (3/30/2009 4:09pm): Twisted tickets &lt;a href='http://twistedmatrix.com/trac/ticket/3585'&gt;#3585&lt;/a&gt;, &lt;a href='http://twistedmatrix.com/trac/ticket/3721'&gt;#3721&lt;/a&gt; are problems on Twisted 8.2.0 but are fixed or should be fixed in Twisted trunk soon.&lt;br /&gt;&lt;br /&gt;Updated (3/30/2009 6:34pm): Both of the above tickets are done.&lt;br /&gt;&lt;/p&gt;</content>
  </entry>
  
</feed>

