<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>The GITS Blog &#187; python</title>
	<atom:link href="http://ginstrom.com/scribbles/category/python/feed/" rel="self" type="application/rss+xml" />
	<link>http://ginstrom.com/scribbles</link>
	<description>Random scribbling about programming, translation, and Japan</description>
	<lastBuildDate>Sun, 07 Mar 2010 08:38:54 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Simple Ajax with cherrypy and jQuery</title>
		<link>http://ginstrom.com/scribbles/2010/03/07/simple-ajax-with-cherrypy-and-jquery/</link>
		<comments>http://ginstrom.com/scribbles/2010/03/07/simple-ajax-with-cherrypy-and-jquery/#comments</comments>
		<pubDate>Sun, 07 Mar 2010 08:27:04 +0000</pubDate>
		<dc:creator>Ryan Ginstrom</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://ginstrom.com/scribbles/?p=1503</guid>
		<description><![CDATA[All the cool kids these days are putting Ajax into their web applications. Ajax is great for when you want to update data on a page without reloading the entire page. Most of the Ajax tutorials use PHP, so I want to show here how easy it is to do Ajax with cherrpy.
Ajax stands for [...]]]></description>
			<content:encoded><![CDATA[<p>All the cool kids these days are putting Ajax into their web applications. Ajax is great for when you want to update data on a page without reloading the entire page. Most of the Ajax tutorials use PHP, so I want to show here how easy it is to do Ajax with <a href="http://www.cherrypy.org/">cherrpy</a>.</p>
<p>Ajax stands for "asynchronous JavaScript and XML," but these days <a href="http://www.json.org/">json</a> is often used as a lighter-weight alternative to XML. In this tutorial, I'm therefore going to show how to use the python <a href="http://pypi.python.org/pypi/simplejson/">simplejson</a> library to enable communication between python and JavaScript using json.</p>
<p>What you will need for this tutorial:</p>
<ul>
<li><a href="http://www.cherrypy.org/">cherrpy</a></li>
<li><a href="http://pypi.python.org/pypi/simplejson/">simplejson</a></li>
<li><a href="http://jquery.com/">jQuery</a></li>
<li>The <a href="/code/ajax_cherrypy_sample.zip">sample project</a></li>
</ul>
<p>You can get cherrypy and simplejson from pypi via easy_install; there's a copy of jQuery in my <a href="/code/ajax_cherrypy_sample.zip">sample project</a>. The sample project consists of three files, in the following structure:</p>
<pre>
ajax_app.py
media/
  + jquery-1.4.2.min.js
  | index.html
</pre>
<p>First, I'll show the HTML file:</p>
<div class="dean_ch" style="white-space: wrap;">
&lt;html&gt;<br />
&lt;head&gt;<br />
&nbsp; &nbsp; &lt;title&gt;AJAX with jQuery and cherrypy&lt;/title&gt;<br />
&nbsp; &nbsp; &lt;script type=&quot;text/javascript&quot; src=&quot;/media/jquery-1.4.2.min.js&quot;&gt;&lt;/script&gt;<br />
&lt;script type=&quot;text/javascript&quot;&gt;<br />
&nbsp; &nbsp; $(function() {<br />
&nbsp; &nbsp; // When the testform is submitted&#8230;<br />
&nbsp; &nbsp; $(&quot;#testform&quot;).submit(function() {<br />
&nbsp; &nbsp; &nbsp; &nbsp; // post the form values via AJAX&#8230;<br />
&nbsp; &nbsp; &nbsp; &nbsp; var postdata = {name: $(&quot;#name&quot;).val()} ;<br />
&nbsp; &nbsp; &nbsp; &nbsp; $.post('/submit', postdata, function(data) {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // and set the title with the result<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $(&quot;#title&quot;).html(data['title']) ;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;});<br />
&nbsp; &nbsp; &nbsp; &nbsp; return false ;<br />
&nbsp; &nbsp; &nbsp; &nbsp; });<br />
&nbsp; &nbsp; });<br />
&lt;/script&gt;<br />
&lt;/head&gt;<br />
&nbsp; &nbsp; &lt;body&gt;<br />
&nbsp; &nbsp; &lt;h1 id=&quot;title&quot;&gt;What's your name?&lt;/h1&gt;</p>
<p>&nbsp; &nbsp; &lt;form id=&quot;testform&quot; action=&quot;#&quot; method=&quot;post&quot;&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &lt;p&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &lt;label for=&quot;name&quot;&gt;Name:&lt;/label&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &lt;input type=&quot;text&quot; id=&quot;name&quot; /&gt; &lt;br /&gt;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &lt;input type=&quot;submit&quot; value=&quot;Set&quot; /&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &lt;/p&gt;<br />
&nbsp; &nbsp; &lt;/form&gt;<br />
&nbsp; &nbsp; &lt;/body&gt;<br />
&lt;/html&gt;</div>
<p>Let's see what this is doing. In the body, you've got a title tag, and bog standard HTML form, which asks for a name.</p>
<p>In the head, you've got an include to the jQuery library, and the following JavaScript code:</p>
<div class="dean_ch" style="white-space: wrap;">
&nbsp; &nbsp; $<span class="br0">&#40;</span><span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="co1">// When the testform is submitted&#8230;</span><br />
&nbsp; &nbsp; $<span class="br0">&#40;</span><span class="st0">&quot;#testform&quot;</span><span class="br0">&#41;</span>.<span class="me1">submit</span><span class="br0">&#40;</span><span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// post the form values via AJAX&#8230;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> postdata = <span class="br0">&#123;</span><span class="kw3">name</span>: $<span class="br0">&#40;</span><span class="st0">&quot;#name&quot;</span><span class="br0">&#41;</span>.<span class="me1">val</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#125;</span> ;<br />
&nbsp; &nbsp; &nbsp; &nbsp; $.<span class="me1">post</span><span class="br0">&#40;</span><span class="st0">'/submit'</span>, postdata, <span class="kw2">function</span><span class="br0">&#40;</span>data<span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// and set the title with the result</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $<span class="br0">&#40;</span><span class="st0">&quot;#title&quot;</span><span class="br0">&#41;</span>.<span class="me1">html</span><span class="br0">&#40;</span>data<span class="br0">&#91;</span><span class="st0">'title'</span><span class="br0">&#93;</span><span class="br0">&#41;</span> ;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#125;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">false</span> ;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; <span class="br0">&#125;</span><span class="br0">&#41;</span>;</div>
<p>The initial <code> $(function() </code> statement is a jQuery construct that says, "When the page loads, execute this anonymous function." That function then creates a callback for the submit event of the element with id "testform" (the form). When the form is submitted, the jQuery <code>post</code> function is executed, which is where the magic happens.</p>
<p><a href="http://api.jquery.com/jQuery.post/">jQuery.post</a> is an Ajax method. The first argument is the URL to post to ("/submit"); the second argument is the data to send in the post (the "name" value from the form); and the third argument is the callback to call with the data we receive from the post.</p>
<p>The function then takes this data, and uses its "title" element to update the title of the page.</p>
<p>Next, here's the ajax_app.py file:</p>
<div class="dean_ch" style="white-space: wrap;">
<span class="kw1">import</span> cherrypy<br />
<span class="kw1">import</span> <span class="kw3">webbrowser</span><br />
<span class="kw1">import</span> <span class="kw3">os</span><br />
<span class="kw1">import</span> simplejson<br />
<span class="kw1">import</span> <span class="kw3">sys</span></p>
<p>MEDIA_DIR = <span class="kw3">os</span>.<span class="me1">path</span>.<span class="me1">join</span><span class="br0">&#40;</span><span class="kw3">os</span>.<span class="me1">path</span>.<span class="me1">abspath</span><span class="br0">&#40;</span><span class="st0">&quot;.&quot;</span><span class="br0">&#41;</span>, u<span class="st0">&quot;media&quot;</span><span class="br0">&#41;</span></p>
<p><span class="kw1">class</span> AjaxApp<span class="br0">&#40;</span><span class="kw2">object</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; @cherrypy.<span class="me1">expose</span><br />
&nbsp; &nbsp; <span class="kw1">def</span> index<span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">open</span><span class="br0">&#40;</span><span class="kw3">os</span>.<span class="me1">path</span>.<span class="me1">join</span><span class="br0">&#40;</span>MEDIA_DIR, u<span class="st0">'index.html'</span><span class="br0">&#41;</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; @cherrypy.<span class="me1">expose</span><br />
&nbsp; &nbsp; <span class="kw1">def</span> submit<span class="br0">&#40;</span><span class="kw2">self</span>, name<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; cherrypy.<span class="me1">response</span>.<span class="me1">headers</span><span class="br0">&#91;</span><span class="st0">'Content-Type'</span><span class="br0">&#93;</span> = <span class="st0">'application/json'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> simplejson.<span class="me1">dumps</span><span class="br0">&#40;</span><span class="kw2">dict</span><span class="br0">&#40;</span>title=<span class="st0">&quot;Hello, %s&quot;</span> % name<span class="br0">&#41;</span><span class="br0">&#41;</span></p>
<p>config = <span class="br0">&#123;</span><span class="st0">'/media'</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><span class="st0">'tools.staticdir.on'</span>: <span class="kw2">True</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">'tools.staticdir.dir'</span>: MEDIA_DIR,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></p>
<p><span class="kw1">def</span> open_page<span class="br0">&#40;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="kw3">webbrowser</span>.<span class="kw2">open</span><span class="br0">&#40;</span><span class="st0">&quot;http://127.0.0.1:8080/&quot;</span><span class="br0">&#41;</span><br />
cherrypy.<span class="me1">engine</span>.<span class="me1">subscribe</span><span class="br0">&#40;</span><span class="st0">'start'</span>, open_page<span class="br0">&#41;</span><br />
cherrypy.<span class="me1">tree</span>.<span class="me1">mount</span><span class="br0">&#40;</span>AjaxApp<span class="br0">&#40;</span><span class="br0">&#41;</span>, <span class="st0">'/'</span>, config=config<span class="br0">&#41;</span><br />
cherrypy.<span class="me1">engine</span>.<span class="me1">start</span><span class="br0">&#40;</span><span class="br0">&#41;</span></div>
<p>First, the <code>AjaxApp</code> class is our application. It's pretty simple, having only two methods: <code>index</code> and <code>submit</code>. </p>
<p>When the index method is called, the app opens the index file and returns it. </p>
<p>The submit method is our Ajax method; when it is called with the form data, we use the information to create a new title, and pass that back as json data using <a href="http://svn.red-bean.com/bob/simplejson/tags/simplejson-1.3/docs/module-simplejson.html#dumps">simplejson.dumps</a>. The JavaScript function that called this method can then use the data to update the page content.</p>
<p>This little piece of code is a convenience for development; when you run the cherrpy app, it loads the index page in your web browser.</p>
<div class="dean_ch" style="white-space: wrap;">
<span class="kw1">def</span> open_page<span class="br0">&#40;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="kw3">webbrowser</span>.<span class="kw2">open</span><span class="br0">&#40;</span><span class="st0">&quot;http://127.0.0.1:8080/&quot;</span><span class="br0">&#41;</span><br />
cherrypy.<span class="me1">engine</span>.<span class="me1">subscribe</span><span class="br0">&#40;</span><span class="st0">'start'</span>, open_page<span class="br0">&#41;</span></div>
<p>Finally, the last two lines mount the app, and start up the server. The "config" dict tells cherrpy to serve up static files from the "media" dir in the script's home directory.</p>
<p>If you download the sample project, unzip it, and run ajax_app.py, you should get the following screen (shown here with the name filled in):</p>
<div id="attachment_1506" class="wp-caption alignnone" style="width: 310px"><a href="http://ginstrom.com/scribbles/wp-content/uploads/2010/03/screen1.png"><img src="http://ginstrom.com/scribbles/wp-content/uploads/2010/03/screen1.png" alt="Ajax app -- step1" title="ajax_app1" width="300" height="175" class="size-full wp-image-1506" /></a><p class="wp-caption-text">Ajax app -- step 1</p></div>
<p>Here it is after filling in the name and clicking <strong>Set</strong>:</p>
<div id="attachment_1507" class="wp-caption alignnone" style="width: 310px"><a href="http://ginstrom.com/scribbles/wp-content/uploads/2010/03/screen2.png"><img src="http://ginstrom.com/scribbles/wp-content/uploads/2010/03/screen2.png" alt="Ajax app -- step 2" title="ajax_app2" width="300" height="175" class="alignnone size-full wp-image-1507" /></a><p class="wp-caption-text">Ajax app -- step 2</p></div>
<h3>When to use Ajax</h3>
<p>Ajax is useful when you want to update the page content without reloading the entire page. This is useful for CRUD apps when you want to do things like edit items in place, delete items, or add items.</p>
<h3>When not to use Ajax</h3>
<p>Since Ajax actions don't correspond to URIs, you can't bookmark Ajax actions, send links to friends, or use the back and forward buttons to navigate like in a normal website.</p>
<p>For this reason, avoid Ajax if you want certain application states to be navigable as URIs. For example, if you have a calendar application, and use Ajax to show all the data, the user won't have any way to bookmark an event on December 12th, 2011. Likewise, if you use an Ajax data grid to show tables of data, you won't be able to email your data views to your colleagues.</p>
<p>One middle way is to offer a "permalink" for each Ajax view, which allows for bookmarking, sending links, etc. This still breaks the back-button functionality, but may be worth the trade-off.</p>
]]></content:encoded>
			<wfw:commentRss>http://ginstrom.com/scribbles/2010/03/07/simple-ajax-with-cherrypy-and-jquery/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Easy SFTP uploading with paramiko</title>
		<link>http://ginstrom.com/scribbles/2009/09/14/easy-sftp-uploading-with-paramiko/</link>
		<comments>http://ginstrom.com/scribbles/2009/09/14/easy-sftp-uploading-with-paramiko/#comments</comments>
		<pubDate>Mon, 14 Sep 2009 08:58:33 +0000</pubDate>
		<dc:creator>Ryan Ginstrom</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://ginstrom.com/scribbles/?p=1276</guid>
		<description><![CDATA[paramiko makes it so easy to use SFTP that it's hard to believe it's legal in this day and age. Command Line Warriors has a wonderful post showing how to use paramiko to do SFTP uploads/downloads.
In this post, I want to share a small helper module called sftp (zip file) (code in post below) that [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.lag.net/paramiko/">paramiko</a> makes it so easy to use SFTP that it's hard to believe it's legal in this day and age. <a href="http://commandline.org.uk/">Command Line Warriors</a> has a wonderful post showing <a href="http://commandline.org.uk/python/sftp-python/">how to use paramiko to do SFTP uploads/downloads</a>.</p>
<p>In this post, I want to share a small helper module called <a href="/code/sftp.zip">sftp (zip file)</a> (code in post below) that wraps paramiko.SFTPClient and makes uploading/downloading via SFTP even simpler.</p>
<p>First, some usage</p>
<p><strong>Upload or download a file</strong></p>
<div class="dean_ch" style="white-space: wrap;">
server = sftp.<span class="me1">Server</span><span class="br0">&#40;</span><span class="st0">&quot;user&quot;</span>, <span class="st0">&quot;pass&quot;</span>, <span class="st0">&quot;example.com&quot;</span><span class="br0">&#41;</span><br />
<span class="co1"># upload a file</span><br />
server.<span class="me1">upload</span><span class="br0">&#40;</span><span class="st0">&quot;/local/path&quot;</span>, <span class="st0">&quot;/remote/path&quot;</span><span class="br0">&#41;</span><br />
<span class="co1"># download a file</span><br />
server.<span class="me1">download</span><span class="br0">&#40;</span><span class="st0">&quot;remote/path&quot;</span>, <span class="st0">&quot;/local/path&quot;</span><span class="br0">&#41;</span><br />
server.<span class="me1">close</span><span class="br0">&#40;</span><span class="br0">&#41;</span></div>
<p><strong>with statement also supported:</strong></p>
<div class="dean_ch" style="white-space: wrap;">
with sftp.<span class="me1">Server</span><span class="br0">&#40;</span><span class="st0">&quot;user&quot;</span>, <span class="st0">&quot;pass&quot;</span>, <span class="st0">&quot;example.com&quot;</span><span class="br0">&#41;</span> as server:<br />
&nbsp; &nbsp; server.<span class="me1">upload</span><span class="br0">&#40;</span><span class="st0">&quot;/local/path&quot;</span>, <span class="st0">&quot;/remote/path&quot;</span><span class="br0">&#41;</span></div>
<p>Finally, a demo recipe for uploading all the png files from a specified local directory to a specified directory on the server:</p>
<div class="dean_ch" style="white-space: wrap;">
<span class="co1"># needed for python 2.5</span><br />
<span class="kw1">from</span> <span class="kw3">__future__</span> <span class="kw1">import</span> with_statement</p>
<p><span class="kw1">import</span> sftp<br />
<span class="kw1">import</span> <span class="kw3">glob</span><br />
<span class="kw1">from</span> <span class="kw3">os</span> <span class="kw1">import</span> path</p>
<p>remote_dir = <span class="st0">&quot;/path/on/remote/server/&quot;</span></p>
<p>with sftp.<span class="me1">Server</span><span class="br0">&#40;</span><span class="st0">&quot;user&quot;</span>, <span class="st0">&quot;pass&quot;</span>, <span class="st0">&quot;www.example.com&quot;</span><span class="br0">&#41;</span> as server:<br />
&nbsp; &nbsp; <span class="kw1">for</span> image <span class="kw1">in</span> <span class="kw3">glob</span>.<span class="kw3">glob</span><span class="br0">&#40;</span><span class="st0">&quot;/local/path/to/*.png&quot;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; base = path.<span class="me1">basename</span><span class="br0">&#40;</span>image<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; server.<span class="me1">upload</span><span class="br0">&#40;</span>image, path.<span class="me1">join</span><span class="br0">&#40;</span>remote_dir, base<span class="br0">&#41;</span><span class="br0">&#41;</span></div>
<p>Now, here's the code for my sftp module:</p>
<div class="dean_ch" style="white-space: wrap;">
<span class="kw1">import</span> paramiko</p>
<p><span class="kw1">class</span> Server<span class="br0">&#40;</span><span class="kw2">object</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;<br />
&nbsp; &nbsp; Wraps paramiko for super-simple SFTP uploading and downloading.<br />
&nbsp; &nbsp; &quot;</span><span class="st0">&quot;&quot;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> <span class="kw4">__init__</span><span class="br0">&#40;</span><span class="kw2">self</span>, username, password, host, port=<span class="nu0">22</span><span class="br0">&#41;</span>:</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">transport</span> = paramiko.<span class="me1">Transport</span><span class="br0">&#40;</span><span class="br0">&#40;</span>host, port<span class="br0">&#41;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">transport</span>.<span class="me1">connect</span><span class="br0">&#40;</span>username=username, password=password<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">sftp</span> = paramiko.<span class="me1">SFTPClient</span>.<span class="me1">from_transport</span><span class="br0">&#40;</span><span class="kw2">self</span>.<span class="me1">transport</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> upload<span class="br0">&#40;</span><span class="kw2">self</span>, local, remote<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">sftp</span>.<span class="me1">put</span><span class="br0">&#40;</span>local, remote<span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> download<span class="br0">&#40;</span><span class="kw2">self</span>, remote, local<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">sftp</span>.<span class="me1">get</span><span class="br0">&#40;</span>remote, local<span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> close<span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;<br />
&nbsp; &nbsp; &nbsp; &nbsp; Close the connection if it's active<br />
&nbsp; &nbsp; &nbsp; &nbsp; &quot;</span><span class="st0">&quot;&quot;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="kw2">self</span>.<span class="me1">transport</span>.<span class="me1">is_active</span><span class="br0">&#40;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">sftp</span>.<span class="me1">close</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">transport</span>.<span class="me1">close</span><span class="br0">&#40;</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; <span class="co1"># with-statement support</span><br />
&nbsp; &nbsp; <span class="kw1">def</span> __enter__<span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">self</span></p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> __exit__<span class="br0">&#40;</span><span class="kw2">self</span>, <span class="kw2">type</span>, value, tb<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">close</span><span class="br0">&#40;</span><span class="br0">&#41;</span></div>
]]></content:encoded>
			<wfw:commentRss>http://ginstrom.com/scribbles/2009/09/14/easy-sftp-uploading-with-paramiko/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>On rapid iteration</title>
		<link>http://ginstrom.com/scribbles/2009/06/07/on-rapid-iteration/</link>
		<comments>http://ginstrom.com/scribbles/2009/06/07/on-rapid-iteration/#comments</comments>
		<pubDate>Sun, 07 Jun 2009 08:39:00 +0000</pubDate>
		<dc:creator>Ryan Ginstrom</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://ginstrom.com/scribbles/?p=1130</guid>
		<description><![CDATA[I think that one of the great strengths of interpreted languages like Python is the ability to iterate rapidly, due to the lack of a compilation step.
I've been reading Richard Feynmann's fascinating reminiscences in Surely You're Joking, Mr. Feynmann. The entire text is available online.
One passage that really struck me was where he described the [...]]]></description>
			<content:encoded><![CDATA[<p>I think that one of the great strengths of interpreted languages like Python is the ability to iterate rapidly, due to the lack of a compilation step.</p>
<p>I've been reading Richard Feynmann's fascinating reminiscences in <a href="http://en.wikipedia.org/wiki/Surely_You%27re_Joking,_Mr._Feynman!">Surely You're Joking, Mr. Feynmann</a>. The entire text is <a href="http://www.gorgorat.com/">available online</a>.</p>
<p>One passage that really struck me was where he described the cyclotrons at Princeton, MIT, and Cornell:</p>
<blockquote><p>
It reminded me of my lab at  home. Nothing at MIT had ever reminded  me of  my  lab at home.  I suddenly realized why Princeton was getting results. They were working with the instrument. They built  the instrument; they knew where everything was, they knew how everything worked, there was no engineer involved, except maybe  he was working  there too. It  was much smaller than the cyclotron at MIT, and "gold-plated"? &#8212; it was  the exact opposite. When they wanted to fix a vacuum, they'd drip glyptal on it,  so there were drops of glyptal on the floor. It was wonderful! Because they worked with it. They didn't have to sit in another room and push buttons! (Incidentally, they had a fire in  that  room, because of all the chaotic mess that they had  &#8212; too many  wires &#8212; and it destroyed the cyclotron. But I'd better not tell about that!)</p>
<p>(When I  got  to Cornell I  went to look  at the cyclotron there.  This<br />
cyclotron hardly required a room: It was about a yard across &#8212; the diameter of the whole thing.  It was the world's smallest cyclotron, but they had got fantastic  results. They had all kinds of  special techniques and tricks. If they wanted to  change something  in the "D's" &#8212;  the D-shaped half circles that  the particles go around &#8212; they'd take a screwdriver, and remove the D's by hand, fix  them, and put them back. At Princeton it was a lot harder, and at MIT you had  to take  a crane  that came rolling  across the ceiling, lower the hooks, and it was a hellllll of a job.)</p></blockquote>
<p>Princeton and Cornell had inferior equipment, but they got superior results partly because of the quick iteration loop, eliminating the step of waiting on the engineers to make changes. Scientists at these schools could very quickly try something, make adjustments, and try again, where at MIT the same adjustments took a lot of time.</p>
<p><a href="http://en.wikipedia.org/wiki/Shuji_Nakamura">Shuji Nakamura</a>, inventor of the blue LED, <a href="http://archive.sciencewatch.com/jan-feb2000/sw_jan-feb2000_page3.htm">said something similar about his work</a>:</p>
<blockquote><p>I had a very, very small budget and had to make everything I needed myself. I even made my own reactors—the furnaces needed to do the crystal work. </p></blockquote>
<p>Nakamura succeeded in creating a blue LED, working by himself, when huge multinationals were pouring hundreds of millions of dollars into R&amp;D without results. Elsewhere, he commented that the ability to make adjustments to his equipment quickly, without getting engineers involved, was one of the secrets to his success.</p>
<p>It struck me that this is one of the reasons why I get better results with Python than with compiled languages like C and C++. With Python, there's no compiler in the loop, so the iteration cycle is very fast &#8212; rarely more than 10 seconds to run all the unit tests.</p>
<p>This affects every part of the development cycle. Development itself is a lot faster, so you get more done. With a faster cycle, refactoring code in small steps is also quick and painless, so it's easier to evolve code. The cost of trying out new ideas is low, so you're encouraged to prototype lots of designs to get the best ones.</p>
<p>I think that in just about any kind of creative endeavor, the ability to rapidly iterate between creation and feedback gives a tremendous boost to productivity. This is one of the reasons why I'm so much more productive with Python.</p>
]]></content:encoded>
			<wfw:commentRss>http://ginstrom.com/scribbles/2009/06/07/on-rapid-iteration/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>mailer version 0.5 released</title>
		<link>http://ginstrom.com/scribbles/2009/05/28/mailer-version-05-released/</link>
		<comments>http://ginstrom.com/scribbles/2009/05/28/mailer-version-05-released/#comments</comments>
		<pubDate>Thu, 28 May 2009 01:02:05 +0000</pubDate>
		<dc:creator>Ryan Ginstrom</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[email]]></category>
		<category><![CDATA[mailer]]></category>

		<guid isPermaLink="false">http://ginstrom.com/scribbles/?p=1094</guid>
		<description><![CDATA[I've released version 0.5 of my mailer python module for sending emails. Thanks to a patch from Douglas Mayle, this version makes it possible to send HTML emails with attachments (previous versions only let you do one or the other).

Project homepage
pypi page

]]></description>
			<content:encoded><![CDATA[<p>I've released version 0.5 of my <a href="http://pypi.python.org/pypi/mailer/">mailer python module</a> for sending emails. Thanks to a patch from Douglas Mayle, this version makes it possible to send HTML emails with attachments (previous versions only let you do one or the other).</p>
<ul>
<li><a href="/code/mailer.html">Project homepage</a></li>
<li><a href="http://pypi.python.org/pypi/mailer/">pypi page</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://ginstrom.com/scribbles/2009/05/28/mailer-version-05-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Converting kanji numbers to integers with Python</title>
		<link>http://ginstrom.com/scribbles/2009/04/28/converting-kanji-numbers-to-integers-with-python/</link>
		<comments>http://ginstrom.com/scribbles/2009/04/28/converting-kanji-numbers-to-integers-with-python/#comments</comments>
		<pubDate>Tue, 28 Apr 2009 05:19:25 +0000</pubDate>
		<dc:creator>Ryan Ginstrom</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[conversion]]></category>
		<category><![CDATA[kanji]]></category>

		<guid isPermaLink="false">http://ginstrom.com/scribbles/?p=1008</guid>
		<description><![CDATA[A question on StackOverflow about converting kanji numbers (e.g. "五十五") into integers in C++ got me interested in solving this using Python.
The result is my kanjinums module, with a function kanji2num that will convert a string containing a kanji num to a Python integer.
Download the source distribution (kanjinums-0.1.zip)
Download the Windows installer (kanjinums-0.1.win32.exe)
Download the unit tests [...]]]></description>
			<content:encoded><![CDATA[<p>A <a href="http://stackoverflow.com/questions/795868/how-to-parse-kanji-numeric-characters-using-icu" rel="nofollow">question on StackOverflow</a> about converting kanji numbers (e.g. "五十五") into integers in C++ got me interested in solving this using Python.</p>
<p>The result is my kanjinums module, with a function kanji2num that will convert a string containing a kanji num to a Python integer.</p>
<p><a href="/code/kanjinums-0.1.zip">Download the source distribution (kanjinums-0.1.zip)</a><br />
<a href="/code/kanjinums-0.1.win32.exe">Download the Windows installer (kanjinums-0.1.win32.exe)</a><br />
<a href="/code/test_kanjinums.zip">Download the unit tests (test_kanjinums.zip)</a></p>
<p>Examples:</p>
<div class="dean_ch" style="white-space: wrap;">
&gt;&gt;&gt; <span class="kw1">import</span> kanjinums<br />
&gt;&gt;&gt; kanjinums.<span class="me1">kanji2num</span><span class="br0">&#40;</span><span class="st0">&quot;五百十一&quot;</span>, <span class="st0">&quot;sjis&quot;</span><span class="br0">&#41;</span><br />
<span class="nu0">511</span><br />
&gt;&gt;&gt; kanjinums.<span class="me1">kanji2num</span><span class="br0">&#40;</span><span class="st0">&quot;三万十五&quot;</span>, <span class="st0">&quot;sjis&quot;</span><span class="br0">&#41;</span><br />
<span class="nu0">30015</span></div>
<p>Here's the full code:</p>
<div class="dean_ch" style="white-space: wrap;"><span class="co1">#coding: UTF8</span><br />
<span class="st0">&quot;&quot;</span><span class="st0">&quot;<br />
Converts kanji numbers into integers</p>
<p>Can covert numbers up to 9,999,999,999,999,999<br />
(九千九百九十九兆九千九百九十九億九千九百九十九万九千九百九十九)</p>
<p>Released under MIT license.<br />
&quot;</span><span class="st0">&quot;&quot;</span><br />
__version__ = <span class="st0">&quot;0.1&quot;</span><br />
__author__ &nbsp;= <span class="st0">&quot;Ryan Ginstrom&quot;</span><br />
__license__ = <span class="st0">&quot;MIT&quot;</span><br />
__description__ = <span class="st0">&quot;A module to convert kanji numbers into Python integers&quot;</span></p>
<p>NUMS = <span class="br0">&#40;</span><span class="br0">&#40;</span><span class="nu0">1</span>, u<span class="st0">&quot;一&quot;</span><span class="br0">&#41;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span><span class="nu0">2</span>, u<span class="st0">&quot;二&quot;</span><span class="br0">&#41;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span><span class="nu0">3</span>, u<span class="st0">&quot;三&quot;</span><span class="br0">&#41;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span><span class="nu0">4</span>, u<span class="st0">&quot;四&quot;</span><span class="br0">&#41;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span><span class="nu0">5</span>, u<span class="st0">&quot;五&quot;</span><span class="br0">&#41;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span><span class="nu0">6</span>, u<span class="st0">&quot;六&quot;</span><span class="br0">&#41;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span><span class="nu0">7</span>, u<span class="st0">&quot;七&quot;</span><span class="br0">&#41;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span><span class="nu0">8</span>, u<span class="st0">&quot;八&quot;</span><span class="br0">&#41;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span><span class="nu0">9</span>, u<span class="st0">&quot;九&quot;</span><span class="br0">&#41;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span><span class="nu0">10</span>, u<span class="st0">&quot;十&quot;</span><span class="br0">&#41;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span><span class="nu0">100</span>, u<span class="st0">&quot;百&quot;</span><span class="br0">&#41;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span><span class="nu0">1000</span>, u<span class="st0">&quot;千&quot;</span><span class="br0">&#41;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span><span class="nu0">10000</span>, u<span class="st0">&quot;万&quot;</span><span class="br0">&#41;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span><span class="nu0">100000000</span>, u<span class="st0">&quot;億&quot;</span><span class="br0">&#41;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span><span class="nu0">1000000000000</span>, u<span class="st0">&quot;兆&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span></p>
<p>KANJIS = <span class="kw2">dict</span><span class="br0">&#40;</span><span class="br0">&#40;</span>kanji, num<span class="br0">&#41;</span> <span class="kw1">for</span> <span class="br0">&#40;</span>num, kanji<span class="br0">&#41;</span> <span class="kw1">in</span> NUMS<span class="br0">&#41;</span></p>
<p><span class="kw1">def</span> _break_down_nums<span class="br0">&#40;</span>nums<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; first, second, third, rest = nums<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span>, nums<span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span>, nums<span class="br0">&#91;</span><span class="nu0">2</span><span class="br0">&#93;</span>, nums<span class="br0">&#91;</span><span class="nu0">3</span>:<span class="br0">&#93;</span><br />
&nbsp; &nbsp; <span class="kw1">if</span> first &lt; third <span class="kw1">or</span> third &lt; second:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="br0">&#91;</span>first+second, third<span class="br0">&#93;</span> + rest<br />
&nbsp; &nbsp; <span class="kw1">else</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="br0">&#91;</span>first, second*third<span class="br0">&#93;</span> + rest</p>
<p><span class="kw1">def</span> kanji2num<span class="br0">&#40;</span>kanji, enc=<span class="st0">&quot;utf-8&quot;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;<br />
&nbsp; &nbsp; Convert the kanji number to a Python integer.<br />
&nbsp; &nbsp; Supply `kanji` as a unicode string, or a byte string<br />
&nbsp; &nbsp; with the encoding specified in `enc`.<br />
&nbsp; &nbsp; &quot;</span><span class="st0">&quot;&quot;</span><br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="kw1">not</span> <span class="kw2">isinstance</span><span class="br0">&#40;</span>kanji, <span class="kw2">unicode</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; kanji = <span class="kw2">unicode</span><span class="br0">&#40;</span>kanji, enc<span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; <span class="co1"># get the string as list of numbers</span><br />
&nbsp; &nbsp; nums = <span class="br0">&#91;</span>KANJIS<span class="br0">&#91;</span>x<span class="br0">&#93;</span> <span class="kw1">for</span> x <span class="kw1">in</span> kanji<span class="br0">&#93;</span></p>
<p>&nbsp; &nbsp; num = <span class="nu0">0</span><br />
&nbsp; &nbsp; <span class="kw1">while</span> <span class="kw2">len</span><span class="br0">&#40;</span>nums<span class="br0">&#41;</span> &gt; <span class="nu0">1</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; first, second, rest = nums<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span>, nums<span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span>, nums<span class="br0">&#91;</span><span class="nu0">2</span>:<span class="br0">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> second &lt; first: <span class="co1"># e.g. [10, 3, ...]</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> any<span class="br0">&#40;</span>x &gt; first <span class="kw1">for</span> x <span class="kw1">in</span> rest<span class="br0">&#41;</span>: <span class="co1"># e.g. [500, 3, 10000, ...]</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; nums = _break_down_nums<span class="br0">&#40;</span>nums<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span>: <span class="co1"># e.g. [500, 3, 10, ...]</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; num += first<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; nums = <span class="br0">&#91;</span>second<span class="br0">&#93;</span> + rest<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span>: <span class="co1"># e.g. [3, 10, ...]</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; nums = <span class="br0">&#91;</span>first*second<span class="br0">&#93;</span> + rest</p>
<p>&nbsp; &nbsp; <span class="kw1">return</span> num + <span class="kw2">sum</span><span class="br0">&#40;</span>nums<span class="br0">&#41;</span></div>
]]></content:encoded>
			<wfw:commentRss>http://ginstrom.com/scribbles/2009/04/28/converting-kanji-numbers-to-integers-with-python/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Version 0.2 of mailer module released</title>
		<link>http://ginstrom.com/scribbles/2009/03/29/version-02-of-mailer-module-released/</link>
		<comments>http://ginstrom.com/scribbles/2009/03/29/version-02-of-mailer-module-released/#comments</comments>
		<pubDate>Sun, 29 Mar 2009 02:45:19 +0000</pubDate>
		<dc:creator>Ryan Ginstrom</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[email]]></category>
		<category><![CDATA[mailer]]></category>
		<category><![CDATA[module]]></category>

		<guid isPermaLink="false">http://ginstrom.com/scribbles/?p=927</guid>
		<description><![CDATA[I updated my mailer module (blogged about here) to version 0.2, and also uploaded it to pyPI.
Improvements in this version:

Default arguments in Message.__init__() method
Support for non-ascii charsets (in body and subject)
Support for Python 2.4

With the support for non-ascii encodings, you can now do this:

from mailer import Mailer
from mailer import Message
mailer = Mailer&#40;'smtp.example.com'&#41;
msg = Message&#40;From=&#34;me@example.com&#34;, To=&#34;you@example.com&#34;&#41;
msg.Subject [...]]]></description>
			<content:encoded><![CDATA[<p>I updated my mailer module (<a href="/scribbles/2009/03/15/a-module-to-send-email-simply-in-python/">blogged about here</a>) to version 0.2, and also uploaded it to <a href="http://pypi.python.org/pypi/mailer/">pyPI</a>.</p>
<p>Improvements in this version:</p>
<ul>
<li>Default arguments in Message.__init__() method</li>
<li>Support for non-ascii charsets (in body and subject)</li>
<li>Support for Python 2.4</li>
</ul>
<p>With the support for non-ascii encodings, you can now do this:</p>
<div class="dean_ch" style="white-space: wrap;">
<span class="kw1">from</span> mailer <span class="kw1">import</span> Mailer<br />
<span class="kw1">from</span> mailer <span class="kw1">import</span> Message</p>
<p>mailer = Mailer<span class="br0">&#40;</span><span class="st0">'smtp.example.com'</span><span class="br0">&#41;</span></p>
<p>msg = Message<span class="br0">&#40;</span>From=<span class="st0">&quot;me@example.com&quot;</span>, To=<span class="st0">&quot;you@example.com&quot;</span><span class="br0">&#41;</span><br />
msg.<span class="me1">Subject</span> = <span class="st0">&quot;テキストメール&quot;</span><br />
msg.<span class="me1">Body</span> = <span class="st0">&quot;これは、日本語のキストメールでございます。&quot;</span><br />
msg.<span class="me1">charset</span> = <span class="st0">&quot;utf-8&quot;</span></p>
<p>mailer.<span class="me1">send</span><span class="br0">&#40;</span>msg<span class="br0">&#41;</span></div>
<p>And the Message instance will properly encode the subject line and message body. Note that there's currently no support for Unicode strings; you've got to pass in encoded strings.</p>
<p>Thanks to everyone who provided feedback on this module.</p>
<p>The mailer module also has a <a href="/code/mailer.html">home page</a>.</p>
<p>The full code of the new module is below.</p>
<div class="dean_ch" style="white-space: wrap;">
<span class="co1">#coding: UTF8</span><br />
<span class="st0">&quot;&quot;</span><span class="st0">&quot;<br />
mailer module</p>
<p>Simple front end to the smtplib and email modules,<br />
to simplify sending email.</p>
<p>A lot of this code was taken from the online examples in the<br />
email module documentation:<br />
http://docs.python.org/library/email-examples.html</p>
<p>Released under MIT license.</p>
<p>Sample code:</p>
<p>import mailer</p>
<p>message = mailer.Message()<br />
message.From = &quot;</span>me@example.<span class="me1">com</span><span class="st0">&quot;<br />
message.To = &quot;</span>you@example.<span class="me1">com</span><span class="st0">&quot;<br />
message.Subject = &quot;</span>My Vacation<span class="st0">&quot;<br />
message.Body = open(&quot;</span>letter.<span class="me1">txt</span><span class="st0">&quot;, &quot;</span>rb<span class="st0">&quot;).read()<br />
message.attach(&quot;</span>picture.<span class="me1">jpg</span><span class="st0">&quot;)</p>
<p>mailer = mailer.Mailer('mail.example.com')<br />
mailer.send(message)</p>
<p>&quot;</span><span class="st0">&quot;&quot;</span><br />
<span class="kw1">import</span> <span class="kw3">smtplib</span></p>
<p><span class="co1"># this is to support name changes</span><br />
<span class="co1"># from version 2.4 to version 2.5</span><br />
<span class="kw1">try</span>:<br />
&nbsp; &nbsp; <span class="kw1">from</span> <span class="kw3">email</span> <span class="kw1">import</span> encoders<br />
&nbsp; &nbsp; <span class="kw1">from</span> <span class="kw3">email</span>.<span class="me1">header</span> <span class="kw1">import</span> make_header<br />
&nbsp; &nbsp; <span class="kw1">from</span> <span class="kw3">email</span>.<span class="me1">message</span> <span class="kw1">import</span> Message<br />
&nbsp; &nbsp; <span class="kw1">from</span> <span class="kw3">email</span>.<span class="me1">mime</span>.<span class="me1">audio</span> <span class="kw1">import</span> MIMEAudio<br />
&nbsp; &nbsp; <span class="kw1">from</span> <span class="kw3">email</span>.<span class="me1">mime</span>.<span class="me1">base</span> <span class="kw1">import</span> MIMEBase<br />
&nbsp; &nbsp; <span class="kw1">from</span> <span class="kw3">email</span>.<span class="me1">mime</span>.<span class="me1">image</span> <span class="kw1">import</span> MIMEImage<br />
&nbsp; &nbsp; <span class="kw1">from</span> <span class="kw3">email</span>.<span class="me1">mime</span>.<span class="me1">multipart</span> <span class="kw1">import</span> MIMEMultipart<br />
&nbsp; &nbsp; <span class="kw1">from</span> <span class="kw3">email</span>.<span class="me1">mime</span>.<span class="me1">text</span> <span class="kw1">import</span> MIMEText<br />
<span class="kw1">except</span> <span class="kw2">ImportError</span>:<br />
&nbsp; &nbsp; <span class="kw1">from</span> <span class="kw3">email</span> <span class="kw1">import</span> Encoders as encoders<br />
&nbsp; &nbsp; <span class="kw1">from</span> <span class="kw3">email</span>.<span class="me1">Header</span> <span class="kw1">import</span> make_header<br />
&nbsp; &nbsp; <span class="kw1">from</span> <span class="kw3">email</span>.<span class="me1">MIMEMessage</span> <span class="kw1">import</span> Message<br />
&nbsp; &nbsp; <span class="kw1">from</span> <span class="kw3">email</span>.<span class="me1">MIMEAudio</span> <span class="kw1">import</span> MIMEAudio<br />
&nbsp; &nbsp; <span class="kw1">from</span> <span class="kw3">email</span>.<span class="me1">MIMEBase</span> <span class="kw1">import</span> MIMEBase<br />
&nbsp; &nbsp; <span class="kw1">from</span> <span class="kw3">email</span>.<span class="me1">MIMEImage</span> <span class="kw1">import</span> MIMEImage<br />
&nbsp; &nbsp; <span class="kw1">from</span> <span class="kw3">email</span>.<span class="me1">MIMEMultipart</span> <span class="kw1">import</span> MIMEMultipart<br />
&nbsp; &nbsp; <span class="kw1">from</span> <span class="kw3">email</span>.<span class="me1">MIMEText</span> <span class="kw1">import</span> MIMEText</p>
<p><span class="co1"># For guessing MIME type based on file name extension</span><br />
<span class="kw1">import</span> <span class="kw3">mimetypes</span></p>
<p><span class="kw1">from</span> <span class="kw3">os</span> <span class="kw1">import</span> path</p>
<p>__version__ = <span class="st0">&quot;0.2&quot;</span><br />
__author__ = <span class="st0">&quot;Ryan Ginstrom&quot;</span><br />
__license__ = <span class="st0">&quot;MIT&quot;</span><br />
__description__ = <span class="st0">&quot;A module to send email simply in Python&quot;</span></p>
<p><span class="kw1">class</span> Mailer<span class="br0">&#40;</span><span class="kw2">object</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;<br />
&nbsp; &nbsp; Represents an SMTP connection.</p>
<p>&nbsp; &nbsp; Use login() to log in with a username and password.<br />
&nbsp; &nbsp; &quot;</span><span class="st0">&quot;&quot;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> <span class="kw4">__init__</span><span class="br0">&#40;</span><span class="kw2">self</span>, host=<span class="st0">&quot;localhost&quot;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">host</span> = host<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>._usr = <span class="kw2">None</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>._pwd = <span class="kw2">None</span></p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> login<span class="br0">&#40;</span><span class="kw2">self</span>, usr, <span class="kw3">pwd</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>._usr = usr<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>._pwd = <span class="kw3">pwd</span></p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> send<span class="br0">&#40;</span><span class="kw2">self</span>, msg<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;<br />
&nbsp; &nbsp; &nbsp; &nbsp; Send one message or a sequence of messages.</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; Every time you call send, the mailer creates a new<br />
&nbsp; &nbsp; &nbsp; &nbsp; connection, so if you have several emails to send, pass<br />
&nbsp; &nbsp; &nbsp; &nbsp; them as a list:<br />
&nbsp; &nbsp; &nbsp; &nbsp; mailer.send([msg1, msg2, msg3])<br />
&nbsp; &nbsp; &nbsp; &nbsp; &quot;</span><span class="st0">&quot;&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; server = <span class="kw3">smtplib</span>.<span class="me1">SMTP</span><span class="br0">&#40;</span><span class="kw2">self</span>.<span class="me1">host</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="kw2">self</span>._usr <span class="kw1">and</span> <span class="kw2">self</span>._pwd:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; server.<span class="me1">login</span><span class="br0">&#40;</span><span class="kw2">self</span>._usr, <span class="kw2">self</span>._pwd<span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">try</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; num_msgs = <span class="kw2">len</span><span class="br0">&#40;</span>msg<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> m <span class="kw1">in</span> msg:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>._send<span class="br0">&#40;</span>server, m<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">except</span> <span class="kw2">TypeError</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>._send<span class="br0">&#40;</span>server, msg<span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; server.<span class="me1">quit</span><span class="br0">&#40;</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> _send<span class="br0">&#40;</span><span class="kw2">self</span>, server, msg<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;<br />
&nbsp; &nbsp; &nbsp; &nbsp; Sends a single message using the server<br />
&nbsp; &nbsp; &nbsp; &nbsp; we created in send()<br />
&nbsp; &nbsp; &nbsp; &nbsp; &quot;</span><span class="st0">&quot;&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; me = msg.<span class="me1">From</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; you = <span class="br0">&#91;</span>x.<span class="me1">strip</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="kw1">for</span> x <span class="kw1">in</span> msg.<span class="me1">To</span>.<span class="me1">split</span><span class="br0">&#40;</span><span class="st0">&quot;,&quot;</span><span class="br0">&#41;</span><span class="br0">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; server.<span class="me1">sendmail</span><span class="br0">&#40;</span>me, you, msg.<span class="me1">as_string</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span></p>
<p><span class="kw1">class</span> Message<span class="br0">&#40;</span><span class="kw2">object</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;<br />
&nbsp; &nbsp; Represents an email message.</p>
<p>&nbsp; &nbsp; Set the To, From, Subject, and Body attributes as<br />
&nbsp; &nbsp; plain-text strings. Optionally, set the Html attribute<br />
&nbsp; &nbsp; to send an HTML email, or use the attach() method<br />
&nbsp; &nbsp; to attach files.</p>
<p>&nbsp; &nbsp; Use the charset property to send messages using other<br />
&nbsp; &nbsp; than us-ascii</p>
<p>&nbsp; &nbsp; If you specify an attachments argument, it should be a<br />
&nbsp; &nbsp; list of attachment filenames: [&quot;</span>file1.<span class="me1">txt</span><span class="st0">&quot;, &quot;</span>file2.<span class="me1">txt</span><span class="st0">&quot;]</p>
<p>&nbsp; &nbsp; Send using the Mailer class.<br />
&nbsp; &nbsp; &quot;</span><span class="st0">&quot;&quot;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> <span class="kw4">__init__</span><span class="br0">&#40;</span><span class="kw2">self</span>, To=<span class="kw2">None</span>, From=<span class="kw2">None</span>, Subject=<span class="kw2">None</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Body=<span class="kw2">None</span>, Html=<span class="kw2">None</span>, attachments=<span class="kw2">None</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; charset=<span class="kw2">None</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">attachments</span> = attachments <span class="kw1">or</span> <span class="br0">&#91;</span><span class="br0">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>._to = To<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">From</span> = From<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">Subject</span> = Subject<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">Body</span> = Body<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">Html</span> = Html<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">charset</span> = charset <span class="kw1">or</span> <span class="st0">'us-ascii'</span></p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> _get_to<span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;<br />
&nbsp; &nbsp; &nbsp; &nbsp; Making this a property so we can be permissive about<br />
&nbsp; &nbsp; &nbsp; &nbsp; how to set the &quot;</span>To<span class="st0">&quot; field, i.e.<br />
&nbsp; &nbsp; &nbsp; &nbsp; me;you/me,you/me; you/me, you<br />
&nbsp; &nbsp; &nbsp; &nbsp; &quot;</span><span class="st0">&quot;&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; addrs = <span class="kw2">self</span>._to.<span class="me1">replace</span><span class="br0">&#40;</span><span class="st0">&quot;;&quot;</span>, <span class="st0">&quot;,&quot;</span><span class="br0">&#41;</span>.<span class="me1">split</span><span class="br0">&#40;</span><span class="st0">&quot;,&quot;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="st0">&quot;, &quot;</span>.<span class="me1">join</span><span class="br0">&#40;</span><span class="br0">&#91;</span>x.<span class="me1">strip</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> x <span class="kw1">in</span> addrs<span class="br0">&#93;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="kw1">def</span> _set_to<span class="br0">&#40;</span><span class="kw2">self</span>, to<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>._to = to</p>
<p>&nbsp; &nbsp; To = <span class="kw2">property</span><span class="br0">&#40;</span>_get_to, _set_to,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; doc=<span class="st0">&quot;&quot;</span><span class="st0">&quot;The recipient(s) of the email.<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Separate multiple recipients with<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; commas or semicolons&quot;</span><span class="st0">&quot;&quot;</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> as_string<span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;Get the email as a string to send in the mailer&quot;</span><span class="st0">&quot;&quot;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="kw1">not</span> <span class="kw2">self</span>.<span class="me1">attachments</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">self</span>._plaintext<span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">self</span>._multipart<span class="br0">&#40;</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> _plaintext<span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;Plain text email with no attachments&quot;</span><span class="st0">&quot;&quot;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="kw1">not</span> <span class="kw2">self</span>.<span class="me1">Html</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; msg = MIMEText<span class="br0">&#40;</span><span class="kw2">self</span>.<span class="me1">Body</span>, <span class="st0">'plain'</span>, <span class="kw2">self</span>.<span class="me1">charset</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; msg &nbsp;= <span class="kw2">self</span>._with_html<span class="br0">&#40;</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>._set_info<span class="br0">&#40;</span>msg<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> msg.<span class="me1">as_string</span><span class="br0">&#40;</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> _with_html<span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;There's an html part&quot;</span><span class="st0">&quot;&quot;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; outer = MIMEMultipart<span class="br0">&#40;</span><span class="st0">'alternative'</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; part1 = MIMEText<span class="br0">&#40;</span><span class="kw2">self</span>.<span class="me1">Body</span>, <span class="st0">'plain'</span>, <span class="kw2">self</span>.<span class="me1">charset</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; part2 = MIMEText<span class="br0">&#40;</span><span class="kw2">self</span>.<span class="me1">Html</span>, <span class="st0">'html'</span>, <span class="kw2">self</span>.<span class="me1">charset</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; outer.<span class="me1">attach</span><span class="br0">&#40;</span>part1<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; outer.<span class="me1">attach</span><span class="br0">&#40;</span>part2<span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> outer</p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> _set_info<span class="br0">&#40;</span><span class="kw2">self</span>, msg<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="kw2">self</span>.<span class="me1">charset</span> == <span class="st0">'us-ascii'</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; msg<span class="br0">&#91;</span><span class="st0">'Subject'</span><span class="br0">&#93;</span> = <span class="kw2">self</span>.<span class="me1">Subject</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; subject = <span class="kw2">unicode</span><span class="br0">&#40;</span><span class="kw2">self</span>.<span class="me1">Subject</span>, <span class="kw2">self</span>.<span class="me1">charset</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; msg<span class="br0">&#91;</span><span class="st0">'Subject'</span><span class="br0">&#93;</span> = <span class="kw2">str</span><span class="br0">&#40;</span>make_header<span class="br0">&#40;</span><span class="br0">&#91;</span><span class="br0">&#40;</span>subject,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">charset</span><span class="br0">&#41;</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; msg<span class="br0">&#91;</span><span class="st0">'From'</span><span class="br0">&#93;</span> = <span class="kw2">self</span>.<span class="me1">From</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; msg<span class="br0">&#91;</span><span class="st0">'To'</span><span class="br0">&#93;</span> = <span class="kw2">self</span>.<span class="me1">To</span></p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> _multipart<span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;The email has attachments&quot;</span><span class="st0">&quot;&quot;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; msg = MIMEMultipart<span class="br0">&#40;</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; msg.<span class="me1">attach</span><span class="br0">&#40;</span>MIMEText<span class="br0">&#40;</span><span class="kw2">self</span>.<span class="me1">Body</span>, <span class="st0">'plain'</span>, <span class="kw2">self</span>.<span class="me1">charset</span><span class="br0">&#41;</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>._set_info<span class="br0">&#40;</span>msg<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; msg.<span class="me1">preamble</span> = <span class="kw2">self</span>.<span class="me1">Subject</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> filename <span class="kw1">in</span> <span class="kw2">self</span>.<span class="me1">attachments</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>._add_attachment<span class="br0">&#40;</span>msg, filename<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> msg.<span class="me1">as_string</span><span class="br0">&#40;</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> _add_attachment<span class="br0">&#40;</span><span class="kw2">self</span>, outer, filename<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; ctype, encoding = <span class="kw3">mimetypes</span>.<span class="me1">guess_type</span><span class="br0">&#40;</span>filename<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> ctype <span class="kw1">is</span> <span class="kw2">None</span> <span class="kw1">or</span> encoding <span class="kw1">is</span> <span class="kw1">not</span> <span class="kw2">None</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1"># No guess could be made, or the file is encoded</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1"># (compressed), so use a generic bag-of-bits type.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ctype = <span class="st0">'application/octet-stream'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; maintype, subtype = ctype.<span class="me1">split</span><span class="br0">&#40;</span><span class="st0">'/'</span>, <span class="nu0">1</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; fp = <span class="kw2">open</span><span class="br0">&#40;</span>filename, <span class="st0">'rb'</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> maintype == <span class="st0">'text'</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1"># Note: we should handle calculating the charset</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; msg = MIMEText<span class="br0">&#40;</span>fp.<span class="me1">read</span><span class="br0">&#40;</span><span class="br0">&#41;</span>, _subtype=subtype<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">elif</span> maintype == <span class="st0">'image'</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; msg = MIMEImage<span class="br0">&#40;</span>fp.<span class="me1">read</span><span class="br0">&#40;</span><span class="br0">&#41;</span>, _subtype=subtype<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">elif</span> maintype == <span class="st0">'audio'</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; msg = MIMEAudio<span class="br0">&#40;</span>fp.<span class="me1">read</span><span class="br0">&#40;</span><span class="br0">&#41;</span>, _subtype=subtype<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; msg = MIMEBase<span class="br0">&#40;</span>maintype, subtype<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; msg.<span class="me1">set_payload</span><span class="br0">&#40;</span>fp.<span class="me1">read</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1"># Encode the payload using Base64</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; encoders.<span class="me1">encode_base64</span><span class="br0">&#40;</span>msg<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; fp.<span class="me1">close</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1"># Set the filename parameter</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; msg.<span class="me1">add_header</span><span class="br0">&#40;</span><span class="st0">'Content-Disposition'</span>, <span class="st0">'attachment'</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; filename=path.<span class="me1">basename</span><span class="br0">&#40;</span>filename<span class="br0">&#41;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; outer.<span class="me1">attach</span><span class="br0">&#40;</span>msg<span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> attach<span class="br0">&#40;</span><span class="kw2">self</span>, filename<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;<br />
&nbsp; &nbsp; &nbsp; &nbsp; Attach a file to the email. Specify the name of<br />
&nbsp; &nbsp; &nbsp; &nbsp; the file; Message will figure out the MIME type<br />
&nbsp; &nbsp; &nbsp; &nbsp; and load the file.<br />
&nbsp; &nbsp; &nbsp; &nbsp; &quot;</span><span class="st0">&quot;&quot;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">attachments</span>.<span class="me1">append</span><span class="br0">&#40;</span>filename<span class="br0">&#41;</span></div>
]]></content:encoded>
			<wfw:commentRss>http://ginstrom.com/scribbles/2009/03/29/version-02-of-mailer-module-released/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>The Adapter Pattern in Python</title>
		<link>http://ginstrom.com/scribbles/2009/03/27/the-adapter-pattern-in-python/</link>
		<comments>http://ginstrom.com/scribbles/2009/03/27/the-adapter-pattern-in-python/#comments</comments>
		<pubDate>Fri, 27 Mar 2009 03:36:57 +0000</pubDate>
		<dc:creator>Ryan Ginstrom</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[adapter]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[GoF]]></category>
		<category><![CDATA[pattern]]></category>

		<guid isPermaLink="false">http://ginstrom.com/scribbles/?p=922</guid>
		<description><![CDATA[Interface mismatches are one of the banes of code reuse. You want to integrate component A and component B into your program, but component A expects a method called half_empty() while component B only has a method called half_full(). The Gang of Four (GoF) Adapter pattern is used to convert the interface of an object [...]]]></description>
			<content:encoded><![CDATA[<p>Interface mismatches are one of the banes of code reuse. You want to integrate component A and component B into your program, but component A expects a method called half_empty() while component B only has a method called half_full(). The <a href="http://en.wikipedia.org/wiki/Gang_of_Four_(software)">Gang of Four (GoF)</a> Adapter pattern is used to convert the interface of an object to one the client expects, allowing collaboration between classes that normally couldn't work together due to differing interfaces.</p>
<h3>2D Land: A Demonstration of the Adapter Pattern</h3>
<p>Let's motivate that with a little example. We're going to start with a simple system, then add components to it with an interface that's different from the one our system expects. We'll use the Adapter pattern to wrap the new components, so we can use them without changing the code in our existing system.</p>
<p>So let's get started. We've been tasked with writing the back-end code for 2D Land, a cutting-edge world simulation program involving poorly drawn cartoon figures. Our initial spec is pretty simple: our world consists of people, and when a person is clicked, their name and a speech bubble is printed. We need to code a Person class, and a click_creature() function that will return a person's name and speech bubble to the GUI team.</p>
<p><img src="/img/adapter01.png" alt="2D Land version 1.0" /></p>
<p>So let's get coding. One way to code this would be as shown below. We have a Person class, with a name property and a make_noise() method. These can be accessed to retrieve the Person's name and speech bubble.</p>
<div class="dean_ch" style="white-space: wrap;">
<span class="kw1">class</span> Person<span class="br0">&#40;</span><span class="kw2">object</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;A representation of a person in 2D Land&quot;</span><span class="st0">&quot;&quot;</span><br />
&nbsp; &nbsp; <span class="kw1">def</span> <span class="kw4">__init__</span><span class="br0">&#40;</span><span class="kw2">self</span>, name<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">name</span> = name<br />
&nbsp; &nbsp; <span class="kw1">def</span> make_noise<span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="st0">&quot;hello&quot;</span></p>
<p><span class="kw1">def</span> click_creature<span class="br0">&#40;</span>creature<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;<br />
&nbsp; &nbsp; React to a click by retrieving the creature's<br />
&nbsp; &nbsp; name and what is says<br />
&nbsp; &nbsp; &quot;</span><span class="st0">&quot;&quot;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">return</span> creature.<span class="me1">name</span>, creature.<span class="me1">make_noise</span><span class="br0">&#40;</span><span class="br0">&#41;</span></div>
<p>The Person class takes a name argument, which it stores in its name attribute. The click_creature() function retrieves the person's name and speech-bubble text. We test it, and everything works as expected. Looks like it's time for a launch party!</p>
<h3>More Features in 2D Land</h3>
<p>After we get back from our team trip to Cancun, we find that our users are so happy with 2D Land that management has decided to build 2D Land version 2.0! The killer new feature of version 2.0 is that in addition to people, 2D Land will now also have dogs.</p>
<p><img src="/img/adapter02.png" alt="2D Land version 2.0" /></p>
<p>Luckily, the programmers over in the Pet Land team are going to let us use their Dog class. The Dog class has a name property, and a bark() method that returns the dog's bark sound.</p>
<div class="dean_ch" style="white-space: wrap;">
<span class="kw1">class</span> Dog<span class="br0">&#40;</span><span class="kw2">object</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;A representation of a dog in 2D Land&quot;</span><span class="st0">&quot;&quot;</span><br />
&nbsp; &nbsp; <span class="kw1">def</span> <span class="kw4">__init__</span><span class="br0">&#40;</span><span class="kw2">self</span>, name<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">name</span> = name<br />
&nbsp; &nbsp; <span class="kw1">def</span> bark<span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="st0">&quot;woof&quot;</span></div>
<p>As it stands, the Dog class doesn't have the interface that our clients expect. It has a name property, but instead of a make_noise() method, it's got a bark() method. But we can use the Adapter pattern to wrap the Dog class and give it the expected interface.</p>
<p>Let's start by solving this the classic GoF way. There are actually two ways to implement Adapter in GoF: the Class Adapter and the Object Adapter. The Class Adapter uses multiple inheritance, while the Object Adapter uses encapsulation. For the sake of completeness I'm going to show both of them, and then explain why the Object Adapter is almost always the best choice for Python.</p>
<p>According to the classic implementation of the Adapter pattern, we need a common class that Person and a dog adapter can inherit from; let's call it a Creature class. The DogClassAdapter and DogObjectAdapter classes will each inherit from Creature; DogClassAdapter will then inherit from Dog, and DogObjectAdapter will wrap Dog.</p>
<p>According to the pattern, Creature is supposed to be an abstract base class (ABC); that is, it's not supposed to be instantiated directly. Python 2.X doesn't have ABCs as a language feature, but we can fake it here by having calls to make_noise() raise a NotImplementedError. This means that we need classes to inherit from Creature and implement make_noise() for us.</p>
<div class="dean_ch" style="white-space: wrap;">
<span class="kw1">from</span> dog <span class="kw1">import</span> Dog</p>
<p><span class="kw1">class</span> Creature<span class="br0">&#40;</span><span class="kw2">object</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;The base class for creatures in 2D Land&quot;</span><span class="st0">&quot;&quot;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> make_noise<span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;<br />
&nbsp; &nbsp; &nbsp; &nbsp; This is a technique to fake an ABC<br />
&nbsp; &nbsp; &nbsp; &nbsp; in Python 2.X<br />
&nbsp; &nbsp; &nbsp; &nbsp; &quot;</span><span class="st0">&quot;&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">raise</span> <span class="kw2">NotImplementedError</span></p>
<p><span class="kw1">class</span> Person<span class="br0">&#40;</span>Creature<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;A representation of a person in 2D Land&quot;</span><span class="st0">&quot;&quot;</span><br />
&nbsp; &nbsp; <span class="kw1">def</span> <span class="kw4">__init__</span><span class="br0">&#40;</span><span class="kw2">self</span>, name<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">name</span> = name</p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> make_noise<span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="st0">&quot;hello&quot;</span></p>
<p><span class="kw1">class</span> DogClassAdapter<span class="br0">&#40;</span>Creature, Dog<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;Adapts the Dog class through multiple inheritance&quot;</span><span class="st0">&quot;&quot;</span><br />
&nbsp; &nbsp; <span class="kw1">def</span> <span class="kw4">__init__</span><span class="br0">&#40;</span><span class="kw2">self</span>, name<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; Dog.<span class="kw4">__init__</span><span class="br0">&#40;</span><span class="kw2">self</span>, name<span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> make_noise<span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;<br />
&nbsp; &nbsp; &nbsp; &nbsp; Provide the 'make_noise' method that<br />
&nbsp; &nbsp; &nbsp; &nbsp; the client expects<br />
&nbsp; &nbsp; &nbsp; &nbsp; &quot;</span><span class="st0">&quot;&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">self</span>.<span class="me1">bark</span><span class="br0">&#40;</span><span class="br0">&#41;</span></div>
<p>DogClassAdapter inherits from Creature and Dog, getting the functionality of both. It takes a name parameter in its __init__() method, which it passes on to Dog. It then implements a make_noise() method, returning the results of the bark() method it inherited from Dog.</p>
<div class="dean_ch" style="white-space: wrap;">
<span class="kw1">class</span> DogObjectAdapter<span class="br0">&#40;</span>Creature<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;Adapts the Dog class through encapsulation&quot;</span><span class="st0">&quot;&quot;</span><br />
&nbsp; &nbsp; <span class="kw1">def</span> <span class="kw4">__init__</span><span class="br0">&#40;</span><span class="kw2">self</span>, canine<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">canine</span> = canine</p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> make_noise<span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;This is the only method that's adapted&quot;</span><span class="st0">&quot;&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">self</span>.<span class="me1">canine</span>.<span class="me1">bark</span><span class="br0">&#40;</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> <span class="kw4">__getattr__</span><span class="br0">&#40;</span><span class="kw2">self</span>, attr<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;Everything else is delegated to the object&quot;</span><span class="st0">&quot;&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">getattr</span><span class="br0">&#40;</span><span class="kw2">self</span>.<span class="me1">canine</span>, attr<span class="br0">&#41;</span></div>
<p>DogObjectAdapter only inherits from Creature. It takes a Dog instance as a parameter to its __init__() method, and stores that instance as self.canine. It implements a make_noise() method, which returns the result of calling the bark() method of its wrapped Dog object. All other calls on the class are passed to its canine instance via the __getattr__() method.</p>
<p>In both cases, we only need to implement the interface we're adapting. DogClassAdapter inherits the rest of the Dog interface, while DogObjectAdapter uses __getattr__() to provide the same interface as the Dog class, with the exception of the methods it implements itself.</p>
<p>And here's why we don't need the Class Adapter. Class Adapter is basically a shortcut to avoid coding stubs. In languages like C++, Object Adapter would force us to implement stubs for every method on the Dog class, just so we could pass them on to the wrapped Dog instance. With Class Adapter, however, we'd already have the behaviour implemented, so wouldn't need to write stubs. This doesn't make any difference in a simple class like Dog, but consider a huge class like StringIO.StringIO from the standard library; writing stubs for every method in that class just to adapt the interface slightly would be a real pain. But in Python, we don't have to write stubs for the behaviour we don't wrap; we can take advantage of dynamic dispatching instead, by implementing the __getattr__() method.</p>
<blockquote><p>__getattr__() is a "magic" method, as denoted by the double underscores. The Python interpreter calls it when it does an attribute lookup on the object, and can't find a matching attribute. By intercepting this call and passing on the attribute lookup to the wrapped object, DogObjectAdapter only needs to implement the make_noise() method; everything else gets passed on to its wrapped object.</p></blockquote>
<h3>Flattening the Object Hierarchy</h3>
<p>The code above works; we can created adapted dogs, and feed them into our click_creature() function. But is inheriting from a Creature base class the best way? With statically typed languages, inheritance is used for two purposes: to coerce types, and to inherit behaviour. By coercing types, I mean using a common base class so that we can feed a common type to the click_creature() function. These are the kinds of hoops you need to jump through to make the compiler happy in statically typed languages. In Python, we don't need to use inheritance to coerce the type system, because we use duck typing; we only need to use inheritance for behaviour.</p>
<blockquote><p><strong>Duck typing</strong>: ask what an object can do, rather than ask what type an object is (i.e. don't ask if it's a duck; ask if it quacks like a duck).</p></blockquote>
<p>So we don't need to inherit from a Creature base class in order to use our various objects in the click_creature() function. And in fact, there's a big problem with this inheritance approach: it would force us to change our existing codebase, by modifying the Person class to inherit from Creature. So let's flatten the hierarchy out:</p>
<p><img src="/img/adapter03.png" alt="Flattening the inheritance hierarchy" /></p>
<p>Here's our code without the Creature base class, and getting rid of the Class Adapter:</p>
<div class="dean_ch" style="white-space: wrap;">
<span class="kw1">from</span> dog <span class="kw1">import</span> Dog</p>
<p><span class="kw1">class</span> Person<span class="br0">&#40;</span><span class="kw2">object</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;A representation of a person in 2D Land&quot;</span><span class="st0">&quot;&quot;</span><br />
&nbsp; &nbsp; <span class="kw1">def</span> <span class="kw4">__init__</span><span class="br0">&#40;</span><span class="kw2">self</span>, name<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">name</span> = name</p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> make_noise<span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="st0">&quot;hello&quot;</span></p>
<p><span class="kw1">class</span> DogAdapter<span class="br0">&#40;</span><span class="kw2">object</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;Adapts the Dog class through encapsulation&quot;</span><span class="st0">&quot;&quot;</span><br />
&nbsp; &nbsp; <span class="kw1">def</span> <span class="kw4">__init__</span><span class="br0">&#40;</span><span class="kw2">self</span>, canine<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">canine</span> = canine</p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> make_noise<span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;This is the only method that's adapted&quot;</span><span class="st0">&quot;&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">self</span>.<span class="me1">canine</span>.<span class="me1">bark</span><span class="br0">&#40;</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> <span class="kw4">__getattr__</span><span class="br0">&#40;</span><span class="kw2">self</span>, attr<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;Everything else is delegated to the object&quot;</span><span class="st0">&quot;&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">getattr</span><span class="br0">&#40;</span><span class="kw2">self</span>.<span class="me1">canine</span>, attr<span class="br0">&#41;</span></p>
<p><span class="kw1">def</span> click_creature<span class="br0">&#40;</span>creature<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;<br />
&nbsp; &nbsp; React to a click by showing the creature's<br />
&nbsp; &nbsp; name and what is says<br />
&nbsp; &nbsp; &quot;</span><span class="st0">&quot;&quot;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">return</span> <span class="br0">&#40;</span>creature.<span class="me1">name</span>, creature.<span class="me1">make_noise</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span></div>
<p>This is a lot simpler. We've captured the intent of the Adapter pattern, without bothering with the trappings of less dynamic languages.</p>
<p>Just because the GoF implement a pattern in a certain way doesn't mean it's the only or even best way to do it in Python. Use the essence of the pattern, and leave out the accidents of implementation.</p>
<h3>Testing out the System</h3>
<p>Let's test out our DogAdapter class with a function that simulates clicks on each type of creature in 2D Land.</p>
<div class="dean_ch" style="white-space: wrap;">
<span class="kw1">from</span> dog <span class="kw1">import</span> Dog<br />
<span class="kw1">from</span> listing3 <span class="kw1">import</span> Person, DogAdapter</p>
<p><span class="kw1">def</span> exercise_system<span class="br0">&#40;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; person = Person<span class="br0">&#40;</span><span class="st0">&quot;Bob&quot;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; canine = DogAdapter<span class="br0">&#40;</span>Dog<span class="br0">&#40;</span><span class="st0">&quot;Fido&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">for</span> critter <span class="kw1">in</span> <span class="br0">&#40;</span>person, canine<span class="br0">&#41;</span>:</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">print</span> critter.<span class="me1">name</span>, <span class="st0">&quot;says&quot;</span>, critter.<span class="me1">make_noise</span><span class="br0">&#40;</span><span class="br0">&#41;</span></p>
<p><span class="kw1">if</span> __name__ == <span class="st0">&quot;__main__&quot;</span>:<br />
&nbsp; &nbsp; exercise_system<span class="br0">&#40;</span><span class="br0">&#41;</span></div>
<p>animate_objects() creates instances of classes Person and DogAdapter; it then prints the name and speech bubbles of each object. The output is shown below.</p>
<p>Output:</p>
<div class="dean_ch" style="white-space: wrap;">
Bob says hello<br />
Fido says woof</div>
<p>Perfect! Looks like we're ready to launch version 2.0.</p>
<h3>Extending the Adapter Concept</h3>
<p>We've got our Adapter working pretty well now, but we can still make it better. Think about how we added a Dog class to 2D Land. What if we later want to add a Cat class, and Bird class, and so on? Here's a Cat class, that has a name attribute, and a meow() method that returns the cat's meow sound.</p>
<div class="dean_ch" style="white-space: wrap;">
<span class="kw1">class</span> Cat<span class="br0">&#40;</span><span class="kw2">object</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;A representation of a cat in 2D Land&quot;</span><span class="st0">&quot;&quot;</span><br />
&nbsp; &nbsp; <span class="kw1">def</span> <span class="kw4">__init__</span><span class="br0">&#40;</span><span class="kw2">self</span>, name<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">name</span> = name<br />
&nbsp; &nbsp; <span class="kw1">def</span> meow<span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="st0">&quot;meow&quot;</span></div>
<p>The problem with the current implementation is that every time we add a new class to our system, we're potentially going to have to write a new adapter class for it.</p>
<p>We can take advantage of Python's dynamic nature to write a single, generic adapter class for all the new classes we add. Our generic adapter will take two arguments in its __init__() method: the object it's going to wrap, and an implementation of make_noise().</p>
<div class="dean_ch" style="white-space: wrap;">
<span class="kw1">class</span> CreatureAdapter<span class="br0">&#40;</span><span class="kw2">object</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;Adapts a creature for clients in 2D Land&quot;</span><span class="st0">&quot;&quot;</span><br />
&nbsp; &nbsp; <span class="kw1">def</span> <span class="kw4">__init__</span><span class="br0">&#40;</span><span class="kw2">self</span>, creature, make_noise<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;Pass in the function to use as 'make_noise'&quot;</span><span class="st0">&quot;&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">creature</span> = creature<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">make_noise</span> = make_noise</p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> <span class="kw4">__getattr__</span><span class="br0">&#40;</span><span class="kw2">self</span>, attr<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;Everything else is delegated to the object&quot;</span><span class="st0">&quot;&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">getattr</span><span class="br0">&#40;</span><span class="kw2">self</span>.<span class="me1">creature</span>, attr<span class="br0">&#41;</span></div>
<p>Note that the code no longer has to know anything about the Dog class or other creatures in 2D land. All we need to do is supply an object to adapt and a method to use for make_noise(), and we're done.</p>
<p>So let's test out the new system, and see how we'd specify the make_noise() method.</p>
<div class="dean_ch" style="white-space: wrap;">
<span class="kw1">from</span> dog <span class="kw1">import</span> Dog<br />
<span class="kw1">from</span> cat <span class="kw1">import</span> Cat<br />
<span class="kw1">from</span> twodeeland <span class="kw1">import</span> Person, CreatureAdapter</p>
<p><span class="kw1">def</span> exercise_system<span class="br0">&#40;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; person = Person<span class="br0">&#40;</span><span class="st0">&quot;Bob&quot;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; fido = Dog<span class="br0">&#40;</span><span class="st0">&quot;Fido&quot;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; canine = CreatureAdapter<span class="br0">&#40;</span>fido, fido.<span class="me1">bark</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; whiskers = Cat<span class="br0">&#40;</span><span class="st0">&quot;Whiskers&quot;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; feline = CreatureAdapter<span class="br0">&#40;</span>whiskers, whiskers.<span class="me1">meow</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">for</span> critter <span class="kw1">in</span> <span class="br0">&#40;</span>person, canine, feline<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">print</span> critter.<span class="me1">name</span>, <span class="st0">&quot;says&quot;</span>, critter.<span class="me1">make_noise</span><span class="br0">&#40;</span><span class="br0">&#41;</span></div>
<p>We have to specify which method to use as the make_noise() method on instance creation, but in return we no longer have to create an Adapter for each new class in the system. I'd say that's a big win.</p>
<p>Output:</p>
<div class="dean_ch" style="white-space: wrap;">
Bob says hello<br />
Fido says woof<br />
Whiskers says meow</div>
<p>One final note about this system: you may have been wondering what happens if the class we're adapting doesn't have a name attribute (for example, if the attribute is called "nickname"). In that case, we could simply create new class that inherits from the creature class, implementing the name attribute via a property, and pass an instance of that to our CreatureAdapter class.</p>
<div class="dean_ch" style="white-space: wrap;">
<span class="kw1">class</span> NicknameCat<span class="br0">&#40;</span><span class="kw2">object</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;A representation of a cat in 2D Land&quot;</span><span class="st0">&quot;&quot;</span><br />
&nbsp; &nbsp; <span class="kw1">def</span> <span class="kw4">__init__</span><span class="br0">&#40;</span><span class="kw2">self</span>, nickname<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">nickname</span> = nickname<br />
&nbsp; &nbsp; <span class="kw1">def</span> meow<span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="st0">&quot;meow&quot;</span></p>
<p><span class="kw1">class</span> NicknameCatAdapter<span class="br0">&#40;</span>NicknameCat<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="kw1">def</span> <span class="kw4">__init__</span><span class="br0">&#40;</span><span class="kw2">self</span>, name<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; NicknameCat.<span class="kw4">__init__</span><span class="br0">&#40;</span><span class="kw2">self</span>, name<span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="kw1">def</span> _get_name<span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">self</span>.<span class="me1">nickname</span><br />
&nbsp; &nbsp; <span class="kw1">def</span> _set_name<span class="br0">&#40;</span><span class="kw2">self</span>, name<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">nickname</span> = name<br />
&nbsp; &nbsp; name = <span class="kw2">property</span><span class="br0">&#40;</span>_get_name, _set_name<span class="br0">&#41;</span></div>
<p>We could then do something like this:</p>
<div class="dean_ch" style="white-space: wrap;">
kitty = NicknameCatAdapter<span class="br0">&#40;</span><span class="st0">&quot;Whiskers&quot;</span><span class="br0">&#41;</span><br />
critter = CreatureAdapter<span class="br0">&#40;</span>kitty, kitty.<span class="me1">meow</span><span class="br0">&#41;</span></div>
<p>Note that this presupposes that the adapted class has some functionality that serves as the name attribute; the Adapter class is all about changing the interface of an object, not adding to its functionality.</p>
<h3>Using Adapter with Objects Other Than Classes</h3>
<p>The Adapter pattern as classically implemented works with classes, but that's just an accident of the languages that the pattern was initially made for. Essentially any object in Python is ripe for adapting. For example, you could adapt a function so that its signature was something that the client expected.</p>
<p>As an example, below we have a countdown() function. It takes as its arguments a number to count down from, and a callback function to call when it's done (callbacks are a common programming technique in things like multithreaded and asynchronous programs). We want to use the completed() function as its callback, but completed() takes an argument (the source), while countdown() calls its callback without any arguments. We can use the adapter pattern to change the signature of completed() to what countdown() expects.</p>
<div class="dean_ch" style="white-space: wrap;">
<span class="kw1">def</span> completed<span class="br0">&#40;</span>source<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="kw1">print</span> source, <span class="st0">&quot;completed&quot;</span></p>
<p><span class="kw1">def</span> countdown<span class="br0">&#40;</span>num, callback<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="kw1">for</span> i <span class="kw1">in</span> <span class="kw2">range</span><span class="br0">&#40;</span>num, <span class="nu0">0</span>, <span class="nu0">-1</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">print</span> <span class="st0">&quot;%s&#8230;&quot;</span> % i<br />
&nbsp; &nbsp; callback<span class="br0">&#40;</span><span class="br0">&#41;</span></p>
<p><span class="kw1">def</span> main<span class="br0">&#40;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="kw1">def</span> nullarg_callback<span class="br0">&#40;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; completed<span class="br0">&#40;</span><span class="st0">&quot;countdown&quot;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; countdown<span class="br0">&#40;</span><span class="nu0">3</span>, nullarg_callback<span class="br0">&#41;</span></p>
<p><span class="kw1">if</span> __name__ == <span class="st0">&quot;__main__&quot;</span>:<br />
&nbsp; &nbsp; main<span class="br0">&#40;</span><span class="br0">&#41;</span></div>
<p>Above, we adapted the completed() function using the nullarg_callback() function.</p>
<p>Output:</p>
<div class="dean_ch" style="white-space: wrap;">
3&#8230;<br />
2&#8230;<br />
1&#8230;<br />
countdown completed</div>
<p>The Adapter pattern changes the interface of an object in order to match the interface that's expected. In the 2D Land example, we adapted the Dog class to provide make_noise() method that our system expects. The Adapter pattern is a good choice any time you're integrating some code into an existing system, and the code has the needed functionality, but not the needed interface.</p>
<p><a href="/code/adapter_pattern.zip">Here's the code for this post</a>, together with unit tests.</p>
]]></content:encoded>
			<wfw:commentRss>http://ginstrom.com/scribbles/2009/03/27/the-adapter-pattern-in-python/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>A module to send email simply in Python</title>
		<link>http://ginstrom.com/scribbles/2009/03/15/a-module-to-send-email-simply-in-python/</link>
		<comments>http://ginstrom.com/scribbles/2009/03/15/a-module-to-send-email-simply-in-python/#comments</comments>
		<pubDate>Sun, 15 Mar 2009 09:14:13 +0000</pubDate>
		<dc:creator>Ryan Ginstrom</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[email]]></category>
		<category><![CDATA[smtp]]></category>

		<guid isPermaLink="false">http://ginstrom.com/scribbles/?p=898</guid>
		<description><![CDATA[Update: I've released version 0.3 of the mailer module. See the mailer home page for details and the latest version.
The email and smtplib modules in Python are very powerful, but they're also a bit complex when you just want to send an email.
I wrote the mailer module as a front end to these two modules, [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Update</strong>: I've released version 0.3 of the mailer module. See the <a href="/code/mailer.html">mailer home page</a> for details and the latest version.</p>
<p>The <a href="http://docs.python.org/library/email.html">email</a> and <a href="http://docs.python.org/library/smtplib.html">smtplib</a> modules in Python are very powerful, but they're also a bit complex when you just want to send an email.</p>
<p>I wrote the <a href="/code/mailer_0.1.zip">mailer module</a> as a front end to these two modules, in order to make the task of sending email in Python using SMTP as simple as possible.</p>
<p>Below are some examples.</p>
<h3>Send a simple plain text email</h3>
<div class="dean_ch" style="white-space: wrap;">
<span class="kw1">import</span> mailer</p>
<p>message = mailer.<span class="me1">Message</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
message.<span class="me1">From</span> = <span class="st0">&quot;me@example.com&quot;</span><br />
message.<span class="me1">To</span> = <span class="st0">&quot;you@example.com&quot;</span><br />
message.<span class="me1">Subject</span> = <span class="st0">&quot;My Vacation&quot;</span><br />
message.<span class="me1">Body</span> = <span class="kw2">open</span><span class="br0">&#40;</span><span class="st0">&quot;letter.txt&quot;</span>, <span class="st0">&quot;rb&quot;</span><span class="br0">&#41;</span>.<span class="me1">read</span><span class="br0">&#40;</span><span class="br0">&#41;</span></p>
<p>mailer = mailer.<span class="me1">Mailer</span><span class="br0">&#40;</span><span class="st0">'mail.example.com'</span><span class="br0">&#41;</span><br />
mailer.<span class="me1">send</span><span class="br0">&#40;</span>message<span class="br0">&#41;</span></div>
<h3>Send an email with an attachment</h3>
<div class="dean_ch" style="white-space: wrap;">
message = mailer.<span class="me1">Message</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
message.<span class="me1">From</span> = <span class="st0">&quot;me@example.com&quot;</span><br />
message.<span class="me1">To</span> = <span class="st0">&quot;you@example.com&quot;</span><br />
message.<span class="me1">Subject</span> = <span class="st0">&quot;My Vacation&quot;</span><br />
message.<span class="me1">Body</span> = <span class="kw2">open</span><span class="br0">&#40;</span><span class="st0">&quot;letter.txt&quot;</span>, <span class="st0">&quot;rb&quot;</span><span class="br0">&#41;</span>.<span class="me1">read</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
message.<span class="me1">attach</span><span class="br0">&#40;</span><span class="st0">&quot;picture.jpg&quot;</span><span class="br0">&#41;</span></p>
<p>mailer = mailer.<span class="me1">Mailer</span><span class="br0">&#40;</span><span class="st0">'mail.example.com'</span><span class="br0">&#41;</span><br />
mailer.<span class="me1">send</span><span class="br0">&#40;</span>message<span class="br0">&#41;</span></div>
<h3>Send an HTML email</h3>
<div class="dean_ch" style="white-space: wrap;">
message = mailer.<span class="me1">Message</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
message.<span class="me1">From</span> = <span class="st0">&quot;me@example.com&quot;</span><br />
message.<span class="me1">To</span> = <span class="st0">&quot;you@example.com&quot;</span><br />
message.<span class="me1">Subject</span> = <span class="st0">&quot;My Vacation&quot;</span><br />
message.<span class="me1">Body</span> = <span class="kw2">open</span><span class="br0">&#40;</span><span class="st0">&quot;letter.txt&quot;</span>, <span class="st0">&quot;rb&quot;</span><span class="br0">&#41;</span>.<span class="me1">read</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
message.<span class="me1">Html</span> = <span class="st0">&quot;&quot;</span><span class="st0">&quot;This email is in &lt;b&gt;HTML&lt;/b&gt;.<br />
&lt;a href=&quot;</span>http://example.<span class="me1">com</span><span class="st0">&quot;&gt;Here's a link.&lt;/a&gt;&quot;</span><span class="st0">&quot;&quot;</span></p>
<p>mailer = mailer.<span class="me1">Mailer</span><span class="br0">&#40;</span><span class="st0">'mail.example.com'</span><span class="br0">&#41;</span><br />
mailer.<span class="me1">send</span><span class="br0">&#40;</span>message<span class="br0">&#41;</span></div>
<p><a href="/code/mailer_0.1.zip">Download the mailer module (zip file)</a>.</p>
<p><strong>Edit:</strong> Here's the source code of the mailer module.</p>
<div class="dean_ch" style="white-space: wrap;">
<span class="co1">#coding: UTF8</span><br />
<span class="st0">&quot;&quot;</span><span class="st0">&quot;<br />
mailer module</p>
<p>Simple front end to the smtplib and email modules,<br />
to simplify sending email.</p>
<p>A lot of this code was taken from the online examples in the<br />
email module documentation:<br />
http://docs.python.org/library/email-examples.html</p>
<p>Released under MIT license.</p>
<p>Sample code:</p>
<p>import mailer</p>
<p>message = mailer.Message()<br />
message.From = &quot;</span>me@example.<span class="me1">com</span><span class="st0">&quot;<br />
message.To = &quot;</span>you@example.<span class="me1">com</span><span class="st0">&quot;<br />
message.Subject = &quot;</span>My Vacation<span class="st0">&quot;<br />
message.Body = open(&quot;</span>letter.<span class="me1">txt</span><span class="st0">&quot;, &quot;</span>rb<span class="st0">&quot;).read()<br />
message.attach(&quot;</span>picture.<span class="me1">jpg</span><span class="st0">&quot;)</p>
<p>mailer = mailer.Mailer('mail.example.com')<br />
mailer.send(message)</p>
<p>&quot;</span><span class="st0">&quot;&quot;</span><br />
<span class="kw1">import</span> <span class="kw3">smtplib</span></p>
<p><span class="co1"># Import the email modules we'll need</span><br />
<span class="kw1">from</span> <span class="kw3">email</span> <span class="kw1">import</span> encoders<br />
<span class="kw1">from</span> <span class="kw3">email</span>.<span class="me1">message</span> <span class="kw1">import</span> Message<br />
<span class="kw1">from</span> <span class="kw3">email</span>.<span class="me1">mime</span>.<span class="me1">audio</span> <span class="kw1">import</span> MIMEAudio<br />
<span class="kw1">from</span> <span class="kw3">email</span>.<span class="me1">mime</span>.<span class="me1">base</span> <span class="kw1">import</span> MIMEBase<br />
<span class="kw1">from</span> <span class="kw3">email</span>.<span class="me1">mime</span>.<span class="me1">image</span> <span class="kw1">import</span> MIMEImage<br />
<span class="kw1">from</span> <span class="kw3">email</span>.<span class="me1">mime</span>.<span class="me1">multipart</span> <span class="kw1">import</span> MIMEMultipart<br />
<span class="kw1">from</span> <span class="kw3">email</span>.<span class="me1">mime</span>.<span class="me1">text</span> <span class="kw1">import</span> MIMEText</p>
<p><span class="co1"># For guessing MIME type based on file name extension</span><br />
<span class="kw1">import</span> <span class="kw3">mimetypes</span></p>
<p><span class="kw1">from</span> <span class="kw3">os</span> <span class="kw1">import</span> path</p>
<p>__version__ = <span class="st0">&quot;0.1&quot;</span><br />
__author__ = <span class="st0">&quot;Ryan Ginstrom&quot;</span><br />
__license__ = <span class="st0">&quot;MIT&quot;</span></p>
<p><span class="kw1">class</span> Mailer<span class="br0">&#40;</span><span class="kw2">object</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;<br />
&nbsp; &nbsp; Represents an SMTP connection.</p>
<p>&nbsp; &nbsp; Use login() to log in with a username and password.<br />
&nbsp; &nbsp; &quot;</span><span class="st0">&quot;&quot;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> <span class="kw4">__init__</span><span class="br0">&#40;</span><span class="kw2">self</span>, host=<span class="st0">&quot;localhost&quot;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">host</span> = host<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>._usr = <span class="kw2">None</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>._pwd = <span class="kw2">None</span></p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> login<span class="br0">&#40;</span><span class="kw2">self</span>, usr, <span class="kw3">pwd</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>._usr = usr<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>._pwd = <span class="kw3">pwd</span></p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> send<span class="br0">&#40;</span><span class="kw2">self</span>, msg<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;<br />
&nbsp; &nbsp; &nbsp; &nbsp; Send one message or a sequence of messages.</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; Every time you call send, the mailer creates a new<br />
&nbsp; &nbsp; &nbsp; &nbsp; connection, so if you have several emails to send, pass<br />
&nbsp; &nbsp; &nbsp; &nbsp; them as a list:<br />
&nbsp; &nbsp; &nbsp; &nbsp; mailer.send([msg1, msg2, msg3])<br />
&nbsp; &nbsp; &nbsp; &nbsp; &quot;</span><span class="st0">&quot;&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; server = <span class="kw3">smtplib</span>.<span class="me1">SMTP</span><span class="br0">&#40;</span><span class="kw2">self</span>.<span class="me1">host</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="kw2">self</span>._usr <span class="kw1">and</span> <span class="kw2">self</span>._pwd:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; server.<span class="me1">login</span><span class="br0">&#40;</span><span class="kw2">self</span>._usr, <span class="kw2">self</span>._pwd<span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">try</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> m <span class="kw1">in</span> msg:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>._send<span class="br0">&#40;</span>server, m<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">except</span> <span class="kw2">TypeError</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>._send<span class="br0">&#40;</span>server, msg<span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; server.<span class="me1">quit</span><span class="br0">&#40;</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> _send<span class="br0">&#40;</span><span class="kw2">self</span>, server, msg<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;<br />
&nbsp; &nbsp; &nbsp; &nbsp; Sends a single message using the server<br />
&nbsp; &nbsp; &nbsp; &nbsp; we created in send()<br />
&nbsp; &nbsp; &nbsp; &nbsp; &quot;</span><span class="st0">&quot;&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; me = msg.<span class="me1">From</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; you = <span class="br0">&#91;</span>x.<span class="me1">strip</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="kw1">for</span> x <span class="kw1">in</span> msg.<span class="me1">To</span>.<span class="me1">split</span><span class="br0">&#40;</span><span class="st0">&quot;,&quot;</span><span class="br0">&#41;</span><span class="br0">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; server.<span class="me1">sendmail</span><span class="br0">&#40;</span>me, you, msg.<span class="me1">as_string</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span></p>
<p><span class="kw1">class</span> Message<span class="br0">&#40;</span><span class="kw2">object</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;<br />
&nbsp; &nbsp; Represents an email message.</p>
<p>&nbsp; &nbsp; Set the To, From, Subject, and Body attributes as plain-text strings.<br />
&nbsp; &nbsp; Optionally, set the Html attribute to send an HTML email, or use the<br />
&nbsp; &nbsp; attach() method to attach files.</p>
<p>&nbsp; &nbsp; Even when sending an HTML email, you have to set the Body<br />
&nbsp; &nbsp; attribute as the alternative text version.</p>
<p>&nbsp; &nbsp; Send using the Mailer class.<br />
&nbsp; &nbsp; &quot;</span><span class="st0">&quot;&quot;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> <span class="kw4">__init__</span><span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">attachments</span> = <span class="br0">&#91;</span><span class="br0">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>._to = <span class="kw2">None</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">From</span> = <span class="kw2">None</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">Subject</span> = <span class="kw2">None</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">Body</span> = <span class="kw2">None</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">Html</span> = <span class="kw2">None</span></p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> _get_to<span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; addrs = <span class="kw2">self</span>._to.<span class="me1">replace</span><span class="br0">&#40;</span><span class="st0">&quot;;&quot;</span>, <span class="st0">&quot;,&quot;</span><span class="br0">&#41;</span>.<span class="me1">split</span><span class="br0">&#40;</span><span class="st0">&quot;,&quot;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="st0">&quot;, &quot;</span>.<span class="me1">join</span><span class="br0">&#40;</span><span class="br0">&#91;</span>x.<span class="me1">strip</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> x <span class="kw1">in</span> addrs<span class="br0">&#93;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="kw1">def</span> _set_to<span class="br0">&#40;</span><span class="kw2">self</span>, to<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>._to = to</p>
<p>&nbsp; &nbsp; To = <span class="kw2">property</span><span class="br0">&#40;</span>_get_to, _set_to,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; doc=<span class="st0">&quot;&quot;</span><span class="st0">&quot;The recipient(s) of the email.<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Separate multiple recipients with commas or semicolons&quot;</span><span class="st0">&quot;&quot;</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> as_string<span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;Get the email as a string to send in the mailer&quot;</span><span class="st0">&quot;&quot;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="kw1">not</span> <span class="kw2">self</span>.<span class="me1">attachments</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">self</span>._plaintext<span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">self</span>._multipart<span class="br0">&#40;</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> _plaintext<span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;Plain text email with no attachments&quot;</span><span class="st0">&quot;&quot;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="kw1">not</span> <span class="kw2">self</span>.<span class="me1">Html</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; msg = MIMEText<span class="br0">&#40;</span><span class="kw2">self</span>.<span class="me1">Body</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; msg &nbsp;= <span class="kw2">self</span>._with_html<span class="br0">&#40;</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>._set_info<span class="br0">&#40;</span>msg<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> msg.<span class="me1">as_string</span><span class="br0">&#40;</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> _with_html<span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;There's an html part&quot;</span><span class="st0">&quot;&quot;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; outer = MIMEMultipart<span class="br0">&#40;</span><span class="st0">'alternative'</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; part1 = MIMEText<span class="br0">&#40;</span><span class="kw2">self</span>.<span class="me1">Body</span>, <span class="st0">'plain'</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; part2 = MIMEText<span class="br0">&#40;</span><span class="kw2">self</span>.<span class="me1">Html</span>, <span class="st0">'html'</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; outer.<span class="me1">attach</span><span class="br0">&#40;</span>part1<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; outer.<span class="me1">attach</span><span class="br0">&#40;</span>part2<span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> outer</p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> _set_info<span class="br0">&#40;</span><span class="kw2">self</span>, msg<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; msg<span class="br0">&#91;</span><span class="st0">'Subject'</span><span class="br0">&#93;</span> = <span class="kw2">self</span>.<span class="me1">Subject</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; msg<span class="br0">&#91;</span><span class="st0">'From'</span><span class="br0">&#93;</span> = <span class="kw2">self</span>.<span class="me1">From</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; msg<span class="br0">&#91;</span><span class="st0">'To'</span><span class="br0">&#93;</span> = <span class="kw2">self</span>.<span class="me1">To</span></p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> _multipart<span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;The email has attachments&quot;</span><span class="st0">&quot;&quot;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; msg = MIMEMultipart<span class="br0">&#40;</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; msg.<span class="me1">attach</span><span class="br0">&#40;</span>MIMEText<span class="br0">&#40;</span><span class="kw2">self</span>.<span class="me1">Body</span>, <span class="st0">'plain'</span><span class="br0">&#41;</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>._set_info<span class="br0">&#40;</span>msg<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; msg.<span class="me1">preamble</span> = <span class="kw2">self</span>.<span class="me1">Subject</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> filename <span class="kw1">in</span> <span class="kw2">self</span>.<span class="me1">attachments</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>._add_attachment<span class="br0">&#40;</span>msg, filename<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> msg.<span class="me1">as_string</span><span class="br0">&#40;</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> _add_attachment<span class="br0">&#40;</span><span class="kw2">self</span>, outer, filename<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; ctype, encoding = <span class="kw3">mimetypes</span>.<span class="me1">guess_type</span><span class="br0">&#40;</span>filename<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> ctype <span class="kw1">is</span> <span class="kw2">None</span> <span class="kw1">or</span> encoding <span class="kw1">is</span> <span class="kw1">not</span> <span class="kw2">None</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1"># No guess could be made, or the file is encoded (compressed), so</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1"># use a generic bag-of-bits type.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ctype = <span class="st0">'application/octet-stream'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; maintype, subtype = ctype.<span class="me1">split</span><span class="br0">&#40;</span><span class="st0">'/'</span>, <span class="nu0">1</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; fp = <span class="kw2">open</span><span class="br0">&#40;</span>filename, <span class="st0">'rb'</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> maintype == <span class="st0">'text'</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1"># Note: we should handle calculating the charset</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; msg = MIMEText<span class="br0">&#40;</span>fp.<span class="me1">read</span><span class="br0">&#40;</span><span class="br0">&#41;</span>, _subtype=subtype<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">elif</span> maintype == <span class="st0">'image'</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; msg = MIMEImage<span class="br0">&#40;</span>fp.<span class="me1">read</span><span class="br0">&#40;</span><span class="br0">&#41;</span>, _subtype=subtype<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">elif</span> maintype == <span class="st0">'audio'</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; msg = MIMEAudio<span class="br0">&#40;</span>fp.<span class="me1">read</span><span class="br0">&#40;</span><span class="br0">&#41;</span>, _subtype=subtype<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; msg = MIMEBase<span class="br0">&#40;</span>maintype, subtype<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; msg.<span class="me1">set_payload</span><span class="br0">&#40;</span>fp.<span class="me1">read</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1"># Encode the payload using Base64</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; encoders.<span class="me1">encode_base64</span><span class="br0">&#40;</span>msg<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; fp.<span class="me1">close</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1"># Set the filename parameter</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; msg.<span class="me1">add_header</span><span class="br0">&#40;</span><span class="st0">'Content-Disposition'</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">'attachment'</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; filename=path.<span class="me1">basename</span><span class="br0">&#40;</span>filename<span class="br0">&#41;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; outer.<span class="me1">attach</span><span class="br0">&#40;</span>msg<span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> attach<span class="br0">&#40;</span><span class="kw2">self</span>, filename<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;<br />
&nbsp; &nbsp; &nbsp; &nbsp; Attach a file to the email. Specify the name of the file;<br />
&nbsp; &nbsp; &nbsp; &nbsp; Message will figure out the MIME type and load the file.<br />
&nbsp; &nbsp; &nbsp; &nbsp; &quot;</span><span class="st0">&quot;&quot;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">attachments</span>.<span class="me1">append</span><span class="br0">&#40;</span>filename<span class="br0">&#41;</span></div>
]]></content:encoded>
			<wfw:commentRss>http://ginstrom.com/scribbles/2009/03/15/a-module-to-send-email-simply-in-python/feed/</wfw:commentRss>
		<slash:comments>28</slash:comments>
		</item>
		<item>
		<title>Conditional &#8220;tee&#8221; with Python</title>
		<link>http://ginstrom.com/scribbles/2009/03/02/conditional-tee-with-python/</link>
		<comments>http://ginstrom.com/scribbles/2009/03/02/conditional-tee-with-python/#comments</comments>
		<pubDate>Mon, 02 Mar 2009 01:21:38 +0000</pubDate>
		<dc:creator>Ryan Ginstrom</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[conditional]]></category>
		<category><![CDATA[functional]]></category>
		<category><![CDATA[generators]]></category>
		<category><![CDATA[iterators]]></category>
		<category><![CDATA[tee]]></category>

		<guid isPermaLink="false">http://ginstrom.com/scribbles/?p=858</guid>
		<description><![CDATA[This post describes the conditional tee ("ctee") module I wrote to split a sequence into two generators, according to a filter function.
The problem
David Beazley has a great article about generator pipelining using Python. This is a technique for handling (potentially very large) streams of data in a flexible yet efficient way. As an example, here's [...]]]></description>
			<content:encoded><![CDATA[<p>This post describes the <a href="/code/ctee.zip">conditional tee ("ctee") module</a> I wrote to split a sequence into two generators, according to a filter function.</p>
<h3>The problem</h3>
<p>David Beazley has <a href="http://www.dabeaz.com/generators/">a great article about generator pipelining</a> using Python. This is a technique for handling (potentially very large) streams of data in a flexible yet efficient way. As an example, here's a code snippet he gives for summing the total bytes from a log file:</p>
<div class="dean_ch" style="white-space: wrap;">
wwwlog = <span class="kw2">open</span><span class="br0">&#40;</span><span class="st0">&quot;access-log&quot;</span><span class="br0">&#41;</span><br />
bytecolumn = <span class="br0">&#40;</span>line.<span class="me1">rsplit</span><span class="br0">&#40;</span><span class="kw2">None</span>,<span class="nu0">1</span><span class="br0">&#41;</span><span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span> <span class="kw1">for</span> line <span class="kw1">in</span> wwwlog<span class="br0">&#41;</span><br />
bytes = <span class="br0">&#40;</span><span class="kw2">int</span><span class="br0">&#40;</span>x<span class="br0">&#41;</span> <span class="kw1">for</span> x <span class="kw1">in</span> bytecolumn <span class="kw1">if</span> x != <span class="st0">'-'</span><span class="br0">&#41;</span></p>
<p><span class="kw1">print</span> <span class="st0">&quot;Total&quot;</span>, <span class="kw2">sum</span><span class="br0">&#40;</span>bytes<span class="br0">&#41;</span></div>
<p>The code above first opens a log file, then gets the byte column for each entry. The byte value (if any) is then calculated for each row. Finally, the generator is consumed (or "pumped"), yielding the sum.</p>
<p>Since the entire file is never loaded into active memory, you could run this on quite huge log files, or even add a few steps and run it on collections of log files, without blowing up your memory. Another feature of this technique is that it's very flexible: you can add steps, combine steps into atomic actions, rearrange them, and so on.</p>
<p>This works great, as long as your pipe doesn't branch. If you want to split your pipe &#8212; say, dividing a stream of integers into one stream of even numbers and another of odds, things get a little complicated. One really elegant way to handle this situation is with the <code>itertools.tee</code> function. <code>tee</code> takes an iterable sequence, and returns <em>n</em> "copies" of that sequence that can be iterated independently.</p>
<h3>Using <code>itertools.tee</code></h3>
<div class="dean_ch" style="white-space: wrap;">
<span class="kw1">import</span> <span class="kw3">itertools</span></p>
<p>lines = <span class="kw2">open</span><span class="br0">&#40;</span><span class="st0">&quot;numbers.txt&quot;</span><span class="br0">&#41;</span><br />
numbers = <span class="br0">&#40;</span><span class="kw2">int</span><span class="br0">&#40;</span>line<span class="br0">&#41;</span> <span class="kw1">for</span> line <span class="kw1">in</span> lines<span class="br0">&#41;</span></p>
<p>first, second = <span class="kw3">itertools</span>.<span class="me1">tee</span><span class="br0">&#40;</span>numbers<span class="br0">&#41;</span></p>
<p>evens = <span class="br0">&#40;</span>i <span class="kw1">for</span> i <span class="kw1">in</span> first <span class="kw1">if</span> <span class="kw1">not</span> i % <span class="nu0">2</span><span class="br0">&#41;</span><br />
odds = <span class="br0">&#40;</span>i <span class="kw1">for</span> i <span class="kw1">in</span> second <span class="kw1">if</span> i % <span class="nu0">2</span><span class="br0">&#41;</span></p>
<p><span class="kw1">print</span> <span class="st0">&quot;Evens total:&quot;</span>, <span class="kw2">sum</span><span class="br0">&#40;</span>evens<span class="br0">&#41;</span><br />
<span class="kw1">print</span> <span class="st0">&quot;Odds total:&quot;</span>, <span class="kw2">sum</span><span class="br0">&#40;</span>odds<span class="br0">&#41;</span></div>
<p>The code first opens a file containing a bunch of random integers, and creates a generator that's a stream of integers. It then uses <code>itertools.tee</code> to make two copies of that generator (first and second), and applies generator expressions to create two streams: one of even numbers, and one of odd numbers. The built-in <code>sum</code> function is then used to consume each tee.</p>
<p><a href="/code/numbers.txt">Here's the number file</a> that I used for this code. It's a list of 1,000 random integers between 1 and 1,000,000.</p>
<p>That's fine in this case, where the filter expression is relatively inexpensive. But what if we have an expensive filter, like testing whether the number is prime, or making a database query? It could really hurt our performance if we have to perform the same test twice. Ideally, we'd just like to perform the test once for each element in our pipeline.</p>
<p>There are lots of ways to handle that situation. One common way is the <a href="http://en.wikipedia.org/wiki/Continuation-passing_style">"continuation-passing" style</a>, where you pass some data, a filter condition, and one or more functions to perform depending on the results of the test.</p>
<p>This works, but it disrupts the pipeline. That costs us the flexibility and dynamic nature of the generator paradigm.</p>
<p>I wrote the conditional tee (ctee) module for cases when you want to use a generator pipeline, but you need to split the sequence into two generators, and the filter condition is expensive. It creates a pair of instances of the <code>ConditionalTee</code> class, which are linked to each other.</p>
<h3>Using conditional tee</h3>
<p>Here's the meat of the code. The module can be <a href="/code/ctee.zip">downloaded here (ctee.zip)</a>.</p>
<div class="dean_ch" style="white-space: wrap;">
<span class="kw1">from</span> <span class="kw3">Queue</span> <span class="kw1">import</span> <span class="kw3">Queue</span></p>
<p><span class="kw1">class</span> ConditionalTee<span class="br0">&#40;</span><span class="kw2">object</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;A conditional tee class&quot;</span><span class="st0">&quot;&quot;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> <span class="kw4">__init__</span><span class="br0">&#40;</span><span class="kw2">self</span>, sequence, condition<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">sequence</span> = sequence<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">condition</span> = condition<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">othertee</span> = <span class="kw2">None</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">q</span> = <span class="kw3">Queue</span><span class="br0">&#40;</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> next<span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;<br />
&nbsp; &nbsp; &nbsp; &nbsp; Get the next item that matches the condition.<br />
&nbsp; &nbsp; &nbsp; &nbsp; Adds items to the queue of the other sequence until<br />
&nbsp; &nbsp; &nbsp; &nbsp; one matching this condition is reached.<br />
&nbsp; &nbsp; &nbsp; &nbsp; &quot;</span><span class="st0">&quot;&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="kw1">not</span> <span class="kw2">self</span>.<span class="me1">q</span>.<span class="me1">empty</span><span class="br0">&#40;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">self</span>.<span class="me1">q</span>.<span class="me1">get</span><span class="br0">&#40;</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; item = <span class="kw2">self</span>.<span class="me1">sequence</span>.<span class="me1">next</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">while</span> <span class="kw1">not</span> <span class="kw2">self</span>.<span class="me1">condition</span><span class="br0">&#40;</span>item<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">othertee</span>.<span class="me1">q</span>.<span class="me1">put</span><span class="br0">&#40;</span>item<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; item = <span class="kw2">self</span>.<span class="me1">sequence</span>.<span class="me1">next</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> item</p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> <span class="kw4">__iter__</span><span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;We are an iterator&quot;</span><span class="st0">&quot;&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">self</span></p>
<p><span class="kw1">def</span> ctee<span class="br0">&#40;</span>sequence, condition<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;<br />
&nbsp; &nbsp; Creates two sequences from sequence: one where<br />
&nbsp; &nbsp; condition holds, and the other where it doesn't<br />
&nbsp; &nbsp; sequence -&gt; (x for x in sequence if condition(x)),<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (x for x in sequence if not condition(x))<br />
&nbsp; &nbsp; &quot;</span><span class="st0">&quot;&quot;</span></p>
<p>&nbsp; &nbsp; yes_iter = ConditionalTee<span class="br0">&#40;</span>sequence, condition<span class="br0">&#41;</span><br />
&nbsp; &nbsp; nocond = <span class="kw1">lambda</span> x : <span class="kw1">not</span> condition<span class="br0">&#40;</span>x<span class="br0">&#41;</span><br />
&nbsp; &nbsp; no_iter = ConditionalTee<span class="br0">&#40;</span>sequence, nocond<span class="br0">&#41;</span><br />
&nbsp; &nbsp; yes_iter.<span class="me1">othertee</span> = no_iter<br />
&nbsp; &nbsp; no_iter.<span class="me1">othertee</span> = yes_iter</p>
<p>&nbsp; &nbsp; <span class="kw1">return</span> yes_iter, no_iter</div>
<p>The <code>ConditionalTee</code> class takes a sequence and a filter condition as arguments to its <code>__init__</code> method. The <code>__init__</code> method also creates an empty queue member, and an <code>othertee</code> member that's initialized to None.</p>
<p>When the <code>next</code> method of a <code>ConditionalTee</code> instance is called, it first looks for any items in its queue. If there is an item on the queue, it returns the first one. Otherwise, it iterates through its sequence; it keeps adding any items that don't match to the queue of its <code>othertee</code> member, until it either finds an item that matches or raises a <code>StopIteration</code> exception.</p>
<p>The <code>ctee</code> function also takes a sequence and a filter condition as arguments. It creates two <code>ConditionalTee</code> instances, and sets their <code>othertee</code> members to each other, then returns the two instances as a pair.</p>
<p>Here's some sample code using ctee:</p>
<div class="dean_ch" style="white-space: wrap;">
lines = <span class="kw2">open</span><span class="br0">&#40;</span><span class="st0">&quot;numbers.txt&quot;</span><span class="br0">&#41;</span><br />
nums = <span class="br0">&#40;</span><span class="kw2">int</span><span class="br0">&#40;</span>line<span class="br0">&#41;</span> <span class="kw1">for</span> line <span class="kw1">in</span> lines<span class="br0">&#41;</span><br />
iseven = <span class="kw1">lambda</span> x : <span class="kw1">not</span> x % <span class="nu0">2</span><br />
evens, odds = ctee.<span class="me1">ctee</span><span class="br0">&#40;</span>nums, iseven<span class="br0">&#41;</span></div>
<p>There's still a problem if you "pump" each of these generators in succession, though: if the amount of data is large, the other generator class is going to accumulate a huge queue of data. It would be better to pump each generator expression alternately, taking an item and processing it from each generator in turn, in order to avoid building up a big queue.</p>
<p>Here's a function that'll do that:</p>
<h3>Pumping generators alternately instead of consecutively</h3>
<div class="dean_ch" style="white-space: wrap;">
<span class="kw1">def</span> diagonalize<span class="br0">&#40;</span>sequences<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;<br />
&nbsp; &nbsp; Takes each sequence in turn, retrieving one item from that<br />
&nbsp; &nbsp; sequence and performing action on it, until all sequences<br />
&nbsp; &nbsp; are exhausted.<br />
&nbsp; &nbsp; sequence is a sequence of (iterable, action) pairs.<br />
&nbsp; &nbsp; &quot;</span><span class="st0">&quot;&quot;</span><br />
&nbsp; &nbsp; sequences = <span class="br0">&#91;</span><span class="br0">&#40;</span><span class="kw2">iter</span><span class="br0">&#40;</span>s<span class="br0">&#41;</span>, a<span class="br0">&#41;</span> <span class="kw1">for</span> <span class="br0">&#40;</span>s, a<span class="br0">&#41;</span> <span class="kw1">in</span> sequences<span class="br0">&#93;</span><br />
&nbsp; &nbsp; <span class="kw1">while</span> sequences:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> sequence, action <span class="kw1">in</span> sequences:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">try</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; item = sequence.<span class="me1">next</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; action<span class="br0">&#40;</span>item<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">except</span> <span class="kw2">StopIteration</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1"># remove the exhausted sequence from the list</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sequences = <span class="br0">&#91;</span><span class="br0">&#40;</span>s, a<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> <span class="br0">&#40;</span>s, a<span class="br0">&#41;</span> <span class="kw1">in</span> sequences<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> s != sequence<span class="br0">&#93;</span></div>
<p>This takes a sequence of (sequence, action) pairs. It iterates through each pair, taking the next item in the sequence and applying the action to it. If the sequence raises <code>StopIteration</code>, it's removed from the list of sequences. The list comprehension at the start of the function is to make <code>sequence</code> test False when empty, and to ensure each sequence in it is an iterable (i.e. supporting <code>next</code>).</p>
<p>Here's an example of using this function:</p>
<div class="dean_ch" style="white-space: wrap;">
lines = <span class="kw2">open</span><span class="br0">&#40;</span><span class="st0">&quot;numbers.txt&quot;</span><span class="br0">&#41;</span><br />
numbers = <span class="br0">&#40;</span><span class="kw2">int</span><span class="br0">&#40;</span>line<span class="br0">&#41;</span> <span class="kw1">for</span> line <span class="kw1">in</span> lines<span class="br0">&#41;</span></p>
<p>evens, odds = ctee<span class="br0">&#40;</span>numbers, <span class="kw1">lambda</span> x : <span class="kw1">not</span> x % <span class="nu0">2</span><span class="br0">&#41;</span></p>
<p>evenout = <span class="kw2">open</span><span class="br0">&#40;</span><span class="st0">&quot;evens.txt&quot;</span>, <span class="st0">&quot;w&quot;</span><span class="br0">&#41;</span><br />
oddout = <span class="kw2">open</span><span class="br0">&#40;</span><span class="st0">&quot;odds.txt&quot;</span>, <span class="st0">&quot;w&quot;</span><span class="br0">&#41;</span></p>
<p><span class="kw1">def</span> writeline<span class="br0">&#40;</span>out, item<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="kw1">print</span> &gt;&gt; out, item</p>
<p>evenaction = <span class="kw1">lambda</span> x : writeline<span class="br0">&#40;</span>evenout, x<span class="br0">&#41;</span><br />
oddaction = <span class="kw1">lambda</span> x : writeline<span class="br0">&#40;</span>oddout, x<span class="br0">&#41;</span></p>
<p>diagonalize<span class="br0">&#40;</span><span class="br0">&#40;</span><span class="br0">&#40;</span>evens, evenaction<span class="br0">&#41;</span>, <span class="br0">&#40;</span>odds, oddaction<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span></div>
<p>This code will write all the even numbers to "evens.txt", and all the odd numbers to "odds.txt".</p>
<p>You might ask, how is this different from the continuation passing style? And you'd have a point; this is essentially continuation passing.</p>
<p>The thing is that here, the pumping only happens at the end. You can still go on wrapping all sorts of other filtering and transforming generators around your two conditional tees; the sequence won't actually be processed until you start pumping the generators at the end, so you won't build up enormous queues of data.</p>
]]></content:encoded>
			<wfw:commentRss>http://ginstrom.com/scribbles/2009/03/02/conditional-tee-with-python/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Coming from C++/Java to Python should bend your mind</title>
		<link>http://ginstrom.com/scribbles/2009/02/03/coming-from-cjava-to-python-should-bend-your-mind/</link>
		<comments>http://ginstrom.com/scribbles/2009/02/03/coming-from-cjava-to-python-should-bend-your-mind/#comments</comments>
		<pubDate>Tue, 03 Feb 2009 02:30:38 +0000</pubDate>
		<dc:creator>Ryan Ginstrom</dc:creator>
				<category><![CDATA[c++]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[pythonic]]></category>

		<guid isPermaLink="false">http://ginstrom.com/scribbles/?p=839</guid>
		<description><![CDATA[Coming from C++ or Java to Python should bend your mind. If it doesn't, then you haven't learned Python yet &#8212; you're just writing C++ or Java in Python.
If you only knew a statically typed and compiled language like C++ or Java before, and learning Python hasn't changed the way you think about programming, then [...]]]></description>
			<content:encoded><![CDATA[<p>Coming from C++ or Java to Python should bend your mind. If it doesn't, then you haven't learned Python yet &#8212; you're just writing C++ or Java in Python.</p>
<p>If you only knew a statically typed and compiled language like C++ or Java before, and learning Python hasn't changed the way you think about programming, then check your programs for lots of type-checking code, inheritance, array indexing, and mutable variables. Look at some <a href="http://effbot.org/">excellent</a> <a href="http://www.aleax.it/python_mat_en.html">Python</a> <a href="http://code.activestate.com/recipes/">code</a>, and identify where your code diverges from it.</p>
]]></content:encoded>
			<wfw:commentRss>http://ginstrom.com/scribbles/2009/02/03/coming-from-cjava-to-python-should-bend-your-mind/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
