<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">

  <title><![CDATA[Blueprint Forge.]]></title>
  
  <link href="http://blueprintforge.com/" />
  <updated>2013-02-17T17:24:52+00:00</updated>
  <id>http://blueprintforge.com/</id>
  <author>
    <name><![CDATA[Matt Cottingham]]></name>
    
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/BlueprintForge" /><feedburner:info uri="blueprintforge" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry>
    <title type="html"><![CDATA[Updates to Coder Weekly]]></title>
    <link href="http://feedproxy.google.com/~r/BlueprintForge/~3/zpdXZEBpn4Q/" />
    <updated>2013-02-16T18:02:00+00:00</updated>
    <id>http://blueprintforge.com/blog/2013/02/16/updates-to-coder-weekly</id>
    <content type="html">&lt;p&gt;&lt;a href="http://coderweekly.com"&gt;Coder Weekly&lt;/a&gt; has been running for over a year. Over that time, the subscriber base has continued to grow (now approaching 5,000), and the format and content has changed somewhat.
I thought that this would be a good point to look back at what&amp;#8217;s worked, and describe some changes that will be made to Coder Weekly in the near future.&lt;/p&gt;

&lt;h5&gt;Link submissions&lt;/h5&gt;

&lt;p&gt;I&amp;#8217;ve had many tips submitted for content over the past year. If I recall correctly, all of them have been used because they&amp;#8217;ve all been of high quality. I encourage people to keep submitting tips as there&amp;#8217;s always something I will miss!&lt;/p&gt;

&lt;p&gt;One thing to bear in mind when submitting tips is that a high proportion of readers are on mobile devices.&lt;/p&gt;

&lt;h5&gt;Job postings&lt;/h5&gt;

&lt;p&gt;This week I&amp;#8217;ll be accepting the first job postings to Coder Weekly. This is a trial to see how things work &amp;#8211; in particular, I want make sure it provides value both to subscribers, and those submitting job postings. Suffice it to say that there will be no agency or recruiter postings.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://coderweekly.com/jobs.html"&gt;See here for details about submitting jobs&lt;/a&gt;.&lt;/p&gt;

&lt;h5&gt;Book reviews and affiliates&lt;/h5&gt;

&lt;p&gt;I&amp;#8217;ve featured many books over the last year. There are two upcoming changes to this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I plan to actively start reviewing books and publish the reviews either here or on the Coder Weekly website.&lt;/li&gt;
&lt;li&gt;The links to these books (on the site and in the newsletter) may use an affiliate scheme, if one exists, for the vendor.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Aside from my time, there are material costs to running a newsletter. The affiliate links are to offset this.&lt;/p&gt;

&lt;p&gt;Listed books will be read by me, and I will only list the best stuff. I don&amp;#8217;t want to waste my time or anyone else&amp;#8217;s with mediocre books.&lt;/p&gt;

&lt;p&gt;Book tips are great too!&lt;/p&gt;

&lt;h5&gt;Let me know what you think&lt;/h5&gt;

