<?xml version="1.0" encoding="UTF-8"?>
<feed
  xmlns="http://www.w3.org/2005/Atom"
  xmlns:thr="http://purl.org/syndication/thread/1.0"
  xml:lang="en"
   >
  <title type="text">Doug Latornell</title>
  <subtitle type="text"></subtitle>

  <updated>2017-06-29T00:57:29Z</updated>
  <generator uri="http://blogofile.com/">Blogofile</generator>

  <link rel="alternate" type="text/html" href="http://douglatornell.ca/blog"/>
  <id>http://douglatornell.ca/blog/feed/atom/</id>
  <link rel="self" type="application/atom+xml" href="http://douglatornell.ca/blog/feed/atom/"/>
  <entry>
    <author>
      <name></name>
      <uri>http://douglatornell.ca/blog</uri>
    </author>
    <title type="html"><![CDATA[Using Sublime Text Build System for Project Unit Tests]]></title>
    <link rel="alternate" type="text/html" href="http://douglatornell.ca/blog/2013/07/04/sublime-text-build-system-for-project-unit-tests"/>
    <id>http://douglatornell.ca/blog/2013/07/04/sublime-text-build-system-for-project-unit-tests</id>
    <updated>2013-07-04T16:03:41Z</updated>
    <published>2013-07-04T16:03:41Z</published>
    <category scheme="http://douglatornell.ca/blog" term="python"/>
    <category scheme="http://douglatornell.ca/blog" term="sublime-text"/>
    <category scheme="http://douglatornell.ca/blog" term="testing"/>
    <summary type="html"><![CDATA[Using Sublime Text Build System for Project Unit Tests]]></summary>
    <content type="html" xml:base="http://douglatornell.ca/blog/2013/07/04/sublime-text-build-system-for-project-unit-tests"><![CDATA[<div class="document">
<p>I spent some time today learning about the <a class="reference external" href="http://docs.sublimetext.info/en/latest/file_processing/build_systems.html">Build System</a>.
In addition to the built-in build systems for various languages,
and the possibility of defining custom build systems at the user preference level,
you can also specify <a class="reference external" href="http://www.sublimetext.com/docs/3/projects.html">project build systems</a>.</p>
<p>I added the following stanza to one of my <tt class="docutils literal"><span class="pre">.sublime-project</span></tt> files:</p>


<div class="pygments_default"><pre><span></span><span class="s2">&quot;build_systems&quot;</span><span class="err">:</span>
 <span class="p">[</span>
     <span class="p">{</span>
         <span class="nt">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;unittest-discover&quot;</span><span class="p">,</span>
         <span class="nt">&quot;shell_cmd&quot;</span><span class="p">:</span> <span class="s2">&quot;~/.virtualenvs/randopony-tetra-2.7/bin/python</span>
<span class="s2">                       -m unittest discover ${project_path}&quot;</span>
     <span class="p">}</span>
 <span class="p">]</span>
</pre></div>



<p>to enable me to run the test suite for the project within Sublime at the touch of a key.</p>
<p>Things to note:</p>
<ul class="simple">
<li>The <tt class="docutils literal">name</tt> element defines how the build will appear in the <tt class="docutils literal">Tools &gt; Build System</tt> menu.</li>
<li>In the <tt class="docutils literal">shell_cmd</tt> element:<ul>
<li>I use an explicit path to the <tt class="docutils literal">python</tt> interpreter in the project's <tt class="docutils literal">virtualenv</tt> so that the project's dependencies are found correctly.</li>
<li>The shell that the Sublime <tt class="docutils literal">build</tt> command launches will have as its <tt class="docutils literal">cwd</tt> the directory that the file you initiate the <tt class="docutils literal">build</tt> command from is in.
<tt class="docutils literal">${project_path}</tt> is a <a class="reference external" href="http://docs.sublimetext.info/en/latest/reference/build_systems.html#build-system-variables">build system variable</a> that points to the directory where the <tt class="docutils literal"><span class="pre">.sublime-project</span></tt> file is,
and I use that to tell <tt class="docutils literal">unittest discover</tt> where to start searching for tests.</li>
</ul>
</li>
<li>You can define as many build systems as you want in the <tt class="docutils literal"><span class="pre">.sublime-project</span></tt> file,
just be sure to give them different names.</li>
</ul>
<p>After reloading the <tt class="docutils literal"><span class="pre">.sublime-project</span></tt> file,
choose <tt class="docutils literal"><span class="pre">unittest-discover</span></tt> from the <tt class="docutils literal">Tools &gt; Build System</tt> menu,
and launch a build (<tt class="docutils literal">⌘B</tt> on OS/X),
and voilà,
the test suite runs in a pane that pops up at the bottom of the Sublime window.</p>
</div>
]]></content>
  </entry>
  <entry>
    <author>
      <name></name>
      <uri>http://douglatornell.ca/blog</uri>
    </author>
    <title type="html"><![CDATA[Pyramid, Persona & Group-Level Auth]]></title>
    <link rel="alternate" type="text/html" href="http://douglatornell.ca/blog/2012/10/27/pyramid-persona-group-level-auth"/>
    <id>http://douglatornell.ca/blog/2012/10/27/pyramid-persona-group-level-auth</id>
    <updated>2012-10-27T10:07:23Z</updated>
    <published>2012-10-27T10:07:23Z</published>
    <category scheme="http://douglatornell.ca/blog" term="python"/>
    <category scheme="http://douglatornell.ca/blog" term="pyramid"/>
    <category scheme="http://douglatornell.ca/blog" term="persona authentication"/>
    <summary type="html"><![CDATA[Pyramid, Persona & Group-Level Auth]]></summary>
    <content type="html" xml:base="http://douglatornell.ca/blog/2012/10/27/pyramid-persona-group-level-auth"><![CDATA[<div class="document">
<p>Georges Dubus has created <a class="reference external" href="http://pypi.python.org/pypi/pyramid_persona">pyramid_persona</a>, a nice library to integrate
<a class="reference external" href="http://www.mozilla.org/persona/">Mozilla Persona</a> authentication into <a class="reference external" href="http://www.pylonsproject.org/">Pyramid</a> projects.
He also wrote a tutorial <a class="reference external" href="http://compiletoi.net/quick-authentication-on-pyramid-with-persona.html">blog post</a> explaining the basics of how to use
the library.
In principle it should be easy to go from what Georges has written to getting
Persona-based authentication fully integrated with group or object level
authorization in a Pyramid project,
but it took some head scratching for me to do that.
What better reason to blog about what I came up with and build on Georges'
excellent work...</p>
<p>By the way,
<a class="reference external" href="http://pypi.python.org/pypi/pyramid_persona">pyramid_persona</a> is also a really nice example of <a class="reference external" href="http://docs.pylonsproject.org/projects/pyramid_cookbook/en/latest/configuration/whirlwind_tour.html">advanced configuration
tactics</a> in Pyramid that show off the framework's plug-in friendliness.</p>
<p>Before diving is, I should also mention that Michael Merickel's
<a class="reference external" href="http://michael.merickel.org/projects/pyramid_auth_demo/">authentication and authorization tutorial</a> is an indispensable reference.</p>
<p><strong>The Goal:</strong> The example I'm going to use is a very simple group-level authorization one.
We'll create a site with a public side that anyone can interact with,
and a private side that only allows access by users who have authenticated
via Persona,
and are known to the app as members of the <tt class="docutils literal">admin</tt> group.
We'll use the <a class="reference external" href="http://docs.pylonsproject.org/projects/pyramid/en/1.4-branch/narr/project.html#scaffolds-included-with-pyramid">alchemy scaffold</a>,
so the app will have URL mapping via URL dispatch and persistence via
SQLAlchemy.</p>
<p>So, let's get started.</p>
<p>Create a virtualenv,
install Pyramid,
and create an alchemy scaffold app:</p>


<div class="pygments_default"><pre><span></span><span class="o">(</span>ppga<span class="o">)</span>$ pcreate -s alchemy pyramid_persona_group_auth_demo
</pre></div>



<p>Add <tt class="docutils literal">pyramid_persona</tt> to the <tt class="docutils literal">requires</tt> list in <tt class="docutils literal">setup.py</tt>,
and add some settings to <tt class="docutils literal">development.ini</tt>:</p>


<div class="pygments_default"><pre><span></span><span class="na">persona.secret</span> <span class="o">=</span> <span class="s">some secret string</span>
<span class="na">persona.audiences</span> <span class="o">=</span> <span class="s">http://localhost:6543</span>
<span class="na">persona.siteName</span> <span class="o">=</span> <span class="s">Pyramid Persona Group Auth Demo</span>

<span class="na">mako.directories</span> <span class="o">=</span> <span class="s">pyramid_persona_group_auth_demo:templates</span>
</pre></div>



<p>The <tt class="docutils literal">persona</tt> settings are described in the Configuration section of the
<a class="reference external" href="http://pypi.python.org/pypi/pyramid_persona">pyramid_persona</a> README.
The <tt class="docutils literal">mako.directories</tt> setting is needed because we're going to use Mako for
our login and admin page templates.</p>
<p>Next up, we add an <tt class="docutils literal">Administrator</tt> class to our <tt class="docutils literal">models.py</tt> file:</p>


<div class="pygments_default"><pre><span></span><span class="k">class</span> <span class="nc">Administrator</span><span class="p">(</span><span class="n">Base</span><span class="p">):</span>
    <span class="n">__tablename__</span> <span class="o">=</span> <span class="s1">&#39;admins&#39;</span>
    <span class="nb">id</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">Integer</span><span class="p">,</span> <span class="n">primary_key</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
    <span class="n">persona_email</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">Text</span><span class="p">,</span> <span class="n">index</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span> <span class="n">unique</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>

    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">persona_email</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">persona_email</span> <span class="o">=</span> <span class="n">persona_email</span>
</pre></div>



<p>We also need to bootstrap our Persona email address into the database
so that we can sign-in to our app when we first start it up.
To do that, import <tt class="docutils literal">Administrator</tt> into <tt class="docutils literal">scripts/initializedb.py</tt>
and add a couple of lines to the end of the <tt class="docutils literal">main</tt> function in that file:</p>


<div class="pygments_default"><pre><span></span><span class="kn">from</span> <span class="nn">..models</span> <span class="kn">import</span> <span class="n">Administrator</span>
<span class="o">...</span>
<span class="k">with</span> <span class="n">transaction</span><span class="o">.</span><span class="n">manager</span><span class="p">:</span>
    <span class="n">model</span> <span class="o">=</span> <span class="n">MyModel</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="s1">&#39;one&#39;</span><span class="p">,</span> <span class="n">value</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
    <span class="n">DBSession</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">model</span><span class="p">)</span>
    <span class="n">admin</span> <span class="o">=</span> <span class="n">Administrator</span><span class="p">(</span><span class="n">persona_email</span><span class="o">=</span><span class="s1">&#39;me@example.com&#39;</span><span class="p">)</span>
    <span class="n">DBSession</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">admin</span><span class="p">)</span>
</pre></div>



<p>Obviously, you'll want to use an email address that you have registered with
Persona in place of <tt class="docutils literal">me&#64;example.com</tt>.</p>
<p>Now it's time to create some templates and views for the admin site of our
site.
These pages are almost verbatim from Georges' <a class="reference external" href="http://compiletoi.net/quick-authentication-on-pyramid-with-persona.html">blog post</a> or the
<a class="reference external" href="http://pypi.python.org/pypi/pyramid_persona">pyramid_persona</a> README - he really has done most of the heavy lifting!
We start with a stub for the admin home page in <tt class="docutils literal">templates/admin_home.mako</tt>:</p>


<div class="pygments_default"><pre><span></span><span class="cp">&lt;!DOCTYPE html&gt;</span>
<span class="p">&lt;</span><span class="nt">html</span><span class="p">&gt;</span>
<span class="p">&lt;</span><span class="nt">head</span><span class="p">&gt;</span>
  <span class="p">&lt;</span><span class="nt">script</span> <span class="na">type</span><span class="o">=</span><span class="s">&quot;text/javascript&quot;</span>
    <span class="na">src</span><span class="o">=</span><span class="s">&quot;//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js&quot;</span><span class="p">&gt;</span>
  <span class="p">&lt;/</span><span class="nt">script</span><span class="p">&gt;</span>
  <span class="p">&lt;</span><span class="nt">script</span> <span class="na">src</span><span class="o">=</span><span class="s">&quot;https://login.persona.org/include.js&quot;</span><span class="p">&gt;&lt;/</span><span class="nt">script</span><span class="p">&gt;</span>
  <span class="p">&lt;</span><span class="nt">script</span> <span class="p">&gt;</span><span class="nx">$</span><span class="p">{</span><span class="nx">request</span><span class="p">.</span><span class="nx">persona_js</span><span class="p">}&lt;/</span><span class="nt">script</span><span class="p">&gt;</span>
<span class="p">&lt;/</span><span class="nt">head</span><span class="p">&gt;</span>
<span class="p">&lt;</span><span class="nt">body</span><span class="p">&gt;</span>
  <span class="p">&lt;</span><span class="nt">h1</span><span class="p">&gt;</span>Pyramid Persona Group Auth Demo Admin<span class="p">&lt;/</span><span class="nt">h1</span><span class="p">&gt;</span>
  Welcome to the admin side, ${userid}
  ${request.persona_button}
<span class="p">&lt;/</span><span class="nt">body</span><span class="p">&gt;</span>
<span class="p">&lt;/</span><span class="nt">html</span><span class="p">&gt;</span>
</pre></div>



<p>All we've done here is hooked into Persona, and set up a welcome message and
a sign-out button in lieu of any real admin interface content and funtionality.</p>
<p>The <tt class="docutils literal">request.person_js</tt> and <tt class="docutils literal">request.persona_button</tt> attributes are
available thanks to <tt class="docutils literal">config.set_request_property()</tt> calls in
<tt class="docutils literal">pyramid_persona.__init__.py</tt>.
Recall that I mentioned what a nice example
of advanced Pyramid configuration <tt class="docutils literal">pyramid_persona</tt> is -
it's well worth reading Georges' code to learn how he has made things so
easy for the rest of us.</p>
<p>We'll also create a very similar looking template for our sign-in page in
<tt class="docutils literal">templates/admin_signin.mako</tt>:</p>


<div class="pygments_default"><pre><span></span><span class="cp">&lt;!DOCTYPE html&gt;</span>
<span class="p">&lt;</span><span class="nt">html</span><span class="p">&gt;</span>
<span class="p">&lt;</span><span class="nt">head</span><span class="p">&gt;</span>
  <span class="p">&lt;</span><span class="nt">script</span> <span class="na">type</span><span class="o">=</span><span class="s">&quot;text/javascript&quot;</span>
    <span class="na">src</span><span class="o">=</span><span class="s">&quot;//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js&quot;</span><span class="p">&gt;</span>
  <span class="p">&lt;/</span><span class="nt">script</span><span class="p">&gt;</span>
  <span class="p">&lt;</span><span class="nt">script</span> <span class="na">src</span><span class="o">=</span><span class="s">&quot;https://login.persona.org/include.js&quot;</span><span class="p">&gt;&lt;/</span><span class="nt">script</span><span class="p">&gt;</span>
  <span class="p">&lt;</span><span class="nt">script</span> <span class="p">&gt;</span><span class="nx">$</span><span class="p">{</span><span class="nx">request</span><span class="p">.</span><span class="nx">persona_js</span><span class="p">}&lt;/</span><span class="nt">script</span><span class="p">&gt;</span>
<span class="p">&lt;/</span><span class="nt">head</span><span class="p">&gt;</span>
<span class="p">&lt;</span><span class="nt">body</span><span class="p">&gt;</span>
<span class="p">&lt;</span><span class="nt">h1</span><span class="p">&gt;</span>Pyramid Persona Group Auth Demo Admin<span class="p">&lt;/</span><span class="nt">h1</span><span class="p">&gt;</span>
  ${request.persona_button}
<span class="p">&lt;/</span><span class="nt">body</span><span class="p">&gt;</span>
<span class="p">&lt;/</span><span class="nt">html</span><span class="p">&gt;</span>
</pre></div>



<p>There are obviously some opportunities to use template inheritance here,
to say nothing of the total absence of styling in those templates.</p>
<p>Moving along to the views that render those templates, we create
<tt class="docutils literal">admin_views.py</tt> containing:</p>


<div class="pygments_default"><pre><span></span><span class="kn">from</span> <span class="nn">pyramid.renderers</span> <span class="kn">import</span> <span class="n">render</span>
<span class="kn">from</span> <span class="nn">pyramid.response</span> <span class="kn">import</span> <span class="n">Response</span>
<span class="kn">from</span> <span class="nn">pyramid.security</span> <span class="kn">import</span> <span class="n">authenticated_userid</span>
<span class="kn">from</span> <span class="nn">pyramid.view</span> <span class="kn">import</span> <span class="p">(</span>
    <span class="n">forbidden_view_config</span><span class="p">,</span>
    <span class="n">view_config</span><span class="p">,</span>
    <span class="p">)</span>

<span class="nd">@forbidden_view_config</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">admin_signin</span><span class="p">(</span><span class="n">request</span><span class="p">):</span>
    <span class="n">body</span> <span class="o">=</span> <span class="n">render</span><span class="p">(</span><span class="s1">&#39;admin_signin.mako&#39;</span><span class="p">,</span> <span class="p">{},</span> <span class="n">request</span><span class="o">=</span><span class="n">request</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">Response</span><span class="p">(</span><span class="n">body</span><span class="p">,</span> <span class="n">status</span><span class="o">=</span><span class="s1">&#39;403 Forbidden&#39;</span><span class="p">)</span>

<span class="nd">@view_config</span><span class="p">(</span>
    <span class="n">route_name</span><span class="o">=</span><span class="s1">&#39;admin.home&#39;</span><span class="p">,</span>
    <span class="n">renderer</span><span class="o">=</span><span class="s1">&#39;admin_home.mako&#39;</span><span class="p">,</span>
    <span class="n">permission</span><span class="o">=</span><span class="s1">&#39;admin&#39;</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">admin_home</span><span class="p">(</span><span class="n">request</span><span class="p">):</span>
    <span class="n">userid</span> <span class="o">=</span> <span class="n">authenticated_userid</span><span class="p">(</span><span class="n">request</span><span class="p">)</span>
    <span class="k">return</span> <span class="p">{</span><span class="s1">&#39;userid&#39;</span><span class="p">:</span> <span class="n">userid</span><span class="p">}</span>
</pre></div>



<p>The <tt class="docutils literal">admin_signin</tt> function renders our <tt class="docutils literal">admin_signin.mako</tt> template
and packages it up as a <tt class="docutils literal">403 Forbidden</tt> response.
That function is decorated with <tt class="docutils literal">&#64;forbidden_view_config()</tt> so that it will
replace the default forbidden view that <a class="reference external" href="http://pypi.python.org/pypi/pyramid_persona">pyramid_persona</a> supplies.
That's how we get our sign-in page to appear when an unauthenticated user
hits the admin URL.</p>
<p>The <tt class="docutils literal">admin_home</tt> function renders our admin home page stub.
The important thing to note here is the <tt class="docutils literal"><span class="pre">permission='admin'</span></tt> argument in
the <tt class="docutils literal">&#64;view_config</tt> decorator.</p>
<p>Finally, we add our security policy to
<tt class="docutils literal">pyramid_persona_group_auth_demo/__init__.py</tt> and add our admin home page
view to the route map.
We need some new imports:</p>


<div class="pygments_default"><pre><span></span><span class="kn">from</span> <span class="nn">pyramid.authentication</span> <span class="kn">import</span> <span class="n">AuthTktAuthenticationPolicy</span>
<span class="kn">from</span> <span class="nn">pyramid.security</span> <span class="kn">import</span> <span class="n">ALL_PERMISSIONS</span>
<span class="kn">from</span> <span class="nn">pyramid.security</span> <span class="kn">import</span> <span class="n">Allow</span>
<span class="kn">from</span> <span class="nn">sqlalchemy.orm.exc</span> <span class="kn">import</span> <span class="n">NoResultFound</span>
<span class="kn">from</span> <span class="nn">.models</span> <span class="kn">import</span> <span class="n">Administrator</span>
</pre></div>



<p>Then we add a dirt simple resource tree to provide the access control list
that implements our security policy; i.e. any user in the <tt class="docutils literal">admin</tt> group
has full access to admin resources:</p>


<div class="pygments_default"><pre><span></span><span class="k">class</span> <span class="nc">Root</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;Simplest possible resource tree to map groups to permissions.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="n">__acl__</span> <span class="o">=</span> <span class="p">[</span>
        <span class="p">(</span><span class="n">Allow</span><span class="p">,</span> <span class="s1">&#39;g:admin&#39;</span><span class="p">,</span> <span class="n">ALL_PERMISSIONS</span><span class="p">),</span>
    <span class="p">]</span>

    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">request</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">request</span> <span class="o">=</span> <span class="n">request</span>
</pre></div>



<p>We also need a <tt class="docutils literal">groupfinder</tt> function to provide to the authentication
policy constructor so that it can identify whether or not an authenticated
user is in the <tt class="docutils literal">admin</tt> group:</p>


<div class="pygments_default"><pre><span></span><span class="k">def</span> <span class="nf">groupfinder</span><span class="p">(</span><span class="n">userid</span><span class="p">,</span> <span class="n">request</span><span class="p">):</span>
    <span class="n">query</span> <span class="o">=</span> <span class="n">DBSession</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="n">Administrator</span><span class="p">)</span><span class="o">.</span>\
                <span class="nb">filter</span><span class="p">(</span><span class="n">Administrator</span><span class="o">.</span><span class="n">persona_email</span> <span class="o">==</span> <span class="n">userid</span><span class="p">)</span>
    <span class="k">try</span><span class="p">:</span>
        <span class="n">query</span><span class="o">.</span><span class="n">one</span><span class="p">()</span>
        <span class="k">return</span> <span class="p">[</span><span class="s1">&#39;g:admin&#39;</span><span class="p">]</span>
    <span class="k">except</span> <span class="n">NoResultFound</span><span class="p">:</span>
        <span class="k">return</span> <span class="bp">None</span>
</pre></div>



<p>Now let's hook everything together via the configuration in the
<tt class="docutils literal">main</tt> function.
We add our resource tree to the <tt class="docutils literal">Configurator</tt> constructor call:</p>


<div class="pygments_default"><pre><span></span><span class="n">config</span> <span class="o">=</span> <span class="n">Configurator</span><span class="p">(</span><span class="n">settings</span><span class="o">=</span><span class="n">settings</span><span class="p">,</span> <span class="n">root_factory</span><span class="o">=</span><span class="n">Root</span><span class="p">)</span>
</pre></div>



<p>as well as including the <a class="reference external" href="http://pypi.python.org/pypi/pyramid_persona">pyramid_persona</a> configuration,
and overriding its authentication policy setting with our own that hooks in
the <tt class="docutils literal">groupfinder</tt> function:</p>


<div class="pygments_default"><pre><span></span><span class="n">config</span><span class="o">.</span><span class="n">include</span><span class="p">(</span><span class="s1">&#39;pyramid_persona&#39;</span><span class="p">)</span>
<span class="n">authn_policy</span> <span class="o">=</span> <span class="n">AuthTktAuthenticationPolicy</span><span class="p">(</span>
    <span class="n">settings</span><span class="p">[</span><span class="s1">&#39;persona.secret&#39;</span><span class="p">],</span>
    <span class="n">callback</span><span class="o">=</span><span class="n">groupfinder</span><span class="p">)</span>
<span class="n">config</span><span class="o">.</span><span class="n">set_authentication_policy</span><span class="p">(</span><span class="n">authn_policy</span><span class="p">)</span>
</pre></div>



<p>Last but not least, we add a route to map <tt class="docutils literal">/admin</tt> to our admin home page:</p>


<div class="pygments_default"><pre><span></span><span class="n">config</span><span class="o">.</span><span class="n">add_route</span><span class="p">(</span><span class="s1">&#39;admin.home&#39;</span><span class="p">,</span> <span class="s1">&#39;/admin&#39;</span><span class="p">)</span>
</pre></div>



<p>It's time to test!</p>
<p>Install our app to get all of the dependencies installed,
initialize the database with the handy
<tt class="docutils literal">initialize_pyramid_persona_group_auth_demo_db</tt> command that Pyramid
creates for us during installation of an <tt class="docutils literal">alchemy</tt> scaffold app,
and start the server:</p>


<div class="pygments_default"><pre><span></span><span class="o">(</span>ppga<span class="o">)</span>$ python setup.py develop
<span class="o">(</span>ppga<span class="o">)</span>$ <span class="c1"># lots of output</span>
<span class="o">(</span>ppga<span class="o">)</span>$ initialize_pyramid_persona_group_auth_demo_db development.ini
<span class="o">(</span>ppga<span class="o">)</span>$ pserve --reload development.ini
</pre></div>



<p>Browsing to <tt class="docutils literal"><span class="pre">http://localhost:6543</span></tt> should show you the default Pyramid
app page - that's the public side of our site.</p>
<p>Going to <tt class="docutils literal"><span class="pre">http://localhost:6543/admin</span></tt> should show you the admin
sign-in page:</p>
<img alt="../../../../../images/2012-10-27-admin_signin.png" src="../../../../../images/2012-10-27-admin_signin.png" style="width: 600px;" />
<p>and, if you inspect the requests and responses with your browser's web dev
tools, you'll see that we got the expected <tt class="docutils literal">403 Forbidden</tt> response status.</p>
<p>Clicking the sign-in button pops the <tt class="docutils literal">login.persona.org</tt> site in a new
window with our site name and audience domain displayed:</p>
<img alt="../../../../../images/2012-10-27-persona.png" src="../../../../../images/2012-10-27-persona.png" style="width: 600px;" />
<p>And, upon successfully signing in at Persona, we are redirected to the admin
home page of our site:</p>
<img alt="../../../../../images/2012-10-27-admin_page.png" src="../../../../../images/2012-10-27-admin_page.png" style="width: 600px;" />
<p>And that's all there is to it!
Extending the site security to a more fine-grained group-level hierachy,
or to object-level security should be relatively easy with the guidance
in Michael Merickel's <a class="reference external" href="http://michael.merickel.org/projects/pyramid_auth_demo/">authentication and authorization tutorial</a>.</p>
<p>The source code for the demo I've created here is available on Bitbucket at
<a class="reference external" href="https://bitbucket.org/douglatornell/pyramid_persona_group_auth_demo">https://bitbucket.org/douglatornell/pyramid_persona_group_auth_demo</a></p>
<p>Thanks again to Georges Dubus for making this easy with the <a class="reference external" href="http://pypi.python.org/pypi/pyramid_persona">pyramid_persona</a>
library, and to Mozilla for creating Persona.</p>
<p><strong>Updated 2012-11-02</strong></p>
<ul class="simple">
<li>Fixed typo in <tt class="docutils literal">import</tt> statement for Administrator model.
Thanks ppaez!</li>
<li>Added index on <tt class="docutils literal">persona_email</tt> column of Administrator model.
Thanks Georges Dubus!</li>
</ul>
</div>
]]></content>
  </entry>
  <entry>
    <author>
      <name></name>
      <uri>http://douglatornell.ca/blog</uri>
    </author>
    <title type="html"><![CDATA[Implementing An HTTP Server for Python 2 and 3]]></title>
    <link rel="alternate" type="text/html" href="http://douglatornell.ca/blog/2012/06/04/implementing-an-http-server-for-python-2-and-3"/>
    <id>http://douglatornell.ca/blog/2012/06/04/implementing-an-http-server-for-python-2-and-3</id>
    <updated>2012-06-04T05:40:13Z</updated>
    <published>2012-06-04T05:40:13Z</published>
    <category scheme="http://douglatornell.ca/blog" term="blogofile"/>
    <category scheme="http://douglatornell.ca/blog" term="python"/>
    <category scheme="http://douglatornell.ca/blog" term="python3 porting"/>
    <summary type="html"><![CDATA[Implementing An HTTP Server for Python 2 and 3]]></summary>
    <content type="html" xml:base="http://douglatornell.ca/blog/2012/06/04/implementing-an-http-server-for-python-2-and-3"><![CDATA[<div class="document">
<p>I've done some work recently to get the <a class="reference external" href="https://github.com/EnigmaCurry/blogofile">blogofile plugins branch</a> working
under Python 2.6, 2.7 and 3.2 from single codebase.
The <tt class="docutils literal">blogofile serve</tt> command runs an HTTP server on localhost to let you
check the results of your <tt class="docutils literal">blogofile build</tt> before you deploy it to the
waiting world.
In Python 3 (in which the plugins branch was initially implemented) the
relevant bits of the implementation go like:</p>


<div class="pygments_default"><pre><span></span><span class="kn">import</span> <span class="nn">http.server</span>
<span class="kn">import</span> <span class="nn">threading</span>

<span class="k">class</span> <span class="nc">Server</span><span class="p">(</span><span class="n">threading</span><span class="o">.</span><span class="n">Thread</span><span class="p">):</span>
    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">port</span><span class="p">,</span> <span class="n">address</span><span class="p">):</span>
        <span class="n">HandlerClass</span> <span class="o">=</span> <span class="n">BlogofileRequestHandler</span>
        <span class="n">ServerClass</span> <span class="o">=</span> <span class="n">http</span><span class="o">.</span><span class="n">server</span><span class="o">.</span><span class="n">HTTPServer</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">httpd</span> <span class="o">=</span> <span class="n">ServerClass</span><span class="p">((</span><span class="s1">&#39;127.0.0.1&#39;</span><span class="p">,</span> <span class="mi">8080</span><span class="p">),</span> <span class="n">HandlerClass</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">run</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">httpd</span><span class="o">.</span><span class="n">serve_forever</span><span class="p">()</span>

    <span class="k">def</span> <span class="nf">shutdown</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">httpd</span><span class="o">.</span><span class="n">shutdown</span><span class="p">()</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">httpd</span><span class="o">.</span><span class="n">socket</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>

<span class="k">class</span> <span class="nc">BlogofileRequestHandler</span><span class="p">(</span><span class="n">http</span><span class="o">.</span><span class="n">server</span><span class="o">.</span><span class="n">SimpleHTTPRequestHandler</span><span class="p">):</span>
    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
        <span class="n">http</span><span class="o">.</span><span class="n">server</span><span class="o">.</span><span class="n">SimpleHTTPRequestHandler</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span>
            <span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">translate_path</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">path</span><span class="p">):</span>
        <span class="o">...</span>
</pre></div>



<p>Some <tt class="docutils literal">import</tt> acrobatics are required to get that to also run under Python 2:</p>


<div class="pygments_default"><pre><span></span><span class="k">try</span><span class="p">:</span>
    <span class="kn">from</span> <span class="nn">http.server</span> <span class="kn">import</span> <span class="n">HTTPServer</span> <span class="k">as</span> <span class="n">http_server</span>
<span class="k">except</span> <span class="ne">ImportError</span><span class="p">:</span>
    <span class="kn">from</span> <span class="nn">SocketServer</span> <span class="kn">import</span> <span class="n">TCPServer</span> <span class="k">as</span> <span class="n">http_server</span>
<span class="k">try</span><span class="p">:</span>
    <span class="kn">from</span> <span class="nn">http.server</span> <span class="kn">import</span> <span class="n">SimpleHTTPRequestHandler</span> \
        <span class="k">as</span> <span class="n">http_handler</span>
<span class="k">except</span> <span class="ne">ImportError</span><span class="p">:</span>
    <span class="kn">from</span> <span class="nn">SimpleHTTPServer</span> <span class="kn">import</span> <span class="n">SimpleHTTPRequestHandler</span> \
        <span class="k">as</span> <span class="n">http_handler</span>
<span class="kn">import</span> <span class="nn">threading</span>

<span class="k">class</span> <span class="nc">Server</span><span class="p">(</span><span class="n">threading</span><span class="o">.</span><span class="n">Thread</span><span class="p">):</span>
    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">port</span><span class="p">,</span> <span class="n">address</span><span class="p">):</span>
        <span class="n">HandlerClass</span> <span class="o">=</span> <span class="n">BlogofileRequestHandler</span>
        <span class="n">ServerClass</span> <span class="o">=</span> <span class="n">http_server</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">httpd</span> <span class="o">=</span> <span class="n">ServerClass</span><span class="p">((</span><span class="s1">&#39;127.0.0.1&#39;</span><span class="p">,</span> <span class="mi">8080</span><span class="p">),</span> <span class="n">HandlerClass</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">run</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">httpd</span><span class="o">.</span><span class="n">serve_forever</span><span class="p">()</span>

    <span class="k">def</span> <span class="nf">shutdown</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">httpd</span><span class="o">.</span><span class="n">shutdown</span><span class="p">()</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">httpd</span><span class="o">.</span><span class="n">socket</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>

<span class="k">class</span> <span class="nc">BlogofileRequestHandler</span><span class="p">(</span><span class="n">http_handler</span><span class="p">):</span>
    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
        <span class="n">http_handler</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">translate_path</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">path</span><span class="p">):</span>
        <span class="o">...</span>
</pre></div>



<p>The <a class="reference external" href="http://packages.python.org/six/">six library</a> provides a nice way to clean up the hard to read
<tt class="docutils literal"><span class="pre">try:...</span> except <span class="pre">ImportError:...</span></tt> blocks:</p>


<div class="pygments_default"><pre><span></span><span class="kn">import</span> <span class="nn">threading</span>
<span class="kn">from</span> <span class="nn">six.moves</span> <span class="kn">import</span> <span class="n">SimpleHTTPServer</span>
<span class="kn">from</span> <span class="nn">six.moves</span> <span class="kn">import</span> <span class="n">socketserver</span>

<span class="n">http_server</span> <span class="o">=</span> <span class="n">socketserver</span><span class="o">.</span><span class="n">TCPServer</span>
<span class="n">http_handler</span> <span class="o">=</span> <span class="n">SimpleHTTPServer</span><span class="o">.</span><span class="n">SimpleHTTPRequestHandler</span>

<span class="k">class</span> <span class="nc">Server</span><span class="p">(</span><span class="n">threading</span><span class="o">.</span><span class="n">Thread</span><span class="p">):</span>
    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">port</span><span class="p">,</span> <span class="n">address</span><span class="p">):</span>
        <span class="n">HandlerClass</span> <span class="o">=</span> <span class="n">BlogofileRequestHandler</span>
        <span class="n">ServerClass</span> <span class="o">=</span> <span class="n">http_server</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">httpd</span> <span class="o">=</span> <span class="n">ServerClass</span><span class="p">((</span><span class="s1">&#39;127.0.0.1&#39;</span><span class="p">,</span> <span class="mi">8080</span><span class="p">),</span> <span class="n">HandlerClass</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">run</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">httpd</span><span class="o">.</span><span class="n">serve_forever</span><span class="p">()</span>

    <span class="k">def</span> <span class="nf">shutdown</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">httpd</span><span class="o">.</span><span class="n">shutdown</span><span class="p">()</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">httpd</span><span class="o">.</span><span class="n">socket</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>

<span class="k">class</span> <span class="nc">BlogofileRequestHandler</span><span class="p">(</span><span class="n">http_handler</span><span class="p">):</span>
    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
        <span class="n">http_handler</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">translate_path</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">path</span><span class="p">):</span>
        <span class="o">...</span>
</pre></div>



<p>Note that this implementation steps back from the
Python 3 <tt class="docutils literal">http.server.HTTPServer</tt> as the server class
to the underlying <tt class="docutils literal">socketserver.TCPServer</tt>
(or <tt class="docutils literal">SocketServer.TCPServer</tt> in Python 2).</p>
</div>
]]></content>
  </entry>
  <entry>
    <author>
      <name></name>
      <uri>http://douglatornell.ca/blog</uri>
    </author>
    <title type="html"><![CDATA[Blogofile Improvements]]></title>
    <link rel="alternate" type="text/html" href="http://douglatornell.ca/blog/2012/05/03/blogofile-improvements"/>
    <id>http://douglatornell.ca/blog/2012/05/03/blogofile-improvements</id>
    <updated>2012-05-03T19:42:33Z</updated>
    <published>2012-05-03T19:42:33Z</published>
    <category scheme="http://douglatornell.ca/blog" term="blogofile"/>
    <category scheme="http://douglatornell.ca/blog" term="python"/>
    <category scheme="http://douglatornell.ca/blog" term="blog maintenance"/>
    <summary type="html"><![CDATA[Blogofile Improvements]]></summary>
    <content type="html" xml:base="http://douglatornell.ca/blog/2012/05/03/blogofile-improvements"><![CDATA[<div class="document">
<p>I finally got around to fixing a couple of minor annoyances I have with
<a class="reference external" href="http://www.blogofile.com/">Blogofile</a>.
These fixes apply to the <a class="reference external" href="https://github.com/EnigmaCurry/blogofile/branches/plugins">plugins</a> development branch of Blogofile
and the <a class="reference external" href="https://github.com/EnigmaCurry/blogofile_blog">Blogofile_blog</a> plugin,
but they should be easily backport-able to the Blogofile master branch.
I opened pull requests for these changes on Github
and I'm happy to report that <a class="reference external" href="http://twitter.com/#!/EnigmaCurry">&#64;EnigmaCurry</a> merged the Blogofile_blog ones
within hours!
But since Blogofile development and this blog have been languishing
for a while,
I figured I should write about the changes here.</p>
<p>Using Python 2.7 and 3.2 with the <tt class="docutils literal">PYTHONWARNINGS</tt> environment
variable set to <tt class="docutils literal">default</tt>
reveals that both Blogofile and the Blogofile_blog plugin raise
<tt class="docutils literal">ResourceWarning</tt> exceptions when the <tt class="docutils literal">blogofile build</tt> command is run.
Admittedly, this is a really minor issue,
but seeing a screen full of tracebacks every time I build my site is
annoying,
and it can obscure more serious problems.
Those warnings are easily silenced by changing the offending
<tt class="docutils literal">open</tt> statements to use <tt class="docutils literal">with</tt> statement context managers.
The fix for Blogofile is in <a class="reference external" href="https://github.com/EnigmaCurry/blogofile/pull/119">pull request 119</a>
and the one for Blogofile_blog is in <a class="reference external" href="https://github.com/EnigmaCurry/blogofile_blog/pull/7">pull request 7</a>.</p>
<p>The <tt class="docutils literal">blogofile blog create post</tt> command creates a file with the extension
<tt class="docutils literal">.markdown</tt> by default
but Blogofile also supports <a class="reference external" href="http://docutils.sourceforge.net/rst.html">RST</a> and <a class="reference external" href="http://textile.thresholdstate.com/">Textile</a> markup.
I use RST and really want my newly created post files to have the extension
<tt class="docutils literal">.rst</tt> so that emacs goes to <tt class="docutils literal"><span class="pre">rst-mode</span></tt> automatically when
I open a post file for editing.
Again,
a minor annoyance,
and my fix was easily implemented.
I chose to add a <tt class="docutils literal">blog.post.default_markup</tt> config option.
With <tt class="docutils literal">blog.post.default_markup = 'rst'</tt> in my site's <tt class="docutils literal">_config.py</tt> file
my new posts get the <tt class="docutils literal">.rst</tt> extension I want.
If <tt class="docutils literal">blog.post.default_markup</tt> is not set the created post file extension
defaults to <tt class="docutils literal">.markdown</tt> as before.
This feature is in <a class="reference external" href="https://github.com/EnigmaCurry/blogofile_blog/pull/8">pull request 8</a>.</p>
<p>I really like Blogofile
and using it's plugins branch was my spur to get serious about using
Python 3 and blogging again.
So, I'm really happy to see &#64;EnigmaCurry accepting pull requests again
on the project. Hooray!!</p>
</div>
]]></content>
  </entry>
  <entry>
    <author>
      <name></name>
      <uri>http://douglatornell.ca/blog</uri>
    </author>
    <title type="html"><![CDATA[CSV Downloads from Web Apps]]></title>
    <link rel="alternate" type="text/html" href="http://douglatornell.ca/blog/2012/02/09/csv-downloads-from-pylons"/>
    <id>http://douglatornell.ca/blog/2012/02/09/csv-downloads-from-pylons</id>
    <updated>2012-02-09T21:34:51Z</updated>
    <published>2012-02-09T21:34:51Z</published>
    <category scheme="http://douglatornell.ca/blog" term="pylons"/>
    <category scheme="http://douglatornell.ca/blog" term="python"/>
    <summary type="html"><![CDATA[CSV Downloads from Web Apps]]></summary>
    <content type="html" xml:base="http://douglatornell.ca/blog/2012/02/09/csv-downloads-from-pylons"><![CDATA[<div class="document">
<p>One of the users of an intranet app I maintain was using copy/paste to
put data from the app into Excel. She asked if there was a better
way. The pages she was copying from have tables of datastore objects,
so adding a CSV download feature was an obvious solution. Providing
that feature turned out to be pretty easy with the help of the
<a class="reference external" href="http://docs.python.org/library/stringio.html">StringIO</a> and <a class="reference external" href="http://docs.python.org/library/csv.html">csv</a> modules in the standard library.</p>
<p>While the code below is from a Pylons controller class, I can't see it
being difficult to implement this in Django, Pyramid, or other web
framework stacks.</p>
<p>The request handler for the CSV download looks like:</p>


<div class="pygments_default"><pre><span></span><span class="kn">import</span> <span class="nn">cString</span>
<span class="kn">import</span> <span class="nn">csv</span>

<span class="k">def</span> <span class="nf">csv_download</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">...</span><span class="p">):</span>
    <span class="n">csv_buffer</span> <span class="o">=</span> <span class="n">cStringIO</span><span class="o">.</span><span class="n">StringIO</span><span class="p">()</span>
    <span class="n">csv_writer</span> <span class="o">=</span> <span class="n">csv</span><span class="o">.</span><span class="n">writer</span><span class="p">(</span><span class="n">csv_buffer</span><span class="p">)</span>
    <span class="n">header</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_build</span> <span class="n">csv_header</span><span class="p">(</span><span class="o">...</span><span class="p">)</span>
    <span class="n">csv_writer</span><span class="o">.</span><span class="n">writerow</span><span class="p">(</span><span class="n">header</span><span class="p">)</span>
    <span class="n">query_result</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_data_for_csv</span><span class="p">(</span><span class="o">...</span><span class="p">)</span>
    <span class="k">for</span> <span class="n">result</span> <span class="ow">in</span> <span class="n">query_result</span><span class="p">:</span>
        <span class="n">row</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_build_csv_row</span><span class="p">(</span><span class="n">result</span><span class="p">)</span>
        <span class="n">csv_writer</span><span class="o">.</span><span class="n">writerow</span><span class="p">(</span><span class="n">row</span><span class="p">)</span>
    <span class="n">content</span> <span class="o">=</span> <span class="n">csv_buffer</span><span class="o">.</span><span class="n">getvalue</span><span class="p">()</span>
    <span class="n">csv_buffer</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
    <span class="n">response</span><span class="o">.</span><span class="n">content_type</span> <span class="o">=</span> <span class="s1">&#39;text/csv; charset=utf-8&#39;</span>
    <span class="n">response</span><span class="o">.</span><span class="n">content_disposition</span> <span class="o">=</span> <span class="p">(</span>
        <span class="s1">&#39;attachment; filename=&quot;your_file.csv&quot;&#39;</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">content</span>
</pre></div>



<p>This method uses <tt class="docutils literal">StringIO</tt> to set up a file-like memory buffer, and
instantiates a default CSV writer to write to the buffer. Next we
build the header row and write it to the buffer. Then we get an
iterator for the content that we want to write the the CSV file from
the datastore, and format and write it to the buffer, one line at a
time. Finally we get the CSV data from the buffer, set the response
headers appropriately, and return the CSV data for download.</p>
<p>One thing I'm uncertain about: Is it necessary to explicitly call
<tt class="docutils literal">close</tt> method on a <tt class="docutils literal">StringIO</tt> instance, or could I just do:</p>


<div class="pygments_default"><pre><span></span><span class="k">return</span> <span class="n">csv_buffer</span><span class="o">.</span><span class="n">getvalue</span><span class="p">()</span>
</pre></div>



<p>and let garbage collection take care of releasing the memory allocated
for <tt class="docutils literal">csv_buffer</tt>?</p>
<p>To get Excel to play nice with UTF-8 encoded data it's necessary to
include 3 specific bytes as a Byte Order Mark (BOM) at the beginning
of the file. I did that by prepending them to the heading string for
the first column:</p>


<div class="pygments_default"><pre><span></span><span class="k">def</span> <span class="nf">_build_csv_header</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">...</span><span class="p">)</span>
    <span class="n">UTF_8_BOM</span> <span class="o">=</span> <span class="s1">&#39;</span><span class="se">\xef\xbb\xbf</span><span class="s1">&#39;</span>
    <span class="n">header</span> <span class="o">=</span> <span class="p">[</span>
        <span class="n">UTF_8_BOM</span> <span class="o">+</span> <span class="s1">&#39;Column 1 Heading&#39;</span><span class="p">,</span>
        <span class="o">...</span>
    <span class="p">]</span>
    <span class="k">return</span> <span class="n">header</span>
</pre></div>



<p>Building the content for each row of the CSV file is just a matter of
formatting each query result into an array of strings. Fields
containing non-ASCII characters stored as Unicode need to be encoded
to UTF-8:</p>


<div class="pygments_default"><pre><span></span><span class="k">def</span> <span class="nf">_build_csv_row</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">result</span><span class="p">)</span>
    <span class="n">row</span> <span class="o">=</span> <span class="p">[</span>
        <span class="n">result</span><span class="o">.</span><span class="n">column_1_value</span><span class="p">,</span>
        <span class="s1">&#39;{:%Y-%m-</span><span class="si">%d</span><span class="s1">}&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">result</span><span class="o">.</span><span class="n">some_date</span><span class="p">)</span>
        <span class="o">...</span>
        <span class="n">result</span><span class="o">.</span><span class="n">unicode_value</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s1">&#39;utf-8&#39;</span><span class="p">),</span>
        <span class="o">...</span>
    <span class="p">]</span>
    <span class="k">return</span> <span class="n">row</span>
</pre></div>



<p>I had an additional complication to deal with. The data for one of the
CSV columns is stored in the database as HTML fragments that may
contain non-ASCII characters. That data had to be rendered to Unicode
before it could be added to the CSV row (encoded as UTF-8). It turns
out that the Python standard library provides a fairly painless way of
handling that complication too, but I'll leave that for another post.</p>
</div>
]]></content>
  </entry>
  <entry>
    <author>
      <name></name>
      <uri>http://douglatornell.ca/blog</uri>
    </author>
    <title type="html"><![CDATA[YAML Fixtures in Django Tests]]></title>
    <link rel="alternate" type="text/html" href="http://douglatornell.ca/blog/2012/01/23/yaml-fixtures-in-django-tests"/>
    <id>http://douglatornell.ca/blog/2012/01/23/yaml-fixtures-in-django-tests</id>
    <updated>2012-01-23T16:14:25Z</updated>
    <published>2012-01-23T16:14:25Z</published>
    <category scheme="http://douglatornell.ca/blog" term="python"/>
    <category scheme="http://douglatornell.ca/blog" term="django"/>
    <category scheme="http://douglatornell.ca/blog" term="testing"/>
    <summary type="html"><![CDATA[YAML Fixtures in Django Tests]]></summary>
    <content type="html" xml:base="http://douglatornell.ca/blog/2012/01/23/yaml-fixtures-in-django-tests"><![CDATA[<div class="document">
<p>I have a Django project called <a class="reference external" href="http://randopony.randonneurs.bc.ca/">RandoPony</a> that handles event
registration for the <a class="reference external" href="http://www.randonneurs.bc.ca/">BC Randonneurs Cycling Club</a>. It's on an annual
release cycle; i.e. I spend the few weeks that pass for winter in
Vancouver updating the project. That's when I bump it to the latest
version of Django, fixing minor bugs, and adding new features that I
and other users have come up with during the preceding year. Once I
release a new version for the new year, I usually don't have to worry
about the code until the next winter. The pony just works,
facilitating people doing <a class="reference external" href="http://www.randonneurs.bc.ca/recbook1/part_sum.html">hundreds of thousands of kilometres</a> of
crazy long cycling events, and we like it that way!</p>
<p>My workflow at the beginning of the annual update looks something
like:</p>
<ul class="simple">
<li>Create a new <tt class="docutils literal">virtualenv</tt></li>
<li>Install the latest version of Django and other project dependencies</li>
<li>Read the release notes for the Django releases since the one I was
working with last</li>
<li>Run the RandoPony test suite to find deprecations and other obvious
breakage</li>
<li>Start hacking</li>
</ul>
<p>I recently started working on the 2012 release of RandoPony and was
blown away when I ran the test suite because there were <em>over 60
failing tests!</em> It took me way longer than it should have to figure
out why things were so massively broken.</p>
<p>The problem was that the test fixtures weren't being installed. They
weren't being installed because they are YAML files and I had
forgotten to install PyYAML in the <tt class="docutils literal">virtualenv</tt>. What's really
annoying is that the fixtures files were being ignored silently.</p>
<p>It turns out that if you specify a YAML fixture for a Django
TestCase:</p>


<div class="pygments_default"><pre><span></span><span class="k">class</span> <span class="nc">TestPopulairesListView</span><span class="p">(</span><span class="n">django</span><span class="o">.</span><span class="n">test</span><span class="o">.</span><span class="n">TestCase</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;Functional tests for populaires-list view.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="n">fixtures</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;populaires&#39;</span><span class="p">]</span>
</pre></div>



<p>without giving the fixture file a <tt class="docutils literal">.yaml</tt> extension, the fixture will
be silently ignored if PyYAML isn't installed. Really, Django?!</p>
<p>So, the number 1 thing that I should have done to save myself from
this thrash was to explicitly specify the serialization format of my
fixtures:</p>


<div class="pygments_default"><pre><span></span><span class="k">class</span> <span class="nc">TestPopulairesListView</span><span class="p">(</span><span class="n">django</span><span class="o">.</span><span class="n">test</span><span class="o">.</span><span class="n">TestCase</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;Functional tests for populaires-list view.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="n">fixtures</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;populaires.yaml&#39;</span><span class="p">]</span>
</pre></div>



<p>Then the Django test runner would have told me:</p>


<div class="pygments_default"><pre><span></span>Problem installing fixture &#39;populaires&#39;: yaml is not a known
serialization format.
</pre></div>



<p>I'll take the hit for ignoring the <a class="reference external" href="http://www.python.org/dev/peps/pep-0020/">PEP 20</a> aphorism &quot;Explicit is
better than implicit&quot;. But shouldn't Django get docked for &quot;Errors
should never pass silently&quot;?</p>
<p>The other thing I should have done was use a <a class="reference external" href="http://www.pip-installer.org/en/latest/requirements.html">pip requirements file</a>
for the project.</p>
<p>RandoPony has 2 requirements files now. <tt class="docutils literal">requirements.txt</tt> for the
packages required for the production deployment, and
<tt class="docutils literal"><span class="pre">requirements-dev.txt</span></tt> for the additional packages, like PyYAML,
required for development work. Now I just have to hope that I'm smart
enough when I start work on the 2013 release to do:</p>


<div class="pygments_default"><pre><span></span><span class="o">(</span>randopony<span class="o">)</span>$ pip install -r requirements.txt
<span class="o">(</span>randopony<span class="o">)</span>$ pip install -r requirements-dev.txt
</pre></div>



</div>
]]></content>
  </entry>
  <entry>
    <author>
      <name></name>
      <uri>http://douglatornell.ca/blog</uri>
    </author>
    <title type="html"><![CDATA[Stayin' Alive]]></title>
    <link rel="alternate" type="text/html" href="http://douglatornell.ca/blog/2012/01/08/staying-alive"/>
    <id>http://douglatornell.ca/blog/2012/01/08/staying-alive</id>
    <updated>2012-01-08T17:05:21Z</updated>
    <published>2012-01-08T17:05:21Z</published>
    <category scheme="http://douglatornell.ca/blog" term="python"/>
    <category scheme="http://douglatornell.ca/blog" term="pyramid"/>
    <category scheme="http://douglatornell.ca/blog" term="mysql"/>
    <category scheme="http://douglatornell.ca/blog" term="sqlalchemy"/>
    <summary type="html"><![CDATA[Stayin' Alive]]></summary>
    <content type="html" xml:base="http://douglatornell.ca/blog/2012/01/08/staying-alive"><![CDATA[<div class="document" id="stayin-alive">
<h1 class="title">Stayin' Alive</h1>
<h2 class="subtitle" id="mysql-connection-timeout-and-sqlalchemy-connection-pool-recycling">MySQL Connection Timeout and SQLAlchemy Connection Pool Recycling</h2>
<p>Recently a Pyramid web app surprised me with some odd behaviour. The
app uses SQLAlchemy to interface with a MySQL database. The first
request of the day would always fail with a traceback that ended with
some sort of database connection failure, though not always the same
error. This was happening in the development environment where I was
the only one sending requests to the server. Hitting refresh, or
sending another request resulted in the expected response, and things
would continue to work that way - until the next morning...</p>
<p>The subtitle gives lots of hints about what was going on, so if you're
still reading at this point I'll assume that you're still as puzzled
as I was.</p>
<p>It took a surprising number of tries on Google before I found <a class="reference external" href="http://www.sqlalchemy.org/docs/core/pooling.html?highlight=pool_recycle#setting-pool-recycle">this
section</a> of the SQLAlchemy docs which explains all. To summarize, the
default configuration of MySQL drops connections on which there has
been no activity for 8 hours. SQLAlchemy provides the <tt class="docutils literal">pool_recycle</tt>
parameter for its engine creation functions as a way of working around
that behaviour. (Although, as noted in the <a class="reference external" href="http://www.sqlalchemy.org/docs/core/engines.html?highlight=pool_recycle#engine-creation-api">SQLAlchemy Engine creation
API docs</a> full description of <tt class="docutils literal">pool_recycle</tt>, the behaviour is also
configurable at the MySQLDB connection, and database configuration
levels too.)</p>
<p>Since my Pyramid app uses the <tt class="docutils literal">sqlalchemy.engine_from_config</tt>
function, all I had to do was add:</p>


<div class="pygments_default"><pre><span></span><span class="na">sqlalchemy.pool_recycle</span> <span class="o">=</span> <span class="s">3600</span>
</pre></div>



<p>to my <tt class="docutils literal">development.ini</tt> and <tt class="docutils literal">production.ini</tt> config files, and ... problem
solved.</p>
<p>P.S. Sorry - I couldn't resist the <a class="reference external" href="http://www.youtube.com/watch?v=I_izvAbhExY">Bee Gees reference</a> in the
title. It's an age thing...</p>
</div>
]]></content>
  </entry>
  <entry>
    <author>
      <name></name>
      <uri>http://douglatornell.ca/blog</uri>
    </author>
    <title type="html"><![CDATA[2012 Python Meme]]></title>
    <link rel="alternate" type="text/html" href="http://douglatornell.ca/blog/2011/12/30/2012-python-meme"/>
    <id>http://douglatornell.ca/blog/2011/12/30/2012-python-meme</id>
    <updated>2011-12-30T14:49:46Z</updated>
    <published>2011-12-30T14:49:46Z</published>
    <category scheme="http://douglatornell.ca/blog" term="python"/>
    <summary type="html"><![CDATA[2012 Python Meme]]></summary>
    <content type="html" xml:base="http://douglatornell.ca/blog/2011/12/30/2012-python-meme"><![CDATA[<div class="document">
<p>Following <a class="reference external" href="http://tarekziade.wordpress.com/2011/12/20/new-years-python-meme-2/">Tarek Ziade's lead</a>:</p>
<ol class="arabic">
<li><p class="first"><strong>What’s the coolest Python application, framework or library you
have discovered in 2011?</strong></p>
<p>It's a toss-up between <a class="reference external" href="http://docs.pylonsproject.org/en/latest/docs/pyramid.html">Pyramid</a> and <a class="reference external" href="http://docs.python-requests.org/en/latest/index.html">requests</a>.</p>
<p>For the admittedly small, specialized application that I've used
Pyramid for, I like how the framework interface is largely confined
to the <tt class="docutils literal">__init__.py</tt> module. Outside of that I find myself just
writing Python code to get stuff done and throwing in a few
decorators here and there to link into the framework. I find the
Pyramid docs to be really well organized, informative, and
complete. They worked for me at the introductory level (though I
did arrive with quite a bit of experience of other Python web
frameworks) and continue to work as I dig deeper and do more
advanced things.</p>
<p>Requests has made my life so much better in several projects,
whether its collecting data from well structured web services or
scraping hydrometric data from a particularly annoying Government
of Canada site.</p>
</li>
<li><p class="first"><strong>What new programming technique did you learn in 2011?</strong></p>
<p>I got a lot better at writing simple, clean, uncoupled unit tests,
inspired in large part by the <a class="reference external" href="http://docs.pylonsproject.org/en/latest/community/testing.html">Pyramid unit testing guidelines</a>. I
shifted from being a skeptic to a proponent of mocking thanks to
the <a class="reference external" href="http://www.voidspace.org.uk/python/mock/">mock</a> library. I was spurred in that by the need to refactor a
test suite that had become way too slow to be useful.</p>
<p>I also got a lot more proficient in JavaScript, using it for
client-side stuff in web apps, database views for CouchDB, and a
Firefox add-on.</p>
</li>
<li><p class="first"><strong>What’s the name of the open source project you contributed the
most in 2011? What did you do?</strong></p>
<p><a class="reference external" href="http://couchdbkit.org/">CouchDBkit</a>. I spent most of my time at the PyCon 2011 sprints
adding the <tt class="docutils literal">SetProperty</tt> and <tt class="docutils literal">LazySet</tt> class to store Python
sets as lists of unique elements in CouchDB. I also added some
missing Python list methods to the <tt class="docutils literal">LazyList</tt> class. It was a
good learning experience in the realm of subclassing Python
builtins. It was also cool to work sitting beside <a class="reference external" href="http://twitter.com/#!/benoitc">&#64;benoitc</a> (the
CouchDBkit lead developer) in contrast to communicating
electronically across 9 time zones.</p>
</li>
<li><p class="first"><strong>What was the Python blog or website you read the most in 2011?</strong></p>
<p>The <a class="reference external" href="http://planet.python.org/">Planet Python</a> feed, by far.</p>
</li>
<li><p class="first"><strong>What are the three top things you want to learn in 2012?</strong></p>
<ul class="simple">
<li>Message passing systems. I've got a Django project that needs to
get some asynchronicity and I'm planning to explore <a class="reference external" href="http://celeryproject.org/">Celery</a> for
that.</li>
<li>More message passing systems. I've got some devops issues around
server synchronization and failover that I think I might be able
to address with <a class="reference external" href="http://www.zeromq.org/">ZeroMQ</a>.</li>
<li>Python 3. Because it's time! Most of the libraries that I use
have already been ported, so the transition shouldn't be
overwhelmingly difficult, and perhaps I can lend a hand porting
some of the libraries that I need that haven't made the jump yet.</li>
</ul>
</li>
<li><p class="first"><strong>What are the top software, app or lib you wish someone would
write in 2012?</strong></p>
<p>I wish there were more open source libraries and applications in
the home automation realm. One of my first personal Python projects
was a wrapper around <a class="reference external" href="http://www.heyu.org/">heyu</a> to make our house look lived in when we
are away. It's still working okay after nearly 6 years, but the X10
hardware it interfaces with is getting rather long in the
tooth. Sadly, newer home automation hardware and protocols seem to
be mired in the muck of &quot;vendor associations&quot; that only pay lip
service to openness.</p>
</li>
</ol>
<p>Want to do your own list ? here’s how:</p>
<ul class="simple">
<li>copy-paste the questions and answer to them in your blog</li>
<li>tweet it with the <a class="reference external" href="http://twitter.com/#!/search/%232012pythonmeme">#2012pythonmeme</a> hashtag</li>
</ul>
</div>
]]></content>
  </entry>
  <entry>
    <author>
      <name></name>
      <uri>http://douglatornell.ca/blog</uri>
    </author>
    <title type="html"><![CDATA[New Blog for Christmas]]></title>
    <link rel="alternate" type="text/html" href="http://douglatornell.ca/blog/2011/12/28/new-blog-for-christmas"/>
    <id>http://douglatornell.ca/blog/2011/12/28/new-blog-for-christmas</id>
    <updated>2012-01-02T16:21:32Z</updated>
    <published>2011-12-28T17:19:47Z</published>
    <category scheme="http://douglatornell.ca/blog" term="blog maintenance"/>
    <category scheme="http://douglatornell.ca/blog" term="python"/>
    <summary type="html"><![CDATA[New Blog for Christmas]]></summary>
    <content type="html" xml:base="http://douglatornell.ca/blog/2011/12/28/new-blog-for-christmas"><![CDATA[<div class="document">
<p>I decided to give myself a new blog for Christmas. All of <a class="reference external" href="http://sadahome.ca/blogs/doug.php">my</a> <a class="reference external" href="http://sadahome.ca/blogs/adventures.php">other</a>
<a class="reference external" href="http://sadahome.ca/blogs/paradocs.php">blogs</a> are based on <a class="reference external" href="http://b2evolution.net">b2evolution</a>. It has served me well for years but
I don't use much of its functionality, and hate dealing with its
comment spam issues so much that I've turned off comments on all of
those blogs. Most of all though, I want to use <a class="reference external" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> to
write blog posts, just like I use it to write the vast majority of
other content and docs that I create.</p>
<p><a class="reference external" href="http://blogofile.com">Blogofile</a> caught my eye a while ago, not just because it easy
supports reStructuredText markup, but also because:</p>
<ul class="simple">
<li>it simplifies the blogging workflow to:<ul>
<li>write in your favourite editor</li>
<li>build</li>
<li>upload</li>
</ul>
</li>
<li>it gets rid of the overhead of a blogging app and database backend</li>
<li>it fits nicely into a version control workflow</li>
<li>it encourages delegation of comments, etc. (and the related spam
issues) to <a class="reference external" href="http://disqus.com">Disqus</a></li>
</ul>
<div class="section" id="in-for-a-penny-in-for-a-python-3-pound">
<h1>In for a Penny, in for a Python 3 Pound</h1>
<p>There are <a class="reference external" href="http://blogofile.com/blog/2011/04/30/preview-of-blogofile-0.8/">lots of cool features</a> in the development version of
Blogofile, but running it requires Python 3. That's okay with me
though because with <a class="reference external" href="http://pypi.python.org/pypi?:action=browse&amp;c=533&amp;show=all">all the libraries and frameworks that run under
Python 3 now</a> it's about time I started to use it for something
serious.</p>
<p>A couple of observations:</p>
<ul class="simple">
<li>I still have Python 2.6 set as my default version (for now), so
that's what <a class="reference external" href="http://pypi.python.org/pypi/virtualenv">virtualenv</a> runs under. But <tt class="docutils literal">virtualenv <span class="pre">-p</span> python3
<span class="pre">blogofile-dev</span></tt> happily built a Python 3 virtualenv for me to
install Blogofile and its dependencies in. Is there no end to the
awesome that virtualenv delivers?!</li>
<li>I installed Blogofile with <tt class="docutils literal">python setup.py develop</tt> and noticed
some pauses as the various dependency libraries were being installed
in the virtualenv that were longer than what I'm used to when those
libraries are installed under Python 2. My totally uninformed guess
is that pauses were due to <tt class="docutils literal">2to3</tt> being run in the libraries'
setup.</li>
</ul>
<p>So far I've had no need to touch Python code in the Blogofile
context. It has all been <a class="reference external" href="http://www.makotemplates.org">Mako</a>, HTML5, CSS and reStructuredText so
far. Perhaps when I start to write a converter to migrate old posts
from <a class="reference external" href="http://sadahome.ca/blogs/doug.php">sadahome.ca/blogs/doug.php</a> to here I'll have more to say on the
differences between Python 3 and Python 2.</p>
</div>
<div class="section" id="a-whole-new-site-actually">
<h1>A Whole New Site, Actually</h1>
<p>Blogofile is more than a blogging tool though; it's a static site
builder. So, I took the opportunity to add some structure and style to
the whole <tt class="docutils literal">douglatornell.ca</tt> site. Migrating the content was easy,
largely because it was already all in reStructuredText markup. The
biggest time-sink was my attempt to create a new theme with a
different colour scheme. Once again I was reminded at how badly I suck
at the design aspect of web development. I settled for changing the
title font to something that looks less like Comic Sans.</p>
</div>
<div class="section" id="things-that-still-need-to-be-done">
<h1>Things That Still Need to be Done</h1>
<p><em>Updated 2011-12-29 20:52:51</em></p>
<ul class="simple">
<li><span class="strikethrough">Automate the process of pushing new content to
Webfaction (affiliate link), either via a Mercurial hook, or a
Fabric task, in contrast to the manual rsync command I'm using now</span>
Getting a <a class="reference external" href="https://groups.google.com/forum/#!topic/blogofile-discuss/4D-UKzZVIY4">Mercurial hook</a> working turned out to be pretty easy.</li>
</ul>
<p><em>Updated 2012-01-02 16:21:32</em></p>
<ul class="simple">
<li><span class="strikethrough">Use Disqus for comments</span> Incredibly easy!</li>
<li>Migrate at least the Python-related content from sadahome.ca/blogs/doug.php</li>
<li>Convert the <a class="reference external" href="http://pypi.python.org/pypi/nosy">Nosy</a> docs to <a class="reference external" href="http://sphinx.pocoo.org/">Sphinx</a> and move them to <a class="reference external" href="http://readthedocs.org/">Read the Docs</a></li>
</ul>
<p><em>Updated 2012-01-02 10:18:37</em></p>
<ul class="simple">
<li><span class="strikethrough">Add a Flickr badge to display a selection of my
images in the sidebar</span> Done, though the <a class="reference external" href="http://www.flickr.com/badge.gne">Flickr badge</a> markup is
pretty old and crufty looking, so I may revisit this to try to do
something more modern using <a class="reference external" href="http://jquery.com/">jQuery</a>.</li>
</ul>
</div>
</div>
]]></content>
  </entry>
</feed>
