<?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">MorganGoose.com</title>
  <subtitle type="text">notes about various technical subjects</subtitle>

  <updated>2016-12-08T01:14:37Z</updated>
  <generator uri="http://blogofile.com/">Blogofile</generator>

  <link rel="alternate" type="text/html" href="http://morgangoose.com/blog" />
  <id>http://morgangoose.com/blog/feed/atom/</id>
  <link rel="self" type="application/atom+xml" href="http://morgangoose.com/blog/feed/atom/" />
  <entry>
    <author>
      <name></name>
      <uri>http://morgangoose.com/blog</uri>
    </author>
    <title type="html"><![CDATA[Using the parallel branch of Fabric]]></title>
    <link rel="alternate" type="text/html" href="http://morgangoose.com/blog/2011/01/06/using-the-parallel-branch-of-fabric" />
    <id>http://morgangoose.com/blog/2011/01/06/using-the-parallel-branch-of-fabric</id>
    <updated>2011-01-06T18:50:48Z</updated>
    <published>2011-01-06T18:50:48Z</published>
    <category scheme="http://morgangoose.com/blog" term="Programming" />
    <summary type="html"><![CDATA[Using the parallel branch of Fabric]]></summary>
    <content type="html" xml:base="http://morgangoose.com/blog/2011/01/06/using-the-parallel-branch-of-fabric"><![CDATA[<div class="document" id="changes-and-notes">
<h1 class="title">Changes and Notes</h1>
<p>So I've updated the branch to add in a useful bit for the parallel decorator.
I also need to talk out a few things related to it's use in the environment
and some bugs or hiccups one might run into trying to use it. Hopefully I'll
be hitting this up some more soon, and pulling some more of the crazy cool
updates that people have been making to fabric trunk. I have a to-do list,
let me know if you want me to add anything to it!</p>
<div class="section" id="additional-feature">
<h1>Additional feature</h1>
<p>So there's always been a flag to make the pool size of the bubble, and that was
nice, but I wanted a way to make these more permanent as well as simpler to
remember. So it's now an option in the runs_parallel decorator. To use it you'd
just simply give it a size to use:</p>
<div class="highlight"><pre><span class="c">#!/usr/bin/env python</span>

<span class="kn">from</span> <span class="nn">fabric.api</span> <span class="kn">import</span> <span class="o">*</span>

<span class="n">env</span><span class="o">.</span><span class="n">hosts</span> <span class="o">=</span> <span class="p">[</span><span class="s">&#39;host</span><span class="si">%2d</span><span class="s">.com&#39;</span> <span class="o">%</span> <span class="n">x</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">20</span><span class="p">)]</span>

<span class="nd">@runs_parallel</span><span class="p">(</span><span class="n">with_bubble_of</span><span class="o">=</span><span class="mi">10</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">poke</span><span class="p">():</span>
    <span class="n">run</span><span class="p">(</span><span class="s">&#39;uptime&#39;</span><span class="p">)</span>
</pre></div>
<p>This I feel makes a cleaner fabfile, and puts this information where it should
be, in the code, and out of the writer's head.</p>
</div>
<div class="section" id="how-to-use-both-ways-or-just-one">
<h1>How to use both ways, or just one</h1>
<p>A big thing to note in using parallel tasks, is that anything put into shared
variables, like env, is <strong>forgotten</strong> outside the execution of the one instance of
the task. So if you don't add a &#64;runs_once or &#64;runs_sequential decorator to a
task that say sets the env.hosts before an actual parallel task, the work done
inside the env setting task is forgotten.</p>
<p>The reason adding these decorators addresses this, is that by adding them, the
task isn't executed using the parallel bits. It is instead run inside the main
fab process, and isn't creating a fork pool of size 1 and forgetting about it
when the fork is finished executing.</p>
<p>So as an example, if one were to try and run a fabfile w/o setting up
decorators for their functions, and running: <em>fab -P set_hosts uptime</em></p>
<div class="highlight"><pre><span class="c">#!/usr/bin/env python</span>

<span class="kn">from</span> <span class="nn">fabric.api</span> <span class="kn">import</span> <span class="n">env</span><span class="p">,</span> <span class="n">local</span><span class="p">,</span> <span class="n">run</span><span class="p">,</span> <span class="n">sudo</span>

<span class="n">env</span><span class="o">.</span><span class="n">hosts</span> <span class="o">=</span> <span class="p">[</span><span class="s">&#39;somehost.com&#39;</span><span class="p">]</span>

<span class="k">def</span> <span class="nf">set_hosts</span><span class="p">():</span>
    <span class="n">env</span><span class="o">.</span><span class="n">hosts</span> <span class="o">=</span> <span class="p">[</span><span class="s">&#39;web-0&#39;</span><span class="p">,</span> <span class="s">&#39;web-1&#39;</span><span class="p">]</span>

<span class="k">def</span> <span class="nf">uptime</span><span class="p">():</span>
    <span class="n">run</span><span class="p">(</span><span class="s">&#39;uptime&#39;</span><span class="p">)</span>
</pre></div>
<p>They'd get into an issue where the set_hosts not being specifically set to run
sequential or once, would have the settings it made to the env.hosts var only
apply inside the task, since it's been forked out. Which would cause the uptime
to only run on somehost.com, and not both web-0 and web-1 as expected.</p>
<div class="section" id="fixing-it">
<h2>Fixing it</h2>
<p>To get around this the tasks that need to set variable globally, and affect
other tasks later will need to be decorated to not use forking. Below is the
same fabfile tweaked to do so, as well as explicitly state how functions should
behave.</p>
<p>Note that setting up a task to <em>&#64;runs_once</em> will be backwards compatible,
but <em>&#64;runs_parallel</em> isn't. The added benefit to this being that one can drop
using the <em>-P</em> flag, as neither task in this example can switch hit.</p>
<div class="highlight"><pre><span class="c">#!/usr/bin/env python</span>

<span class="kn">from</span> <span class="nn">fabric.api</span> <span class="kn">import</span> <span class="o">*</span>

<span class="c">#thanks to Eric who pointed this out, visit his site, it&#39;s neat</span>
<span class="n">env</span><span class="o">.</span><span class="n">hosts</span> <span class="o">=</span> <span class="p">[</span><span class="s">&#39;ericholscher.com&#39;</span><span class="p">]</span>

<span class="nd">@runs_once</span>
<span class="k">def</span> <span class="nf">set_hosts</span><span class="p">():</span>
    <span class="n">env</span><span class="o">.</span><span class="n">hosts</span> <span class="o">=</span> <span class="p">[</span><span class="s">&#39;web-0&#39;</span><span class="p">,</span> <span class="s">&#39;web-1&#39;</span><span class="p">]</span>

<span class="nd">@runs_parallel</span>
<span class="k">def</span> <span class="nf">uptime</span><span class="p">():</span>
    <span class="n">run</span><span class="p">(</span><span class="s">&#39;uptime&#39;</span><span class="p">)</span>
</pre></div>
</div>
</div>
<div class="section" id="maybe-it-ll-help">
<h1>Maybe it'll help</h1>
<p>As a boon to people using both the parallel branch and Trunk, on a single
fabfile, note that which one is being used can be determined at runtime using
some silly introspection:</p>
<div class="highlight"><pre><span class="o">&gt;&gt;&gt;</span> <span class="kn">from</span> <span class="nn">fabric</span> <span class="kn">import</span> <span class="n">decorators</span>
<span class="o">&gt;&gt;&gt;</span> <span class="nb">dir</span><span class="p">(</span><span class="n">decorators</span><span class="p">)</span>
<span class="p">[</span><span class="s">&#39;StringTypes&#39;</span><span class="p">,</span> <span class="s">&#39;__builtins__&#39;</span><span class="p">,</span> <span class="s">&#39;__doc__&#39;</span><span class="p">,</span> <span class="s">&#39;__file__&#39;</span><span class="p">,</span> <span class="s">&#39;__name__&#39;</span><span class="p">,</span>
<span class="s">&#39;__package__&#39;</span><span class="p">,</span> <span class="s">&#39;_parallel&#39;</span><span class="p">,</span> <span class="s">&#39;_sequential&#39;</span><span class="p">,</span> <span class="s">&#39;hosts&#39;</span><span class="p">,</span> <span class="s">&#39;is_parallel&#39;</span><span class="p">,</span>
<span class="s">&#39;is_sequential&#39;</span><span class="p">,</span> <span class="s">&#39;needs_multiprocessing&#39;</span><span class="p">,</span> <span class="s">&#39;roles&#39;</span><span class="p">,</span> <span class="s">&#39;runs_once&#39;</span><span class="p">,</span>
<span class="s">&#39;runs_parallel&#39;</span><span class="p">,</span> <span class="s">&#39;runs_sequential&#39;</span><span class="p">,</span> <span class="s">&#39;wraps&#39;</span><span class="p">]</span>
<span class="o">&gt;&gt;&gt;</span> <span class="s">&quot;runs_once&quot;</span> <span class="ow">in</span> <span class="nb">dir</span><span class="p">(</span><span class="n">decorators</span><span class="p">)</span>
<span class="bp">True</span>
</pre></div>
<p>So one could just flip a Boolean and decorate/use things accordingly. Though I
suggest using &#64;runs_once on any tasks that are just that, single shots that do
stuff local, or set vars for the fabfile, and to reserve using &#64;runs_sequential
for tasks that still need to have multiple hosts, but need to not run side by
side.</p>
</div>
<div class="section" id="bug-outstanding">
<h1>Bug outstanding</h1>
<p>Finally there is a outstanding bug with use of this branch on windows,
<a class="reference external" href="https://github.com/goosemo/fabric/issues#issue/5">https://github.com/goosemo/fabric/issues#issue/5</a>, that'll bite people. I'll try
and work this out, but I'm a bad developer and am dragging my feet on having to
install windows to debug this. But it's the new year so I'll make it a
resolution, and we all know people never drop those.</p>
<p><strong>I've updated this a bit since the first push of the post</strong></p>
</div>
</div>
]]></content>
  </entry>
  <entry>
    <author>
      <name>Morgan Goose</name>
      <uri>http://morgangoose.com/blog</uri>
    </author>
    <title type="html"><![CDATA[Parallel execution with fabric]]></title>
    <link rel="alternate" type="text/html" href="http://morgangoose.com/blog/2010/10/08/parallel-execution-with-fabric" />
    <id>http://morgangoose.com/blog/2010/10/08/parallel-execution-with-fabric</id>
    <updated>2010-10-08T19:00:15Z</updated>
    <published>2010-10-08T19:00:15Z</published>
    <category scheme="http://morgangoose.com/blog" term="Programming" />
    <summary type="html"><![CDATA[Parallel execution with fabric]]></summary>
    <content type="html" xml:base="http://morgangoose.com/blog/2010/10/08/parallel-execution-with-fabric"><![CDATA[<div class="document">
<div class="section" id="it-s-been-a-wish-for-some-for-a-long-time">
<h1>It's been a wish for some for a long time</h1>
<p>Since at least <a class="reference external" href="http://code.fabfile.org/issues/show/19">07/21/2009</a> the
desire to have fully parallel execution across hosts, or something similar to
that.  I stumbled upon the thread around March of this year.  Being that I'd
been using <a class="reference external" href="http://docs.fabfile.org">Fabric</a> for a number of months at this point, and had recently made
a script set for work stuff that leveraged <a class="reference external" href="http://docs.python.org/library/multiprocessing.html">multiprocessing</a> I decided to give
the issue a go.</p>
</div>
<div class="section" id="what-i-implemented-and-why">
<h1>What I implemented, and why</h1>
<p>The short of it being that I made a data structure, <a class="reference external" href="http://github.com/goosemo/job_queue">Job_Queue</a> that I feed fab
tasks into and it will keep a running 'bubble' (works like a pool) of
multiprocessing Processes going executing the <a class="reference external" href="http://docs.fabfile.org">Fabric</a> tasks as they are able
to do so. The job queue having a pool size as set by the user, or 1/2 the size
of the host list if not specified, or if the pool size is larger than the host
list size, it will match the host list size.</p>
<div class="section" id="why-not-threads">
<h2>Why not threads?</h2>
<p>Because they won't do what I want parallel execution in <a class="reference external" href="http://docs.fabfile.org">Fabric</a> to accomplish.
Namely</p>
<ul class="simple">
<li>I can't be sure that the task is only IO bound as users can call anything
as it 'just python', and the GIL will trip up fully parallel tasks.</li>
<li>With threads there is an issue noted in the docs about <a class="reference external" href="http://docs.python.org/library/threading.html#importing-in-threaded-code">importing in threaded
code</a> which is something a user of <a class="reference external" href="http://docs.fabfile.org">Fabric</a> is more than welcome to do.</li>
<li>The need for inter-process communication isn't there. Tasks are by their
nature encapsulated, and don't talk to one another when being run.</li>
</ul>
</div>
<div class="section" id="ok-so-why-not-x-instead">
<h2>OK so why not X instead?</h2>
<p>There seems to have been a glut of good work done recently in the python
ecosystem on getting around the issues people are having with the GIL. Some
names that I can recall being <a class="reference external" href="http://twistedmatrix.com/documents/current/core/howto/threading.html">Twisted</a>, <a class="reference external" href="http://www.tornadoweb.org/documentation#low-level-modules">Tornado</a>, <a class="reference external" href="http://www.boddie.org.uk/python/pprocess.html">pprocess</a>, and <a class="reference external" href="http://www.parallelpython.com/">PP</a>. I am
sure there are a lot more. There also the neat looking <a class="reference external" href="http://codespeak.net/execnet/">execnet</a> project that
offers direct communication to a python interpreter over an open socket.</p>
<p>Those got tossed out because they each have something that causes them to not
fit some or all three requirements I gave modules to use.</p>
<ul class="simple">
<li>Cross platform Win/Mac/Linux</li>
<li>Works on Python 2.5+</li>
<li>Is in the stdlib</li>
</ul>
<p>All of those fail the last requirement, and granted it perhaps wouldn't be hard
to get users to install yet another dep, but it is best to avoid things like
that if at all possible. Keeps the moving parts down, and the issues you have
to debug less foreign. Note though that the other two criteria I set could
actually be met by any in list above, I am writing this much removed from my
initial decision process.</p>
</div>
<div class="section" id="so-forks-why-create-a-new-queue-pool">
<h2>So forks, why create a new Queue/Pool?</h2>
<p>Trickery.</p>
<p>The <a class="reference external" href="http://docs.python.org/library/multiprocessing.html">multiprocessing</a> module has a lot of really nice builtins that I attempted
to leverage, but there really just wasn't a way to do what I needed to do with
them. Queue was nice for having a list of Processes, but I needed a worker
pool. Pool provided this, but then the workers were anonymous, and I wasn't
able to set names as a cheap way to keep track of which host it was to run on.</p>
<p>So I had to make something up. That's what <a class="reference external" href="http://github.com/goosemo/job_queue">Job_Queue</a> is for. All it does if
take a load of Processes and then when the job queue is closed, one starts it,
and off it goes. It'll make a bubble of a certain size that it will keep the
number of currently running forks under, and will just move that bubble along
the internal queue it had from the loading.</p>
<p>So it looks a bit like this:</p>
<pre class="literal-block">
---------------------------
[-----]--------------------
---[-----]-----------------
---------[-----]-----------
------------------[-----]--
--------------------[-----]
---------------------------
</pre>
<p>The trickery comes in when in the fabric job_queue.py I set the job.name of the
Process to the host, and inside the queue I leverage this with:</p>
<pre class="literal-block">
env.host_string = env.host = job.name
job.start()
self._running.append(job)
</pre>
<p>Which will set the host for the task at run time, since otherwise <a class="reference external" href="http://docs.fabfile.org">Fabric</a> would
have gotten confused. It would have continued to iterate the same host, because
of the shared state env and it's host list isn't really able to be progressed,
because the forks aren't sharing it anymore, and are instead working in
isolation from one another.</p>
<p>While that could have been a reason to use threads, or something like the
Manager that <a class="reference external" href="http://docs.python.org/library/multiprocessing.html">multiprocessing</a> offers, it's really the only time it comes up,
and it keeps things a lot simper at the moment. Not to say that if someone is
convincing enough I'd probably get behind a more robust solution.</p>
</div>
</div>
<div class="section" id="what-this-branch-adds-to-fabric">
<h1>What this branch adds to Fabric</h1>
<p>There are new command flags for fab:</p>
<pre class="literal-block">
-P, --parallel        use the multiprocessing module to fork by hosts
-z FORKS, --pool-size=FORKS Set the number of forks to use in the pool.
</pre>
<p>I have also added two decorators:</p>
<pre class="literal-block">
&#64;runs_parallel
&#64;runs_sequential
</pre>
<p>These will allow a fab file command to be set to be run either in parallel or
sequentially regardless of the fab command flag. Without these commands switch
when the flag is set.</p>
<p>What that means is that any tasks that are decorated are always run as either
parallel or sequential. Tasks that omit these decorators though, are going to
be able to switch back and forth between running parallel or running
sequentially. Something the user would be specifying at run time with the -P
flag.</p>
</div>
<div class="section" id="with-the-new-stuff-comes-a-few-caveats">
<h1>With the new stuff comes a few caveats</h1>
<p>If you are interested in the guts, the implementation is in the main.py file,
and uses the Job_Queue class in the job_queue.py file. Note that this is only
implemented in the fab command, as there is no way to determine how one will
execute functions if they are using Fabric as a helper library.</p>
<p>If the runs_once decorator is being used on a function that is called from
inside a fabric task, it won't be able to be honored. Because the states in the
forks are separate, and every fork will think it's the first one to run the
function. Simple solution being to make the call it's own task call.</p>
</div>
<div class="section" id="now-to-see-it-in-use">
<h1>Now to see it in use</h1>
<p>Here is a little example of a fab file that is running some command on the
server that will take 10 seconds to run. Yeah sleep is a bit of cheat for this,
but it's good enough to show the benefit of forking out tasks that'd take a
crap ton of time otherwise</p>
<div class="highlight"><pre><span class="kn">from</span> <span class="nn">fabric.api</span> <span class="kn">import</span> <span class="o">*</span>
<span class="kn">from</span> <span class="nn">server_list</span> <span class="kn">import</span> <span class="n">servers</span>

<span class="n">env</span><span class="o">.</span><span class="n">roledefs</span> <span class="o">=</span> <span class="n">servers</span><span class="o">.</span><span class="n">server_classes</span>

<span class="nd">@roles</span><span class="p">(</span><span class="s">&#39;servers&#39;</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">poke</span><span class="p">():</span>
    <span class="n">run</span><span class="p">(</span><span class="s">&quot;sleep 10&quot;</span><span class="p">)</span>
</pre></div>
<div class="section" id="running-it">
<h2>Running it</h2>
<p>In parallel, as specified on the cli. Note that this is an example of not in
using the decorators to set this in the code, so it as a task/function can
toggle between being run in parallel or sequentially. There are 49 servers in
the 'servers' list that I'm applying to this task.</p>
<div class="highlight"><pre><span class="nv">$ </span><span class="nb">time </span>fab poke -P -z 20
...

real   0m45.868s
user   1m7.928s
sys    0m8.425s
</pre></div>
<p>Now the long runner. It takes ... forever.</p>
<div class="highlight"><pre><span class="nv">$ </span><span class="nb">time </span>fab poke
...

real   8m51.477s
user   6m3.239s
sys    1m26.637s
</pre></div>
<p>The difference is pretty dramatic. We get a 8 min fab task dropped down to less
than one min.</p>
</div>
<div class="section" id="just-cause-i-though-it-was-neat">
<h2>Just cause I though it was neat</h2>
<p>This is a glimpse of what it'll look like in the process tree. Those are the
forks running their tasks, and the children under them are the threads that
<a class="reference external" href="http://github.com/bitprophet">bitprophet</a> added into <a class="reference external" href="http://docs.fabfile.org">Fabric</a> core for greatly improved stream handling.</p>
<div class="highlight"><pre><span class="nv">$ </span>pstree -paul
...
│   ├─bash,20062
│   │   └─fab,21455 /home/mgoose/.virtualenvs/fabric-merge/bin/fab poke -P -z 20
│   │       ├─fab,21462 /home/mgoose/.virtualenvs/fabric-merge/bin/fab poke -P -z 20
│   │       │   └─<span class="o">{</span>fab<span class="o">}</span>,21493
│   │       ├─fab,21463 /home/mgoose/.virtualenvs/fabric-merge/bin/fab poke -P -z 20
│   │       │   ├─<span class="o">{</span>fab<span class="o">}</span>,21484
│   │       │   ├─<span class="o">{</span>fab<span class="o">}</span>,21505
│   │       │   ├─<span class="o">{</span>fab<span class="o">}</span>,21511
│   │       │   └─<span class="o">{</span>fab<span class="o">}</span>,21517
│   │       ├─fab,21464 /home/mgoose/.virtualenvs/fabric-merge/bin/fab poke -P -z 20
│   │       │   └─<span class="o">{</span>fab<span class="o">}</span>,21487
│   │       ├─fab,21465 /home/mgoose/.virtualenvs/fabric-merge/bin/fab poke -P -z 20
│   │       │   ├─<span class="o">{</span>fab<span class="o">}</span>,21483
│   │       │   ├─<span class="o">{</span>fab<span class="o">}</span>,21502
│   │       │   ├─<span class="o">{</span>fab<span class="o">}</span>,21503
│   │       │   └─<span class="o">{</span>fab<span class="o">}</span>,21504
...
<span class="o">(</span>16 more fab lines<span class="o">)</span>
</pre></div>
</div>
</div>
<div class="section" id="use-it-and-let-me-know">
<h1>Use it and let me know</h1>
<p>I'd love to hear how people are using this, and if they find any holes in my
implementation. I've got a few more things I want/need to add into this, and
I've got them listed in the <a class="reference external" href="http://github.com/goosemo/fabric/issues">github issues</a> just until this gets integrated
into the <a class="reference external" href="http://docs.fabfile.org">Fabric</a> mainline.</p>
</div>
</div>
]]></content>
  </entry>
  <entry>
    <author>
      <name>Morgan Goose</name>
      <uri>http://morgangoose.com/blog</uri>
    </author>
    <title type="html"><![CDATA[Getting twitter feed running for Blogofile]]></title>
    <link rel="alternate" type="text/html" href="http://morgangoose.com/blog/2010/09/28/getting-twitter-feed-running-for-blogofile" />
    <id>http://morgangoose.com/blog/2010/09/28/getting-twitter-feed-running-for-blogofile</id>
    <updated>2010-09-28T19:21:05Z</updated>
    <published>2010-09-28T19:21:05Z</published>
    <category scheme="http://morgangoose.com/blog" term="Website" />
    <category scheme="http://morgangoose.com/blog" term="Programming" />
    <summary type="html"><![CDATA[Getting twitter feed running for Blogofile]]></summary>
    <content type="html" xml:base="http://morgangoose.com/blog/2010/09/28/getting-twitter-feed-running-for-blogofile"><![CDATA[<div class="document">
<div class="section" id="a-small-part-to-making-it-match">
<h1>A small part to making it match</h1>
<p><a class="reference external" href="http://wordpress.org">Wordpress</a> has plugins, lots and lots of plugins. In my conversion from it to
<a class="reference external" href="http://www.blogofile.com">blogofile</a> I wanted to make it match my old site as closely as I could. Having
a twitter feed of my latest tweets was something I'd have to get on the site.</p>
</div>
<div class="section" id="fails">
<h1>Fails</h1>
<p>I though I might make a python api call and then pipe that into my sidebar.
This worked. But it sucked because I'd have to rebuild the page every tweet. I
don't mind static content for my posts and navigation and the like. That's just
good caching I feel.</p>
<p>Tweets though are a constantly, or would be for anyone else but me, updating
service.</p>
</div>
<div class="section" id="in-comes-the-javascript">
<h1>In comes the JavaScript</h1>
<p>So in looking for simple things to give me a twitter feed I found Remy Sharp's
site and his <a class="reference external" href="http://remysharp.com/2007/05/18/add-twitter-to-your-blog-step-by-step/">directions</a> on how to put a javascript based feed into a site.</p>
<p>It was simple as could be, and I had a base, but hard coded feed up an running
in short order.</p>
</div>
<div class="section" id="making-it-better-for-blogofile-users">
<h1>Making it better for blogofile users</h1>
<p>Part of open source is giving back. Something I really want to do more of, and I
feel am getting into the swing of it a bit more. But that's whatever, I found
the useful and perfect plugin, and got it working in <a class="reference external" href="http://www.blogofile.com">blogofile</a> without much
trouble.</p>
<p>I now started thinking about how others might like to use this and would not
really want to hard code it too much. So I made it into a controller, and
configurable by the <strong>_config.py</strong> file. I made it kinda simple, but a bit
overkilled with the folder and an __init__.py, but I was aiming for it to be
more work.</p>
<div class="section" id="controllers-tweets-init-py">
<h2>_controllers/tweets/__init__.py</h2>
<div class="highlight"><pre><span class="kn">import</span> <span class="nn">logging</span>

<span class="kn">from</span> <span class="nn">blogofile.cache</span> <span class="kn">import</span> <span class="n">bf</span>

<span class="n">config</span> <span class="o">=</span> <span class="p">{</span>
    <span class="s">&quot;name&quot;</span><span class="p">:</span> <span class="s">&quot;Twitter&quot;</span><span class="p">,</span>
    <span class="s">&quot;description&quot;</span><span class="p">:</span> <span class="s">&quot;Makes a sidebar widget for twitter&quot;</span><span class="p">,</span>
    <span class="s">&quot;priority&quot;</span><span class="p">:</span> <span class="mf">70.0</span><span class="p">,</span>
    <span class="p">}</span>

<span class="k">def</span> <span class="nf">run</span><span class="p">():</span>
    <span class="n">tweets</span> <span class="o">=</span> <span class="n">bf</span><span class="o">.</span><span class="n">config</span><span class="o">.</span><span class="n">controllers</span><span class="o">.</span><span class="n">tweets</span>
    <span class="n">tweets</span><span class="o">.</span><span class="n">logger</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="n">config</span><span class="p">[</span><span class="s">&#39;name&#39;</span><span class="p">])</span>
</pre></div>
<p>After making it a controller then we're able to put in config vars and set them
as we want. Which makes it nice for me later i want to change some things,
since all configs are in this one file.</p>
</div>
<div class="section" id="configure-py">
<h2>_configure.py</h2>
<div class="highlight"><pre><span class="c">### Twitter Settings ###</span>
<span class="n">controllers</span><span class="o">.</span><span class="n">tweets</span><span class="o">.</span><span class="n">enabled</span> <span class="o">=</span> <span class="bp">True</span>
<span class="n">tweets</span> <span class="o">=</span> <span class="n">controllers</span><span class="o">.</span><span class="n">tweets</span>
<span class="n">tweets</span><span class="o">.</span><span class="n">username</span> <span class="o">=</span> <span class="s">&quot;morganiangoose&quot;</span>
<span class="n">tweets</span><span class="o">.</span><span class="n">count</span> <span class="o">=</span> <span class="mi">3</span>
<span class="n">tweets</span><span class="o">.</span><span class="n">enable_links</span> <span class="o">=</span> <span class="s">&#39;true&#39;</span>
<span class="n">tweets</span><span class="o">.</span><span class="n">ignore_replies</span> <span class="o">=</span> <span class="s">&#39;false&#39;</span>
<span class="n">tweets</span><span class="o">.</span><span class="n">template</span> <span class="o">=</span> <span class="p">(</span><span class="s">&#39;&lt;li&gt;&lt;div class=&quot;item&quot;&gt;%text% &lt;a href=&quot;http://twitter.c&#39;</span>
        <span class="s">&#39;om/</span><span class="si">%u</span><span class="s">ser_screen_name%/statuses/</span><span class="si">%i</span><span class="s">d%/&quot;&gt;%time%&lt;/a&gt;&lt;/div&gt;&lt;/li&gt;&lt;br/&gt;&#39;</span><span class="p">)</span>
</pre></div>
<p>I then threw this, which is pretty much directly from remy's <a class="reference external" href="http://remysharp.com/2007/05/18/add-twitter-to-your-blog-step-by-step/">directions</a> with
mako var, into my sidebar template.</p>
</div>
<div class="section" id="templates-sidebar-mako">
<h2>_templates/sidebar.mako</h2>
<div class="highlight"><pre><span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">&quot;sidebar_item&quot;</span><span class="nt">&gt;</span>
<span class="nt">&lt;h3&gt;</span>Twitter<span class="nt">&lt;/h3&gt;</span>
    <span class="nt">&lt;script </span><span class="na">src=</span><span class="s">&quot;http://twitterjs.googlecode.com/svn/trunk/src/twitter.min.js&quot;</span>
    <span class="na">type=</span><span class="s">&quot;text/javascript&quot;</span><span class="nt">&gt;&lt;/script&gt;</span>
    <span class="nt">&lt;script </span><span class="na">type=</span><span class="s">&quot;text/javascript&quot;</span> <span class="na">charset=</span><span class="s">&quot;utf-8&quot;</span><span class="nt">&gt;</span>
        <span class="nx">getTwitters</span><span class="p">(</span><span class="s1">&#39;tweet&#39;</span><span class="p">,</span> <span class="p">{</span>
            <span class="nx">id</span><span class="o">:</span> <span class="s1">&#39;${bf.config.tweets.username}&#39;</span><span class="p">,</span>
            <span class="nx">count</span><span class="o">:</span> <span class="nx">$</span><span class="p">{</span><span class="nx">bf</span><span class="p">.</span><span class="nx">config</span><span class="p">.</span><span class="nx">tweets</span><span class="p">.</span><span class="nx">count</span><span class="p">},</span>
            <span class="nx">enableLinks</span><span class="o">:</span> <span class="nx">$</span><span class="p">{</span><span class="nx">bf</span><span class="p">.</span><span class="nx">config</span><span class="p">.</span><span class="nx">tweets</span><span class="p">.</span><span class="nx">enable_links</span><span class="p">},</span>
            <span class="nx">ignoreReplies</span><span class="o">:</span> <span class="nx">$</span><span class="p">{</span><span class="nx">bf</span><span class="p">.</span><span class="nx">config</span><span class="p">.</span><span class="nx">tweets</span><span class="p">.</span><span class="nx">ignore_replies</span><span class="p">},</span>
            <span class="nx">clearContents</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span>
            <span class="nx">template</span><span class="o">:</span> <span class="s1">&#39;${bf.config.tweets.template}&#39;</span><span class="p">,</span>
            <span class="p">});</span>
    <span class="nt">&lt;/script&gt;</span>
    <span class="nt">&lt;div</span> <span class="na">id=</span><span class="s">&quot;tweet&quot;</span><span class="nt">&gt;</span>
    <span class="nt">&lt;/div&gt;</span>
<span class="nt">&lt;/div&gt;</span>
<span class="nt">&lt;br</span> <span class="nt">/&gt;</span>
</pre></div>
<p>Now when I compile the site it'll just throw all this into the sidebar, which
will load up my twitter feed as I described in the template. And I won't have
to have a twitter trigger or the like for updating my blog, which is I feel the
best of both worlds.</p>
</div>
</div>
</div>
]]></content>
  </entry>
  <entry>
    <author>
      <name>Morgan Goose</name>
      <uri>http://morgangoose.com/blog</uri>
    </author>
    <title type="html"><![CDATA[Switching to Blogofile]]></title>
    <link rel="alternate" type="text/html" href="http://morgangoose.com/blog/2010/09/28/switching-to-blogofile" />
    <id>http://morgangoose.com/blog/2010/09/28/switching-to-blogofile</id>
    <updated>2010-09-28T13:03:00Z</updated>
    <published>2010-09-28T13:03:00Z</published>
    <category scheme="http://morgangoose.com/blog" term="Website" />
    <category scheme="http://morgangoose.com/blog" term="Programming" />
    <summary type="html"><![CDATA[Switching to Blogofile]]></summary>
    <content type="html" xml:base="http://morgangoose.com/blog/2010/09/28/switching-to-blogofile"><![CDATA[<div class="document">
<div class="section" id="so-wordpress-is-out">
<h1>So wordpress is out</h1>
<p>It had a nice run, and really did a lot of things I liked, highest among those
being that it worked. But even with my vim plugin for posting to the site, I
never really found myself happy with the whole setup. Then I stumbled upon
<a class="reference external" href="http://www.blogofile.com">blogofile</a> via a fork I spied in my github feed. After inspecting the project
and reading though the docs a bit I decided to give it a try.</p>
</div>
<div class="section" id="conversion-process">
<h1>Conversion process</h1>
<p>It was criminal how simple this was. I added <a class="reference external" href="http://disqus.com/">Disqus</a> comments (should have done
that ages ago) and imported all my old comments to the account. After that I
followed the <a class="reference external" href="http://www.blogofile.com/documentation/migrating_blogs.html#wordpress">directions</a> to switch from wordpress and used the two scripts they
provided. After a few mysql hickups (dumped the db to a machine that had
python-mysql), the scripts worked flawlessly.</p>
<p>I now had all of my posts, not a lot granted, in html <a class="reference external" href="http://www.blogofile.com">blogofile</a> form. Now I
mainly switched so that I could write up my posts in <a class="reference external" href="http://docutils.sourceforge.net/rst.html">rst</a> which I like a lot,
and use in other <a class="reference external" href="http://morgangoose.com/blog/2010/02/gnu-tools-presentation/">projects</a>. So now I had some conversions to make by hand to
get these posts into rst form.</p>
</div>
<div class="section" id="after-some-hand-editing">
<h1>After some hand editing</h1>
<p>I go to publish the site, and it's not liking my code directives. I use
these in other presentations and forgot that I'd made some changes to use the
directive, which I go into more depth about in a previous <a class="reference internal" href="#post">post</a>, but needed to
now retrofit into this project.</p>
<p id="post">The simple blog template had some helpers, but I had to pull the
rst_template.py filter from the blogofile.com template and edit it to give me the
highlighting control that I wanted.</p>
<div class="section" id="rst-template-py-changes">
<h2>rst_template.py changes</h2>
<div class="highlight"><pre><span class="c"># Set to True if you want inline CSS styles instead of classes</span>
<span class="n">INLINESTYLES</span> <span class="o">=</span> <span class="bp">False</span>
<span class="n">STYLE</span> <span class="o">=</span> <span class="s">&quot;fruity&quot;</span>

<span class="kn">from</span> <span class="nn">pygments.formatters</span> <span class="kn">import</span> <span class="n">HtmlFormatter</span>

<span class="c"># The default formatter</span>
<span class="n">DEFAULT</span> <span class="o">=</span> <span class="n">HtmlFormatter</span><span class="p">(</span><span class="n">noclasses</span><span class="o">=</span><span class="n">INLINESTYLES</span><span class="p">,</span> <span class="n">style</span><span class="o">=</span><span class="n">STYLE</span><span class="p">)</span>

<span class="c"># Add name -&gt; formatter pairs for every variant you want to use</span>
<span class="n">VARIANTS</span> <span class="o">=</span> <span class="p">{</span>
        <span class="s">&#39;linenos&#39;</span><span class="p">:</span> <span class="n">HtmlFormatter</span><span class="p">(</span><span class="n">noclasses</span><span class="o">=</span><span class="n">INLINESTYLES</span><span class="p">,</span> <span class="n">linenos</span><span class="o">=</span><span class="bp">False</span><span class="p">),</span>
    <span class="p">}</span>


<span class="kn">from</span> <span class="nn">docutils</span> <span class="kn">import</span> <span class="n">nodes</span>
<span class="kn">from</span> <span class="nn">docutils.parsers.rst</span> <span class="kn">import</span> <span class="n">directives</span><span class="p">,</span> <span class="n">Directive</span>
<span class="kn">from</span> <span class="nn">docutils.core</span> <span class="kn">import</span> <span class="n">publish_parts</span><span class="p">,</span> <span class="n">default_description</span>

<span class="kn">from</span> <span class="nn">pygments</span> <span class="kn">import</span> <span class="n">highlight</span>
<span class="kn">from</span> <span class="nn">pygments.lexers</span> <span class="kn">import</span> <span class="n">get_lexer_by_name</span><span class="p">,</span> <span class="n">TextLexer</span>


<span class="k">class</span> <span class="nc">Pygments</span><span class="p">(</span><span class="n">Directive</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot; Source code execution.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="n">required_arguments</span> <span class="o">=</span> <span class="mi">1</span>
    <span class="n">optional_arguments</span> <span class="o">=</span> <span class="mi">0</span>
    <span class="n">final_argument_whitespace</span> <span class="o">=</span> <span class="bp">True</span>
    <span class="n">option_spec</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">([(</span><span class="n">key</span><span class="p">,</span> <span class="n">directives</span><span class="o">.</span><span class="n">flag</span><span class="p">)</span> <span class="k">for</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">VARIANTS</span><span class="p">])</span>
    <span class="n">has_content</span> <span class="o">=</span> <span class="bp">True</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">assert_has_content</span><span class="p">()</span>
        <span class="k">try</span><span class="p">:</span>
            <span class="n">lexer</span> <span class="o">=</span> <span class="n">get_lexer_by_name</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">arguments</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
        <span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
            <span class="c"># no lexer found - use the text one instead of an exception</span>
            <span class="n">lexer</span> <span class="o">=</span> <span class="n">TextLexer</span><span class="p">()</span>
        <span class="c"># take an arbitrary option if more than one is given</span>
        <span class="n">formatter</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">options</span> <span class="ow">and</span> <span class="n">VARIANTS</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">options</span><span class="o">.</span><span class="n">keys</span><span class="p">()[</span><span class="mi">0</span><span class="p">]]</span> <span class="ow">or</span> <span class="n">DEFAULT</span>

        <span class="k">print</span> <span class="o">&gt;&gt;</span><span class="nb">open</span><span class="p">(</span><span class="s">&#39;css/pygments_fruity.css&#39;</span><span class="p">,</span> <span class="s">&#39;w&#39;</span><span class="p">),</span> <span class="n">formatter</span><span class="o">.</span><span class="n">get_style_defs</span><span class="p">(</span>
                <span class="s">&#39;.highlight&#39;</span><span class="p">)</span>
        <span class="n">parsed</span> <span class="o">=</span> <span class="n">highlight</span><span class="p">(</span><span class="s">u&#39;</span><span class="se">\n</span><span class="s">&#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">content</span><span class="p">),</span> <span class="n">lexer</span><span class="p">,</span> <span class="n">formatter</span><span class="p">)</span>
        <span class="k">return</span> <span class="p">[</span><span class="n">nodes</span><span class="o">.</span><span class="n">raw</span><span class="p">(</span><span class="s">&#39;&#39;</span><span class="p">,</span> <span class="n">parsed</span><span class="p">,</span> <span class="n">format</span><span class="o">=</span><span class="s">&#39;html&#39;</span><span class="p">)]</span>


<span class="n">config</span> <span class="o">=</span> <span class="p">{</span>
    <span class="s">&#39;name&#39;</span> <span class="p">:</span> <span class="s">&quot;reStructuredText&quot;</span><span class="p">,</span>
    <span class="s">&#39;description&#39;</span> <span class="p">:</span> <span class="s">&quot;Renders reStructuredText formatted text to HTML&quot;</span><span class="p">,</span>
    <span class="s">&#39;aliases&#39;</span> <span class="p">:</span> <span class="p">[</span><span class="s">&#39;rst&#39;</span><span class="p">]</span>
<span class="p">}</span>

<span class="k">def</span> <span class="nf">run</span><span class="p">(</span><span class="n">content</span><span class="p">):</span>
    <span class="n">directives</span><span class="o">.</span><span class="n">register_directive</span><span class="p">(</span><span class="s">&#39;sourcecode&#39;</span><span class="p">,</span> <span class="n">Pygments</span><span class="p">)</span>
    <span class="n">directives</span><span class="o">.</span><span class="n">register_directive</span><span class="p">(</span><span class="s">&#39;code&#39;</span><span class="p">,</span> <span class="n">Pygments</span><span class="p">)</span>
    <span class="n">directives</span><span class="o">.</span><span class="n">register_directive</span><span class="p">(</span><span class="s">&#39;code&#39;</span><span class="p">,</span> <span class="n">Pygments</span><span class="p">)</span>

    <span class="n">description</span> <span class="o">=</span> <span class="p">(</span><span class="s">&#39;Generates S5 (X)HTML slideshow documents from standalone &#39;</span>
            <span class="s">&#39;reStructuredText sources.  &#39;</span> <span class="o">+</span> <span class="n">default_description</span><span class="p">)</span>

    <span class="k">return</span> <span class="n">publish_parts</span><span class="p">(</span><span class="n">content</span><span class="p">,</span> <span class="n">writer_name</span><span class="o">=</span><span class="s">&#39;html&#39;</span><span class="p">)[</span><span class="s">&#39;html_body&#39;</span><span class="p">]</span>
</pre></div>
<p>So I added a lot into my site, and put in the theme I wanted to use in the css/
folder so that the style would publish when I build the site.</p>
</div>
</div>
</div>
]]></content>
  </entry>
  <entry>
    <author>
      <name>Morgan Goose</name>
      <uri>http://morgangoose.com/blog</uri>
    </author>
    <title type="html"><![CDATA[Using rst for presentations]]></title>
    <link rel="alternate" type="text/html" href="http://morgangoose.com/blog/2010/09/12/using-rst-for-presentations" />
    <id>http://morgangoose.com/blog/2010/09/12/using-rst-for-presentations</id>
    <updated>2010-09-12T18:03:00Z</updated>
    <published>2010-09-12T18:03:00Z</published>
    <category scheme="http://morgangoose.com/blog" term="Programming" />
    <summary type="html"><![CDATA[Using rst for presentations]]></summary>
    <content type="html" xml:base="http://morgangoose.com/blog/2010/09/12/using-rst-for-presentations"><![CDATA[<div class="document">
<div class="section" id="presentations-are-hard">
<h1>Presentations are hard</h1>
<p>Not even just giving them, but the process of taking an idea and putting it
down in a concise and clear manner, that will be simple to show and distribute.</p>
<p>I am not going to make a claim that I am good at giving or writing up
presentations, but I do think I have a pretty slick setup going for making them
simple to show and distribute with minimal effort.</p>
</div>
<div class="section" id="restructuredtext">
<h1>reStructuredText</h1>
<p>People may be familiar with it already, but it's a markup language that's well
supported in python and used in the <a class="reference external" href="http://sphinx.pocoo.org/">Sphinx</a> project. It fits my brain well (in
most places) and only requires a text editor.</p>
<p>Since it comes with some tools to take a simple plain text document and
transform it into other well known formats (latex, html, and pdf), caused me
to use it in a number of projects and for notes without much friction.</p>
</div>
<div class="section" id="how-i-use-rest">
<h1>How I use reST</h1>
<p>I mentioned in a previous <a class="reference external" href="http://morgangoose.com/blog/2010/02/how-fabric-gets-it-right/">post</a> about my setup and how I leverage <a class="reference external" href="http://docs.fabfile.org">fabric</a> to
build and post my presentations, but I didn't really get too much into the
specifics of how the <a class="reference external" href="http://docutils.sourceforge.net/rst.html">rst</a> document was formatted, and built.</p>
<p>I write a presentation in rst just like I would write any other document in
rst. The goal I had was to write once, and have that document change into other
formats without an issue. I do leverage a few classes and directives that
aren't in the normal rst toolbox, to get my presentations just so. But these
aren't out of line, and after a tweak or two in my pipeline don't break the
other formats I build to.</p>
</div>
<div class="section" id="s5">
<h1>s5</h1>
<blockquote>
S5 is a slide show format based entirely on XHTML, CSS, and JavaScript.</blockquote>
<p>And rst2s5 takes a reStructuredText document and complies it into the
corresponding s5 representation. Giving back a plain html page with some
JavaScript magic that is simple to post and host.</p>
<p>No need for server side scripting, or fancy Apache/lighttpd/nginx setups or any
need for proxies or their kin. So using <a class="reference external" href="http://meyerweb.com/eric/tools/s5/">s5</a> alone will give me the goal of
simple to show, since I can post a presentation and have accesses to it
anywhere there is internet and a browser. I can even keep a copy on a
thumb drive in case the internet dies, and browse the slides locally.</p>
</div>
<div class="section" id="rest-with-s5">
<h1>reST with s5</h1>
<p>To meet the last part of my goal, I have to have a simple distribution medium.
For a presentation that is a pdf. It's akin to a paper, even though it is much
more broken down and split up into slides. Leveraging the <em>handout</em> class that
the s5 and pdf converters from <a class="reference external" href="http://docutils.sourceforge.net/rst.html">rst</a> know, I am able to have parts of the
presentation invisible in slide form, and show up only when the presentation
is expanded, or complied into a pdf.</p>
<div class="section" id="eg">
<h2>eg</h2>
<div class="highlight"><pre><span class="gh">=========</span>
<span class="gh">GNU tools</span>
<span class="gh">=========</span>
<span class="gh">----------------------------</span>
<span class="gh">*mostly for text processing*</span>
<span class="gh">----------------------------</span>

<span class="p">..</span> <span class="ow">class</span><span class="p">::</span> right

    <span class="nv">`Morgan Goose http://morgangoose.com`</span>
    January 2010

<span class="p">..</span> <span class="ow">class</span><span class="p">::</span> handout

    This work is licensed under the Creative Commons
    Attribution-Noncommercial-Share Alike 3.0 United States License.
    To view a copy of this license, visit
    http://creativecommons.org/licenses/by-nc-sa/3.0/us/ or send a letter
    to Creative Commons, 171 Second Street, Suite 300, San Francisco,
    California, 94105, USA.
</pre></div>
<p>So the above will show my name on the first slide, but not the license. In the
pdf though that will all be on the first page. More tips on the s5 rst meshing
can be found on the docutils site's section for <a class="reference external" href="http://docutils.sourceforge.net/docs/user/slide-shows.html">slide-shows</a></p>
</div>
</div>
<div class="section" id="code-blocks">
<h1>Code blocks</h1>
<p>Normal reST had code directives that will differentiate the code, and in most
instances (Sphinx/Trac) will attempt to highlight the code accordingly. I ran
into issues here because rst2pdf and rst2s5 had different ideas on what these
should be named and neither really was highlighting the code. After searching a
bit I found that pygments, a code highlighter in python, already had some
docutils hooks that they <a class="reference external" href="http://pygments.org/docs/rstdirective/">mention on their site</a>.</p>
<p>Using that as a stepping stone I added in code, code, and source code,
directives to use pygments for the code they contained. In my presentations
though I made sure to only use code because this is the directive that
rst2pdf is expecting when it goes to format the document.</p>
<p>After that my code goes through the ringer as shown in the <a class="reference external" href="http://morgangoose.com/blog/2010/02/how-fabric-gets-it-right/">post</a> I gave
for fabric, in the line executing the rst-directive.py file and passing in the
pygments css for the theme that I prefer.</p>
<p>the final rst-directive.py looks like this though:</p>
<div class="highlight"><pre><span class="c"># -*- coding: utf-8 -*-</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    The Pygments reStructuredText directive</span>
<span class="sd">    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</span>

<span class="sd">    This fragment is a Docutils_ 0.5 directive that renders source code</span>
<span class="sd">    (to HTML only, currently) via Pygments.</span>

<span class="sd">    To use it, adjust the options below and copy the code into a module</span>
<span class="sd">    that you import on initialization.  The code then automatically</span>
<span class="sd">    registers a ``sourcecode`` directive that you can use instead of</span>
<span class="sd">    normal code blocks like this::</span>

<span class="sd">        .. sourcecode-block:: python</span>

<span class="sd">            My code goes here.</span>

<span class="sd">    If you want to have different code styles, e.g. one with line numbers</span>
<span class="sd">    and one without, add formatters with their names in the VARIANTS dict</span>
<span class="sd">    below.  You can invoke them instead of the DEFAULT one by using a</span>
<span class="sd">    directive option::</span>

<span class="sd">        .. sourcecode-block:: python</span>
<span class="sd">            :linenos:</span>

<span class="sd">            My code goes here.</span>

<span class="sd">    Look at the `directive documentation`_ to get all the gory details.</span>

<span class="sd">    .. _Docutils: http://docutils.sf.net/</span>
<span class="sd">    .. _directive documentation:</span>
<span class="sd">       http://docutils.sourceforge.net/docs/howto/rst-directives.html</span>

<span class="sd">    :copyright: Copyright 2006-2009 by the Pygments team, see AUTHORS.</span>
<span class="sd">    :license: BSD, see LICENSE for details.</span>
<span class="sd">&quot;&quot;&quot;</span>

<span class="c"># Options</span>
<span class="c"># ~~~~~~~</span>

<span class="c"># Set to True if you want inline CSS styles instead of classes</span>
<span class="n">INLINESTYLES</span> <span class="o">=</span> <span class="bp">False</span>
<span class="n">STYLE</span> <span class="o">=</span> <span class="s">&quot;fruity&quot;</span>

<span class="kn">from</span> <span class="nn">pygments.formatters</span> <span class="kn">import</span> <span class="n">HtmlFormatter</span>

<span class="c"># The default formatter</span>
<span class="n">DEFAULT</span> <span class="o">=</span> <span class="n">HtmlFormatter</span><span class="p">(</span><span class="n">noclasses</span><span class="o">=</span><span class="n">INLINESTYLES</span><span class="p">,</span> <span class="n">style</span><span class="o">=</span><span class="n">STYLE</span><span class="p">)</span>

<span class="c"># Add name -&gt; formatter pairs for every variant you want to use</span>
<span class="n">VARIANTS</span> <span class="o">=</span> <span class="p">{</span>
    <span class="s">&#39;linenos&#39;</span><span class="p">:</span> <span class="n">HtmlFormatter</span><span class="p">(</span><span class="n">noclasses</span><span class="o">=</span><span class="n">INLINESTYLES</span><span class="p">,</span> <span class="n">linenos</span><span class="o">=</span><span class="bp">False</span><span class="p">),</span>
<span class="p">}</span>


<span class="kn">from</span> <span class="nn">docutils</span> <span class="kn">import</span> <span class="n">nodes</span>
<span class="kn">from</span> <span class="nn">docutils.parsers.rst</span> <span class="kn">import</span> <span class="n">directives</span><span class="p">,</span> <span class="n">Directive</span>

<span class="kn">from</span> <span class="nn">pygments</span> <span class="kn">import</span> <span class="n">highlight</span>
<span class="kn">from</span> <span class="nn">pygments.lexers</span> <span class="kn">import</span> <span class="n">get_lexer_by_name</span><span class="p">,</span> <span class="n">TextLexer</span>

<span class="k">class</span> <span class="nc">Pygments</span><span class="p">(</span><span class="n">Directive</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot; Source code execution.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="n">required_arguments</span> <span class="o">=</span> <span class="mi">1</span>
    <span class="n">optional_arguments</span> <span class="o">=</span> <span class="mi">0</span>
    <span class="n">final_argument_whitespace</span> <span class="o">=</span> <span class="bp">True</span>
    <span class="n">option_spec</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">([(</span><span class="n">key</span><span class="p">,</span> <span class="n">directives</span><span class="o">.</span><span class="n">flag</span><span class="p">)</span> <span class="k">for</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">VARIANTS</span><span class="p">])</span>
    <span class="n">has_content</span> <span class="o">=</span> <span class="bp">True</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">assert_has_content</span><span class="p">()</span>
        <span class="k">try</span><span class="p">:</span>
            <span class="n">lexer</span> <span class="o">=</span> <span class="n">get_lexer_by_name</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">arguments</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
        <span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
            <span class="c"># no lexer found - use the text one instead of an exception</span>
            <span class="n">lexer</span> <span class="o">=</span> <span class="n">TextLexer</span><span class="p">()</span>
        <span class="c"># take an arbitrary option if more than one is given</span>
        <span class="n">formatter</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">options</span> <span class="ow">and</span> <span class="n">VARIANTS</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">options</span><span class="o">.</span><span class="n">keys</span><span class="p">()[</span><span class="mi">0</span><span class="p">]]</span> <span class="ow">or</span> <span class="n">DEFAULT</span>

        <span class="k">print</span> <span class="o">&gt;&gt;</span><span class="nb">open</span><span class="p">(</span><span class="s">&#39;pygments.css&#39;</span><span class="p">,</span> <span class="s">&#39;w&#39;</span><span class="p">),</span> <span class="n">formatter</span><span class="o">.</span><span class="n">get_style_defs</span><span class="p">(</span><span class="s">&#39;.highlight&#39;</span><span class="p">)</span>
        <span class="n">parsed</span> <span class="o">=</span> <span class="n">highlight</span><span class="p">(</span><span class="s">u&#39;</span><span class="se">\n</span><span class="s">&#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">content</span><span class="p">),</span> <span class="n">lexer</span><span class="p">,</span> <span class="n">formatter</span><span class="p">)</span>
        <span class="k">return</span> <span class="p">[</span><span class="n">nodes</span><span class="o">.</span><span class="n">raw</span><span class="p">(</span><span class="s">&#39;&#39;</span><span class="p">,</span> <span class="n">parsed</span><span class="p">,</span> <span class="n">format</span><span class="o">=</span><span class="s">&#39;html&#39;</span><span class="p">)]</span>

<span class="n">directives</span><span class="o">.</span><span class="n">register_directive</span><span class="p">(</span><span class="s">&#39;sourcecode&#39;</span><span class="p">,</span> <span class="n">Pygments</span><span class="p">)</span>
<span class="n">directives</span><span class="o">.</span><span class="n">register_directive</span><span class="p">(</span><span class="s">&#39;code&#39;</span><span class="p">,</span> <span class="n">Pygments</span><span class="p">)</span>
<span class="n">directives</span><span class="o">.</span><span class="n">register_directive</span><span class="p">(</span><span class="s">&#39;code&#39;</span><span class="p">,</span> <span class="n">Pygments</span><span class="p">)</span>

<span class="kn">from</span> <span class="nn">docutils.core</span> <span class="kn">import</span> <span class="n">publish_cmdline</span><span class="p">,</span> <span class="n">default_description</span>

<span class="n">description</span> <span class="o">=</span> <span class="p">(</span><span class="s">&#39;Generates S5 (X)HTML slideshow documents from standalone &#39;</span>
               <span class="s">&#39;reStructuredText sources.  &#39;</span> <span class="o">+</span> <span class="n">default_description</span><span class="p">)</span>

<span class="n">publish_cmdline</span><span class="p">(</span><span class="n">writer_name</span><span class="o">=</span><span class="s">&#39;s5&#39;</span><span class="p">,</span> <span class="n">description</span><span class="o">=</span><span class="n">description</span><span class="p">)</span>
</pre></div>
<p>And in combination with my <a class="reference external" href="http://morgangoose.com/blog/2010/02/how-fabric-gets-it-right/">fabric setup</a>
I can make new posts, publish to html and pdf, and republish with relative ease:</p>
<div class="highlight"><pre><span class="nv">$ </span>fab new:new_stuff
<span class="nv">$ </span>vim new_stuff/new_stuff.rst
<span class="nv">$ </span>fab upload:new_stuff
</pre></div>
</div>
</div>
]]></content>
  </entry>
  <entry>
    <author>
      <name>Morgan Goose</name>
      <uri>http://morgangoose.com/blog</uri>
    </author>
    <title type="html"><![CDATA[How fabric gets it right]]></title>
    <link rel="alternate" type="text/html" href="http://morgangoose.com/blog/2010/02/how-fabric-gets-it-right/" />
    <id>http://morgangoose.com/blog/2010/02/how-fabric-gets-it-right/</id>
    <updated>2010-02-11T00:56:33Z</updated>
    <published>2010-02-11T00:56:33Z</published>
    <category scheme="http://morgangoose.com/blog" term="Tools" />
    <category scheme="http://morgangoose.com/blog" term="Programming" />
    <category scheme="http://morgangoose.com/blog" term="Linux" />
    <summary type="html"><![CDATA[How fabric gets it right]]></summary>
    <content type="html" xml:base="http://morgangoose.com/blog/2010/02/how-fabric-gets-it-right/"><![CDATA[<div class="document">
<div class="section" id="i-like-fabric-a-lot">
<h1>I like <a class="reference external" href="http://docs.fabfile.org">fabric</a>. A lot.</h1>
<p>Its a easy to use tool that continually makes my life simpler, and my projects smarter and more automated. Not much out there can really say that. At least nothing I use daily, without noticing, and dependably.</p>
<p>I used to use vellum, and that did what I needed. But fabric being under active development, and getting new features each version it seems is a huge plus. That and it does the network stuff for you, along with the nitty gritty.</p>
<p>Recently I have been giving presentations to the <a class="reference external" href="http://opensource.osu.edu/">Ohio State University's Open Source Club</a> about <a class="reference external" href="http://morgangoose.com/p/gnu_tools/">gnu tools</a>, <a class="reference external" href="http://morgangoose.com/p/tool_oriented_python/">python tools</a>, and soon some cli apps. Fabric really helped make this simple for me to get a whole system down for making and uploading these.</p>
<p>I made all of those presentations in restrctured text, and compiled them into their final formats. All of which was scripted in fabric. I became really attached to ReST after getting introduced to it watching <a class="reference external" href="http://catherinedevlin.pythoneers.com/">Catherine Devlin</a> give a <a class="reference external" href="ahref=&quot;http://catherinedevlin.pythoneers.com/presentations/rst/olf.html">talk about restructured text</a> at Ohio Linux Fest. I ended up finding a cool rst2s5 command that makes nice presentations and with a little tweaking it now also has syntax highlighted code blocks, and can make nice pdfs.</p>
<p>In starting to use fabric you'll notice the basic idea is that you'd make a fabfile that works a lot like a Makefile or a SConstruct file would, with make and scons respectively. You'll make calls with the fab command in the directory the fabfile is located and it will supply the targets.</p>
<p>Below in this example, two targets are made, pack and deploy. The pack target will just makes a tarball, using the local function fabric provides. The deploy target calls pack to make this tarball, then using the put function will place the tarball into the tmp directory, then change into the web dir provided, and extract the archive. It knows automaticly to do this to both hosts I provided, and since I am using an ssh key does all this trickery autonomously.</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">fabfile.py:</th><td class="field-body"></td>
</tr>
</tbody>
</table>
<div class="highlight"><pre><span class="kn">from</span> <span class="nn">fabric.api</span> <span class="kn">import</span> <span class="o">*</span>

<span class="n">env</span><span class="o">.</span><span class="n">user</span> <span class="o">=</span> <span class="s">&#39;username&#39;</span>
<span class="n">env</span><span class="o">.</span><span class="n">hosts</span> <span class="o">=</span> <span class="p">[</span><span class="s">&#39;host1.com&#39;</span><span class="p">,</span> <span class="s">&#39;host2.com&#39;</span><span class="p">]</span>

<span class="k">def</span> <span class="nf">pack</span><span class="p">():</span>
    <span class="n">local</span><span class="p">(</span><span class="s">&#39;tar czf /tmp/project_foo.tgz project_foo/&#39;</span><span class="p">,</span> <span class="n">capture</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span>

<span class="k">def</span> <span class="nf">deploy</span><span class="p">():</span>
    <span class="n">pack</span><span class="p">()</span>
    <span class="n">put</span><span class="p">(</span><span class="s">&#39;/tmp/project_foo.tgz&#39;</span><span class="p">,</span> <span class="s">&#39;/tmp/&#39;</span><span class="p">)</span>

    <span class="k">with</span> <span class="n">cd</span><span class="p">(</span><span class="s">&#39;/var/www/foo/&#39;</span><span class="p">):</span>
        <span class="n">run</span><span class="p">(</span><span class="s">&#39;tar xzf /tmp/project_foo.tgz&#39;</span><span class="p">)</span>
</pre></div>
</div>
<div class="section" id="fabric-can-do-a-lot-more-than-just-deploy">
<h1>Fabric can do a lot more than just deploy</h1>
<p>It's <a class="reference external" href="http://docs.fabfile.org">docs</a> have a lot of detail, and explain most everything well. A last example of some a cool fabric config would be the one I use to publish my presentations to this site.</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">fabfile.py:</th><td class="field-body"></td>
</tr>
</tbody>
</table>
<div class="highlight"><pre><span class="kn">from</span> <span class="nn">fabric.api</span> <span class="kn">import</span> <span class="o">*</span>

<span class="n">env</span><span class="o">.</span><span class="n">roledefs</span> <span class="o">=</span> <span class="p">{</span>
    <span class="s">&#39;production&#39;</span><span class="p">:</span> <span class="p">[</span><span class="s">&quot;morgangoose.com&quot;</span><span class="p">],</span>
    <span class="p">}</span>


<span class="k">def</span> <span class="nf">setup_vars</span><span class="p">(</span><span class="n">project</span><span class="p">):</span>
    <span class="k">global</span> <span class="n">presentation</span>
    <span class="k">global</span> <span class="n">presentation_archive</span>
    <span class="k">global</span> <span class="n">rst_source</span>
    <span class="k">global</span> <span class="n">pdf</span>

    <span class="n">project</span> <span class="o">=</span> <span class="n">project</span><span class="o">.</span><span class="n">strip</span><span class="p">(</span><span class="s">&quot;/&quot;</span><span class="p">)</span>
    <span class="n">presentation</span> <span class="o">=</span> <span class="n">project</span>
    <span class="n">presentation_archive</span> <span class="o">=</span> <span class="s">&quot;</span><span class="si">%s</span><span class="s">.tar.gz&quot;</span> <span class="o">%</span> <span class="n">presentation</span>
    <span class="n">rst_source</span> <span class="o">=</span> <span class="s">&quot;</span><span class="si">%s</span><span class="s">.rst&quot;</span> <span class="o">%</span> <span class="n">presentation</span>
    <span class="n">pdf</span> <span class="o">=</span> <span class="s">&quot;</span><span class="si">%s</span><span class="s">.pdf&quot;</span> <span class="o">%</span> <span class="n">presentation</span>

<span class="nd">@roles</span><span class="p">(</span><span class="s">&#39;production&#39;</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">upload</span><span class="p">(</span><span class="n">project</span><span class="p">):</span>
    <span class="n">env</span><span class="o">.</span><span class="n">user</span> <span class="o">=</span> <span class="s">&quot;username&quot;</span>
    <span class="n">p_dir</span> <span class="o">=</span> <span class="s">&quot;/var/www/html/p/&quot;</span>

    <span class="n">package</span><span class="p">(</span><span class="n">project</span><span class="p">)</span>
    <span class="n">put</span><span class="p">(</span><span class="n">presentation_archive</span><span class="p">,</span> <span class="n">p_dir</span><span class="p">)</span>
    <span class="n">put</span><span class="p">(</span><span class="s">&quot;</span><span class="si">%s</span><span class="s">/</span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">presentation</span><span class="p">,</span> <span class="n">pdf</span><span class="p">),</span> <span class="n">p_dir</span><span class="p">)</span>
    <span class="k">with</span> <span class="n">cd</span><span class="p">(</span><span class="n">p_dir</span><span class="p">):</span>
        <span class="n">run</span><span class="p">(</span><span class="s">&quot;rm -rf </span><span class="si">%s</span><span class="s">/&quot;</span> <span class="o">%</span> <span class="n">presentation</span><span class="p">)</span>
        <span class="n">run</span><span class="p">(</span><span class="s">&quot;tar zxvf </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="n">presentation_archive</span><span class="p">)</span>

    <span class="n">local</span><span class="p">(</span><span class="s">&quot;rm -f </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="n">presentation_archive</span><span class="p">)</span>

<span class="k">def</span> <span class="nf">package</span><span class="p">(</span><span class="n">project</span><span class="p">):</span>
    <span class="n">setup_vars</span><span class="p">(</span><span class="n">project</span><span class="p">)</span>
    <span class="n">make_presentation</span><span class="p">()</span>
    <span class="n">local</span><span class="p">(</span><span class="s">&quot;tar zcvf </span><span class="si">%s</span><span class="s"> </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">presentation_archive</span><span class="p">,</span> <span class="n">presentation</span><span class="p">))</span>

<span class="k">def</span> <span class="nf">make_presentation</span><span class="p">():</span>
    <span class="c">#PDF first</span>
    <span class="n">local</span><span class="p">(</span><span class="s">&quot;rst2pdf </span><span class="si">%s</span><span class="s">/</span><span class="si">%s</span><span class="s"> -o </span><span class="si">%s</span><span class="s">/</span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="p">(</span>
        <span class="n">presentation</span><span class="p">,</span> <span class="n">rst_source</span><span class="p">,</span> <span class="n">presentation</span><span class="p">,</span> <span class="n">pdf</span><span class="p">,</span> <span class="p">))</span>

    <span class="c">#Then s5 html presentation</span>
    <span class="n">local</span><span class="p">(</span><span class="s">&quot;python rst-directive.py </span><span class="se">\</span>
<span class="s">            --stylesheet=pygments.css </span><span class="se">\</span>
<span class="s">            --theme=small-black </span><span class="se">\</span>
<span class="s">            --quiet </span><span class="se">\</span>
<span class="s">            </span><span class="si">%s</span><span class="s">/</span><span class="si">%s</span><span class="s"> &gt; </span><span class="si">%s</span><span class="s">/index.html&quot;</span> <span class="o">%</span> <span class="p">(</span>
                <span class="n">presentation</span><span class="p">,</span> <span class="n">rst_source</span><span class="p">,</span> <span class="n">presentation</span><span class="p">,</span> <span class="p">))</span>

<span class="k">def</span> <span class="nf">new</span><span class="p">(</span><span class="n">project</span><span class="p">):</span>
    <span class="n">setup_vars</span><span class="p">(</span><span class="n">project</span><span class="p">)</span>
    <span class="n">local</span><span class="p">(</span><span class="s">&quot;mkdir -p </span><span class="si">%s</span><span class="s">/{,files}&quot;</span> <span class="o">%</span> <span class="n">presentation</span><span class="p">)</span>
    <span class="n">local</span><span class="p">(</span><span class="s">&quot;cp -R ui </span><span class="si">%s</span><span class="s">/&quot;</span> <span class="o">%</span> <span class="n">presentation</span><span class="p">)</span>
    <span class="n">local</span><span class="p">(</span><span class="s">&quot;touch </span><span class="si">%s</span><span class="s">/</span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">presentation</span><span class="p">,</span> <span class="n">rst_source</span><span class="p">))</span>
</pre></div>
<p>This has some more complicated bits, where it uses the role decorator to specify only to use the hosts listed in the production role definitions.</p>
<p>It also takes advantage of an awesome feature I didn't know fabric had where, one can send arguments to a fabric target. So the project parameter in the targets here can be, and is, supplied via the command line.</p>
</div>
<div class="section" id="for-example">
<h1>For example</h1>
<p>I used this to deploy the updates to my most recent presentation:</p>
<div class="highlight"><pre><span class="nv">$ </span>fab upload:tool_oriented_python
</pre></div>
<p>That's telling fabric to run the upload target, and send the string &quot;tool_oriented_python&quot; as an argument to the function.</p>
<p>If you forget the targets you have just do:</p>
<div class="highlight"><pre><span class="nv">$ </span>fab -l
</pre></div>
</div>
</div>
]]></content>
  </entry>
  <entry>
    <author>
      <name>Morgan Goose</name>
      <uri>http://morgangoose.com/blog</uri>
    </author>
    <title type="html"><![CDATA[Decouple with kwargs]]></title>
    <link rel="alternate" type="text/html" href="http://morgangoose.com/blog/2009/07/decouple-with-kwargs/" />
    <id>http://morgangoose.com/blog/2009/07/decouple-with-kwargs/</id>
    <updated>2009-07-22T17:26:42Z</updated>
    <published>2009-07-22T17:26:42Z</published>
    <category scheme="http://morgangoose.com/blog" term="Programming" />
    <category scheme="http://morgangoose.com/blog" term="Linux" />
    <summary type="html"><![CDATA[Decouple with kwargs]]></summary>
    <content type="html" xml:base="http://morgangoose.com/blog/2009/07/decouple-with-kwargs/"><![CDATA[<div class="document">
<p>So I've been attempting to make a suite of cli scripts for work. I recently discovered the <a class="reference external" href="http://docs.python.org/library/multiprocessing.html">multiprocessing</a> module for python, and really liked its simplicity, and started using it, with great success. Everything was faster.</p>
<p>This then spurred me to take the scripts that were for the most part, copy common-ish bits and then modify to suite, and turn them into a library of sorts. The neat part then arose when I wanted to import a argument parser, as well as pass off to a proc creation component.</p>
<p>In doing this I had in mind that the 'script' would need to only define a function to make a list of commands to run on a given server, and a __main__ section that would pass in a list of servers, the function to make a command list and some other info. This way the script itself would only be two definition sections, and only the parts that were going to be unique for the most part.</p>
<p>The problem that came up in doing this is when I wanted the function that makes the command list to have more arguments that normal. How would I pass them in, and how would I define them so that I don't have to edit my libraries to accommodate this argument passing.  It was kwargs that saved me there, that and some <a class="reference external" href="http://docs.python.org/library/optparse.html">optparse</a> tweaking.</p>
<p>Here is a basic example:</p>
<div class="section" id="script-py">
<h1>script.py</h1>
<div class="highlight"><pre><span class="k">def</span> <span class="nf">get_commands</span><span class="p">(</span><span class="n">host</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
    <span class="n">command_list</span> <span class="o">=</span> <span class="p">[]</span>

    <span class="n">user</span> <span class="o">=</span> <span class="n">kwargs</span><span class="p">[</span><span class="s">&#39;user&#39;</span><span class="p">]</span>
    <span class="n">key_file</span> <span class="o">=</span> <span class="n">kwargs</span><span class="p">[</span><span class="s">&#39;key_file&#39;</span><span class="p">]</span>

    <span class="n">command_list</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s">&quot;echo </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="n">user</span><span class="p">)</span>

    <span class="k">return</span> <span class="n">command_list</span>

<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">&#39;__main__&#39;</span><span class="p">:</span>
    <span class="kn">import</span> <span class="nn">automation</span>

    <span class="n">hosts</span> <span class="o">=</span> <span class="p">[]</span>

    <span class="p">(</span><span class="n">hosts</span><span class="p">,</span> <span class="n">options</span><span class="p">)</span> <span class="o">=</span> <span class="n">automation</span><span class="o">.</span><span class="n">process_args</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">)</span>

    <span class="n">automation</span><span class="o">.</span><span class="n">thread_hosts</span><span class="p">(</span>
            <span class="n">hosts</span><span class="p">,</span>
            <span class="n">get_commands</span><span class="p">,</span>
            <span class="n">options</span><span class="p">,</span>
            <span class="n">user</span><span class="o">=</span><span class="s">&quot;test&quot;</span>
            <span class="p">)</span>
</pre></div>
</div>
<div class="section" id="automation-py-library-w-functions">
<h1>automation.py (library w/ functions)</h1>
<div class="highlight"><pre><span class="k">def</span> <span class="nf">thread_hosts</span><span class="p">(</span><span class="n">hosts</span><span class="p">,</span> <span class="n">get_commands</span><span class="p">,</span> <span class="n">options</span><span class="o">=</span><span class="p">{},</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
    <span class="kn">import</span> <span class="nn">multiprocessing</span>

    <span class="n">kwargs</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">options</span><span class="p">)</span>

    <span class="n">jobs</span> <span class="o">=</span> <span class="p">[]</span>

    <span class="k">for</span> <span class="n">host</span> <span class="ow">in</span> <span class="n">hosts</span><span class="p">:</span>
        <span class="n">p</span> <span class="o">=</span> <span class="n">multiprocessing</span><span class="o">.</span><span class="n">Process</span><span class="p">(</span>
                <span class="n">target</span><span class="o">=</span><span class="n">run_commands</span><span class="p">,</span>
                <span class="n">args</span><span class="o">=</span><span class="p">(</span>
                    <span class="n">host</span><span class="p">,</span>
                    <span class="n">get_commands</span><span class="p">(</span><span class="n">host</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">),</span>
                    <span class="p">),</span> <span class="p">)</span>

        <span class="n">jobs</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">p</span><span class="p">)</span>
        <span class="n">p</span><span class="o">.</span><span class="n">start</span><span class="p">()</span>
</pre></div>
<p>So this example is a script that defines the function to return a command list, and provides an options var, and list of hosts. The thread hosts then loops over the hosts each time  passing the host and the get_commands function to another library function that connects to said host, and loops over the returned command list.</p>
<p>A part that might be confusing is that the parse_args function returns optparse's options variable but the options.__dict__ representation specifically. This then allows me to be able to update kwargs with any options that I allow to be set at the command line. The example in the script being the key_file variable.</p>
<p>The neat part of all this is being able to take the kwargs for one function and pass it right along to the next. This is key, because it allows for the library function in this case to be able to be entirely decoupled from the script itself.</p>
<p>With this implementation I am able to write a script that defines extra args to use, and only the script need know what they are. In the examples the library will just dumbly pass them along in the kwargs dict, I never have to tell it that I want to pass a user variable to it, and it makes the script a nice self contained unit.</p>
</div>
</div>
]]></content>
  </entry>
</feed>
