<?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>schmichael&#039;s blog &#187; Python</title>
	<atom:link href="http://blog.schmichael.com/category/technology/python/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.schmichael.com</link>
	<description>good good study, day day up</description>
	<lastBuildDate>Mon, 02 Aug 2010 17:28:53 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Making Server-Side MongoDB Functions Less Awkward</title>
		<link>http://blog.schmichael.com/2010/01/11/making-server-side-mongodb-functions-less-awkward/</link>
		<comments>http://blog.schmichael.com/2010/01/11/making-server-side-mongodb-functions-less-awkward/#comments</comments>
		<pubDate>Tue, 12 Jan 2010 00:54:19 +0000</pubDate>
		<dc:creator>Michael Schurter</dc:creator>
				<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[mongodb]]></category>
		<category><![CDATA[pymongo]]></category>

		<guid isPermaLink="false">http://michael.susens-schurter.com/blog/?p=796</guid>
		<description><![CDATA[I&#8217;ve recently switched my project at work to use MongoDB for the user database and a few other datasets. Currently I don&#8217;t use many JavaScript functions, but when I do I like to store them on the server so that &#8230; <a href="http://blog.schmichael.com/2010/01/11/making-server-side-mongodb-functions-less-awkward/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve recently switched my project at work to use MongoDB for the user database and a few other datasets.</p>
<p>Currently I don&#8217;t use many JavaScript functions, but when I do I like to store them on the server so that they&#8217;re accessible when I&#8217;m poking around in a console.</p>
<p>I use something similar to the following function to load all of my JS functions onto the server when my app starts:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">os</span>
<span style="color: #ff7700;font-weight:bold;">import</span> pymongo
<span style="color: #ff7700;font-weight:bold;">import</span> pkg_resources
&nbsp;
<span style="color: #808080; font-style: italic;"># Relative to distribution's root</span>
SCRIPT_DIR = <span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">join</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'model'</span>, <span style="color: #483d8b;">'js'</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> init_js<span style="color: black;">&#40;</span>db<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">''</span><span style="color: #483d8b;">'Initializes server-side javascript functions'</span><span style="color: #483d8b;">''</span>
    scripts = <span style="color: #008000;">filter</span><span style="color: black;">&#40;</span>
            <span style="color: #ff7700;font-weight:bold;">lambda</span> f: f.<span style="color: black;">endswith</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'.js'</span><span style="color: black;">&#41;</span>,
            pkg_resources.<span style="color: black;">resource_listdir</span><span style="color: black;">&#40;</span>__name__, SCRIPT_DIR<span style="color: black;">&#41;</span>
        <span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">for</span> script <span style="color: #ff7700;font-weight:bold;">in</span> scripts:
        <span style="color: #808080; font-style: italic;"># Name the function after the script name</span>
        func_name, _ = script.<span style="color: black;">split</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'.'</span>, <span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
        script_path = <span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">join</span><span style="color: black;">&#40;</span>SCRIPT_DIR, script<span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #808080; font-style: italic;"># Create a pymongo Code object</span>
        <span style="color: #808080; font-style: italic;"># otherwise it will be stored as a string</span>
        <span style="color: #dc143c;">code</span> = pymongo.<span style="color: #dc143c;">code</span>.<span style="color: black;">Code</span><span style="color: black;">&#40;</span>
                pkg_resources.<span style="color: black;">resource_string</span><span style="color: black;">&#40;</span>__name__, script_path<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #808080; font-style: italic;"># Upsert the function</span>
        db.<span style="color: black;">system</span>.<span style="color: black;">js</span>.<span style="color: black;">save</span><span style="color: black;">&#40;</span><span style="color: black;">&#123;</span> <span style="color: #483d8b;">'_id'</span>: func_name, <span style="color: #483d8b;">'value'</span>: <span style="color: #dc143c;">code</span>, <span style="color: black;">&#125;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>However, using server-side functions from Python is awkward at best.  Say I have the JavaScript function:</p>
<p><strong>add.js</strong></p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>x<span style="color: #339933;">,</span> y<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">return</span> x <span style="color: #339933;">+</span> y<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>To run that function via PyMongo requires wrapping the function call with placeholder parameters in a Code object and passing in values as a dict:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">var1 = <span style="color: #ff4500;">1</span>
var2 = <span style="color: #ff4500;">2</span>
result = db.<span style="color: #008000;">eval</span><span style="color: black;">&#40;</span>pymongo.<span style="color: #dc143c;">code</span>.<span style="color: black;">Code</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'add(a, b)'</span>, <span style="color: black;">&#123;</span><span style="color: #483d8b;">'a'</span>: var1, <span style="color: #483d8b;">'b'</span>: var2,<span style="color: black;">&#125;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">assert</span> result == <span style="color: #ff4500;">3</span></pre></div></div>

<p><strong>Update:</strong> See <a href="http://michael.susens-schurter.com/blog/2010/01/11/making-server-side-mongodb-functions-less-awkward/comment-page-1/#comment-68027">MongoDB dev Mike Dirolf comment</a> to see a much more concise way of executing server-side functions.</p>
<p>Bearable for simple functions, but having to manually map parameters to values is tiresome and error prone with longer function signatures.</p>
<p>What I wanted was something more natural like:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">var1 = <span style="color: #ff4500;">1</span>
var2 = <span style="color: #ff4500;">2</span>
result = db.<span style="color: black;">add</span><span style="color: black;">&#40;</span>var1, var2<span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">assert</span> result == <span style="color: #ff4500;">3</span></pre></div></div>

<p>I use a simple PyMongo Database object wrapper to make my life easier:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">string</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">from</span> pymongo.<span style="color: #dc143c;">code</span> <span style="color: #ff7700;font-weight:bold;">import</span> Code
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> ServerSideFunctions<span style="color: black;">&#40;</span><span style="color: #008000;">object</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, db<span style="color: black;">&#41;</span>:
        <span style="color: #008000;">self</span>.<span style="color: black;">db</span> = db
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> func_wrapper<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, func<span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">''</span><span style="color: #483d8b;">'Returns a closure for calling a server-side function.'</span><span style="color: #483d8b;">''</span>
        params = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span> <span style="color: #808080; font-style: italic;"># To keep params ordered</span>
        kwargs = <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span>
        <span style="color: #ff7700;font-weight:bold;">def</span> server_side_func<span style="color: black;">&#40;</span><span style="color: #66cc66;">*</span>args<span style="color: black;">&#41;</span>:
            <span style="color: #483d8b;">''</span><span style="color: #483d8b;">'Calls server side function with positional arguments.'</span><span style="color: #483d8b;">''</span>
            <span style="color: #808080; font-style: italic;"># Could be removed with better param generating logic</span>
            <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>args<span style="color: black;">&#41;</span> <span style="color: #66cc66;">&gt;</span> <span style="color: #008000;">len</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">string</span>.<span style="color: black;">letters</span><span style="color: black;">&#41;</span>:
                <span style="color: #ff7700;font-weight:bold;">raise</span> <span style="color: #008000;">TypeError</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'%s() takes at most %d arguments (%d given)'</span>
                        <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>func, <span style="color: #008000;">len</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">string</span>.<span style="color: black;">letters</span><span style="color: black;">&#41;</span>, <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>args<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
            <span style="color: #808080; font-style: italic;"># Prepare arguments</span>
            <span style="color: #ff7700;font-weight:bold;">for</span> k, v <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">zip</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">string</span>.<span style="color: black;">letters</span>, args<span style="color: black;">&#41;</span>:
                kwargs<span style="color: black;">&#91;</span>k<span style="color: black;">&#93;</span> = v
                params.<span style="color: black;">append</span><span style="color: black;">&#40;</span>k<span style="color: black;">&#41;</span> 
&nbsp;
            <span style="color: #808080; font-style: italic;"># Prepare code object</span>
            <span style="color: #dc143c;">code</span> = Code<span style="color: black;">&#40;</span><span style="color: #483d8b;">'%s(%s)'</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>func, <span style="color: #483d8b;">', '</span>.<span style="color: black;">join</span><span style="color: black;">&#40;</span>params<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>, kwargs<span style="color: black;">&#41;</span>
&nbsp;
            <span style="color: #808080; font-style: italic;"># Return result of server-side function</span>
            <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">self</span>.<span style="color: black;">db</span>.<span style="color: #008000;">eval</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">code</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">return</span> server_side_func
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__getattr__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, func<span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">''</span><span style="color: #483d8b;">'Return a closure for calling server-side function named `func`'</span><span style="color: #483d8b;">''</span>
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">self</span>.<span style="color: black;">func_wrapper</span><span style="color: black;">&#40;</span>func<span style="color: black;">&#41;</span>
&nbsp;
dbjs = ServerSideFunctions<span style="color: black;">&#40;</span><span style="color: #483d8b;">'foo'</span><span style="color: black;">&#41;</span>
var1 = <span style="color: #ff4500;">1</span>
var2 = <span style="color: #ff4500;">2</span>
result = dbjs.<span style="color: black;">add</span><span style="color: black;">&#40;</span>var1, var2<span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">assert</span> result == <span style="color: #ff4500;">3</span></pre></div></div>

<p>I&#8217;m tempted to monkey-patch PyMongo&#8217;s Database class to add a ServerSideFunctions instance directly as a js attribute, so then I could drop the confusing <code>dbjs</code> variable and just use:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">assert</span> db.<span style="color: black;">js</span>.<span style="color: black;">add</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span>,<span style="color: #ff4500;">2</span><span style="color: black;">&#41;</span> == <span style="color: #ff4500;">3</span></pre></div></div>

<p>If someone knows of a better way to access server-side MongoDB functions from Python, please let me know!</p>
<p><small>I modified this code to remove code specific to my project, so please let me know if there are errors.</small></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.schmichael.com/2010/01/11/making-server-side-mongodb-functions-less-awkward/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>lxml vs. ElementTree</title>
		<link>http://blog.schmichael.com/2009/10/14/lxml-vs-elementtree/</link>
		<comments>http://blog.schmichael.com/2009/10/14/lxml-vs-elementtree/#comments</comments>
		<pubDate>Wed, 14 Oct 2009 23:18:31 +0000</pubDate>
		<dc:creator>Michael Schurter</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[benchmarks]]></category>
		<category><![CDATA[ElementTree]]></category>
		<category><![CDATA[lxml]]></category>
		<category><![CDATA[xml]]></category>

		<guid isPermaLink="false">http://michael.susens-schurter.com/blog/?p=736</guid>
		<description><![CDATA[While lxml has some excellent benchmarks about the speed of lxml.etree vs. ElementTree, I wanted to run some tests that were as close as possible to my own use case (fairly simple multi-megabyte XML files). Here are the results of &#8230; <a href="http://blog.schmichael.com/2009/10/14/lxml-vs-elementtree/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>While lxml has some <a href="http://codespeak.net/lxml/performance.html">excellent benchmarks about the speed of lxml.etree vs. ElementTree</a>, I wanted to run some tests that were as close as possible to my own use case (fairly simple multi-megabyte XML files).</p>
<p>Here are the results of my little test script <a href="http://blog.schmichael.com/files/lxml-v-etree.py-remove-me">lxml-v-etree.py</a> (times are in milliseconds):</p>
<pre>
name           generate | tostring | total | write | parse | find | total
------------------------+----------+-------+-------+-------+------+------
xml.cElementTree    132 |   2430   |  2562 |  2433 |   158 |   58 |   216
xml.cElementTree    112 |   2384   |  2497 |  2387 |   158 |   25 |   183
xml.cElementTree    113 |   2393   |  2507 |  2396 |   161 |   25 |   187
xml.ElementTree     591 |   2571   |  3163 |  2574 |  3613 |   25 |  3638
xml.ElementTree     619 |   2567   |  3187 |  2570 |  3589 |   55 |  3644
xml.ElementTree     609 |   2578   |  3188 |  2581 |  3564 |   55 |  3619
lxml                333 |     75   |   409 |    82 |   200 |    0 |   201
lxml                355 |     93   |   448 |    95 |   182 |   32 |   214
lxml                310 |     94   |   404 |    96 |   156 |   56 |   213
------------------------+----------+-------+-------+-------+------+------
name           generate | tostring | total | write | parse | find | total
------------------------+----------+-------+-------+-------+------+------
</pre>
<p>Note that the first &#8220;total&#8221; is &#8220;generate + tostring&#8221; while the second &#8220;total&#8221; is for the 2 parsing related tests (previous 2 columns summed).</p>
<p>My parsing tests are basically &#8220;etree.parse&#8221; and then running &#8220;Element.getchildren()&#8221; 3 times, which is ridiculously simplistic and should probably be ignored.  My writing tests are far more thorough/realistic.</p>
<p>I&#8217;m running Python 2.6.2 with lxml 2.1.5 and libxml2 2.6.32 on Ubuntu 9.04 x86_64.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.schmichael.com/2009/10/14/lxml-vs-elementtree/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Python Packaging Talk</title>
		<link>http://blog.schmichael.com/2009/09/09/python-packaging-talk/</link>
		<comments>http://blog.schmichael.com/2009/09/09/python-packaging-talk/#comments</comments>
		<pubDate>Wed, 09 Sep 2009 18:29:01 +0000</pubDate>
		<dc:creator>Michael Schurter</dc:creator>
				<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[distribute]]></category>
		<category><![CDATA[distutils]]></category>
		<category><![CDATA[packaging]]></category>
		<category><![CDATA[pdxpython]]></category>
		<category><![CDATA[pip]]></category>
		<category><![CDATA[setuptools]]></category>
		<category><![CDATA[slides]]></category>
		<category><![CDATA[whereampy]]></category>

		<guid isPermaLink="false">http://michael.susens-schurter.com/blog/?p=708</guid>
		<description><![CDATA[I gave a talk at PDX Python last night on Python Packaging. It&#8217;s just an overview and introduction completely lacking in any practical examples. Python Packaging slides (ODP) Python Packaging slides (PDF) Let me know if the ODP source is &#8230; <a href="http://blog.schmichael.com/2009/09/09/python-packaging-talk/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I gave a talk at <a href="http://pdxpython.org/">PDX Python</a> last night on Python Packaging.  It&#8217;s just an overview and introduction completely lacking in any practical examples.</p>
<ul>
<li><a href="http://blog.schmichael.com/files/packaging.odp">Python Packaging slides (ODP)</a></li>
<li><a href="http://blog.schmichael.com/files/packaging-2.pdf">Python Packaging slides (PDF)</a></li>
</ul>
<p><small>Let me know if the ODP source is messed up.  OpenOffice.org liked randomly losing background images and forgetting other formatting.</small></p>
<p>So as penance I quick hacked up a silly little command line utility and uploaded it to PyPI to serve as a simple packaging example:</p>
<ul>
<li><a href="http://pypi.python.org/pypi/whereampy">whereampy on PyPI</a></li>
<li><a href="http://bitbucket.org/schmichael/whereampy/">whereampy on bitbucket</a></li>
</ul>
<p>It&#8217;d be nice to add some more advanced features like test running, including package data, and building C extensions.  If you feel adventurous please <a href="http://bitbucket.org/schmichael/whereampy/fork/">fork</a> it and send me a <a href="http://bitbucket.org/schmichael/whereampy/pull/">pull request</a> on BitBucket.</p>
<p>Thanks to everyone who came to PDX Python last night!  Especially <a href="http://lucumr.pocoo.org/">Armin Ronacher</a> who was able to clarify and elaborate on a number of different distutils/setuptools topics!</p>
<p><strong>Update:</strong> Just spotted <a href="http://tarekziade.wordpress.com/2009/09/12/static-metadata-for-distutils/">an excellent post on distutils and setuptools by Tarek Ziadé.</a>  Make sure to <a href="http://tarekziade.wordpress.com/">read his blog if you&#8217;re interested in packaging in Python.</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.schmichael.com/2009/09/09/python-packaging-talk/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Switched tc-rest to webob</title>
		<link>http://blog.schmichael.com/2009/08/10/switched-tc-est-to-webob/</link>
		<comments>http://blog.schmichael.com/2009/08/10/switched-tc-est-to-webob/#comments</comments>
		<pubDate>Tue, 11 Aug 2009 06:12:56 +0000</pubDate>
		<dc:creator>Michael Schurter</dc:creator>
				<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[bitbucket]]></category>
		<category><![CDATA[fapws3]]></category>
		<category><![CDATA[tc-rest]]></category>
		<category><![CDATA[tokyo cabinet]]></category>

		<guid isPermaLink="false">http://michael.susens-schurter.com/blog/?p=704</guid>
		<description><![CDATA[Small update on my toy tc-rest project: I switched to using WebOb for creating HTTP Request and Response objects. Cleaned up the code a bit, but a real dispatcher is what&#8217;s needed to really remove the cruft. I&#8217;m anxious to &#8230; <a href="http://blog.schmichael.com/2009/08/10/switched-tc-est-to-webob/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Small update on my toy tc-rest project: I switched to using <a href="http://pythonpaste.org/webob/">WebOb</a> for creating HTTP Request and Response objects.  Cleaned up the code a bit, but a real dispatcher is what&#8217;s needed to really remove the cruft.</p>
<p>I&#8217;m anxious to extend the API and add features, but I have no clue when I&#8217;ll have time to touch it again.  In the mean time I&#8217;ve <a href="http://bitbucket.org/schmichael/tc-rest/overview/">pushed tc-rest to bitbucket.org if you want to take a look</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.schmichael.com/2009/08/10/switched-tc-est-to-webob/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>TokyoCabinet + fapws3 = tc-rest</title>
		<link>http://blog.schmichael.com/2009/08/08/tokyocabinet-fapws3-tc-rest/</link>
		<comments>http://blog.schmichael.com/2009/08/08/tokyocabinet-fapws3-tc-rest/#comments</comments>
		<pubDate>Sun, 09 Aug 2009 05:53:12 +0000</pubDate>
		<dc:creator>Michael Schurter</dc:creator>
				<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[fapws3]]></category>
		<category><![CDATA[tc-rest]]></category>
		<category><![CDATA[tokyo cabinet]]></category>

		<guid isPermaLink="false">http://michael.susens-schurter.com/blog/?p=695</guid>
		<description><![CDATA[Have you ever wondered how hard it would be to tack a RESTful HTTP interface on top of a fast key/value database like TokyoCabinet? Probably not, but I did: tc-rest.tar.gz Components: TokyoCabinet &#8211; my favorite persistent key/value database pytc &#8211; &#8230; <a href="http://blog.schmichael.com/2009/08/08/tokyocabinet-fapws3-tc-rest/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Have you ever wondered how hard it would be to tack a RESTful HTTP interface on top of a fast key/value database like TokyoCabinet?</p>
<p>Probably not, but I did: <a href="http://blog.schmichael.com/files/tc-rest.tar.gz">tc-rest.tar.gz</a></p>
<p>Components:</p>
<ul>
<li><a href="http://tokyocabinet.sourceforge.net/">TokyoCabinet</a> &#8211; my favorite persistent key/value database</li>
<li><a href="http://pypi.python.org/pypi/pytc/">pytc</a> &#8211; a wonderful Python wrapper for TC</li>
<li><a href="http://github.com/william-os4y/fapws3/tree/master">fapws3</a> &#8211; a fast libev based HTTP/<a href="http://www.python.org/dev/peps/pep-0333/">WSGI</a> server</li>
<li><a href="http://code.google.com/p/simplejson/">simpleson</a> &#8211; (or Python >= 2.6) for encapsulating HTTP responses</li>
<li><a href="http://www.aminus.net/wiki/Okapi">okapi</a> &#8211; a fantastic little static HTML page for testing HTTP APIs</li>
</ul>
<p>Getting TokyoCabinet+pytc to work inside a <a href="http://pypi.python.org/pypi/virtualenv/">virtualenv</a> was a bit tricky, so check out my <code>run.sh</code> script if you&#8217;re having trouble getting it to start.</p>
<p>Once you get it started, load okapi in your browser:</p>
<p><a href="http://localhost:8080/static/okapi.html">http://localhost:8080/static/okapi.html</a></p>
<p>And then create a database by doing a POST like:</p>
<p><code>http://localhost:8080/foo/</code></p>
<p>And finally store/get keys and values using GET and POST requests like:</p>
<p><code>http://localhost:8080/foo/bar/</code><br />
<code>http://localhost:8080/foo/baz/</code></p>
<p>Doing a GET request to a database URL lists keys.</p>
<p>At any rate, I had big dreams for building a system where you would store JSON, specify indexes on certain keys, and the server would maintain those indexes for you by creating ad hoc TokyoCabinet databases.</p>
<p>Instead I ended up wasting most of my time learning how to write a low-level WSGI app.  I should have just used CherryPy or Django from the beginning, but I had never written a pure WSGI app before.  It was a good lesson even if it meant not getting some of my features implemented.</p>
<p>I&#8217;ll probably keep playing with this idea, but the next version will probably be based on some existing framework.  Parsing <code>environ['PATH_INFO']</code> and running <code>start_response(...)</code> manually gets old fast.</p>
<p>fapws3 is pretty neat, but had lots of annoying rough edges.  I had to manually create a <code>README</code> file because its setup.py expects one to exist.  Then I had to manually allow DELETE HTTP methods in fapws/base.py, otherwise it would return an HTML error message for me!  That was a bit shocking since I was working under the assumption fapws3 is just a low-level HTTP/WSGI server.</p>
<p><strong>Update</strong></p>
<ol>
<li><a href="http://michael.susens-schurter.com/blog/2009/03/11/tokyo-cabinet-pytyrant-talk/">If you&#8217;re new to TokyoCabinet, I posted my presentation on it that I did at Portland Python meetup</a>.</li>
<li>Someone want to benchmark this for me?  Might be interesting since its made with the fastest libs available in Python for their respective tasks.  I&#8217;m just feeling lazy at this point.  <img src='http://blog.schmichael.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://blog.schmichael.com/2009/08/08/tokyocabinet-fapws3-tc-rest/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>I Love Python: ZipFile Edition</title>
		<link>http://blog.schmichael.com/2009/07/08/i-love-python-zipfile-edition/</link>
		<comments>http://blog.schmichael.com/2009/07/08/i-love-python-zipfile-edition/#comments</comments>
		<pubDate>Wed, 08 Jul 2009 18:42:49 +0000</pubDate>
		<dc:creator>Michael Schurter</dc:creator>
				<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[zip]]></category>

		<guid isPermaLink="false">http://michael.susens-schurter.com/blog/?p=664</guid>
		<description><![CDATA[For a client web project I needed to create a zip file containing a number of generated XML files. This isn&#8217;t something I need to do very often, so I briefly considered just writing the XML files to disk and &#8230; <a href="http://blog.schmichael.com/2009/07/08/i-love-python-zipfile-edition/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>For a client web project I needed to create a zip file containing a number of generated XML files.  This isn&#8217;t something I need to do very often, so I briefly considered just writing the XML files to disk and running a zip command.  Ugly, but surely trying to dig up a pleasant Python zip library would be more work?</p>
<p>Turns out Python has had a wonderful zip library in its standard library since 1.6!  The <code><a href="http://docs.python.org/library/zipfile.html">zipfile</a></code> module makes creating zip files a breeze:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">os</span>
<span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">zipfile</span> <span style="color: #ff7700;font-weight:bold;">import</span> ZipFile, ZIP_DEFLATED
&nbsp;
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">template</span>.<span style="color: black;">defaultfilters</span> <span style="color: #ff7700;font-weight:bold;">import</span> slugify
&nbsp;
<span style="color: #ff7700;font-weight:bold;">from</span> somewhere_else <span style="color: #ff7700;font-weight:bold;">import</span> render_spam_xml, render_egg_xml
&nbsp;
ZIP_PATH = <span style="color: #483d8b;">&quot;/some/system/path/for/zips&quot;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> create_zip<span style="color: black;">&#40;</span>spam<span style="color: black;">&#41;</span>:
    spam_slug = slugify<span style="color: black;">&#40;</span>spam.<span style="color: black;">name</span><span style="color: black;">&#41;</span>
    filename = <span style="color: #483d8b;">&quot;%s.zip&quot;</span> <span style="color: #66cc66;">%</span> spam_slug
    abspath = <span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">join</span><span style="color: black;">&#40;</span>ZIP_PATH, filename<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Create zip</span>
    z = ZipFile<span style="color: black;">&#40;</span>abspath, <span style="color: #483d8b;">&quot;w&quot;</span>, ZIP_DEFLATED<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Write spam xml directly to zip</span>
    z.<span style="color: black;">writestr</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;%s.xml&quot;</span> <span style="color: #66cc66;">%</span> spam_slug, render_spam_xml<span style="color: black;">&#40;</span>spam<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Write xml files to zip</span>
    <span style="color: #ff7700;font-weight:bold;">for</span> egg <span style="color: #ff7700;font-weight:bold;">in</span> spam.<span style="color: black;">egg_set</span>.<span style="color: #008000;">all</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
        egg_slug = slugify<span style="color: black;">&#40;</span>egg.<span style="color: black;">name</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #808080; font-style: italic;"># Renders the egg object to an xml string</span>
        <span style="color: #dc143c;">xml</span> = render_egg_xml<span style="color: black;">&#40;</span>egg<span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #808080; font-style: italic;"># Note how easy it is to specify paths in the zip file:</span>
        z.<span style="color: black;">writestr</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;eggs/%s.xml&quot;</span> <span style="color: #66cc66;">%</span> egg_slug, <span style="color: #dc143c;">xml</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Zip file must be closed to be valid</span>
    z.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> abspath</pre></div></div>

<p><small>(Sorry for the Django bits in there, but they should be easy to replace.)</small></p>
<p>My favorite part is that you can use either the <code>ZipFile.write</code> method to add files to the zip or the <code>ZipFile.writestr</code> method to write bytes (strings in my case) directly to the zip file.</p>
<p>At any rate, just wanted to blog about it, so when I need to do it again in a few years I don&#8217;t do something stupid like running the zip command.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.schmichael.com/2009/07/08/i-love-python-zipfile-edition/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
