<?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; cherrypy</title>
	<atom:link href="http://blog.schmichael.com/tag/cherrypy/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.schmichael.com</link>
	<description>good good study, day day up</description>
	<lastBuildDate>Wed, 16 May 2012 23:59:27 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>(Yet Another) Deploying Django with CherryPy Script</title>
		<link>http://blog.schmichael.com/2009/02/18/deploying-django-with-cherrypy/</link>
		<comments>http://blog.schmichael.com/2009/02/18/deploying-django-with-cherrypy/#comments</comments>
		<pubDate>Wed, 18 Feb 2009 23:36:06 +0000</pubDate>
		<dc:creator>Michael Schurter</dc:creator>
				<category><![CDATA[GNU/Linux]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[cherrypy]]></category>
		<category><![CDATA[django]]></category>

		<guid isPermaLink="false">http://michael.susens-schurter.com/blog/?p=529</guid>
		<description><![CDATA[Recently I deployed a Django project on an OSX server. I foolishly thought this would be as easy as on Linux until I ran into the mess that is x86_64 Apache + mod_wsgi* + Django + psycopg2 + i386 PostgreSQL. &#8230; <a href="http://blog.schmichael.com/2009/02/18/deploying-django-with-cherrypy/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Recently I deployed a <a href="http://www.djangoproject.com/">Django</a> project on an OSX server.  I foolishly thought this would be as easy as on Linux until I ran into the mess that is <em>x86_64</em> Apache + <a href="http://www.modwsgi.org/">mod_wsgi</a>* + Django + psycopg2 + <em>i386</em> PostgreSQL.  After wasting far too much time googling and recompiling various bits trying to get everything happy, I followed <a href="http://www.eflorenzano.com/blog/post/hosting-django-site-pure-python/">Eric Florenzano&#8217;s post</a> on deploying Django using <a href="http://www.cherrypy.org/">CherryPy</a>&#8216;s** <a href="http://www.cherrypy.org/wiki/CherryPyDownload#StandaloneWSGIserver">wsgiserver</a>.</p>
<p>Here&#8217;s my lightly modified version of Eric&#8217;s script:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> wsgiserver
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">sys</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">os</span>
<span style="color: #ff7700;font-weight:bold;">import</span> django.<span style="color: black;">core</span>.<span style="color: black;">handlers</span>.<span style="color: black;">wsgi</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">&quot;__main__&quot;</span>:
    <span style="color: #808080; font-style: italic;"># Setup paths - a bit hackish, but works for me.</span>
    <span style="color: #808080; font-style: italic;"># Assumes an absolute path is stored in &lt;project&gt;.local_settings.ROOT</span>
    <span style="color: #dc143c;">sys</span>.<span style="color: black;">path</span>.<span style="color: black;">append</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">realpath</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">dirname</span><span style="color: black;">&#40;</span>__file__<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">from</span> foo.<span style="color: black;">local_settings</span> <span style="color: #ff7700;font-weight:bold;">import</span> ROOT
    <span style="color: #dc143c;">sys</span>.<span style="color: black;">path</span>.<span style="color: black;">append</span><span style="color: black;">&#40;</span>ROOT<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Startup Django</span>
    <span style="color: #dc143c;">os</span>.<span style="color: black;">environ</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">'DJANGO_SETTINGS_MODULE'</span><span style="color: black;">&#93;</span> = <span style="color: #483d8b;">'foo.settings'</span>
    server = wsgiserver.<span style="color: black;">CherryPyWSGIServer</span><span style="color: black;">&#40;</span>
        <span style="color: black;">&#40;</span><span style="color: #483d8b;">'0.0.0.0'</span>, <span style="color: #ff4500;">8888</span><span style="color: black;">&#41;</span>,  <span style="color: #808080; font-style: italic;"># Use '127.0.0.1' to only bind to the localhost</span>
        django.<span style="color: black;">core</span>.<span style="color: black;">handlers</span>.<span style="color: black;">wsgi</span>.<span style="color: black;">WSGIHandler</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    <span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">try</span>:
        server.<span style="color: black;">start</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #008000;">KeyboardInterrupt</span>:
        <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'Stopping'</span>
        server.<span style="color: black;">stop</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>I also went with the latest stable version of CherryPy&#8217;s wsgiserver instead of checking out trunk like Eric&#8217;s post suggested.</p>
<p>Then I just enabled <code>mod_proxy</code> in Apache and setup the following VirtualHost:</p>

<div class="wp_syntax"><div class="code"><pre class="apache" style="font-family:monospace;">&lt;<span style="color: #000000; font-weight:bold;">Proxy</span> *&gt;
    <span style="color: #00007f;">Order</span> <span style="color: #00007f;">allow</span>,<span style="color: #00007f;">deny</span>
    <span style="color: #00007f;">Allow</span> from <span style="color: #0000ff;">all</span>
&lt;/<span style="color: #000000; font-weight:bold;">Proxy</span>&gt;
&lt;<span style="color: #000000; font-weight:bold;">Location</span> <span style="color: #7f007f;">&quot;/&quot;</span>&gt;
    <span style="color: #00007f;">ProxyPass</span> http://127.0.0.1:<span style="color: #ff0000;">8888</span>/
    <span style="color: #00007f;">ProxyPassReverse</span> http://127.0.0.1:<span style="color: #ff0000;">8888</span>/
&lt;/<span style="color: #000000; font-weight:bold;">Location</span>&gt;</pre></div></div>

<p>If you&#8217;re cool you&#8217;ll write some sort of system specific script to launch your web app on boot.  In a pinch, you can always use a crontab:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">@</span>reboot <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>python <span style="color: #000000; font-weight: bold;">/</span>path<span style="color: #000000; font-weight: bold;">/</span>to<span style="color: #000000; font-weight: bold;">/</span>app.py <span style="color: #000000; font-weight: bold;">&amp;</span></pre></div></div>

<p>YMMV <img src='http://blog.schmichael.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p><small><br />
* To mod_wsgi&#8217;s credit, it took about 10 seconds to compile, generated a Universal binary, and in general Just Worked.</p>
<p>** I&#8217;m already a CherryPy fan thanks to <a href="http://www.dowski.com/">dowski</a>, so it wasn&#8217;t a hard decision.<br />
</small></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.schmichael.com/2009/02/18/deploying-django-with-cherrypy/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Looking for CherryPy Case Studies</title>
		<link>http://blog.schmichael.com/2008/03/18/looking-for-cherrypy-case-studies/</link>
		<comments>http://blog.schmichael.com/2008/03/18/looking-for-cherrypy-case-studies/#comments</comments>
		<pubDate>Tue, 18 Mar 2008 21:12:00 +0000</pubDate>
		<dc:creator>Michael Schurter</dc:creator>
				<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[cherrypy]]></category>
		<category><![CDATA[pycon2008]]></category>

		<guid isPermaLink="false">http://michael.susens-schurter.com/blog/2008/03/18/looking-for-cherrypy-case-studies/</guid>
		<description><![CDATA[At the CherryPy BOF[1] at Pycon in Chicago we discussed how people are using CherryPy in lots of different ways. We&#8217;re afraid people aren&#8217;t grokking how flexible CherryPy is just by briefly glancing at the web site and thought having &#8230; <a href="http://blog.schmichael.com/2008/03/18/looking-for-cherrypy-case-studies/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<div style="float: right; padding: 0px 0px 5px 5px;"><a href="http://cherrypy.org"><img src="http://michael.susens-schurter.com/files/cplogo.jpg" alt="CherryPy Logo" /></a></div>
<p>At the <a href="http://cherrypy.org/">CherryPy</a> <a href="http://groups.google.com/group/cherrypy-users/browse_thread/thread/7926752b6605d9fe">BOF</a>[1] at <a href="http://us.pycon.org/2008/about/">Pycon in Chicago</a> we discussed how people are using CherryPy in lots of different ways.  We&#8217;re afraid people aren&#8217;t grokking how flexible CherryPy is just by briefly glancing at the web site and thought having some interesting case studies would be useful.</p>
<p>The <a href="http://www.cherrypy.org/wiki/SuccessStories">wiki has a good start</a>.  However, its a bit out of date, and it&#8217;d be nice to have some great Case Studies as well as a separate list of Projects using CherryPy.</p>
<p>If your company deploys CherryPy or you&#8217;ve used CherryPy for a client, I&#8217;d love to hear the story.  Here&#8217;s a basic format you could follow:</p>
<ol>
<li><strong>Who</strong> is using CherryPy: (your name)</li>
<li><strong>Where</strong> are you using Cherrypy?<br />
    (Company or client name.  You can of course remain anonymous)</li>
<li><strong>What</strong> do you do with CherryPy?<br />
    (What&#8217;s your project:  a traditional public web site?  internal web services?)</li>
<li><strong>How</strong> is CherryPy deployed?<br />
   (Behind modproxy/modpython/modwsgi, on a cluster behind a load balancer, or is it your frontend HTTP server?)</li>
<li><strong>How long</strong> have you used CherryPy?<br />
    (The &#8220;when&#8221; question)</li>
<li><strong>Why</strong> did you choose CherryPy?<br />
    (While &#8220;because its the best&#8221; is obviously the answer, a little more detail would be nice. <img src='http://blog.schmichael.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  )</li>
</ol>
<p>Feel free to include screenshots, links, code snippets, diagrams, etc, and <strong><a href="mailto:michael@susens-schurter.com">e-mail me!</a></strong></p>
<p>With <a href="http://download.cherrypy.org/cherrypy/3.1.0beta3/">3.1 nearing release</a>, it&#8217;d be nice if we could launch an updated version of the web site at the same time, so your help is greatly appreciated!</p>
<p><small>I also posted <a href="http://groups.google.com/group/cherrypy-users/browse_thread/thread/1774049cc582a595?hl=en">this over at the cherrypy-user mailing list</a>.</small></p>
<p><strong>[1]</strong></p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">if</span> excuse <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: black;">&#91;</span><span style="color: #483d8b;">'at funeral'</span>, <span style="color: #483d8b;">'giving birth'</span>, <span style="color: #483d8b;">'saving planet'</span><span style="color: black;">&#93;</span>:
	<span style="color: #ff7700;font-weight:bold;">raise</span> <span style="color: #008000;">Exception</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'%s is no reason to miss the CherryPy BOF'</span> <span style="color: #66cc66;">%</span> excuse<span style="color: black;">&#41;</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://blog.schmichael.com/2008/03/18/looking-for-cherrypy-case-studies/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Permanent home for firewall-admin</title>
		<link>http://blog.schmichael.com/2008/02/17/permanent-home-for-firewall-admin/</link>
		<comments>http://blog.schmichael.com/2008/02/17/permanent-home-for-firewall-admin/#comments</comments>
		<pubDate>Sun, 17 Feb 2008 20:42:43 +0000</pubDate>
		<dc:creator>Michael Schurter</dc:creator>
				<category><![CDATA[GNU/Linux]]></category>
		<category><![CDATA[IT]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[cherrypy]]></category>
		<category><![CDATA[genshi]]></category>
		<category><![CDATA[iptables]]></category>

		<guid isPermaLink="false">http://michael.susens-schurter.com/blog/2008/02/17/permanent-home-for-firewall-admin/</guid>
		<description><![CDATA[The little recipe I posted for a dedicated Linux firewall with a CherryPy powered administrative interface finally has a permanent home over at Google Code. Many thanks to Kyle Waremburg for creating the project page and helping me develop firewall-admin! &#8230; <a href="http://blog.schmichael.com/2008/02/17/permanent-home-for-firewall-admin/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>The <a href="http://michael.susens-schurter.com/blog/2007/11/06/recipe-for-a-transparent-linux-firewall-and-cherrypy-control-panel/">little recipe I posted</a> for a dedicated Linux firewall with a CherryPy powered administrative interface finally has a <a href="http://code.google.com/p/firewall-admin/">permanent home over at Google Code</a>.</p>
<p>Many thanks to Kyle Waremburg for creating the project page and helping me develop <a href="http://code.google.com/p/firewall-admin/">firewall-admin</a>!  I hope other people find it useful.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.schmichael.com/2008/02/17/permanent-home-for-firewall-admin/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Fun with Django and modwsgi</title>
		<link>http://blog.schmichael.com/2008/02/05/fun-with-django-and-modwsgi/</link>
		<comments>http://blog.schmichael.com/2008/02/05/fun-with-django-and-modwsgi/#comments</comments>
		<pubDate>Wed, 06 Feb 2008 05: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[apache]]></category>
		<category><![CDATA[cherrypy]]></category>
		<category><![CDATA[diy]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[dreamhost]]></category>
		<category><![CDATA[fastcgi]]></category>
		<category><![CDATA[modwsgi]]></category>
		<category><![CDATA[mod_python]]></category>
		<category><![CDATA[wsgi]]></category>

		<guid isPermaLink="false">http://michael.susens-schurter.com/blog/2008/02/05/fun-with-django-and-modwsgi/</guid>
		<description><![CDATA[Today I deployed my first Django application for a client. Its yet-another-blog, so I&#8217;ll refrain from posting the code and cluttering up the django-*blog* namespace on Google Code. Before you roll your eyes and complain about why I didn&#8217;t use &#8230; <a href="http://blog.schmichael.com/2008/02/05/fun-with-django-and-modwsgi/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Today I deployed my first <a href="http://www.djangoproject.com/">Django</a> application for a client.  Its yet-another-blog, so I&#8217;ll refrain from posting the code and cluttering up the django-*blog* namespace on Google Code.  Before you roll your eyes and complain about why I didn&#8217;t use an existing solution, I think I have 2 somewhat valid reasons:</p>
<ol>
<li>The client actually needed a <em>sub</em>set of the features most blogs offer, so I wouldn&#8217;t really have anything to contribute back to an existing project.</li>
<li>Blogs are one of the simplest content driven web applications in existence.  Wikis are just a bit simpler perhaps.  At any rate, creating a blog app is an excellent way to learn a framework.</li>
</ol>
<p><strong>Python Deployment Decisions</strong></p>
<p>In the past I&#8217;ve used <a href="http://michael.susens-schurter.com/blog/2007/08/16/deploying-cherrypy-on-apache-2-using-mod_proxy/">CherryPy as my framework and a simple mod_proxy configuration to run the applications behind Apache</a>.  <a href="http://www.djangoproject.com/documentation/django-admin/#runserver-optional-port-number-or-ipaddr-port">Django considers its built-in web server a development tool only</a>, so I figured it was time to explore the myriad of Python web app deployment alternatives: <a href="http://www.modpython.org">mod_python</a>, <a href="http://www.fastcgi.com/">FastCGI</a>, <a href="http://www.modwsgi.org">modwsgi</a>.  I&#8217;m sure there are many more, but I&#8217;d say those are the big 3.</p>
<p>I had tried to deploy Python web applications on DreamHost using FastCGI before and entered <a href="http://www.al3x.net/2008/01/shared-hosting-is-ghetto.html">the hell that is deploying Python web apps on shared hosts</a>.  <em>So FastCGI wasn&#8217;t my first choice this time.</em></p>
<p>I had also tried mod_python for deploying <a href="http://www.cherrypy.org/">CherryPy</a> apps on my <a href="http://www.linode.com/">Linode</a> before and for whatever reason just found <a href="http://httpd.apache.org/docs/2.2/mod/mod_proxy.html">mod_proxy</a> to be <em>much</em> easier to setup and manage.</p>
<p>I was kind of eager to try out modwsgi because its been getting a lot of attention lately, so I downloaded the source and compiled it on my <a href="http://www.debian.org/">Debian</a> <a href="http://www.debian.org/releases/etch/">Etch</a> server.</p>
<p><strong>Deploying a Django App via modwsgi</strong></p>
<p>modwsgi was quite easy to setup as long as you follow the instructions in their wiki for Django integration.  I was hit by <a href="http://code.djangoproject.com/ticket/3762">bug #3762</a>, but the modwsgi documentation got me through it.  <small>(For what its worth the attached wsgi.patch also worked, but I don&#8217;t really want to run a patched version of Django.)</small></p>
<p>One big problem I ran into was <a href="http://docs.python.org/lib/module-sqlite3.html">sqlite3</a> gave me <code>OperationalError: unable to open database file</code> whenever I did anything that would write to the database.  My database file was owned by <code>www-data</code> (the Apache process owner) and had the permissions <code>664</code>.</p>
<p>I switched to <a href="http://www.postgresql.org/">PostgreSQL</a>, ran <a href="http://www.djangoproject.com/documentation/django-admin/#syncdb"><code>syncdb</code></a>, and everything worked beautifully.</p>
<p>My wsgi script file /srv/spam/eggs/eggs.wsgi:</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: #dc143c;">sys</span>
<span style="color: #dc143c;">sys</span>.<span style="color: black;">path</span>.<span style="color: black;">append</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'/srv/spam'</span><span style="color: black;">&#41;</span>
<span style="color: #dc143c;">sys</span>.<span style="color: black;">path</span>.<span style="color: black;">append</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'/srv/spam/eggs'</span><span style="color: black;">&#41;</span>
<span style="color: #dc143c;">os</span>.<span style="color: black;">environ</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">'DJANGO_SETTINGS_MODULE'</span><span style="color: black;">&#93;</span> = <span style="color: #483d8b;">'eggs.wsgi_settings'</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">import</span> django.<span style="color: black;">core</span>.<span style="color: black;">handlers</span>.<span style="color: black;">wsgi</span>
&nbsp;
_application = django.<span style="color: black;">core</span>.<span style="color: black;">handlers</span>.<span style="color: black;">wsgi</span>.<span style="color: black;">WSGIHandler</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> application<span style="color: black;">&#40;</span>environ, start_response<span style="color: black;">&#41;</span>:
    environ<span style="color: black;">&#91;</span><span style="color: #483d8b;">'PATH_INFO'</span><span style="color: black;">&#93;</span> = environ<span style="color: black;">&#91;</span><span style="color: #483d8b;">'SCRIPT_NAME'</span><span style="color: black;">&#93;</span> + environ<span style="color: black;">&#91;</span><span style="color: #483d8b;">'PATH_INFO'</span><span style="color: black;">&#93;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> _application<span style="color: black;">&#40;</span>environ, start_response<span style="color: black;">&#41;</span></pre></div></div>

<p>Note I use <code>wsgi_settings</code> instead of my usual settings file.  wsgi_settings just imports my main settings file and changes some to their production values.</p>
<p>My Django application actually drops into the <code>/blog/</code> and <code>/accounts/</code> folders under a VirtualHost otherwise occupied by static files and some PHP scripts.  modwsgi made this easy by putting this in my existing VirtualHost:</p>

<div class="wp_syntax"><div class="code"><pre class="apache" style="font-family:monospace;">WSGIScriptAliasMatch /(blog|accounts)/.* /srv/spam/eggs/eggs.wsgi
&nbsp;
<span style="color: #adadad; font-style: italic;"># A simple Alias directive handles my static files</span>
<span style="color: #00007f;">Alias</span> /static/ /srv/spam/eggs/static/</pre></div></div>

<p><strong>Bottom Line</strong></p>
<p>I highly recommend using modwsgi for deploying Python web applications.  sqlite3 may work for you.  In my case its probably best I use PostgreSQL for a number of reasons.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.schmichael.com/2008/02/05/fun-with-django-and-modwsgi/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Fun with SQLObject and mxDateTime</title>
		<link>http://blog.schmichael.com/2007/11/29/fun-with-sqlobject-and-mxdatetime/</link>
		<comments>http://blog.schmichael.com/2007/11/29/fun-with-sqlobject-and-mxdatetime/#comments</comments>
		<pubDate>Fri, 30 Nov 2007 00:03:23 +0000</pubDate>
		<dc:creator>Michael Schurter</dc:creator>
				<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[cherrypy]]></category>
		<category><![CDATA[mxdatetime]]></category>
		<category><![CDATA[sqlobject]]></category>
		<category><![CDATA[xml]]></category>

		<guid isPermaLink="false">http://michael.susens-schurter.com/blog/2007/11/29/fun-with-sqlobject-and-mxdatetime/</guid>
		<description><![CDATA[I&#8217;m working on a small CherryPy web service that among other things saves timestamps to a database. The timestamp is in RFC 3339 format (like 2007-07-31T16:05:00.000-05:00), and I needed to store the timezone. Luckily mxDateTime and SQLObject&#8217;s DateTimeCol both support &#8230; <a href="http://blog.schmichael.com/2007/11/29/fun-with-sqlobject-and-mxdatetime/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m working on a small <a href="http://cherrypy.org">CherryPy</a> web service that among other things saves timestamps to a database.  The timestamp is in <a href="http://www.ietf.org/rfc/rfc3339.txt">RFC 3339</a> format (like <code>2007-07-31T16:05:00.000-05:00</code>), and I needed to store the timezone.</p>
<p>Luckily <a href="http://www.egenix.com/products/python/mxBase/mxDateTime/">mxDateTime</a> and SQLObject&#8217;s DateTimeCol both support full dates with times and time zone.  Unfortunately its not immediately obvious from <a href="http://sqlobject.org/SQLObject.html">SQLObject&#8217;s lackluster documentation</a> how to use mxDateTime instead of Python&#8217;s built-in datetime.</p>
<p>A little searching brought me to a mailing list post about <a href="http://pythonpaste.org/archives/message/20070410.064412.fa195fb7.en.html">how to use mxDateTime by default in SQLObject</a>.  (I don&#8217;t know why the sample code includes the conditional as I would think you&#8217;d want your code to outright fail if you&#8217;re unable to use the datetime library you expect.)</p>
<p>So my model&#8217;s code looks something like this:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">from</span> sqlobject <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #66cc66;">*</span>
<span style="color: #ff7700;font-weight:bold;">from</span> sqlobject <span style="color: #ff7700;font-weight:bold;">import</span> col
&nbsp;
col.<span style="color: black;">default_datetime_implementation</span> = MXDATETIME_IMPLEMENTATION
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> Foo<span style="color: black;">&#40;</span>SQLObject<span style="color: black;">&#41;</span>:
    timestamp = DateTimeCol<span style="color: black;">&#40;</span>default=DateTimeCol.<span style="color: black;">now</span><span style="color: black;">&#41;</span></pre></div></div>

<p>Then my parsing code looks something like this:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> model
<span style="color: #ff7700;font-weight:bold;">from</span> mx <span style="color: #ff7700;font-weight:bold;">import</span> DateTime
&nbsp;
timestamp = <span style="color: #483d8b;">'2007-07-31T16:05:00.000-05:00'</span>
bar = model.<span style="color: black;">Foo</span><span style="color: black;">&#40;</span>timestamp=DateTime.<span style="color: black;">DateTimeFrom</span><span style="color: black;">&#40;</span>timestamp<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'UTC Timestamp:'</span>, bar.<span style="color: black;">timestamp</span>
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'Local Timestamp:'</span>, bar.<span style="color: black;">timestamp</span>.<span style="color: black;">localtime</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>Basically once you use the magic line <code>col.default_datetime_implementation = MXDATETIME_IMPLEMENTATION</code>, everything Just Works.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.schmichael.com/2007/11/29/fun-with-sqlobject-and-mxdatetime/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Recipe for a Transparent Linux Firewall and CherryPy Control Panel</title>
		<link>http://blog.schmichael.com/2007/11/06/recipe-for-a-transparent-linux-firewall-and-cherrypy-control-panel/</link>
		<comments>http://blog.schmichael.com/2007/11/06/recipe-for-a-transparent-linux-firewall-and-cherrypy-control-panel/#comments</comments>
		<pubDate>Tue, 06 Nov 2007 18:50:19 +0000</pubDate>
		<dc:creator>Michael Schurter</dc:creator>
				<category><![CDATA[GNU/Linux]]></category>
		<category><![CDATA[IT]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[cherrypy]]></category>
		<category><![CDATA[debian etch]]></category>
		<category><![CDATA[iptables]]></category>

		<guid isPermaLink="false">http://michael.susens-schurter.com/blog/2007/11/06/recipe-for-a-transparent-linux-firewall-and-cherrypy-control-panel/</guid>
		<description><![CDATA[At my previous job I built a transparent firewall with the help of a student. He hacked up some iptables scripts, and I hacked up a CherryPy application to control the firewall. It turned out to be pretty handy, so &#8230; <a href="http://blog.schmichael.com/2007/11/06/recipe-for-a-transparent-linux-firewall-and-cherrypy-control-panel/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<div style="float: right; padding: 10px;"><a href="http://michael.susens-schurter.com/files/firewalladmin.png"><img alt="firewalladmin screenshot" src="http://michael.susens-schurter.com/files/firewalladmin-small.png"></a></div>
<p>At my previous job I built a transparent firewall with the help of a student.  He hacked up some iptables scripts, and I hacked up a CherryPy application to control the firewall.  It turned out to be pretty handy, so I&#8217;m finally getting around to posting it somewhere&#8230;</p>
<p><strong>Recipe:</strong> A transparent firewall to block certain IP addresses and a nice web based control panel to edit the blacklist.</p>
<p><strong>Ingredients:</strong></p>
<ul>
<li>Old computer (preferably a PIII) with 3 NICs</li>
<li><a href="http://www.debian.org/releases/etch/">Debian Etch</a> (or your Linux flavor of choice)</li>
<li>Packages: <a href="http://packages.debian.org/etch/iptables">iptables</a>, <a href="http://packages.debian.org/etch/bridge-utils">bridge-utils</a>, <a href="http://packages.debian.org/etch/python/python">Python</a>, <a href="http://packages.debian.org/etch/python/python-setuptools">setuptools</a>, CherryPy 3 (use easy_install), Genshi (use easy_install), <a href="http://packages.debian.org/etch/python/python-adns">Python-ADNS</a>, <a href="http://packages.debian.org/etch/python/python-sqlobject">SQLObject</a></li>
<li><a href="http://michael.susens-schurter.com/code/firewall-admin.tar.gz">firewall-admin.tar.gz</a> &#8211; my exceedingly creatively named firewall administration CherryPy web app</li>
</ul>
<p><strong>Directions:</strong></p>
<ol>
<li>Extract firewall-admin.tar.gz and change to the base directory.  By default its setup to be in /srv/firewall-admin</li>
<li>If you didn&#8217;t extract to <code>/srv/firewall-admin</code>, edit etc/rc.local and <em>basedir</em> in <code>firewalladmin.config</code> to reflect the current directory.</li>
<li>By default <code>firewalladmin/lib/bridge.py</code> <a href="http://www.linux-foundation.org/en/Net:Bridge">bridges</a> <em>eth1</em> and <em>eth2</em>, and <em>eth0</em> should be attached to your LAN to access SSH and the web control panel.</li>
<li>Edit firewalladmin.config to run on the IP address assigned to your administrative NIC and remember what port its set to run on.</li>
<li>Add the commands from <code>etc/rc.local</code> to your system&#8217;s existing <code>/etc/rc.local</code> script.  This will start the transparent firewall and web control panel on boot.</li>
<li>Next you&#8217;ll need to setup the database.  Edit line 28 in <code>firewalladmin/model.py</code> to set a default password and then run <code>createdb.py</code></li>
<li>You&#8217;re now ready to start the firewall and control panel simply by running <code>sudo etc/rc.local</code> (see <em>Caveats</em> below).  You can always test out just the web interface by running <code>start-firewalladmin.py</code></li>
<li>Browse to the web interface using the IP and Port setup in step 4, login using the username and password setup in step 6, and start configuring your transparent firewall!</li>
</ol>
<p>The firewall allows creating multiple blacklists (aka Categories) which can be edited/paused/deleted individually.  It has has <em>allow lists</em> (aka Whitelists) which can be used to allow specific internal IPs access to specific sites that might otherwise be blocked by a blacklist.</p>
<p><strong>Important:</strong> When a user visits a blocked site they are redirected to the IP and Port specified on line 10 of <code>firewalladmin/lib/iptables.py</code>.  We setup Apache to listen on that port and serve up a generic <em>You&#8217;ve been blocked</em> page, but you could be even more clever.  You&#8217;ll need a <code>.htaccess</code> file like the following to properly map all blocked traffic to your block page:</p>

<div class="wp_syntax"><div class="code"><pre class="htaccess" style="font-family:monospace;">RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.html [L,QSA]</pre></div></div>

<p><strong>Caveats</strong></p>
<ul>
<li>All scripts as well as the web control panel are <strong>executed as root</strong>.  This setup should only be run on dedicated hardware and not on a server with other services.</li>
<li>No test suite.  Mea culpa.</li>
<li>Little to no error handling.  You&#8217;ve been warned. <img src='http://blog.schmichael.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </li>
<li>Basically this is a quick hack and should not be used in the same way you use tested and maintained software.  YMMV</li>
</ul>
<p>This little setup has proved very useful at the school for augmenting their existing content filtering system, and all web traffic passes through it without trouble.  An old PIII can run a 3,000 domain blacklist at wirespeed on a 10 Mbps link while using less than 10% of the CPU.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.schmichael.com/2007/11/06/recipe-for-a-transparent-linux-firewall-and-cherrypy-control-panel/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>