&lt;p&gt;Comments are always welcome: you can reach me at &lt;a href="mailto:matt@coderweekly.com"&gt;matt@coderweekly.com&lt;/a&gt;, or on &lt;a href="http://coderweekly.com"&gt;twitter&lt;/a&gt;.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/BlueprintForge/~4/zpdXZEBpn4Q" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://blueprintforge.com/blog/2013/02/16/updates-to-coder-weekly/</feedburner:origLink></entry>
  
  <entry>
    <title type="html"><![CDATA[Exploring SQLite's Virtual Database Engine]]></title>
    <link href="http://feedproxy.google.com/~r/BlueprintForge/~3/rVutrCblC14/" />
    <updated>2012-10-16T22:12:00+01:00</updated>
    <id>http://blueprintforge.com/blog/2012/10/16/exploring-sqlites-virtual-database-engine</id>
    <content type="html">&lt;p&gt;I&amp;#8217;ve written an article over at Coder Weekly on SQLite&amp;#8217;s Virtual Database Engine. It&amp;#8217;s part I in a series on the topic of SQLite&amp;#8217;s inner workings.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://coderweekly.com/articles/exploring-sqlites-virtual-database-engine.html"&gt;Go to the full article&lt;/a&gt;&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/BlueprintForge/~4/rVutrCblC14" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://blueprintforge.com/blog/2012/10/16/exploring-sqlites-virtual-database-engine/</feedburner:origLink></entry>
  
  <entry>
    <title type="html"><![CDATA[6 Weeks of Coder Weekly: the Numbers]]></title>
    <link href="http://feedproxy.google.com/~r/BlueprintForge/~3/9xGjCouLQrQ/" />
    <updated>2012-03-13T19:00:00+00:00</updated>
    <id>http://blueprintforge.com/blog/2012/03/13/6-weeks-of-coder-weekly-the-numbers</id>
    <content type="html">&lt;p&gt;Coder Weekly has been running for over 6 weeks now, so it seems like a good time to share some numbers. So far, the community feedback has been really positive and we&amp;#8217;ve reached 3,000 email subscribers, with another 800 or so on RSS.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Initial Traffic&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The first peak in this graph is the submission to Hacker News, and the second is the submission to /r/programming. You can see that, overall, reddit sent a lot more visitors. Due to the ranking algorithm differences of the two sites, traffic from reddit also continued for longer.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://blueprintforge.com/images/uniques.png" alt="" /&gt;&lt;/p&gt;

&lt;p&gt;Below, you can see how these spikes in traffic translated into new subscribers (y-axis shows new subs/day). You can&amp;#8217;t quite attribute all signups to Hacker News and reddit since there were other traffic sources too (e.g. twitter), but it gives a reasonable indication of the conversions.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://blueprintforge.com/images/subs.png" alt="" /&gt;&lt;/p&gt;

&lt;p&gt;Overall, well over 2,000 subscriptions occurred from these ~19,000 unique visitors, a conversion rate over 10%. Unfortunately I haven&amp;#8217;t run the numbers from the new version of the landing page, so I can&amp;#8217;t on speculate whether this has improved the conversion rate.&lt;/p&gt;

&lt;p&gt;Finally, the image below shows the number of RSS subscribers, which quickly rose past 800. It was clear from the outset that a large number of readers preferred this, so I&amp;#8217;m glad Mailchimp made it so easy to offer.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://blueprintforge.com/images/feedsubs.png" alt="" /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ongoing Growth&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;After each issue, there is an uptick in subscribe rate. It&amp;#8217;s great that people are tweeting about Coder Weekly and forwarding the emails. Conversely, unsubscribe rates are extremely low &amp;#8211; we&amp;#8217;re looking at between 2-5 subscribers per issue.&lt;/p&gt;

&lt;p&gt;So, although we haven&amp;#8217;t enjoyed the same incredible growth of the first week, there is steady growth that seems to be driven primarily by current subscribers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Click Data&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There&amp;#8217;s lots to be said about click rates for different articles. As you&amp;#8217;d expect, there is a strong correlation between the position in the list and click rate. The article&amp;#8217;s title is clearly an important factor too, with titles that describe an opinion or technique doing well. Below, you can see the top clicked links in Coder Weekly Issue #5.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://blueprintforge.com/images/clicks.png" alt="" /&gt;&lt;/p&gt;

&lt;p&gt;I intend to do a longer post discussing click data in future, hopefully with some interesting split testing data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Future&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I hope this brief overview has provided some interesting numbers for those of you who are curious. In future, there are a few ideas I&amp;#8217;d like to work on. Providing a separate feed for individual stories is something that&amp;#8217;s been asked for many times that I&amp;#8217;m still working on, and it would also be illuminating to do some split testing on the landing page.&lt;/p&gt;

&lt;p&gt;Finally, a huge thanks to all of you who&amp;#8217;ve subscribed and/or given feedback!&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/BlueprintForge/~4/9xGjCouLQrQ" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://blueprintforge.com/blog/2012/03/13/6-weeks-of-coder-weekly-the-numbers/</feedburner:origLink></entry>
  
  <entry>
    <title type="html"><![CDATA[Static Modification of Python with Python: the AST Module]]></title>
    <link href="http://feedproxy.google.com/~r/BlueprintForge/~3/BStUCksZGmY/" />
    <updated>2012-02-27T10:00:00+00:00</updated>
    <id>http://blueprintforge.com/blog/2012/02/27/static-modification-of-python-with-python-the-ast-module</id>
    <content type="html">&lt;p&gt;Source code modification can be useful in a number of testing and analysis scenarios. Here, we&amp;#8217;ll look at how you can modify Python source code using the &lt;code&gt;ast&lt;/code&gt; module, and some tools where this technique is used.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The CPython compilation process&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src="http://blueprintforge.com/images/pep339.png" style="float:left;margin-right:10px;"&gt;&lt;/img&gt;&lt;/p&gt;

&lt;p&gt;To begin, let&amp;#8217;s take a look at the CPython compilation process, as described in &lt;a href="http://www.python.org/dev/peps/pep-0339/"&gt;PEP 339&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Detailed knowledge of these steps isn&amp;#8217;t required for reading this article, but it helps to have a rough idea of the whole process.&lt;/p&gt;

&lt;p&gt;First, a parse tree is generated from the source code. Next, an Abstract Syntax Tree (AST) is built from the parse tree. From the AST, a control flow graph is generated, and finally, the code object is compiled from the control flow graph.&lt;/p&gt;

&lt;p&gt;Marked in blue is the AST stage, since that&amp;#8217;s what we&amp;#8217;ll be focusing on today. The &lt;code&gt;ast&lt;/code&gt; module appeared in its current form in Python 2.6, and exposes a simple method of visiting and modifying the AST.&lt;/p&gt;

&lt;p&gt;From there, we can generate a code object from our modified AST. We can also re-generate source code from our modified AST for explanatory purposes.&lt;/p&gt;

&lt;br&gt;


&lt;p&gt;&lt;strong&gt;Creating an AST&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let&amp;#8217;s define a simple expression, an &lt;code&gt;add&lt;/code&gt; function, and inspect the generated AST.&lt;/p&gt;

&lt;figure class='code'&gt;&lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;span class='line-number'&gt;2&lt;/span&gt;
&lt;span class='line-number'&gt;3&lt;/span&gt;
&lt;span class='line-number'&gt;4&lt;/span&gt;
&lt;span class='line-number'&gt;5&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class=''&gt;&lt;span class='line'&gt;&amp;gt;&amp;gt;&amp;gt; import ast
&lt;/span&gt;&lt;span class='line'&gt;&amp;gt;&amp;gt;&amp;gt; expr = """def add(arg1, arg2): return arg1 + arg2"""
&lt;/span&gt;&lt;span class='line'&gt;&amp;gt;&amp;gt;&amp;gt; expr_ast = ast.parse(expr)
&lt;/span&gt;&lt;span class='line'&gt;&amp;gt;&amp;gt;&amp;gt; expr_ast
&lt;/span&gt;&lt;span class='line'&gt;&amp;lt;_ast.Module object at 0x7f8718b171d0&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;Now that we have generated an &lt;code&gt;ast.Module&lt;/code&gt; object, let&amp;#8217;s dump the contents:&lt;/p&gt;

&lt;figure class='code'&gt;&lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;span class='line-number'&gt;2&lt;/span&gt;
&lt;span class='line-number'&gt;3&lt;/span&gt;
&lt;span class='line-number'&gt;4&lt;/span&gt;
&lt;span class='line-number'&gt;5&lt;/span&gt;
&lt;span class='line-number'&gt;6&lt;/span&gt;
&lt;span class='line-number'&gt;7&lt;/span&gt;
&lt;span class='line-number'&gt;8&lt;/span&gt;
&lt;span class='line-number'&gt;9&lt;/span&gt;
&lt;span class='line-number'&gt;10&lt;/span&gt;
&lt;span class='line-number'&gt;11&lt;/span&gt;
&lt;span class='line-number'&gt;12&lt;/span&gt;
&lt;span class='line-number'&gt;13&lt;/span&gt;
&lt;span class='line-number'&gt;14&lt;/span&gt;
&lt;span class='line-number'&gt;15&lt;/span&gt;
&lt;span class='line-number'&gt;16&lt;/span&gt;
&lt;span class='line-number'&gt;17&lt;/span&gt;
&lt;span class='line-number'&gt;18&lt;/span&gt;
&lt;span class='line-number'&gt;19&lt;/span&gt;
&lt;span class='line-number'&gt;20&lt;/span&gt;
&lt;span class='line-number'&gt;21&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class=''&gt;&lt;span class='line'&gt;&amp;gt;&amp;gt;&amp;gt; ast.dump(expr_ast)
&lt;/span&gt;&lt;span class='line'&gt;"Module(
&lt;/span&gt;&lt;span class='line'&gt;    body=[
&lt;/span&gt;&lt;span class='line'&gt;        FunctionDef(
&lt;/span&gt;&lt;span class='line'&gt;            name='add', args=arguments(
&lt;/span&gt;&lt;span class='line'&gt;                args=[
&lt;/span&gt;&lt;span class='line'&gt;                    Name(id='arg1', ctx=Param()),
&lt;/span&gt;&lt;span class='line'&gt;                    Name(id='arg2', ctx=Param())
&lt;/span&gt;&lt;span class='line'&gt;                    ],
&lt;/span&gt;&lt;span class='line'&gt;                    vararg=None,
&lt;/span&gt;&lt;span class='line'&gt;                    kwarg=None,
&lt;/span&gt;&lt;span class='line'&gt;                    defaults=[]),
&lt;/span&gt;&lt;span class='line'&gt;            body=[
&lt;/span&gt;&lt;span class='line'&gt;                Return(
&lt;/span&gt;&lt;span class='line'&gt;                    value=BinOp(
&lt;/span&gt;&lt;span class='line'&gt;                        left=Name(id='arg1', ctx=Load()),
&lt;/span&gt;&lt;span class='line'&gt;                        op=Add(),
&lt;/span&gt;&lt;span class='line'&gt;                        right=Name(id='arg2', ctx=Load())))
&lt;/span&gt;&lt;span class='line'&gt;                ], 
&lt;/span&gt;&lt;span class='line'&gt;             decorator_list=[])
&lt;/span&gt;&lt;span class='line'&gt;    ])"&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;As we can see, &lt;code&gt;Module&lt;/code&gt; is the parent node. The &lt;code&gt;Module&lt;/code&gt; body contains a list with a single element: our function definition. The function definition has a name, list of arguments, and a body. The body contains a single &lt;code&gt;Return&lt;/code&gt; node, which contains the &lt;code&gt;Add&lt;/code&gt; operation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Modifying the AST&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;How can we modify this tree and change how the code works? To illustrate, let&amp;#8217;s do something crazy that you would never want to do in your code. We&amp;#8217;ll traverse the tree, and replace the &lt;code&gt;Add&lt;/code&gt; operation with a &lt;code&gt;Mult&lt;/code&gt; operation. See, I told you it was crazy!&lt;/p&gt;

&lt;p&gt;We&amp;#8217;ll start by subclassing the &lt;code&gt;NodeTransformer&lt;/code&gt; class, and defining the &lt;code&gt;visit_BinOp&lt;/code&gt; method which is called when the transformer visits a binary operator node:&lt;/p&gt;

&lt;figure class='code'&gt;&lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;span class='line-number'&gt;2&lt;/span&gt;
&lt;span class='line-number'&gt;3&lt;/span&gt;
&lt;span class='line-number'&gt;4&lt;/span&gt;
&lt;span class='line-number'&gt;5&lt;/span&gt;
&lt;span class='line-number'&gt;6&lt;/span&gt;
&lt;span class='line-number'&gt;7&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class=''&gt;&lt;span class='line'&gt;class CrazyTransformer(ast.NodeTransformer):
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;    def visit_BinOp(self, node):
&lt;/span&gt;&lt;span class='line'&gt;        print node.__dict__
&lt;/span&gt;&lt;span class='line'&gt;        node.op = ast.Mult()
&lt;/span&gt;&lt;span class='line'&gt;        print node.__dict__
&lt;/span&gt;&lt;span class='line'&gt;        return node&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;Now that we&amp;#8217;ve defined our transformer which performs this unhealthy action, let&amp;#8217;s see it run on the expression defined above:&lt;/p&gt;

&lt;figure class='code'&gt;&lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;span class='line-number'&gt;2&lt;/span&gt;
&lt;span class='line-number'&gt;3&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class=''&gt;&lt;span class='line'&gt;&amp;gt;&amp;gt;&amp;gt; parser.visit(expr_ast)
&lt;/span&gt;&lt;span class='line'&gt;{'op': &amp;lt;_ast.Add object at 0x226b810&amp;gt;, 'right': &amp;lt;_ast.Name object at 0x285fe10&amp;gt;, 'lineno': 1, 'col_offset': 28, 'left': &amp;lt;_ast.Name object at 0x285fdd0&amp;gt;}
&lt;/span&gt;&lt;span class='line'&gt;{'op': &amp;lt;_ast.Mult object at 0x28eb090&amp;gt;, 'right': &amp;lt;_ast.Name object at 0x285fe10&amp;gt;, 'lineno': 1, 'col_offset': 28, 'left': &amp;lt;_ast.Name object at 0x285fdd0&amp;gt;}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;You can see the &lt;code&gt;Add&lt;/code&gt; node is replaced with a &lt;code&gt;Mult&lt;/code&gt;, as shown by the modified &lt;code&gt;__dict__&lt;/code&gt;. There are a couple of things we haven&amp;#8217;t dealt with here, like visiting child nodes, but this is enough to illustrate the principle.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Compiling and executing the modified AST&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;After adding a call to our operation, i.e.:&lt;/p&gt;

&lt;figure class='code'&gt;&lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class=''&gt;&lt;span class='line'&gt;print add(4, 5)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;&amp;#8230;to the end of our script, let&amp;#8217;s see how the code evaluates:&lt;/p&gt;

&lt;figure class='code'&gt;&lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;span class='line-number'&gt;2&lt;/span&gt;
&lt;span class='line-number'&gt;3&lt;/span&gt;
&lt;span class='line-number'&gt;4&lt;/span&gt;
&lt;span class='line-number'&gt;5&lt;/span&gt;
&lt;span class='line-number'&gt;6&lt;/span&gt;
&lt;span class='line-number'&gt;7&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class=''&gt;&lt;span class='line'&gt;&amp;gt;&amp;gt;&amp;gt; unmodified = ast.parse(expr)
&lt;/span&gt;&lt;span class='line'&gt;&amp;gt;&amp;gt;&amp;gt; exec compile(unmodified, '&amp;lt;string&amp;gt;', 'exec')
&lt;/span&gt;&lt;span class='line'&gt;9
&lt;/span&gt;&lt;span class='line'&gt;&amp;gt;&amp;gt;&amp;gt; transformer = CrazyTransformer()
&lt;/span&gt;&lt;span class='line'&gt;&amp;gt;&amp;gt;&amp;gt; modified = transformer.visit(unmodified)
&lt;/span&gt;&lt;span class='line'&gt;&amp;gt;&amp;gt;&amp;gt; exec compile(modified, '&amp;lt;string&amp;gt;', 'exec')
&lt;/span&gt;&lt;span class='line'&gt;20&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;As we can see, our unmodified and modified ASTs compile to code that prints 9 and 20 respectively.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Translating back to source code&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Finally, we can use &lt;code&gt;unparse&lt;/code&gt; &lt;a href="http://svn.python.org/projects/python/trunk/Demo/parser/unparse.py"&gt;found here&lt;/a&gt; to view the source code corresponding to our modified AST:&lt;/p&gt;

&lt;figure class='code'&gt;&lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;span class='line-number'&gt;2&lt;/span&gt;
&lt;span class='line-number'&gt;3&lt;/span&gt;
&lt;span class='line-number'&gt;4&lt;/span&gt;
&lt;span class='line-number'&gt;5&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class=''&gt;&lt;span class='line'&gt;&amp;gt;&amp;gt;&amp;gt; unparse.Unparser(modified, sys.stdout)
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;def add(arg1, arg2):
&lt;/span&gt;&lt;span class='line'&gt;    return (arg1 * arg2)
&lt;/span&gt;&lt;span class='line'&gt;print add(4, 5)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;As we can see, the &lt;code&gt;*&lt;/code&gt; operator has replaced &lt;code&gt;+&lt;/code&gt;. Unparse is useful for understanding how your AST transformer modifies code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Practical applications&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Clearly, our above example serves little practical purpose. However, static analysis and modification of source code can be extremely useful.&lt;/p&gt;

&lt;p&gt;You could, for instance, inject code for testing purposes. See &lt;a href="http://blip.tv/pycon-us-videos-2009-2010-2011/pycon-2011-what-would-you-do-with-an-ast-4898264"&gt;this Pycon talk&lt;/a&gt; for an understanding of how a node transformer can be used to inject instrumentation code for testing purposes.&lt;/p&gt;

&lt;p&gt;In addition, the &lt;a href="http://pythoscope.org"&gt;pythoscope project&lt;/a&gt; uses an AST visitor to process source files and generate tests from method signatures.&lt;/p&gt;

&lt;p&gt;Projects such as pylint also use an AST walking method to analyze source code.
In the case of pylint, Logilab have created a module which aims:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;to provide a common base representation of python source code for projects such as pychecker, pyreverse, pylint&amp;#8230;&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="http://www.logilab.org/856"&gt;See here&lt;/a&gt; for more information.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;References&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blip.tv/pycon-us-videos-2009-2010-2011/pycon-2011-what-would-you-do-with-an-ast-4898264"&gt;This Pycon talk&lt;/a&gt; by Matthew J Desmarais and &lt;a href="http://eli.thegreenplace.net/2009/11/28/python-internals-working-with-python-asts/"&gt;this blog post by Eli Bendersky&lt;/a&gt; were invaluable in writing this post.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/BlueprintForge/~4/BStUCksZGmY" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://blueprintforge.com/blog/2012/02/27/static-modification-of-python-with-python-the-ast-module/</feedburner:origLink></entry>
  
  <entry>
    <title type="html"><![CDATA[Websockets in Play 2.0]]></title>
    <link href="http://feedproxy.google.com/~r/BlueprintForge/~3/0hiXtoldf9w/" />
    <updated>2012-02-13T08:10:00+00:00</updated>
    <id>http://blueprintforge.com/blog/2012/02/13/websockets-in-play-2-dot-0</id>
    <content type="html">&lt;p&gt;&lt;em&gt;Update: this post was written in early 2012 when Play 2.0 was beta software and is preserved for posterity. I make no promises about its suitability for current development with Play, and hope to do an updated post in future.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The source code for this guide can be found in the &lt;a href="https://github.com/MattCottingham/websocks2"&gt;github repository&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Websockets allow full-duplex communication over a TCP socket, normally between a browser and a server-side application. In a similar vein to &lt;a href="http://playframework.wordpress.com/2011/04/25/websockets-in-play/"&gt;this post&lt;/a&gt; on websockets in Play 1.x, this article shows how to create a websockets-enabled application in Play 2.0.&lt;/p&gt;

&lt;p&gt;Remember that Play 2.0 is still in beta, so the APIs shown below are subject to change. If that happens, I&amp;#8217;ll endeavour to update this article with the changes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Obtaining Play 2.0&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I encountered an issue with the packaged beta, so I downloaded the Play source (&lt;a href="https://github.com/playframework/Play20/wiki/BuildingFromSource"&gt;full instructions&lt;/a&gt;):&lt;/p&gt;

&lt;figure class='code'&gt;&lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;span class='line-number'&gt;2&lt;/span&gt;
&lt;span class='line-number'&gt;3&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class=''&gt;&lt;span class='line'&gt;git clone --depth=1 https://github.com/playframework/Play20.git
&lt;/span&gt;&lt;span class='line'&gt;cd Play20/framework
&lt;/span&gt;&lt;span class='line'&gt;./build&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;While it builds, you&amp;#8217;ll probably want to get some coffee. Then, at the sbt prompt:&lt;/p&gt;

&lt;figure class='code'&gt;&lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class=''&gt;&lt;span class='line'&gt;publish-local&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;Now, create the project:&lt;/p&gt;

&lt;figure class='code'&gt;&lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class=''&gt;&lt;span class='line'&gt;./play new websocks2&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;You can run the &lt;code&gt;eclipsify&lt;/code&gt; command (or equivalent) if you want to open the project in your IDE.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Creating the Websockets Controller&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;With setup done, let&amp;#8217;s define the controller that will serve our index page and establish a websocket with the client. Open &lt;code&gt;controllers/Application.java&lt;/code&gt; and add the following code:&lt;/p&gt;

&lt;figure class='code'&gt;&lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;span class='line-number'&gt;2&lt;/span&gt;
&lt;span class='line-number'&gt;3&lt;/span&gt;
&lt;span class='line-number'&gt;4&lt;/span&gt;
&lt;span class='line-number'&gt;5&lt;/span&gt;
&lt;span class='line-number'&gt;6&lt;/span&gt;
&lt;span class='line-number'&gt;7&lt;/span&gt;
&lt;span class='line-number'&gt;8&lt;/span&gt;
&lt;span class='line-number'&gt;9&lt;/span&gt;
&lt;span class='line-number'&gt;10&lt;/span&gt;
&lt;span class='line-number'&gt;11&lt;/span&gt;
&lt;span class='line-number'&gt;12&lt;/span&gt;
&lt;span class='line-number'&gt;13&lt;/span&gt;
&lt;span class='line-number'&gt;14&lt;/span&gt;
&lt;span class='line-number'&gt;15&lt;/span&gt;
&lt;span class='line-number'&gt;16&lt;/span&gt;
&lt;span class='line-number'&gt;17&lt;/span&gt;
&lt;span class='line-number'&gt;18&lt;/span&gt;
&lt;span class='line-number'&gt;19&lt;/span&gt;
&lt;span class='line-number'&gt;20&lt;/span&gt;
&lt;span class='line-number'&gt;21&lt;/span&gt;
&lt;span class='line-number'&gt;22&lt;/span&gt;
&lt;span class='line-number'&gt;23&lt;/span&gt;
&lt;span class='line-number'&gt;24&lt;/span&gt;
&lt;span class='line-number'&gt;25&lt;/span&gt;
&lt;span class='line-number'&gt;26&lt;/span&gt;
&lt;span class='line-number'&gt;27&lt;/span&gt;
&lt;span class='line-number'&gt;28&lt;/span&gt;
&lt;span class='line-number'&gt;29&lt;/span&gt;
&lt;span class='line-number'&gt;30&lt;/span&gt;
&lt;span class='line-number'&gt;31&lt;/span&gt;
&lt;span class='line-number'&gt;32&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class=''&gt;&lt;span class='line'&gt;package controllers;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;import play.*;
&lt;/span&gt;&lt;span class='line'&gt;import play.mvc.*;
&lt;/span&gt;&lt;span class='line'&gt;import play.libs.F.Callback;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;import views.html.*;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;public class Application extends Controller {
&lt;/span&gt;&lt;span class='line'&gt;  
&lt;/span&gt;&lt;span class='line'&gt;  public static Result index() {
&lt;/span&gt;&lt;span class='line'&gt;    return ok(index.render());
&lt;/span&gt;&lt;span class='line'&gt;  }
&lt;/span&gt;&lt;span class='line'&gt;  
&lt;/span&gt;&lt;span class='line'&gt;  public static WebSocket&amp;lt;String&amp;gt; sockHandler() {
&lt;/span&gt;&lt;span class='line'&gt;      return new WebSocket&amp;lt;String&amp;gt;() {
&lt;/span&gt;&lt;span class='line'&gt;          // called when the websocket is established
&lt;/span&gt;&lt;span class='line'&gt;          public void onReady(WebSocket.In&amp;lt;String&amp;gt; in, WebSocket.Out&amp;lt;String&amp;gt; out) {
&lt;/span&gt;&lt;span class='line'&gt;              // register a callback for processing instream events
&lt;/span&gt;&lt;span class='line'&gt;              in.onMessage(new Callback&amp;lt;String&amp;gt;() {
&lt;/span&gt;&lt;span class='line'&gt;                  public void invoke(String event) {
&lt;/span&gt;&lt;span class='line'&gt;                      Logger.info(event);
&lt;/span&gt;&lt;span class='line'&gt;                  } 
&lt;/span&gt;&lt;span class='line'&gt;               });
&lt;/span&gt;&lt;span class='line'&gt;              
&lt;/span&gt;&lt;span class='line'&gt;              // write out a greeting
&lt;/span&gt;&lt;span class='line'&gt;              out.write("I'm contacting you regarding your recent websocket.");
&lt;/span&gt;&lt;span class='line'&gt;          }
&lt;/span&gt;&lt;span class='line'&gt;      };
&lt;/span&gt;&lt;span class='line'&gt;  }
&lt;/span&gt;&lt;span class='line'&gt;  
&lt;/span&gt;&lt;span class='line'&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;As you can see, alongside the pre-generated code, we&amp;#8217;ve added a static method &lt;code&gt;sockHandler&lt;/code&gt; that returns a websocket. The inner &lt;code&gt;onReady&lt;/code&gt; method takes two arguments: the &lt;code&gt;in&lt;/code&gt; channel and &lt;code&gt;out&lt;/code&gt; channel.&lt;/p&gt;

&lt;p&gt;At this point, we could pass those channels to a model which retains them. But for this example, we simply register a logger for inbound messages, and write a greeting message to the &lt;code&gt;out&lt;/code&gt; socket.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Routing the Websocket Connection&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Next, we need to add a route to our websocket connection. In &lt;code&gt;conf/routes&lt;/code&gt;, add the following:&lt;/p&gt;

&lt;figure class='code'&gt;&lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;span class='line-number'&gt;2&lt;/span&gt;
&lt;span class='line-number'&gt;3&lt;/span&gt;
&lt;span class='line-number'&gt;4&lt;/span&gt;
&lt;span class='line-number'&gt;5&lt;/span&gt;
&lt;span class='line-number'&gt;6&lt;/span&gt;
&lt;span class='line-number'&gt;7&lt;/span&gt;
&lt;span class='line-number'&gt;8&lt;/span&gt;
&lt;span class='line-number'&gt;9&lt;/span&gt;
&lt;span class='line-number'&gt;10&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class=''&gt;&lt;span class='line'&gt;# Routes
&lt;/span&gt;&lt;span class='line'&gt;# This file defines all application routes (Higher priority routes first)
&lt;/span&gt;&lt;span class='line'&gt;# ~~~~
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;# Home page
&lt;/span&gt;&lt;span class='line'&gt;GET     /                           controllers.Application.index()
&lt;/span&gt;&lt;span class='line'&gt;GET     /greeter                    controllers.Application.sockHandler()
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;# Map static resources from the /public folder to the /assets URL path
&lt;/span&gt;&lt;span class='line'&gt;GET     /assets/*file               controllers.Assets.at(path="/public", file)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;We don&amp;#8217;t actually request &lt;code&gt;/greeter&lt;/code&gt; explicitly; instead, we&amp;#8217;ll use a &lt;a href="http://www.playframework.org/documentation/1.2.4/templates#Actionsor"&gt;reverse generated URL&lt;/a&gt; in our template.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Adding the Template&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now that we have our controller and route in place, we can specify the client-side code for our websocket.&lt;/p&gt;

&lt;figure class='code'&gt;&lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;span class='line-number'&gt;2&lt;/span&gt;
&lt;span class='line-number'&gt;3&lt;/span&gt;
&lt;span class='line-number'&gt;4&lt;/span&gt;
&lt;span class='line-number'&gt;5&lt;/span&gt;
&lt;span class='line-number'&gt;6&lt;/span&gt;
&lt;span class='line-number'&gt;7&lt;/span&gt;
&lt;span class='line-number'&gt;8&lt;/span&gt;
&lt;span class='line-number'&gt;9&lt;/span&gt;
&lt;span class='line-number'&gt;10&lt;/span&gt;
&lt;span class='line-number'&gt;11&lt;/span&gt;
&lt;span class='line-number'&gt;12&lt;/span&gt;
&lt;span class='line-number'&gt;13&lt;/span&gt;
&lt;span class='line-number'&gt;14&lt;/span&gt;
&lt;span class='line-number'&gt;15&lt;/span&gt;
&lt;span class='line-number'&gt;16&lt;/span&gt;
&lt;span class='line-number'&gt;17&lt;/span&gt;
&lt;span class='line-number'&gt;18&lt;/span&gt;
&lt;span class='line-number'&gt;19&lt;/span&gt;
&lt;span class='line-number'&gt;20&lt;/span&gt;
&lt;span class='line-number'&gt;21&lt;/span&gt;
&lt;span class='line-number'&gt;22&lt;/span&gt;
&lt;span class='line-number'&gt;23&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class=''&gt;&lt;span class='line'&gt;@main(null) {
&lt;/span&gt;&lt;span class='line'&gt;    
&lt;/span&gt;&lt;span class='line'&gt;    &amp;lt;div class="greeting"&amp;gt;&amp;lt;/div&amp;gt;
&lt;/span&gt;&lt;span class='line'&gt;    &amp;lt;button class="send"&amp;gt;Send&amp;lt;/button&amp;gt;
&lt;/span&gt;&lt;span class='line'&gt;    
&lt;/span&gt;&lt;span class='line'&gt;    &amp;lt;script type="text/javascript" charset="utf-8"&amp;gt;
&lt;/span&gt;&lt;span class='line'&gt;    
&lt;/span&gt;&lt;span class='line'&gt;        $(function() {
&lt;/span&gt;&lt;span class='line'&gt;            var WS = window['MozWebSocket'] ? MozWebSocket : WebSocket
&lt;/span&gt;&lt;span class='line'&gt;            var sock = new WS("@routes.Application.sockHandler().webSocketURL(request)")
&lt;/span&gt;&lt;span class='line'&gt;            
&lt;/span&gt;&lt;span class='line'&gt;            sock.onmessage = function(event) {
&lt;/span&gt;&lt;span class='line'&gt;                $('.greeting').append(event.data)
&lt;/span&gt;&lt;span class='line'&gt;            }
&lt;/span&gt;&lt;span class='line'&gt;            
&lt;/span&gt;&lt;span class='line'&gt;            $('button.send').click(function() {
&lt;/span&gt;&lt;span class='line'&gt;                sock.send("I'm sending a message now.")
&lt;/span&gt;&lt;span class='line'&gt;            });            
&lt;/span&gt;&lt;span class='line'&gt;        })
&lt;/span&gt;&lt;span class='line'&gt;    
&lt;/span&gt;&lt;span class='line'&gt;    &amp;lt;/script&amp;gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;Here, we declare a &lt;code&gt;greeting&lt;/code&gt; which is populated when the websocket receives a message. We also register a button action to send a message to the server, so we can demonstrate bi-directional messaging. If you&amp;#8217;re familiar with Play 1.x, you&amp;#8217;ll notice that the templating is a little different.&lt;/p&gt;

&lt;p&gt;Now, when we start the app, we see the following.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://blueprintforge.com/images/websockets.png" alt="Screenshot of websocket page" /&gt;&lt;/p&gt;

&lt;p&gt;Clicking the &lt;code&gt;Send&lt;/code&gt; button generates the following log line:&lt;/p&gt;

&lt;figure class='code'&gt;&lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class=''&gt;&lt;span class='line'&gt;[info] application - I'm sending a message now.&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So, that&amp;#8217;s all that needs to be done to create a websocket-enabled application in Play. We&amp;#8217;ve both sent messages from, and to, the browser with simple code on both client and server side. In a real application, we would probably pass the &lt;code&gt;in&lt;/code&gt; and &lt;code&gt;out&lt;/code&gt; streams to a model, but it should be straightforward to see how this is done from the example.&lt;/p&gt;

&lt;p&gt;For further information, you can look at the examples, particularly the &lt;a href="https://github.com/playframework/Play20/tree/master/samples/java/websocket-chat"&gt;websocket chat app&lt;/a&gt;, upon which this guide is based. In a future post I&amp;#8217;d like to go into more detail by looking at the Akka actor model implementation, which is used in the chat application sample.&lt;/p&gt;

&lt;p&gt;This article comes with a small disclaimer &amp;#8211; Play is still a new framework to me, so some of the above code may not demonstrate best practice (although I did attempt to follow the sample application closely). If you notice anything that could be improved, let me know and I&amp;#8217;ll update accordingly.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/BlueprintForge/~4/0hiXtoldf9w" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://blueprintforge.com/blog/2012/02/13/websockets-in-play-2-dot-0/</feedburner:origLink></entry>
  
  <entry>
    <title type="html"><![CDATA[A Django Developer's First Experience of Play]]></title>
    <link href="http://feedproxy.google.com/~r/BlueprintForge/~3/qN8javMdzwU/" />
    <updated>2012-01-31T13:20:00+00:00</updated>
    <id>http://blueprintforge.com/blog/2012/01/31/a-django-developers-first-experience-of-play</id>
    <content type="html">&lt;p&gt;Having used Django (and other python web frameworks) on and off for three years, I came across the &lt;a href="http://www.playframework.org/"&gt;Play framework&lt;/a&gt; some time ago. However, it&amp;#8217;s only recently
that I&amp;#8217;ve been able to use it for for a project. Note that this post is written from a Django developer&amp;#8217;s perspective, but I&amp;#8217;m not attempting a &amp;#8220;Django vs Play&amp;#8221; type of comparison. Instead, the following notes how a Django developer might approach the framework and map their own experience to it.&lt;/p&gt;

&lt;p&gt;Play looks great for a number of reasons: it&amp;#8217;s simple to set up, has a wide range of libraries and plugins that come out of the box, and has an active community surrounding it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Initial Project Setup&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Project setup is simple, and generates the necessary files and directory structure.&lt;/p&gt;

&lt;figure class='code'&gt;&lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class=''&gt;&lt;span class='line'&gt;play new [app]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;Replaces the familiar &lt;code&gt;startproject&lt;/code&gt; command.&lt;/p&gt;

&lt;p&gt;A range of libraries are already packaged with Play, including &lt;a href="http://joda-time.sourceforge.net/"&gt;Joda Time&lt;/a&gt;, &lt;a href="http://code.google.com/p/google-gson/"&gt;google-gson&lt;/a&gt;, Log4j, test runners, and database connectors. &amp;#8220;Convention over configuration&amp;#8221; is often cited as one of Play&amp;#8217;s aims.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;IDE Support&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Creating an Eclipse project configuration for your project happens through the &lt;code&gt;eclipsify&lt;/code&gt; command. Pydev, on the other hand, requires some manual setup, particularly if you are using different interpreters with &lt;code&gt;vitualenv&lt;/code&gt;. Though simple, this can become tedious. And of course, static analysis capability is likely to differ signficantly because of the different type systems, but that&amp;#8217;s a discussion outside the scope of this article.&lt;/p&gt;

&lt;p&gt;Although this is not directly related to IDE support, it&amp;#8217;s also worth mentioning that both frameworks support automatic application reloading based on file changes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Model Declaration&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Play exposes its own JPA (Java Persistence API) interface. The entity manager is already configured and can be easily accessed (e.g. for transactions).&lt;/p&gt;

&lt;figure class='code'&gt;&lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;span class='line-number'&gt;2&lt;/span&gt;
&lt;span class='line-number'&gt;3&lt;/span&gt;
&lt;span class='line-number'&gt;4&lt;/span&gt;
&lt;span class='line-number'&gt;5&lt;/span&gt;
&lt;span class='line-number'&gt;6&lt;/span&gt;
&lt;span class='line-number'&gt;7&lt;/span&gt;
&lt;span class='line-number'&gt;8&lt;/span&gt;
&lt;span class='line-number'&gt;9&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class=''&gt;&lt;span class='line'&gt;import javax.persistence.Entity;
&lt;/span&gt;&lt;span class='line'&gt;import play.db.jpa.Model;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;@Entity
&lt;/span&gt;&lt;span class='line'&gt;public class TestEntity extends Model {
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;    public String title;
&lt;/span&gt;&lt;span class='line'&gt;    public Integer count;
&lt;/span&gt;&lt;span class='line'&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;As you can see, model declaration is concise, though the OO Architect in you might be shouting about encapsulation. Models are accessed directly through &lt;code&gt;model.attribute&lt;/code&gt;, but getters and setters are automatically generated and used for access. These can be easily overridden. As a python developer, you might already be missing descriptors and the &lt;code&gt;@property&lt;/code&gt; annotation!&lt;/p&gt;

&lt;p&gt;A pre-configured entity manager is provided, but can easily be adjusted. In fact, my first application used an exisiting database, so I needed to declare models but disable DDL generation. This was easily done in &lt;code&gt;application.conf&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Templating&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Generally, Play&amp;#8217;s templating engine can be described as similar to Django&amp;#8217;s.&lt;/p&gt;

&lt;p&gt;One nice feature is the &lt;code&gt;%{ }%&lt;/code&gt; (script) tag that allows you to write scripts (with variable assignment, etc.) Of course, you don&amp;#8217;t want to be doing any heavy lifting in the templates, but it can be very useful, e.g.:&lt;/p&gt;

&lt;figure class='code'&gt;&lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;span class='line-number'&gt;2&lt;/span&gt;
&lt;span class='line-number'&gt;3&lt;/span&gt;
&lt;span class='line-number'&gt;4&lt;/span&gt;
&lt;span class='line-number'&gt;5&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class=''&gt;&lt;span class='line'&gt;%{
&lt;/span&gt;&lt;span class='line'&gt;       nameCaps= name.toUpperCase();
&lt;/span&gt;&lt;span class='line'&gt;}%
&lt;/span&gt;&lt;span class='line'&gt; 
&lt;/span&gt;&lt;span class='line'&gt; &amp;lt;h1&amp;gt;${nameCaps}&amp;lt;/h1&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;Java object extensions (methods added to an object when used in a template) are another useful feature. To take the example from the documentation, the &lt;code&gt;format&lt;/code&gt; method applied to &lt;code&gt;Java.lang.Number&lt;/code&gt; gives the formatted result:&lt;/p&gt;

&lt;figure class='code'&gt;&lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class=''&gt;&lt;span class='line'&gt; &amp;lt;p&amp;gt;Total: ${order.total.format('## ###,00')}&amp;lt;/p&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;See the &lt;a href="http://www.playframework.org/documentation/1.2.4/templates"&gt;play template documentation&lt;/a&gt; for more details on these and more.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Test Framework Integration&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Both Django and Play feature excellent test framework integration. Play has integrated the selenium test framework, and also allows tests to be run from the browser, a very handy feature.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://blueprintforge.com/images/selenium.png" alt="Screenshot of the selenium test runner in Play Framework" /&gt;&lt;/p&gt;

&lt;p&gt;Selenium support will ship in Django 1.4, but is not currently available.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Admin Interface&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A great help in Django development is the admin interface. While it requires a little more setup, the CRUD module in Play gives a simple browser-based way of managing entities.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://blueprintforge.com/images/admin.png" alt="Screenshot of the CRUD interface in Play Framework" /&gt;&lt;/p&gt;

&lt;p&gt;See more in the &lt;a href="http://www.playframework.org/documentation/1.0.1/crud"&gt;CRUD documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Both frameworks have many strengths, and it is encouraging to see highly active development in both. There are a few features in Play
which might make a Django developer envious, such as modules for OAuth/OAuth2 authentication and websockets built in. However,
the frameworks are certainly very evenly matched.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/BlueprintForge/~4/qN8javMdzwU" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://blueprintforge.com/blog/2012/01/31/a-django-developers-first-experience-of-play/</feedburner:origLink></entry>
  
  <entry>
    <title type="html"><![CDATA[Measuring & Optimising Django Database Performance]]></title>
    <link href="http://feedproxy.google.com/~r/BlueprintForge/~3/GAsF_4tyX3M/" />
    <updated>2012-01-24T08:47:00+00:00</updated>
    <id>http://blueprintforge.com/blog/2012/01/24/measuring-optimising-database-performance-in-django</id>
    <content type="html">&lt;p&gt;Database performance is a crucial factor in web application performance, and can mean the difference between a responsive web application and a slow one. Here, we summarise methods for identifying database performance issues, and how to approach fixing them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Benchmarking Overall Performance&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;First, it is worth establishing whether database queries are a performance bottleneck, or whether you should be focusing your efforts on something else. There are a number of ways to do this, and two that I&amp;#8217;ve found simple and effective are &lt;code&gt;django-snippetscream&lt;/code&gt; and &lt;code&gt;django-debug-toolbar&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Install &lt;code&gt;django-snippetscream&lt;/code&gt;:&lt;/p&gt;

&lt;figure class='code'&gt;&lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class=''&gt;&lt;span class='line'&gt;pip install django-snippetscream&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;and add the following middleware class to &lt;code&gt;settings.py&lt;/code&gt;:&lt;/p&gt;

&lt;figure class='code'&gt;&lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class=''&gt;&lt;span class='line'&gt;MIDDLEWARE_CLASSES = MIDDLEWARE_CLASSES + ('snippetscream.ProfileMiddleware',)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;Now, you can simply append &lt;code&gt;?prof&lt;/code&gt; to your application URLs to profile the code run to generate the page. This gives a quick way of telling whether any particular methods are consuming disproportionate resources. Sample output is shown below.&lt;/p&gt;

&lt;figure class='code'&gt;&lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;span class='line-number'&gt;2&lt;/span&gt;
&lt;span class='line-number'&gt;3&lt;/span&gt;
&lt;span class='line-number'&gt;4&lt;/span&gt;
&lt;span class='line-number'&gt;5&lt;/span&gt;
&lt;span class='line-number'&gt;6&lt;/span&gt;
&lt;span class='line-number'&gt;7&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class=''&gt;&lt;span class='line'&gt;72063 function calls (68833 primitive calls) in 0.267 seconds
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;Ordered by: internal time, call count
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;ncalls  tottime  percall  cumtime  percall filename:lineno(function)
&lt;/span&gt;&lt;span class='line'&gt;8084    0.034    0.000    0.034    0.000 env/lib/python2.7/posixpath.py:60(join)
&lt;/span&gt;&lt;span class='line'&gt;8515    0.031    0.000    0.039    0.000 env/lib/python2.7/posixpath.py:130(islink)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;See the snippetscream &lt;a href="http://pypi.python.org/pypi/django-snippetscream"&gt;documentation&lt;/a&gt; for more details.&lt;/p&gt;

&lt;p&gt;The &lt;a href="http://pypi.python.org/pypi/django-debug-toolbar/0.9.4"&gt;django-debug-toolbar&lt;/a&gt; is another easy-to-use profiler (and has many other functions). To install:&lt;/p&gt;

&lt;figure class='code'&gt;&lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class=''&gt;&lt;span class='line'&gt;pip install django-debug-toolbar&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;And add the following to your &lt;code&gt;settings.py&lt;/code&gt;:&lt;/p&gt;

&lt;figure class='code'&gt;&lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;span class='line-number'&gt;2&lt;/span&gt;
&lt;span class='line-number'&gt;3&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class=''&gt;&lt;span class='line'&gt;MIDDLEWARE_CLASSES = MIDDLEWARE_CLASSES + ('debug_toolbar.middleware.DebugToolbarMiddleware',)
&lt;/span&gt;&lt;span class='line'&gt;INSTALLED_APPS = INSTALLED_APPS + ('debug_toolbar',)
&lt;/span&gt;&lt;span class='line'&gt;INTERNAL_IPS = ('127.0.0.1',)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;Now, when you visit your site in a browser, the SQL query view will display queries that have been executed and the time taken.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://blueprintforge.com/images/debugtoolbar.png" alt="Django debug toolbar database query view" /&gt;&lt;/p&gt;

&lt;p&gt;So, you can now judge for yourself whether your application is slow executing queries or if there is some other performance bottleneck. To deal with database issues, read on.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A closer look at SQL query generation in Django&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now that you have a couple of tools by which to measure performance, let&amp;#8217;s look at some examples of optimising database performance. We&amp;#8217;ll use the following simple models for our discussion.&lt;/p&gt;

&lt;figure class='code'&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;span class='line-number'&gt;2&lt;/span&gt;
&lt;span class='line-number'&gt;3&lt;/span&gt;
&lt;span class='line-number'&gt;4&lt;/span&gt;
&lt;span class='line-number'&gt;5&lt;/span&gt;
&lt;span class='line-number'&gt;6&lt;/span&gt;
&lt;span class='line-number'&gt;7&lt;/span&gt;
&lt;span class='line-number'&gt;8&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class='python'&gt;&lt;span class='line'&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Article&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="n"&gt;owner&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ForeignKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="n"&gt;tags&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ManyToManyField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;Tag&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TextField&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;&lt;strong&gt;Fetching Multiple Models at Once&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For our first example, assume we want to print a list of articles with the author&amp;#8217;s name. We could do the following:&lt;/p&gt;

&lt;figure class='code'&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;span class='line-number'&gt;2&lt;/span&gt;
&lt;span class='line-number'&gt;3&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class='python'&gt;&lt;span class='line'&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;article&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;Article&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;object&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;all&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="n"&gt;article&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="n"&gt;article&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;owner&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;How many SQL queries would this generate? Let&amp;#8217;s use &lt;code&gt;debugsqlshell&lt;/code&gt;:&lt;/p&gt;

&lt;figure class='code'&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;span class='line-number'&gt;2&lt;/span&gt;
&lt;span class='line-number'&gt;3&lt;/span&gt;
&lt;span class='line-number'&gt;4&lt;/span&gt;
&lt;span class='line-number'&gt;5&lt;/span&gt;
&lt;span class='line-number'&gt;6&lt;/span&gt;
&lt;span class='line-number'&gt;7&lt;/span&gt;
&lt;span class='line-number'&gt;8&lt;/span&gt;
&lt;span class='line-number'&gt;9&lt;/span&gt;
&lt;span class='line-number'&gt;10&lt;/span&gt;
&lt;span class='line-number'&gt;11&lt;/span&gt;
&lt;span class='line-number'&gt;12&lt;/span&gt;
&lt;span class='line-number'&gt;13&lt;/span&gt;
&lt;span class='line-number'&gt;14&lt;/span&gt;
&lt;span class='line-number'&gt;15&lt;/span&gt;
&lt;span class='line-number'&gt;16&lt;/span&gt;
&lt;span class='line-number'&gt;17&lt;/span&gt;
&lt;span class='line-number'&gt;18&lt;/span&gt;
&lt;span class='line-number'&gt;19&lt;/span&gt;
&lt;span class='line-number'&gt;20&lt;/span&gt;
&lt;span class='line-number'&gt;21&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class='python'&gt;&lt;span class='line'&gt;&lt;span class="n"&gt;SELECT&lt;/span&gt; &lt;span class="sb"&gt;`testapp_article`&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="sb"&gt;`id`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;       &lt;span class="sb"&gt;`testapp_article`&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="sb"&gt;`owner_id`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;       &lt;span class="sb"&gt;`testapp_article`&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="sb"&gt;`title`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;       &lt;span class="sb"&gt;`testapp_article`&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="sb"&gt;`content`&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="n"&gt;FROM&lt;/span&gt; &lt;span class="sb"&gt;`testapp_article`&lt;/span&gt;  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;0.13&lt;/span&gt;&lt;span class="n"&gt;ms&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="n"&gt;SELECT&lt;/span&gt; &lt;span class="sb"&gt;`auth_user`&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="sb"&gt;`id`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;       &lt;span class="sb"&gt;`auth_user`&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="sb"&gt;`username`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;       &lt;span class="sb"&gt;`auth_user`&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="sb"&gt;`first_name`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;       &lt;span class="sb"&gt;`auth_user`&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="sb"&gt;`last_name`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;       &lt;span class="sb"&gt;`auth_user`&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="sb"&gt;`email`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;       &lt;span class="sb"&gt;`auth_user`&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="sb"&gt;`password`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;       &lt;span class="sb"&gt;`auth_user`&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="sb"&gt;`is_staff`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;       &lt;span class="sb"&gt;`auth_user`&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="sb"&gt;`is_active`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;       &lt;span class="sb"&gt;`auth_user`&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="sb"&gt;`is_superuser`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;       &lt;span class="sb"&gt;`auth_user`&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="sb"&gt;`last_login`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;       &lt;span class="sb"&gt;`auth_user`&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="sb"&gt;`date_joined`&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="n"&gt;FROM&lt;/span&gt; &lt;span class="sb"&gt;`auth_user`&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="n"&gt;WHERE&lt;/span&gt; &lt;span class="sb"&gt;`auth_user`&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="sb"&gt;`id`&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;0.84&lt;/span&gt;&lt;span class="n"&gt;ms&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="n"&gt;etc&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;For each article, there will be a separate query to retrieve details about the user. We can avoid this by using &lt;code&gt;select_related&lt;/code&gt;, which tells
Django&amp;#8217;s ORM to select related models in the same query:&lt;/p&gt;

&lt;figure class='code'&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;span class='line-number'&gt;2&lt;/span&gt;
&lt;span class='line-number'&gt;3&lt;/span&gt;
&lt;span class='line-number'&gt;4&lt;/span&gt;
&lt;span class='line-number'&gt;5&lt;/span&gt;
&lt;span class='line-number'&gt;6&lt;/span&gt;
&lt;span class='line-number'&gt;7&lt;/span&gt;
&lt;span class='line-number'&gt;8&lt;/span&gt;
&lt;span class='line-number'&gt;9&lt;/span&gt;
&lt;span class='line-number'&gt;10&lt;/span&gt;
&lt;span class='line-number'&gt;11&lt;/span&gt;
&lt;span class='line-number'&gt;12&lt;/span&gt;
&lt;span class='line-number'&gt;13&lt;/span&gt;
&lt;span class='line-number'&gt;14&lt;/span&gt;
&lt;span class='line-number'&gt;15&lt;/span&gt;
&lt;span class='line-number'&gt;16&lt;/span&gt;
&lt;span class='line-number'&gt;17&lt;/span&gt;
&lt;span class='line-number'&gt;18&lt;/span&gt;
&lt;span class='line-number'&gt;19&lt;/span&gt;
&lt;span class='line-number'&gt;20&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class='python'&gt;&lt;span class='line'&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;article&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;Article&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;all&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;select_related&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="n"&gt;article&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;owner&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="n"&gt;SELECT&lt;/span&gt; &lt;span class="sb"&gt;`testapp_article`&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="sb"&gt;`id`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;       &lt;span class="sb"&gt;`testapp_article`&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="sb"&gt;`owner_id`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;       &lt;span class="sb"&gt;`testapp_article`&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="sb"&gt;`title`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;       &lt;span class="sb"&gt;`testapp_article`&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="sb"&gt;`content`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;       &lt;span class="sb"&gt;`auth_user`&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="sb"&gt;`id`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;       &lt;span class="sb"&gt;`auth_user`&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="sb"&gt;`username`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;       &lt;span class="sb"&gt;`auth_user`&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="sb"&gt;`first_name`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;       &lt;span class="sb"&gt;`auth_user`&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="sb"&gt;`last_name`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;       &lt;span class="sb"&gt;`auth_user`&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="sb"&gt;`email`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;       &lt;span class="sb"&gt;`auth_user`&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="sb"&gt;`password`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;       &lt;span class="sb"&gt;`auth_user`&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="sb"&gt;`is_staff`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;       &lt;span class="sb"&gt;`auth_user`&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="sb"&gt;`is_active`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;       &lt;span class="sb"&gt;`auth_user`&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="sb"&gt;`is_superuser`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;       &lt;span class="sb"&gt;`auth_user`&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="sb"&gt;`last_login`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;       &lt;span class="sb"&gt;`auth_user`&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="sb"&gt;`date_joined`&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="n"&gt;FROM&lt;/span&gt; &lt;span class="sb"&gt;`testapp_article`&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="n"&gt;INNER&lt;/span&gt; &lt;span class="n"&gt;JOIN&lt;/span&gt; &lt;span class="sb"&gt;`auth_user`&lt;/span&gt; &lt;span class="n"&gt;ON&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sb"&gt;`testapp_article`&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="sb"&gt;`owner_id`&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sb"&gt;`auth_user`&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="sb"&gt;`id`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;0.39&lt;/span&gt;&lt;span class="n"&gt;ms&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;Here, we see that the article&amp;#8217;s owner is retrieved using the &lt;code&gt;JOIN&lt;/code&gt; clause. So in this example, use of &lt;code&gt;select_related&lt;/code&gt; has halved the number of queries executed.&lt;/p&gt;

&lt;p&gt;One thing that should be remembered about &lt;code&gt;select_related&lt;/code&gt; is that &lt;em&gt;it does not work for many-to-many fields&lt;/em&gt;.
In our example, that means that article tags would not be fetched in a single query.
For these model attributes, there is a new method included in Django 1.4 called &lt;code&gt;prefetch_related&lt;/code&gt;. Django 1.4 is currently an alpha release, &lt;a href="https://www.djangoproject.com/download/"&gt;download it here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Let&amp;#8217;s look at how &lt;code&gt;prefetch_related&lt;/code&gt; reduces the number of queries with our example classes. First, observe what happens if we access article tags without prefetching:&lt;/p&gt;

&lt;figure class='code'&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;span class='line-number'&gt;2&lt;/span&gt;
&lt;span class='line-number'&gt;3&lt;/span&gt;
&lt;span class='line-number'&gt;4&lt;/span&gt;
&lt;span class='line-number'&gt;5&lt;/span&gt;
&lt;span class='line-number'&gt;6&lt;/span&gt;
&lt;span class='line-number'&gt;7&lt;/span&gt;
&lt;span class='line-number'&gt;8&lt;/span&gt;
&lt;span class='line-number'&gt;9&lt;/span&gt;
&lt;span class='line-number'&gt;10&lt;/span&gt;
&lt;span class='line-number'&gt;11&lt;/span&gt;
&lt;span class='line-number'&gt;12&lt;/span&gt;
&lt;span class='line-number'&gt;13&lt;/span&gt;
&lt;span class='line-number'&gt;14&lt;/span&gt;
&lt;span class='line-number'&gt;15&lt;/span&gt;
&lt;span class='line-number'&gt;16&lt;/span&gt;
&lt;span class='line-number'&gt;17&lt;/span&gt;
&lt;span class='line-number'&gt;18&lt;/span&gt;
&lt;span class='line-number'&gt;19&lt;/span&gt;
&lt;span class='line-number'&gt;20&lt;/span&gt;
&lt;span class='line-number'&gt;21&lt;/span&gt;
&lt;span class='line-number'&gt;22&lt;/span&gt;
&lt;span class='line-number'&gt;23&lt;/span&gt;
&lt;span class='line-number'&gt;24&lt;/span&gt;
&lt;span class='line-number'&gt;25&lt;/span&gt;
&lt;span class='line-number'&gt;26&lt;/span&gt;
&lt;span class='line-number'&gt;27&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class='python'&gt;&lt;span class='line'&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;article&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;Article&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;all&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;select_related&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="n"&gt;article&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tags&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;all&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;   &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="n"&gt;SELECT&lt;/span&gt; &lt;span class="sb"&gt;`testapp_article`&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="sb"&gt;`id`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;       &lt;span class="sb"&gt;`testapp_article`&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="sb"&gt;`owner_id`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;       &lt;span class="sb"&gt;`testapp_article`&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="sb"&gt;`content`&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="n"&gt;FROM&lt;/span&gt; &lt;span class="sb"&gt;`testapp_article`&lt;/span&gt;  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;0.50&lt;/span&gt;&lt;span class="n"&gt;ms&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="n"&gt;SELECT&lt;/span&gt; &lt;span class="sb"&gt;`testapp_tag`&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="sb"&gt;`id`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;       &lt;span class="sb"&gt;`testapp_tag`&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="sb"&gt;`name`&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="n"&gt;FROM&lt;/span&gt; &lt;span class="sb"&gt;`testapp_tag`&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="n"&gt;INNER&lt;/span&gt; &lt;span class="n"&gt;JOIN&lt;/span&gt; &lt;span class="sb"&gt;`testapp_article_tags`&lt;/span&gt; &lt;span class="n"&gt;ON&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sb"&gt;`testapp_tag`&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="sb"&gt;`id`&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sb"&gt;`testapp_article_tags`&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="sb"&gt;`tag_id`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="n"&gt;WHERE&lt;/span&gt; &lt;span class="sb"&gt;`testapp_article_tags`&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="sb"&gt;`article_id`&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="n"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;21&lt;/span&gt;  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;1.36&lt;/span&gt;&lt;span class="n"&gt;ms&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Tag&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Tag&lt;/span&gt; &lt;span class="nb"&gt;object&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Tag&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Tag&lt;/span&gt; &lt;span class="nb"&gt;object&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="n"&gt;SELECT&lt;/span&gt; &lt;span class="sb"&gt;`testapp_tag`&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="sb"&gt;`id`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;       &lt;span class="sb"&gt;`testapp_tag`&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="sb"&gt;`name`&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="n"&gt;FROM&lt;/span&gt; &lt;span class="sb"&gt;`testapp_tag`&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="n"&gt;INNER&lt;/span&gt; &lt;span class="n"&gt;JOIN&lt;/span&gt; &lt;span class="sb"&gt;`testapp_article_tags`&lt;/span&gt; &lt;span class="n"&gt;ON&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sb"&gt;`testapp_tag`&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="sb"&gt;`id`&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sb"&gt;`testapp_article_tags`&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="sb"&gt;`tag_id`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="n"&gt;WHERE&lt;/span&gt; &lt;span class="sb"&gt;`testapp_article_tags`&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="sb"&gt;`article_id`&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="n"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;21&lt;/span&gt;  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;0.36&lt;/span&gt;&lt;span class="n"&gt;ms&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Tag&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Tag&lt;/span&gt; &lt;span class="nb"&gt;object&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Tag&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Tag&lt;/span&gt; &lt;span class="nb"&gt;object&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="n"&gt;SELECT&lt;/span&gt; &lt;span class="sb"&gt;`testapp_tag`&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="sb"&gt;`id`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;       &lt;span class="sb"&gt;`testapp_tag`&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="sb"&gt;`name`&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="n"&gt;FROM&lt;/span&gt; &lt;span class="sb"&gt;`testapp_tag`&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="n"&gt;INNER&lt;/span&gt; &lt;span class="n"&gt;JOIN&lt;/span&gt; &lt;span class="sb"&gt;`testapp_article_tags`&lt;/span&gt; &lt;span class="n"&gt;ON&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sb"&gt;`testapp_tag`&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="sb"&gt;`id`&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sb"&gt;`testapp_article_tags`&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="sb"&gt;`tag_id`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="n"&gt;WHERE&lt;/span&gt; &lt;span class="sb"&gt;`testapp_article_tags`&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="sb"&gt;`article_id`&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="n"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;21&lt;/span&gt;  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;0.36&lt;/span&gt;&lt;span class="n"&gt;ms&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;Separate queries are generated to retrieve the tags. And now with tag prefetching:&lt;/p&gt;

&lt;figure class='code'&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;span class='line-number'&gt;2&lt;/span&gt;
&lt;span class='line-number'&gt;3&lt;/span&gt;
&lt;span class='line-number'&gt;4&lt;/span&gt;
&lt;span class='line-number'&gt;5&lt;/span&gt;
&lt;span class='line-number'&gt;6&lt;/span&gt;
&lt;span class='line-number'&gt;7&lt;/span&gt;
&lt;span class='line-number'&gt;8&lt;/span&gt;
&lt;span class='line-number'&gt;9&lt;/span&gt;
&lt;span class='line-number'&gt;10&lt;/span&gt;
&lt;span class='line-number'&gt;11&lt;/span&gt;
&lt;span class='line-number'&gt;12&lt;/span&gt;
&lt;span class='line-number'&gt;13&lt;/span&gt;
&lt;span class='line-number'&gt;14&lt;/span&gt;
&lt;span class='line-number'&gt;15&lt;/span&gt;
&lt;span class='line-number'&gt;16&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class='python'&gt;&lt;span class='line'&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;article&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;Article&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;all&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;prefetch_related&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;tags&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="n"&gt;article&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tags&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;all&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;   &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="n"&gt;SELECT&lt;/span&gt; &lt;span class="sb"&gt;`testapp_article`&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="sb"&gt;`id`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;       &lt;span class="sb"&gt;`testapp_article`&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="sb"&gt;`owner_id`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;       &lt;span class="sb"&gt;`testapp_article`&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="sb"&gt;`content`&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="n"&gt;FROM&lt;/span&gt; &lt;span class="sb"&gt;`testapp_article`&lt;/span&gt;  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;0.21&lt;/span&gt;&lt;span class="n"&gt;ms&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="n"&gt;SELECT&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sb"&gt;`testapp_article_tags`&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="sb"&gt;`article_id`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;AS&lt;/span&gt; &lt;span class="sb"&gt;`_prefetch_related_val`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;       &lt;span class="sb"&gt;`testapp_tag`&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="sb"&gt;`id`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;       &lt;span class="sb"&gt;`testapp_tag`&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="sb"&gt;`name`&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="n"&gt;FROM&lt;/span&gt; &lt;span class="sb"&gt;`testapp_tag`&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="n"&gt;INNER&lt;/span&gt; &lt;span class="n"&gt;JOIN&lt;/span&gt; &lt;span class="sb"&gt;`testapp_article_tags`&lt;/span&gt; &lt;span class="n"&gt;ON&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sb"&gt;`testapp_tag`&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="sb"&gt;`id`&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sb"&gt;`testapp_article_tags`&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="sb"&gt;`tag_id`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="n"&gt;WHERE&lt;/span&gt; &lt;span class="sb"&gt;`testapp_article_tags`&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="sb"&gt;`article_id`&lt;/span&gt; &lt;span class="n"&gt;IN&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;                                              &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;                                              &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;121.34&lt;/span&gt;&lt;span class="n"&gt;ms&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;As we can see, all tags are fetched in a singlee query using an &lt;code&gt;IN&lt;/code&gt; statement. So, &lt;code&gt;select_related&lt;/code&gt; and &lt;code&gt;prefetch_related&lt;/code&gt; are two effective ways of reducing the number of queries needed for accessing models.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Other techniques for reducing generated queries&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you find that your models are too complex to benefit from the above methods, you can always start writing your own SQL. Of course, this comes with the usual disclaimers: your code may be less portable between databases, and may be harder to maintain.&lt;/p&gt;

&lt;p&gt;One method of doing this is to use the &lt;code&gt;extra()&lt;/code&gt; method on a queryset like so:&lt;/p&gt;

&lt;figure class='code'&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class='python'&gt;&lt;span class='line'&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;article&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;Article&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;all&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;extra&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;raw SQL here&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;This can be useful if you need, for example, a nested &lt;code&gt;SELECT&lt;/code&gt; clause. The other option is to use raw queries, which are &lt;a href="https://docs.djangoproject.com/en/dev/topics/db/sql/"&gt;documented here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;One last point worth mentioning is to be careful with the use of &lt;code&gt;iterator()&lt;/code&gt;, which loads only a subset of a query set into memory. If you then iterate over this queryset, this can generate lots of queries. Here&amp;#8217;s a &lt;a href="http://seeknuance.com/2010/12/10/a-performance-lesson-on-django-querysets/"&gt;longer discussion&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Hopefully this post has provided a useful discussion of query generation in Django and how you can optimise database access in your application.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;ll close with a couple of useful resources: some useful tips on &lt;a href="http://www.ibm.com/developerworks/opensource/library/os-django-models/index.html"&gt;writing performant models&lt;/a&gt;, and the &lt;a href="https://docs.djangoproject.com/en/dev/topics/db/optimization/"&gt;official django optimization page&lt;/a&gt;.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/BlueprintForge/~4/GAsF_4tyX3M" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://blueprintforge.com/blog/2012/01/24/measuring-optimising-database-performance-in-django/</feedburner:origLink></entry>
  
  <entry>
    <title type="html"><![CDATA[Remote Debugging Django Applications with Pydevd]]></title>
    <link href="http://feedproxy.google.com/~r/BlueprintForge/~3/yvvqRQQjW9A/" />
    <updated>2012-01-16T13:32:00+00:00</updated>
    <id>http://blueprintforge.com/blog/2012/01/16/remote-debugging-django-mod-wsgi-applications</id>
    <content type="html">&lt;p&gt;&lt;em&gt;Important disclaimer: enabling remote debugging of applications is a potential security risk. The following
method should only be used in a development environment, and on a network you control. Use at your own risk.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Most django application issues can be successfully debugged using a local &lt;code&gt;runserver&lt;/code&gt; instance on your development
machine. But there are times when it is advantageous to be able to debug your application in an environment
that more closely resembles production.&lt;/p&gt;

&lt;p&gt;For instance, I recently encountered a caching issue that was caused by an incorrect &lt;code&gt;Cache-Control&lt;/code&gt; header. The fault was
at the application level, and it was useful to be able to trace the request/response behaviour in the full context
of the web stack.&lt;/p&gt;

&lt;p&gt;This post discusses debugging django, but the same technique can be used to debug any &lt;code&gt;mod_wsgi&lt;/code&gt; application.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Environments and Remote Debugging&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;On my development machine, a set of VMs replicates the web stack. This includes load balancer,
web cache, application server, and database machine. &lt;code&gt;runserver&lt;/code&gt; is used to test the application locally, then I use &lt;a href="http://docs.fabfile.org/en/1.3.3/index.html"&gt;fabric&lt;/a&gt; to push code to the local VMs.&lt;/p&gt;

&lt;p&gt;To debug code when it is running on the server, you can use Aptana&amp;#8217;s &lt;a href="http://pydev.org/"&gt;Pydev&lt;/a&gt; plugin for Eclipse.
This allows you to run a debug session on your local machine which listens for connections. With the correct
setup on your application server, you can step through your application as if it were running locally.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://blueprintforge.com/images/debug.png" alt="Screenshot of pydev remote debugger running in eclipse" /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Setup&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;First, the pydev debugger needs to be accessible to your application. You could use a shared filesystem for this, or you could
clone the &lt;a href="https://github.com/aptana/Pydev"&gt;github repository&lt;/a&gt; (though in theory this might introduce compatibility issues). Whichever method you choose, the
pydevd module needs to be added to &lt;code&gt;$PYTHONPATH&lt;/code&gt;, which is done in your wsgi file.
See the &lt;a href="https://docs.djangoproject.com/en/dev/howto/deployment/wsgi/"&gt;django documentation on deployment with wsgi&lt;/a&gt; if you haven&amp;#8217;t yet created this.&lt;/p&gt;

&lt;figure class='code'&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;span class='line-number'&gt;2&lt;/span&gt;
&lt;span class='line-number'&gt;3&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class='python'&gt;&lt;span class='line'&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;sys&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="c"&gt;# append location of pydev module to $PYTHONPATH&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;srv/site/plugins/org.python.pydev.debug_2.2.4.2011110216/pysrc/&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;After that, invoking the &lt;code&gt;pydevd&lt;/code&gt; debugger is simple:&lt;/p&gt;

&lt;figure class='code'&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;span class='line-number'&gt;2&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class='python'&gt;&lt;span class='line'&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;pydevd&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="n"&gt;pydevd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;settrace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IP_ADDRESS&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;Where &lt;code&gt;IP_ADDRESS&lt;/code&gt; is the IP address of machine where you are running Eclipse. You can omit this if you are running
both Eclipse and Apache on the same host.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ensuring Eclipse has Access to Application Code&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The last thing to do is to ensure that the debugger can display the source code it is stepping through. This is done by modifying &lt;code&gt;pydevd_file_utils.py&lt;/code&gt; on your server like so:&lt;/p&gt;

&lt;figure class='code'&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class='python'&gt;&lt;span class='line'&gt;&lt;span class="n"&gt;PATHS_FROM_ECLIPSE_TO_PYTHON&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[(&lt;/span&gt;&lt;span class="s"&gt;r&amp;#39;/home/matt/site&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;r&amp;#39;/srv/site&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;The first element of the tuple is the path to the source code on the host where Eclipse is
running. The second element gives the
location on the application server. If you don&amp;#8217;t do this, Eclipse will prompt you for the location of the source files when
the debug session starts.&lt;/p&gt;

&lt;p&gt;Once your Eclipse debug session is listening for connections, make sure you have reloaded your application:&lt;/p&gt;

&lt;figure class='code'&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class='bash'&gt;&lt;span class='line'&gt;service apache2 reload
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;Now, just visit the site in your browser. You should see the pydev debugger receive the
connection and spring into action.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Remote debugging is relatively simple to set up, and can be extremely useful for debugging certain issues.&lt;/p&gt;

&lt;p&gt;To organise the code changes shown above, it might be helpful to create a remote-debug branch containing the necessary changes to your wsgi file. Since you won&amp;#8217;t be
developing on this branch, merging master periodically should incur minimal overhead.&lt;/p&gt;

&lt;p&gt;There are a host of other debugging methods for &lt;code&gt;mod_wsgi&lt;/code&gt;, including interactive command-line debugger and a browser-based shell. These are &lt;a href="http://code.google.com/p/modwsgi/wiki/DebuggingTechniques"&gt;described in the mod_wsgi documentation&lt;/a&gt;. There&amp;#8217;s also a good discussion of how you can set up &lt;a href="https://groups.google.com/d/topic/modwsgi/_ZN1GDQ4BHw/discussion"&gt;single and multi-threaded debugging on the mod_wsgi Google Group&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You may also want to view the &lt;a href="http://pydev.org/manual_adv_remote_debugger.html"&gt;pydev documentation on remote debugging&lt;/a&gt;, which was used in writing this article.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/BlueprintForge/~4/yvvqRQQjW9A" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://blueprintforge.com/blog/2012/01/16/remote-debugging-django-mod-wsgi-applications/</feedburner:origLink></entry>
  
  <entry>
    <title type="html"><![CDATA[Python: Injecting Mock Objects for Powerful Testing]]></title>
    <link href="http://feedproxy.google.com/~r/BlueprintForge/~3/O9KV3qGXR2M/" />
    <updated>2012-01-08T11:10:00+00:00</updated>
    <id>http://blueprintforge.com/blog/2012/01/08/python-injecting-mock-objects-for-powerful-testing</id>
    <content type="html">&lt;p&gt;&lt;em&gt;The code discussed in this post can be &lt;a href="https://github.com/MattCottingham/pyclientauth/"&gt;found in the github repository&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;While writing a module to handle Google ClientLogin recently, I wanted to test error handling by simulating error
responses from the server. A simple but powerful way of doing this is to use the
&lt;a href="http://pypi.python.org/pypi/mock"&gt;patching ability&lt;/a&gt; of the &lt;code&gt;mock&lt;/code&gt; module.&lt;/p&gt;

&lt;p&gt;The patching ability allows you to replace objects in scope with mocks so that different side effects or return values can be defined. Note that &amp;#8216;object&amp;#8217; is used here in the pythonic sense &amp;#8211; referring to entities such as modules and functions as well as class instances.&lt;/p&gt;

&lt;p&gt;This is best illustrated by a real example, so in this post we&amp;#8217;re going to mock the &lt;code&gt;requests&lt;/code&gt; module and generate
the exceptions described in the
&lt;a href="http://docs.python-requests.org/en/latest/user/quickstart/#errors-and-exceptions"&gt;documentation&lt;/a&gt; when a request is made.&lt;/p&gt;

&lt;p&gt;Our example module sends credentials to Google&amp;#8217;s ClientLogin service in order to receive an authentication token, required for accessing certain Google services (such as C2DM). If you are interested, you can read more about ClientLogin on the &lt;a href="http://code.google.com/apis/accounts/docs/AuthForInstalledApps.html"&gt;Google Code page&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So, to request an authentication token from the ClientLogin service, you &lt;code&gt;POST&lt;/code&gt; a set of parameters including email and password to the service endpoint. Here is a cut-down version of the code that initiates the authentication request:&lt;/p&gt;

&lt;figure class='code'&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;span class='line-number'&gt;2&lt;/span&gt;
&lt;span class='line-number'&gt;3&lt;/span&gt;
&lt;span class='line-number'&gt;4&lt;/span&gt;
&lt;span class='line-number'&gt;5&lt;/span&gt;
&lt;span class='line-number'&gt;6&lt;/span&gt;
&lt;span class='line-number'&gt;7&lt;/span&gt;
&lt;span class='line-number'&gt;8&lt;/span&gt;
&lt;span class='line-number'&gt;9&lt;/span&gt;
&lt;span class='line-number'&gt;10&lt;/span&gt;
&lt;span class='line-number'&gt;11&lt;/span&gt;
&lt;span class='line-number'&gt;12&lt;/span&gt;
&lt;span class='line-number'&gt;13&lt;/span&gt;
&lt;span class='line-number'&gt;14&lt;/span&gt;
&lt;span class='line-number'&gt;15&lt;/span&gt;
&lt;span class='line-number'&gt;16&lt;/span&gt;
&lt;span class='line-number'&gt;17&lt;/span&gt;
&lt;span class='line-number'&gt;18&lt;/span&gt;
&lt;span class='line-number'&gt;19&lt;/span&gt;
&lt;span class='line-number'&gt;20&lt;/span&gt;
&lt;span class='line-number'&gt;21&lt;/span&gt;
&lt;span class='line-number'&gt;22&lt;/span&gt;
&lt;span class='line-number'&gt;23&lt;/span&gt;
&lt;span class='line-number'&gt;24&lt;/span&gt;
&lt;span class='line-number'&gt;25&lt;/span&gt;
&lt;span class='line-number'&gt;26&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class='python'&gt;&lt;span class='line'&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Authenticator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;object&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="nd"&gt;@staticmethod&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;generate_token&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;                       &lt;span class="n"&gt;account_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;GOOGLE&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;ac2dm&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;        &lt;span class="sd"&gt;&amp;quot;&amp;quot;&amp;quot;Returns an auth token for the supplied service.&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;        &lt;span class="n"&gt;base_url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;https://www.google.com/accounts/ClientLogin&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;        &lt;span class="n"&gt;headers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;            &lt;span class="s"&gt;&amp;#39;content-type&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;application/x-www-form-urlencoded&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;        &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;        &lt;span class="n"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;            &lt;span class="s"&gt;&amp;#39;Email&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;            &lt;span class="s"&gt;&amp;#39;Passwd&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;            &lt;span class="s"&gt;&amp;#39;source&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;            &lt;span class="s"&gt;&amp;#39;accountType&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;account_type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;            &lt;span class="s"&gt;&amp;#39;service&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;        &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;        &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;            &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;base_url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;        &lt;span class="k"&gt;except&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;RequestException&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;            &lt;span class="k"&gt;raise&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;If the &lt;code&gt;requests.post&lt;/code&gt; method throws an exception, we simply &lt;code&gt;raise&lt;/code&gt; it to the caller rather than handling it immediately.
In the &lt;code&gt;requests&lt;/code&gt; module, &lt;code&gt;RequestException&lt;/code&gt; is the base class from which others (like &lt;code&gt;ConnectionError&lt;/code&gt;) inherit. We could improve our approach to exception handling but it is sufficient for this example.&lt;/p&gt;

&lt;p&gt;These exceptions will be thrown from our mocked class, which is patched into the above code using a context manager:&lt;/p&gt;

&lt;figure class='code'&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;span class='line-number'&gt;2&lt;/span&gt;
&lt;span class='line-number'&gt;3&lt;/span&gt;
&lt;span class='line-number'&gt;4&lt;/span&gt;
&lt;span class='line-number'&gt;5&lt;/span&gt;
&lt;span class='line-number'&gt;6&lt;/span&gt;
&lt;span class='line-number'&gt;7&lt;/span&gt;
&lt;span class='line-number'&gt;8&lt;/span&gt;
&lt;span class='line-number'&gt;9&lt;/span&gt;
&lt;span class='line-number'&gt;10&lt;/span&gt;
&lt;span class='line-number'&gt;11&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class='python'&gt;&lt;span class='line'&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;unittest2&lt;/span&gt; &lt;span class="kn"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;unittest&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;requests.exceptions&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;RequestException&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ConnectionError&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;mock&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;patch&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;clientlogin&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Authenticator&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AuthenticationTests&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;unittest&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TestCase&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_connection_error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;        &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;patch&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;object&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;post&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;mock_method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;            &lt;span class="n"&gt;mock_method&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;side_effect&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ConnectionError&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;            &lt;span class="n"&gt;Authenticator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;generate_token&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;mail@example.com&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;password&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;tag&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;Here, we have patched the &lt;code&gt;post&lt;/code&gt; method in the &lt;code&gt;requests&lt;/code&gt; module to throw a &lt;code&gt;ConnectionError&lt;/code&gt;. You can think of this like code injection, where &lt;code&gt;with&lt;/code&gt; acts as the closure.&lt;/p&gt;

&lt;p&gt;In the real test method, we assert the exception was raised with another context manager:&lt;/p&gt;

&lt;figure class='code'&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;span class='line-number'&gt;2&lt;/span&gt;
&lt;span class='line-number'&gt;3&lt;/span&gt;
&lt;span class='line-number'&gt;4&lt;/span&gt;
&lt;span class='line-number'&gt;5&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class='python'&gt;&lt;span class='line'&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_connection_error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;patch&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;object&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;post&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;mock_method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;        &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;assertRaises&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;RequestException&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;            &lt;span class="n"&gt;mock_method&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;side_effect&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ConnectionError&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;            &lt;span class="n"&gt;Authenticator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;generate_token&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;mail@example.com&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;password&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;tag&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;Here, we assert that the &lt;code&gt;ConnectionError&lt;/code&gt; exception is raised to the caller, but we could easily have asserted a different condition. We could, for instance, have verified some exception handling logic.&lt;/p&gt;

&lt;p&gt;As we&amp;#8217;ve seen, mocking objects and methods in this manner is a simple but powerful way of running your code under different simulated conditions, allowing thorough testing of error-handling logic.&lt;/p&gt;

&lt;p&gt;You can see the full module including tests and usage instructions at the &lt;a href="https://github.com/MattCottingham/pyclientauth/"&gt;github repository&lt;/a&gt;. For more information on the &lt;code&gt;mock&lt;/code&gt; module, the &lt;a href="http://www.voidspace.org.uk/python/mock/"&gt;full documentation&lt;/a&gt; is available.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/BlueprintForge/~4/O9KV3qGXR2M" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://blueprintforge.com/blog/2012/01/08/python-injecting-mock-objects-for-powerful-testing/</feedburner:origLink></entry>
  
  <entry>
    <title type="html"><![CDATA[A Short Explanation of Hypermedia Controls in RESTful services]]></title>
    <link href="http://feedproxy.google.com/~r/BlueprintForge/~3/6H9wAMRwcIc/" />
    <updated>2012-01-01T16:07:00+00:00</updated>
    <id>http://blueprintforge.com/blog/2012/01/01/a-short-explanation-of-hypermedia-controls-in-restful-services</id>
    <content type="html">&lt;p&gt;This article roughly follows on from my &lt;a href="http://www.blueprintforge.com/blog/2011/12/13/some-thoughts-on-rest/"&gt;previous post&lt;/a&gt; on REST, which discusses some points relating to the first two levels of the Richardson Maturity Model. Since we&amp;#8217;re only going to discuss the top level of the model in this post (shown below), the other levels are greyed out.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://blueprintforge.com/images/rmmlevel3.png" alt="Diagram of the Richardson Maturity Model showing three elements of RESTful services: resources, http verbs and hypermedia controls" /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Introducing Hypermedia Controls&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Hypermedia as the Engine of Application State&lt;/em&gt; (HATEOAS) is an element of the REST architectural style, which describes how a consumer can control a given web application using &lt;em&gt;hypermedia controls&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Let&amp;#8217;s cut straight to the chase: what do we mean by hypermedia controls?&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;When I say hypertext, I mean the simultaneous presentation of information and controls such that the information becomes the affordance through which the user (or automaton) obtains choices and selects actions&amp;#8230; Hypertext does not need to be HTML on a browser. Machines can follow links when they understand the data format and relationship types.
&amp;#8211;&lt;a href="http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven#comment-718"&gt;Roy Fielding&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;This explanation, from Roy Fielding&amp;#8217;s widely cited blog post &lt;a href="http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven"&gt;REST APIs must be Hypertext driven&lt;/a&gt; mentions the &amp;#8220;simultaneous presentation of information and controls&amp;#8221;. To simplify, we can imagine a hyperlink that our consumer is able to understand and manipulate.&lt;/p&gt;

&lt;p&gt;So that&amp;#8217;s the first word of HATEOAS. What does &amp;#8220;Engine of Application State&amp;#8221; mean? Quite literally, it means that the hyperlinks mentioned above can be used to control (drive) the web application. If you haven&amp;#8217;t already drawn a state machine for your application, now&amp;#8217;s the time!&lt;/p&gt;

&lt;p&gt;Take, for instance, a RESTful webservice that allows virtual machines to be controlled. The &lt;a href="http://kenai.com/projects/suncloudapis/pages/CloudAPIVMRequests#Control_VM"&gt;Sun Cloud API&lt;/a&gt; is one example of such a service &amp;#8211; the examples below are based loosely on the format it uses. If a given virtual machine is stopped, it be may started. Or, if a machine is already running, it may be stopped.&lt;/p&gt;

&lt;p&gt;Example request for a machine representation:&lt;/p&gt;

&lt;figure class='code'&gt;&lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;span class='line-number'&gt;2&lt;/span&gt;
&lt;span class='line-number'&gt;3&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class=''&gt;&lt;span class='line'&gt;GET /machines/1/
&lt;/span&gt;&lt;span class='line'&gt;Host: example.com
&lt;/span&gt;&lt;span class='line'&gt;Accept: application/xml&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;Example response:&lt;/p&gt;

&lt;figure class='code'&gt;&lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;span class='line-number'&gt;2&lt;/span&gt;
&lt;span class='line-number'&gt;3&lt;/span&gt;
&lt;span class='line-number'&gt;4&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class=''&gt;&lt;span class='line'&gt;HTTP/1.1 200 OK
&lt;/span&gt;&lt;span class='line'&gt;Content-Type: application/xml
&lt;/span&gt;&lt;span class='line'&gt;&amp;lt;status&amp;gt;stopped&amp;lt;/status&amp;gt;
&lt;/span&gt;&lt;span class='line'&gt;&amp;lt;link rel="start" method="post" href="machines/2?op=start" /&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;Note the &lt;code&gt;link&lt;/code&gt; tag. This is a hypermedia control which tells the consumer how it could start the VM by POSTing to &lt;code&gt;machines/{id}?op=start&lt;/code&gt;. (For simplicity I&amp;#8217;ve omitted necessary details such as Content-Length and xml schema declaration.)&lt;/p&gt;

&lt;p&gt;If the requested VM is running, the response would be:&lt;/p&gt;

&lt;figure class='code'&gt;&lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;span class='line-number'&gt;2&lt;/span&gt;
&lt;span class='line-number'&gt;3&lt;/span&gt;
&lt;span class='line-number'&gt;4&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class=''&gt;&lt;span class='line'&gt;HTTP/1.1 200 OK
&lt;/span&gt;&lt;span class='line'&gt;Content-Type: application/xml
&lt;/span&gt;&lt;span class='line'&gt;&amp;lt;status&amp;gt;running&amp;lt;/status&amp;gt;
&lt;/span&gt;&lt;span class='line'&gt;&amp;lt;link rel="stop" method="post" href="machines/2?op=stop" /&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;When our VM is running, the resource at &lt;code&gt;machines/1/&lt;/code&gt; contains a &lt;code&gt;rel&lt;/code&gt; link to stop it. Both methods would probably return &lt;code&gt;201 Accepted&lt;/code&gt; in the case of success, as it is unlikely they would run synchronously.&lt;/p&gt;

&lt;p&gt;In a nutshell, this is the concept of HATEOAS &amp;#8211; these hypermedia resources allow us to control application state.&lt;/p&gt;

&lt;p&gt;Note that the operation type in the query parameter could also have been a separate resource (such as &lt;code&gt;machines/1/stop&lt;/code&gt;). There are arguments for either approach but it isn&amp;#8217;t necessary to delve into this to understand the concept of HATEOAS.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why Hypermedia Controls are Important&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In the example above, the representation of a resource also gives us a way to manipulate the resource. In this way, HATEOAS allows certain aspects of the application to be self-describing, fostering loose coupling between service and consumer. If we consider that a service may evolve over time, then this loose coupling could allow the client to evolve with fewer issues than if all controls were hard-coded.&lt;/p&gt;

&lt;p&gt;A useful resource that covers this in more detail is Wayne Lee&amp;#8217;s presentation &lt;a href="http://www.slideshare.net/trilancer/why-hateoas-1547275"&gt;&lt;em&gt;Why HATEOAS&lt;/em&gt;&lt;/a&gt;. Craig McClanahan also &lt;a href="http://blogs.oracle.com/craigmcc/entry/why_hateoas"&gt;discusses&lt;/a&gt; the benefits of HATEOAS for service discovery and integration.&lt;/p&gt;

&lt;p&gt;This post has necessarily glossed over many details of how HATEOAS is implemented, but has hopefully served as a useful introduction to the notion. I recommend &lt;a href="http://www.amazon.co.uk/gp/product/0596805829/ref=as_li_ss_tl?ie=UTF8&amp;amp;tag=blueprintforg-21&amp;amp;linkCode=as2&amp;amp;camp=1634&amp;amp;creative=19450&amp;amp;creativeASIN=0596805829"&gt;REST in Practice&lt;/a&gt; as a resource for going into the subject in more detail. Additionally, the &lt;a href="http://www.amazon.co.uk/gp/product/0596801688/ref=as_li_ss_tl?ie=UTF8&amp;amp;tag=blueprintforg-21&amp;amp;linkCode=as2&amp;amp;camp=1634&amp;amp;creative=19450&amp;amp;creativeASIN=0596801688"&gt;RESTful Services Cookbook&lt;/a&gt; contains details on implementation.&lt;/p&gt;

&lt;p&gt;Further sources:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven"&gt;Roy Fielding: Rest APIs must be Hypermedia Driven&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blog.ianbicking.org/2008/10/24/hypertext-driven-urls/"&gt;Ian Bicking on Hypertext Driven URLs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blog.steveklabnik.com/2011/08/07/some-people-understand-rest-and-http.html"&gt;REST and HATEOAS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://stackoverflow.com/questions/1164154/is-that-rest-api-really-rpc-roy-fielding-seems-to-think-so"&gt;Interesting Stack Overflow discussion&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;img src="http://feeds.feedburner.com/~r/BlueprintForge/~4/6H9wAMRwcIc" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://blueprintforge.com/blog/2012/01/01/a-short-explanation-of-hypermedia-controls-in-restful-services/</feedburner:origLink></entry>
  
  <entry>
    <title type="html"><![CDATA[Some Thoughts on REST]]></title>
    <link href="http://feedproxy.google.com/~r/BlueprintForge/~3/ORuJsrr7-Zg/" />
    <updated>2011-12-13T12:41:00+00:00</updated>
    <id>http://blueprintforge.com/blog/2011/12/13/some-thoughts-on-rest</id>
    <content type="html">&lt;p&gt;This article is in two parts. It started with the wish to talk mostly about hypermedia controls, but I decided it would be better to do a preceding post covering some more foundational notes on building a RESTful service.&lt;/p&gt;

&lt;p&gt;Recently there&amp;#8217;s been plenty of discussion about service platforms &amp;#8211; Steve Yegge&amp;#8217;s &lt;a href="https://plus.google.com/110981030061712822816/posts/AaygmbzVeRq"&gt;accidental post&lt;/a&gt; on Google Plus springs most prominently to mind. This article is partly motivated by these discussions, but it&amp;#8217;s also a product of my own experience designing, implementing, and consuming services. I&amp;#8217;ll include resources I&amp;#8217;ve found useful when working on RESTful services.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;m going to assume basic familiarity with REST, so you may find &lt;a href="http://www.infoq.com/articles/rest-introduction"&gt;this introduction&lt;/a&gt; helpful if you need a place to start.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Using the Richardson Maturity Model as a Guide&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The Richardson Maturity Model is a layered approach to REST. Aside from sounding like a psychological evaluation, it&amp;#8217;s a helpful way of envisioning the different elements that will comprise your service, and how they are composed.&lt;/p&gt;

&lt;p&gt;In essence, the model can be described as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The first level concerns implementing URIs for each resource (like /pizzas/1).&lt;/li&gt;
&lt;li&gt;The second level details how to interact with resources through HTTP methods (GET, POST, PUT, DELETE&amp;#8230;). You can think of this like CRUD operations for resources, though we&amp;#8217;ll discuss later how that doesn&amp;#8217;t quite suffice.&lt;/li&gt;
&lt;li&gt;Finally, the slightly mysterious &amp;#8220;hypermedia controls&amp;#8221; level. I&amp;#8217;ll cover this in a second article, which is why it is greyed out in the diagram.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;&lt;img src="http://blueprintforge.com/images/rmmlevel2.png" alt="Diagram of the Richardson Maturity Model showing three elements of RESTful services: resources, http verbs and hypermedia controls" /&gt;&lt;/p&gt;

&lt;p&gt;I highly recommend you read Martin Fowler&amp;#8217;s &lt;a href="http://martinfowler.com/articles/richardsonMaturityModel.html"&gt;full article&lt;/a&gt; on the Richardson Maturity Model if you haven&amp;#8217;t already. You&amp;#8217;ll notice I&amp;#8217;ve left out quite a bit of detail for simplicity (including the entirety of the lowest level!)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exploring REST and CRUD Further&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It&amp;#8217;s worth looking at HTTP verbs (level 2 in our diagram), and how they map to operations on your resources, in more detail. A common approach is to map the following HTTP verbs like so:&lt;/p&gt;

&lt;figure class='code'&gt;&lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;span class='line-number'&gt;2&lt;/span&gt;
&lt;span class='line-number'&gt;3&lt;/span&gt;
&lt;span class='line-number'&gt;4&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class=''&gt;&lt;span class='line'&gt;GET    # Read a resource
&lt;/span&gt;&lt;span class='line'&gt;POST   # Create a new resource
&lt;/span&gt;&lt;span class='line'&gt;PUT    # Update a resource
&lt;/span&gt;&lt;span class='line'&gt;DELETE # You guessed it...&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;If I want to retrieve a pizza representation, I just GET /pizzas/{id}. If I want to create a new pizza, I POST my representation to /pizzas. Change the topping on a pizza? PUT the updated representation to /pizzas/{id}.&lt;/p&gt;

&lt;p&gt;Using HTTP verbs in this way is a good approach for many applications. But it can, in some cases, lead to lack of good separation between model and controller. Take an example: composite representations. The representation of a news story may include headlines of related stories, user comments, and author metadata. Combining data in this manner is common for e.g. mobile clients where the trade off between composing representations (and increasing response size) and the increased latency of multiple requests is deemed necessary.&lt;/p&gt;

&lt;p&gt;If the service was designed as a CRUD layer over some database models with no additional composition ability, then implementing these representations can lead to unexpected complexity. It pays to think about resources that don&amp;#8217;t map directly to business objects and the way in which a controller will handle this.
See Subbu Allamaraju&amp;#8217;s excellent &lt;a href="http://www.amazon.co.uk/gp/product/0596801688/ref=as_li_tf_tl?ie=UTF8&amp;amp;tag=blueprintforg-21&amp;amp;linkCode=as2&amp;amp;camp=1634&amp;amp;creative=6738&amp;amp;creativeASIN=0596801688"&gt;cookbook recipes (pp. 30-37)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is something that is worth bearing in mind when choosing a framework on which to build your RESTful service. In a number of frameworks, the tendency is to derive controllers directly from models. How would you express the above representation in such a framework? Would it save time to use something with greater flexibility?&lt;/p&gt;

&lt;p&gt;A final point, which leads on from the notion of generating representations directly from models, is &lt;em&gt;versioning&lt;/em&gt;. If your representations are strongly coupled to business objects, changing your database schema implies change to your service. Templating representations helps dissociate the representation from the model, forcing potentially client-breaking to be acknowledged by explicitly modifying a template.&lt;/p&gt;

&lt;p&gt;There are a couple of different ways to ask a webservice for a specific version of a resource. Some architects prefer the version to be passed as a header, but there is also a camp that supports having the version in the URL. Ian Robinson&amp;#8217;s &lt;a href="http://www.slideshare.net/guilhermecaelum/rest-in-practice"&gt;presentation (slide 20)&lt;/a&gt; covers this well.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We&amp;#8217;ve covered the lower two levels of the Richardson Maturity Model with some expansion on mapping resources to business objects. There are many other subjects to cover &amp;#8211; caching, error-handling patterns, content negotiation, but hopefully the above has provided some useful points to consider when designing a RESTful service and choosing a framework.&lt;/p&gt;

&lt;p&gt;In my own work, I have found &lt;a href="http://www.amazon.co.uk/gp/product/0596805829/ref=as_li_ss_tl?ie=UTF8&amp;tag=blueprintforg-21&amp;linkCode=as2&amp;camp=1634&amp;creative=19450&amp;creativeASIN=0596805829"&gt;&lt;em&gt;REST in Practice&lt;/em&gt;&lt;/a&gt;&lt;img src="http://www.assoc-amazon.co.uk/e/ir?t=blueprintforg-21&amp;l=as2&amp;o=2&amp;a=0596805829" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /&gt; by Jim Webber, Savas Parastatidis and Ian Robinson a good resource.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.amazon.co.uk/gp/product/0596805829/ref=as_li_ss_il?ie=UTF8&amp;tag=blueprintforg-21&amp;linkCode=as2&amp;camp=1634&amp;creative=19450&amp;creativeASIN=0596805829"&gt;&lt;img border="0" src="http://ws.assoc-amazon.co.uk/widgets/q?_encoding=UTF8&amp;Format=_SL160_&amp;ASIN=0596805829&amp;MarketPlace=GB&amp;ID=AsinImage&amp;WS=1&amp;tag=blueprintforg-21&amp;ServiceVersion=20070822" &gt;&lt;/a&gt;&lt;img src="http://www.assoc-amazon.co.uk/e/ir?t=blueprintforg-21&amp;l=as2&amp;o=2&amp;a=0596805829" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /&gt;&lt;/p&gt;

&lt;p&gt;In the next article I&amp;#8217;ll talk about the final tier of the Richardson Maturity Model: hypermedia controls.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/BlueprintForge/~4/ORuJsrr7-Zg" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://blueprintforge.com/blog/2011/12/13/some-thoughts-on-rest/</feedburner:origLink></entry>
  
  <entry>
    <title type="html"><![CDATA[Sales Driven Development]]></title>
    <link href="http://feedproxy.google.com/~r/BlueprintForge/~3/eVgMjCp20xo/" />
    <updated>2011-12-06T08:57:00+00:00</updated>
    <id>http://blueprintforge.com/blog/2011/12/06/sales-driven-development</id>
    <content type="html">&lt;blockquote&gt;&lt;p&gt;Customers don&amp;#8217;t know what they want. Stop expecting customers to know what they want.
&amp;#8211;&lt;a href="http://www.joelonsoftware.com/articles/fog0000000356.html" title="The Iceberg Secret, Revealed -- Joel Spolsky"&gt;Joel Spolsky&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;A couple of months ago I attended a &lt;a href="http://www.slideshare.net/HuddleHQ/the-science-of-selling-9334276" title="The Science of Selling -- Neil Ryland"&gt;presentation&lt;/a&gt; by the Head of EMEA Sales at Huddle, Neil Ryland. In describing the sales process, one of the most interesting points raised was how feedback from the sales force is incorporated into the development lifecycle.&lt;/p&gt;

&lt;p&gt;Huddle&amp;#8217;s products are aimed at the enterprise segment. As part of the sales process, there are likely to be multiple conversations between the sales representative and the customer. This direct contact with the client is so valuable that it can be used in planning the next iteration of the product. The process goes something like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Analyze the failed sales. Could the sale have been closed by offering a slightly different feature set?&lt;/li&gt;
&lt;li&gt;Analyze the successful sales. Which features of the product were most influential in the customer&amp;#8217;s decision?&lt;/li&gt;
&lt;li&gt;Highlight the most compelling points to the product manager and development team at planning meetings.&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;Note that this is my interpretation of what was stated &amp;#8211; I&amp;#8217;m not acquainted with Huddle&amp;#8217;s internal processes, so don&amp;#8217;t assume this accurately reflects the process. Yet the important point is this: &lt;em&gt;sales has a direct line to product development&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Clearly, this only one of the different factors that should be considered when a backlog is written or prioritised. But it is an important one that should not be overlooked.&lt;/p&gt;

&lt;p&gt;Out of this process grows the phrase &lt;em&gt;Sales Driven Development&lt;/em&gt;. I&amp;#8217;m fairly reluctant to use it, since it implies a complete development methodology. It&amp;#8217;s not necessarily a driver of product iteration, but behaves more akin to a regulation mechanism.&lt;/p&gt;

&lt;p&gt;An interesting facet to this approach is how it interacts with site-specific customisation, practiced by many software firms targeting the enterprise. Of course, with a cloud-based product such as Huddle&amp;#8217;s, site-specific customisation makes little sense. Instead of customisation, a feature may be built into the next release. And, of course, these two practices certainly aren&amp;#8217;t mutually exclusive approaches.&lt;/p&gt;

&lt;p&gt;Returning to the introductory quotes, what we&amp;#8217;ve covered so far is certainly no counterpoint. I strongly agree with the notion that it is not the customer&amp;#8217;s job to know what they want. But it is interesting to explore how an iteration cycle can incorporate what customers &lt;em&gt;say&lt;/em&gt; they want, particularly when they have already encountered the product.&lt;/p&gt;

&lt;p&gt;In this sense, software companies with a sales force may well be at an advantage. Why? Because of the dialogue a sales representative can engage in with a lead. In terms of customer interaction, it clearly outstrips a feedback form. But this is a fairly obvious point.&lt;/p&gt;

&lt;p&gt;A more interesting question is this: &lt;em&gt;how do we derive frank feedback, and to whom should we listen?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;One method is to focus on the sales successes. With many people in an enterprise using your product, their experience of the product is likely to be wider than an individual might achieve. There may be even internal factors that drive how the product is used. Understanding the initial success and following up on how the product is used internally can provide this.&lt;/p&gt;

&lt;p&gt;Another approach is to look at the unsuccessful cases that included a trial of the product. This provides the grounding that the potential customer was willing to invest time to assess the product and discover why it wasn&amp;#8217;t right for them.&lt;/p&gt;

&lt;p&gt;It&amp;#8217;s interesting to think how this approach might factor into a different revenue model, such as freemium. But since this is essentially a separate discussion, I will attempt to cover it in a future article. In any case, we&amp;#8217;ve covered the main point of this article: examining a case where sales feedback is given a direct line to product iteration.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/BlueprintForge/~4/eVgMjCp20xo" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://blueprintforge.com/blog/2011/12/06/sales-driven-development/</feedburner:origLink></entry>
  
</feed>
