<?xml version="1.0"?>

<rdf:RDF 
  xmlns="http://purl.org/rss/1.0/"
  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  xmlns:dc="http://purl.org/dc/elements/1.1/"
  xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
>

<channel rdf:about="http://simon.incutio.com/syndicate/python/rss1.0">
  <title>Python</title>
  <link>http://simon.incutio.com/</link>
  <description>Simon Willison's Python cateory</description>
  <language>en-uk</language>
  <webMaster>simon@incutio.com</webMaster>
  <items>
    <rdf:Seq>
      <rdf:li rdf:resource="http://simon.incutio.com/archive/2006/10/31/ctypes" />
      <rdf:li rdf:resource="http://simon.incutio.com/archive/2006/09/22/excited" />
      <rdf:li rdf:resource="http://simon.incutio.com/archive/2006/08/08/ydn" />
      <rdf:li rdf:resource="http://simon.incutio.com/archive/2006/04/06/python25" />
      <rdf:li rdf:resource="http://simon.incutio.com/archive/2005/08/03/django" />
      <rdf:li rdf:resource="http://simon.incutio.com/archive/2005/07/17/django" />
      <rdf:li rdf:resource="http://simon.incutio.com/archive/2005/03/28/pycon" />
      <rdf:li rdf:resource="http://simon.incutio.com/archive/2004/12/03/getters" />
      <rdf:li rdf:resource="http://simon.incutio.com/archive/2004/09/28/modpydoc" />
      <rdf:li rdf:resource="http://simon.incutio.com/archive/2004/09/21/python24" />
      <rdf:li rdf:resource="http://simon.incutio.com/archive/2004/09/09/commandline" />
      <rdf:li rdf:resource="http://simon.incutio.com/archive/2004/07/15/instant" />
      <rdf:li rdf:resource="http://simon.incutio.com/archive/2004/07/01/compileall" />
      <rdf:li rdf:resource="http://simon.incutio.com/archive/2004/06/09/backporting" />
      <rdf:li rdf:resource="http://simon.incutio.com/archive/2004/05/07/switch" />
    </rdf:Seq>
  </items>
</channel>

<item rdf:about="http://simon.incutio.com/archive/2006/10/31/ctypes">
  <title>Fun with ctypes</title>
  <description>&lt;p&gt;This probably only works on Intel-based OS X machines:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;python-interactive&quot;&gt;&amp;gt;&amp;gt;&amp;gt; import ctypes
&amp;gt;&amp;gt;&amp;gt; print ctypes.c_char_p(
    -16 * 4096 + 0x1600
).value
Your karma check for today:
There once was was a user that whined
his existing OS was so blind,
he'd do better to pirate
an OS that ran great
but found his hardware declined.
Please don't steal Mac OS!
Really, that's way uncool.
   (C) Apple Computer, Inc.U??VWS?5P
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Adapted from &lt;samp&gt;dsmos.c&lt;/samp&gt; in &lt;a href=&quot;http://osxbook.com/book/bonus/chapter7/binaryprotection/index.html&quot;&gt;Understanding Apple's Binary Protection in Mac OS X&lt;/a&gt; by Amit Singh.&lt;/p&gt;</description>
  <link>http://simon.incutio.com/archive/2006/10/31/ctypes</link>
  <dc:subject>Python</dc:subject>
  <dc:date>2006-10-31T11:36:25-00:00</dc:date>
  <dc:creator>Simon Willison</dc:creator>
</item>
<item rdf:about="http://simon.incutio.com/archive/2006/09/22/excited">
  <title>What I'm excited about, post-conference edition</title>
  <description>&lt;p id=&quot;p-0&quot;&gt;Wow, I've had a really busy month. I've attended (and spoken at) &lt;a href=&quot;http://barcamp.org/BarCampLondon&quot;&gt;BarCamp London&lt;/a&gt;, &lt;a href=&quot;http://www.mediaintransition.com/indexe.html&quot;&gt;Media in Transition&lt;/a&gt;, &lt;a href=&quot;http://2006.dconstruct.org/&quot;&gt;d.Construct&lt;/a&gt;, &lt;a href=&quot;http://europe.railsconf.org/&quot;&gt;RailsConf Europe&lt;/a&gt;, Euro Foo and &lt;a href=&quot;http://conferences.oreillynet.com/euos2006/&quot;&gt;EuroOSCON&lt;/a&gt;. All were excellent, and each one nicely complemented the others. I'm exhausted. I think my brain is full.&lt;/p&gt;

&lt;p id=&quot;p-1&quot;&gt;My favourite question to ask new people I meet at conferences is &quot;what are you excited about?&quot;. It's better than &quot;what do you do?&quot; (their job might not be as exciting as what they do in their spare time) and often gets a really interesting reply. People often ask me the same back, so here are three things that have been catching my attention recently.&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;&lt;p id=&quot;p-2&quot;&gt;&lt;strong&gt;&lt;a href=&quot;http://openid.net/&quot;&gt;OpenID&lt;/a&gt;&lt;/strong&gt;. It's criminal that so few people are playing with this. I gave talks about it at both BarCamp and Euro Foo - it's decentralised single sign-on that works, and it's trivial to implement thanks to really solid libraries for most programming languages. There's also a &lt;a href=&quot;http://iwantmyopenid.org/bounty&quot;&gt;$5,000 bounty&lt;/a&gt; to help spur adoption. I'll be writing a lot more about this in the future.&lt;/p&gt;&lt;/li&gt;
 &lt;li&gt;&lt;p id=&quot;p-3&quot;&gt;&lt;strong&gt;Virtualization&lt;/strong&gt;. This was a common thread at several conferences, and the recent popularity of Parallels for browser testing barely scratches the surface. Virtual servers have a bunch of advantages over physical servers: you can clone them instantly, you can migrate them between machines (while they are still running if you're using Xen) and Amazon's &lt;a href=&quot;http://aws.amazon.com/ec2&quot;&gt;EC2&lt;/a&gt; offers &lt;a href=&quot;http://en.wikipedia.org/wiki/Utility_computing&quot;&gt;utility computing&lt;/a&gt; on an enormous scale.&lt;/p&gt;&lt;/li&gt;
 &lt;li&gt;&lt;p id=&quot;p-4&quot;&gt;&lt;strong&gt;Dynamic languages on virtual machines&lt;/strong&gt;. &lt;a href=&quot;http://www.codeplex.com/Wiki/View.aspx?ProjectName=IronPython&quot;&gt;IronPython 1.0&lt;/a&gt; is out, Sun &lt;a href=&quot;http://www.tbray.org/ongoing/When/200x/2006/09/07/JRuby-guys&quot;&gt;have hired the JRuby guys&lt;/a&gt;. It looks like dynamic languages are finally being taken seriously as useful and powerful alternatives to C# and Java. Programmers on those VMs get more productive languages, while users of those languages gain access to enormous existing class libraries, not to mention the promise of significant performance boosts.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p id=&quot;p-5&quot;&gt;Finally, since I've blogged the &lt;a href=&quot;http://simon.incutio.com/archive/2003/07/30/python23&quot; title=&quot;Python 2.3&quot;&gt;last&lt;/a&gt; &lt;a href=&quot;http://simon.incutio.com/archive/2004/09/21/python24&quot; title=&quot;Python 2.4 highlights&quot;&gt;two&lt;/a&gt; releases of Python I can't resist saying a few things about &lt;a href=&quot;http://www.python.org/download/releases/2.5/&quot;&gt;the new Python 2.5&lt;/a&gt;. It's &lt;a href=&quot;http://docs.python.org/dev/whatsnew/whatsnew25.html&quot; title=&quot;What's New in Python 2.5&quot;&gt;all good&lt;/a&gt;, but the stuff that really stands out is the addition of &lt;a href=&quot;http://docs.python.org/dev/lib/module-sqlite3.html&quot;&gt;sqlite3&lt;/a&gt;, &lt;a href=&quot;http://docs.python.org/dev/lib/module-xml.etree.elementtree.html&quot;&gt;ElementTree&lt;/a&gt; and &lt;a href=&quot;http://docs.python.org/dev/lib/module-ctypes.html&quot;&gt;ctypes&lt;/a&gt; to the standard library. Batteries included!&lt;/p&gt;</description>
  <link>http://simon.incutio.com/archive/2006/09/22/excited</link>
  <dc:subject>Python</dc:subject>
  <dc:date>2006-09-22T00:25:11-00:00</dc:date>
  <dc:creator>Simon Willison</dc:creator>
</item>
<item rdf:about="http://simon.incutio.com/archive/2006/08/08/ydn">
  <title>The YDN Python Developer Center</title>
  <description>&lt;p id=&quot;p-0&quot;&gt;I recently had the opportunity to put together the &lt;a href=&quot;http://developer.yahoo.com/python/&quot;&gt;Python Developer Center&lt;/a&gt; for the &lt;a href=&quot;http://developer.yahoo.com/&quot;&gt;Yahoo! Developer Network&lt;/a&gt;. YDN is one of my favourite parts of Yahoo! so I jumped at the chance, and the resulting mini-site is now online (&lt;a href=&quot;http://developer.yahoo.net/blog/archives/2006/08/introducing_the.html&quot;&gt;YDN blog post here&lt;/a&gt;).&lt;/p&gt;

&lt;p id=&quot;p-1&quot;&gt;The bulk of the content is &lt;a href=&quot;http://developer.yahoo.com/python/#howto&quot;&gt;the HOWTOs&lt;/a&gt;, which discuss ways of accessing Yahoo! APIs using Python:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://developer.yahoo.com/python/python-rest.html&quot;&gt;Make Yahoo! Web Service REST calls with Python&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://developer.yahoo.com/python/python-caching.html&quot;&gt;Cache API calls using Python&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://developer.yahoo.com/python/python-json.html&quot;&gt;Parse JSON using Python&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://developer.yahoo.com/python/python-xml.html&quot;&gt;Parse XML using Python&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://developer.yahoo.com/python/python-pysearch.html&quot;&gt;Access the Yahoo! Search APIs using pYsearch&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://developer.yahoo.com/python/python-rss.html&quot;&gt;Access Yahoo! RSS feeds using Python&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p id=&quot;p-2&quot;&gt;I had a lot of fun playing around with different ways of accessing the APIs and working out which ones were the most natural fit. The HOWTOs use &lt;a href=&quot;http://docs.python.org/lib/module-urllib.html&quot;&gt;urllib&lt;/a&gt;, &lt;a href=&quot;http://docs.python.org/lib/module-urllib2.html&quot;&gt;urllib2&lt;/a&gt; and &lt;a href=&quot;http://docs.python.org/lib/module-xml.dom.minidom.html&quot;&gt;xml.dom.minidom&lt;/a&gt; from the standard library, but also discuss &lt;a href=&quot;http://bitworking.org/projects/httplib2/ref/module-httplib2.html&quot;&gt;httplib2&lt;/a&gt;, &lt;a href=&quot;http://effbot.org/zone/element-index.htm&quot;&gt;ElementTree&lt;/a&gt; and &lt;a href=&quot;http://undefined.org/python/#simplejson&quot;&gt;simplejson&lt;/a&gt; as third party libraries that are worth investigating. Naturally, &lt;a href=&quot;http://www.feedparser.org/&quot;&gt;feedparser&lt;/a&gt; is the recommended tool for accessing Yahoo!'s &lt;a href=&quot;http://developer.yahoo.com/rss/&quot;&gt;multitude of RSS feeds&lt;/a&gt;.&lt;/p&gt;

&lt;p id=&quot;p-3&quot;&gt;Python really is a fantastic language for exploring web service APIs. All of the example code for the HOWTOs was first written in an interactive prompt and then copied to a file once it was working. Test-first development is certainly an important technique, but the power of interactive development should never be underestimated.&lt;/p&gt;</description>
  <link>http://simon.incutio.com/archive/2006/08/08/ydn</link>
  <dc:subject>Web Services, Python</dc:subject>
  <dc:date>2006-08-08T20:56:26-00:00</dc:date>
  <dc:creator>Simon Willison</dc:creator>
</item>
<item rdf:about="http://simon.incutio.com/archive/2006/04/06/python25">
  <title>Exciting stuff in Python 2.5</title>
  <description>&lt;p id=&quot;p-0&quot;&gt;Python 2.5 alpha 1 &lt;a href=&quot;http://www.python.org/download/releases/2.5/&quot; title=&quot;Python 2.5 (alpha 1)&quot;&gt;is out&lt;/a&gt;, and as usual the &lt;a href=&quot;http://docs.python.org/dev/whatsnew/whatsnew25.html&quot;&gt;What's New in Python 2.5&lt;/a&gt; document provides a pleasant overview of the new features. There are some real treats in there. While I'm hoping that the syntax for &lt;a href=&quot;http://docs.python.org/dev/whatsnew/node2.html&quot;&gt;conditional expressions&lt;/a&gt; will grow on me, I'm looking forward to &lt;a href=&quot;http://docs.python.org/dev/whatsnew/node3.html&quot;&gt;Partial function application&lt;/a&gt; becoming a common Python idiom. &lt;a href=&quot;http://docs.python.org/dev/whatsnew/node5.html&quot;&gt;Relative imports&lt;/a&gt; are going to make Django applications a lot easier to redistribute, and I can't wait to see all the crazy hacks that result from the introduction of &lt;a href=&quot;http://docs.python.org/dev/whatsnew/node8.html&quot;&gt;coroutines&lt;/a&gt;.&lt;/p&gt;

&lt;p id=&quot;p-1&quot;&gt;I've seen David Heinemeier Hansson speak a few times, and he often uses ActiveRecord's &lt;a href=&quot;http://wiki.rubyonrails.com/rails/pages/HowToUseTransactions&quot;&gt;transaction support&lt;/a&gt; to illustrate the elegance that well-written Ruby has to offer:&lt;/p&gt;

&lt;blockquote cite=&quot;http://wiki.rubyonrails.com/rails/pages/HowToUseTransactions&quot;&gt;&lt;pre&gt;&lt;code&gt;Account.transaction(account1, account2) do
  account1.withdraw(100)
  account2.deposit(100)
end&lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;

&lt;p id=&quot;p-2&quot;&gt;Here a Ruby block is being used as syntax for a database transaction, guaranteeing that some code will be run before and after the withdraw and deposit lines. The new &lt;a href=&quot;http://docs.python.org/dev/whatsnew/node9.html&quot;&gt;with statement&lt;/a&gt; makes something similar possible with an imaginary Python &lt;acronym title=&quot;Object-Relational Mapper&quot;&gt;ORM&lt;/acronym&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;with Account.transaction(account1, account2):
    account1.withdraw(100)
    account2.deposit(100)&lt;/code&gt;&lt;/pre&gt;

&lt;p id=&quot;p-3&quot;&gt;The highlight of the release might well be the modules that have been added to the standard library - tucked away in &lt;a href=&quot;http://docs.python.org/dev/whatsnew/node14.html&quot;&gt;section 13&lt;/a&gt; of the document. &lt;a href=&quot;http://starship.python.net/crew/theller/ctypes/&quot;&gt;ctypes&lt;/a&gt;, &lt;a href=&quot;http://effbot.org/zone/element-index.htm&quot;&gt;ElementTree&lt;/a&gt;, a new hashlib with support for SHA-224 through 512 and sqlite3 (a renamed &lt;a href=&quot;http://www.pysqlite.org/&quot;&gt;pysqlite&lt;/a&gt;) are all included. ctypes is particularly interesting as it lets you call functions in compiled DLLs and shared libraries without having to compile a Python wrapper.&lt;/p&gt;

&lt;p id=&quot;p-4&quot;&gt;The final Python 2.5 release &lt;a href=&quot;http://mail.python.org/pipermail/python-dev/2005-August/055342.html&quot; title=&quot;[Python-Dev] plans for 2.4.2 and 2.5a1&quot;&gt;appears to be scheduled&lt;/a&gt; for June-July this year, which should give Apple ample time to incorporate it in to OS X Leopard.&lt;/p&gt;</description>
  <link>http://simon.incutio.com/archive/2006/04/06/python25</link>
  <dc:subject>Python</dc:subject>
  <dc:date>2006-04-06T22:15:14-00:00</dc:date>
  <dc:creator>Simon Willison</dc:creator>
</item>
<item rdf:about="http://simon.incutio.com/archive/2005/08/03/django">
  <title>Exciting developments with Django</title>
  <description>&lt;p id=&quot;p-0&quot;&gt;The amount of activity surrounding the &lt;a href=&quot;http://www.djangoproject.com/&quot;&gt;Django web framework&lt;/a&gt; since its not-quite release a few weeks ago is amazing. Adrian, Jacob and Wilson have been working over-time, with 395 check-ins to source control since the 13th of July. They've added &lt;a href=&quot;http://code.djangoproject.com/file/django/trunk/django/core/handlers/wsgi.py&quot;&gt;WSGI support&lt;/a&gt;, a &lt;a href=&quot;http://www.djangoproject.com/weblog/2005/jul/18/local_server/&quot;&gt;development web server&lt;/a&gt;, &lt;a href=&quot;http://www.djangoproject.com/weblog/2005/jul/29/model_examples/&quot;&gt;unit-tests&lt;/a&gt;, a &lt;a href=&quot;http://www.djangoproject.com/documentation/&quot;&gt;ton of documentation&lt;/a&gt;, &lt;a href=&quot;http://www.djangoproject.com/weblog/2005/jul/21/sqlite3/&quot;&gt;SQLite support&lt;/a&gt;, &lt;a href=&quot;http://code.djangoproject.com/changeset/384&quot;&gt;database introspection&lt;/a&gt; and dozens of other feature tweaks and bug fixes. Check out the &lt;a href=&quot;http://code.djangoproject.com/timeline&quot;&gt;project Timeline&lt;/a&gt; for an idea of just how frenetic things have been.&lt;/p&gt;

&lt;p id=&quot;p-1&quot;&gt;The emerging &lt;a href=&quot;http://www.djangoproject.com/community/&quot;&gt;Django community&lt;/a&gt; has been kicking in as well. There's a significant community-led initiative to get &lt;a href=&quot;http://code.djangoproject.com/wiki/InterNationalization&quot;&gt;internationalisation&lt;/a&gt; and &lt;a href=&quot;http://code.djangoproject.com/wiki/Localization&quot;&gt;localisation&lt;/a&gt; going, and a wide number of unofficial tutorials have emerged to complement &lt;a href=&quot;http://www.djangoproject.com/documentation/tutorial1/&quot;&gt;the one on the site&lt;/a&gt;.&lt;/p&gt;

&lt;p id=&quot;p-2&quot;&gt;Here's where things get really interesting: changes at the Journal-World have kick-started the Django job market. Rob Curley, formally in charge of the World Company's web activities, recently &lt;a href=&quot;http://www.digitaledge.org/DigArtPage.cfm?AID=7083&quot;&gt;took up a new position&lt;/a&gt; at the &lt;a href=&quot;http://www.naplesnews.com/&quot;&gt;Naples Daily News&lt;/a&gt; in Florida. Rob &lt;a href=&quot;http://eric.themoritzfamily.com/?p=48&quot;&gt;just hired Eric Moritz&lt;/a&gt;, a regular on the #django IRC channel, to work on Django-powered projects there.&lt;/p&gt;

&lt;p id=&quot;p-3&quot;&gt;Meanwhile, Adrian Holovaty has &lt;a href=&quot;http://www.poynter.org/column.asp?id=31&amp;amp;aid=86489&quot;&gt;taken a new job&lt;/a&gt; at the &lt;a href=&quot;http://www.washingtonpost.com/&quot;&gt;Washington Post&lt;/a&gt; as &quot;Editor, Editorial Innovations&quot; - a role that is sure to involve some very innovative use of Django (Adrian built &lt;a href=&quot;http://chicagocrime.org/&quot;&gt;chicagocrime.org&lt;/a&gt;). Adrian's departure means that the Journal-World are &lt;a href=&quot;http://www.holovaty.com/blog/archive/2005/08/03/0202&quot;&gt;looking for a new developer&lt;/a&gt; - here's &lt;a href=&quot;http://simon.incutio.com/archive/2004/06/29/job&quot; title=&quot;Fancy a job?&quot;&gt;why you should apply&lt;/a&gt;.&lt;/p&gt;

&lt;p id=&quot;p-4&quot;&gt;One thing's for certain: we're going to see some very exciting Django-powered sites in the next few months.&lt;/p&gt;</description>
  <link>http://simon.incutio.com/archive/2005/08/03/django</link>
  <dc:subject>Python, Open Source, Content Management, Django</dc:subject>
  <dc:date>2005-08-03T16:56:34-00:00</dc:date>
  <dc:creator>Simon Willison</dc:creator>
</item>
<item rdf:about="http://simon.incutio.com/archive/2005/07/17/django">
  <title>Introducing Django</title>
  <description>&lt;p id=&quot;p-0&quot;&gt;You may know that I spent a year working in Kansas for a local newspaper - the &lt;a href=&quot;http://www.ljworld.com/&quot;&gt;Lawrence Journal-World&lt;/a&gt;. I'm delighted to announce that a decent chunk of the software I worked on there is now available as open-source, in the form of the &lt;a href=&quot;http://www.djangoproject.com/&quot;&gt;Django web framework&lt;/a&gt;.&lt;/p&gt;

&lt;p id=&quot;p-1&quot;&gt;Django is an &lt;acronym title=&quot;Model View Controller&quot;&gt;MVC&lt;/acronym&gt; Python web development framework with a strong emphasis on content management. While comparisons with &lt;a href=&quot;http://www.rubyonrails.org/&quot;&gt;Rails&lt;/a&gt; are inevitable (I plan to post one myself shortly), it should be emphasized that Django is by no means a clone of Rails - in fact, development on Django started in October 2003, months before the first public Rails release. That the two frameworks share so many ideas is, I feel, a testament to the design of both.&lt;/p&gt;

&lt;p id=&quot;p-2&quot;&gt;Django was initially developed by &lt;a href=&quot;http://www.holovaty.com/&quot;&gt;Adrian Holovaty&lt;/a&gt; and myself, with &lt;a href=&quot;http://www.jacobian.org/&quot;&gt;Jacob Kaplan-Moss&lt;/a&gt; joining the team shortly before my departure. The framework evolved during the construction of a number of sites, which included:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;&lt;a href=&quot;http://www.6newslawrence.com/&quot;&gt;6newslawrence.com&lt;/a&gt;, local TV news, the first site to launch using the then nascent Django framework.&lt;/li&gt;
 &lt;li&gt;&lt;a href=&quot;http://www.lawrence.com/&quot;&gt;lawrence.com&lt;/a&gt;, a local entertainment site. Every town should have a site like this; sadly, very few do.&lt;/li&gt;
 &lt;li&gt;&lt;a href=&quot;http://www.visitlawrence.com/&quot;&gt;VisitLawrence.com&lt;/a&gt;, a local tourism site.&lt;/li&gt;
 &lt;li&gt;&lt;a href=&quot;http://www.kusports.com/&quot;&gt;KUSports.com&lt;/a&gt;, a sports news site covering the University of Kansas.&lt;/li&gt;
 &lt;li&gt;&lt;a href=&quot;http://www.ljworld.com/&quot;&gt;LJWorld.com&lt;/a&gt;, a local news site and the flagship for the Journal-World.&lt;/li&gt;
&lt;/ul&gt;

&lt;p id=&quot;p-3&quot;&gt;It's also purring along under the hood of &lt;a href=&quot;http://www.chicagocrime.org/&quot;&gt;chicagocrime.org&lt;/a&gt; and the &lt;a href=&quot;http://www.djangoproject.com/&quot;&gt;Django project site&lt;/a&gt; itself.&lt;/p&gt;

&lt;p id=&quot;p-4&quot;&gt;Adrian and I developed Django to allow us to create reasonably complex database driven web applications in as little time as possible. A local newspaper produces a huge amount of information - news stories, events listings, obituaries, sports results, marriage announcements, photo galleries, polls, weather reports and dozens of other bits and pieces. To maximise their value and potential for reuse, these things need to be stored in a database. That database needs a user interface for people to add and modify content, and of course the information needs to be published to a website somewhere.&lt;/p&gt;

&lt;p id=&quot;p-5&quot;&gt;Django automates most of this - and makes the rest as easy as possible. You create a &lt;em&gt;data description&lt;/em&gt; (kind of like an &lt;acronym title=&quot;Structured Query Language&quot;&gt;SQL&lt;/acronym&gt; table schema but with additional information about validation rules and interface widgets) and load it in to Django. Django then creates the database tables, model classes and a comprehensive web-based administration interface for your site's staff. All that's left for you to do manually is the code for the public site, which is generally a case of writing a few lines of controller code, configuring some &lt;acronym title=&quot;Universal Republic of Love&quot;&gt;URL&lt;/acronym&gt;s and knocking out some templates.&lt;/p&gt;

&lt;p id=&quot;p-6&quot;&gt;To give you an idea of how much this speeds up the creation of new sites, consider the case of &lt;a href=&quot;http://www.ljworld.com/game/&quot;&gt;Game&lt;/a&gt;. Game was a site created to provide detailed coverage of little-league games in and around Lawrence (for non-Americans, little-league is baseball and softball for children aged around 5 to 11 - it's amazingly popular). The entire Game site, including news, fixtures, match results, team profiles and even weather forecasts for forthcoming matches took &lt;em&gt;two days&lt;/em&gt; to develop.&lt;/p&gt;

&lt;p id=&quot;p-7&quot;&gt;I haven't been involved with Django since leaving the Journal-World back in September, but now that the framework is open-sourced I look forward to contributing to its further development - both in terms of documentation and actual code. There's already plenty to look at on the &lt;a href=&quot;http://www.djangoproject.com/&quot;&gt;Django site&lt;/a&gt; (designed by the ever-talented &lt;a href=&quot;http://www.wilsonminer.com/live/&quot;&gt;Wilson Miner&lt;/a&gt;); I suggest the &lt;a href=&quot;http://www.djangoproject.com/documentation/overview/&quot;&gt;overview&lt;/a&gt; as your first port of call.&lt;/p&gt;

&lt;p id=&quot;p-8&quot;&gt;Expect to hear a lot more about the framework in the next few weeks.&lt;/p&gt;</description>
  <link>http://simon.incutio.com/archive/2005/07/17/django</link>
  <dc:subject>Python, Open Source, Django</dc:subject>
  <dc:date>2005-07-17T11:59:57-00:00</dc:date>
  <dc:creator>Simon Willison</dc:creator>
</item>
<item rdf:about="http://simon.incutio.com/archive/2005/03/28/pycon">
  <title>PyCon observations</title>
  <description>&lt;p&gt;I'm back from my two week stint in the US, and currently suffering from vicious jet-lag (my body wants me to go to sleep at 5am and wake up just past noon). Herewith some observations on PyCon, SxSW and the differences between the two.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://www.python.org/pycon/2005/&quot;&gt;PyCon 2005&lt;/a&gt; was a great conference, and a very different one from &lt;a href=&quot;http://2005.sxsw.com/interactive/&quot;&gt;SxSW Interactive&lt;/a&gt; the week before. While SxSW was one big social party with panels thrown in to fill the gaps, the sessions in PyCon were the main event and the social stuff (with the exception of the sprints, which I didn't really experience) was much less prominent. For the first day of the conference I actually found it quite hard to spark up conversations with strangers, something I'd been doing for pretty much the whole of SxSW. Things got better on the second and third days, but the lack of any organised social events and more reserved atmosphere meant I didn't have nearly as many random social experiences as at SxSW.&lt;/p&gt;

&lt;p&gt;The PyCon sessions really were excellent: three great keynotes (the IronPython keynote was my favourite), an excellent web track and a whole smorgasbord of interesting topics spread over the three days. I have only one big complaint: all sessions apart from the keynotes were half an hour in length. For most sessions this worked fine, but some of the more experienced presenters were obviously shackled by the half hour requirement. Bruce Eckel's presentation was the most noticable in this regard - I love the stuff he covered, but it's obvious he could have gone on for a lot longer without losing the attention of the crowd (he obviously &lt;a href=&quot;http://onthethought.blogspot.com/2005/03/pycon-and-sd.html&quot; title=&quot;PyCon and SD&quot;&gt;thought the same&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;My suggestion for next year would be to keep most of the sessions at half an hour, but schedule a small number of 45 minute sessions for presenters who are obvious candidates for longer talks. I talked to Steve Holden (this year's organiser) briefly about this and he mentioned that 45 minute sessions lead to scheduling difficulties, particularly with respect to coordinating the different tracks. I personally think that the benefits of longer sessions for certain key topics would outweigh the scheduling disadvantages.&lt;/p&gt;

&lt;p&gt;A few other PyCon observations:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;There were over 400 attendees, at least a hundred more than last year. This slightly exceeded the capacity of the conference center, and they'll be mobing to a larger (as yet undecided) venue for 2006.&lt;/li&gt;
 &lt;li&gt;I only attended one of the two lightning talk sessions, but it was great fun and a refreshing change from the regular panels. The highlight for me was the guy who strapped a computer to the back of his motorcycle and drove 7,000 miles across America... with Python to coordinate all of the pieces. You can read more on &lt;a href=&quot;http://ltodyssey.org/&quot; title=&quot;LT Odyssey 2004&quot;&gt;his site&lt;/a&gt;, or in &lt;a href=&quot;http://www.pyzine.com/Issue007/Section_Articles/article_MobileDataCollection.html&quot; title=&quot;Using Python to Create a Mobile Data Collection System&quot;&gt;this article&lt;/a&gt; on Py.&lt;/li&gt;
 &lt;li&gt;The two (sometimes three) tracks were well arranged, with few clashes between things that I wanted to see. This was in contrast to SxSW's 5 tracks which had serious clashes pretty much all the time.&lt;/li&gt;
 &lt;li&gt;Everyone was hiring! The conference package we got was stacked with job brochures from the conference sponsors, and the whiteboard by the registration desk had new jobs added to it every day. Sure-fire evidence that Python is finally starting to gain significance in the job market.&lt;/li&gt;
 &lt;li&gt;The lunches, included in the conference price, were excellent. The price itself was great value too - early bird for students was $125, and $175 for regular attendees. Even late registration was only (from memory) $275.&lt;/li&gt;
 &lt;li&gt;The largest venue at the center, used for the keynotes, had no WiFi! Coverage throughout the rest of the conference was good however.&lt;/li&gt;
 &lt;li&gt;I finally got to join Ted Leung and friends in a SubEthaEdit session during the Python at Google keynote. It was an electrifying experience watching each slide  transcribed in to the notes within seconds of it appearing on screen, with multiple lines developing at the same time. The results of our labour &lt;a href=&quot;http://www.sauria.com/~twl/conferences/pycon2005/20050325/Python%20at%20Google.html&quot; title=&quot;Python at Google.notes&quot;&gt;can be seen here&lt;/a&gt;. Someone really needs to put together a screencast of this kind of thing so the rest of the world knows what they're missing.&lt;/li&gt;
 &lt;li&gt;Despite my observations about the less social nature of the conference above, I met some very interesting people and had a really great time.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It seems to me that Python and SxSW could learn some tricks from each other. Lightning talks and Birds-of-a-feather sessions would be a great addition to the SxSW lineup, while PyCon really does need some more thought put in to the social side of the conference. I hope to attend both again next year.&lt;/p&gt;</description>
  <link>http://simon.incutio.com/archive/2005/03/28/pycon</link>
  <dc:subject>Python</dc:subject>
  <dc:date>2005-03-28T17:08:22-00:00</dc:date>
  <dc:creator>Simon Willison</dc:creator>
</item>
<item rdf:about="http://simon.incutio.com/archive/2004/12/03/getters">
  <title>Casting out getters and setters</title>
  <description>&lt;p&gt;&lt;a href=&quot;http://dirtsimple.org/2004/12/python-is-not-java.html&quot;&gt;Python Is Not Java&lt;/a&gt; by Phillip J. Eby (via &lt;a href=&quot;http://www.nedbatchelder.com/blog/200412.html#e20041202T223025&quot;&gt;Ned&lt;/a&gt;) is the most useful article on programming I've read in ages. If you have any interest at all in either language, go and read it. It's all good, but the part that really struck a nerve for me was this:&lt;/p&gt;

&lt;blockquote cite=&quot;http://dirtsimple.org/2004/12/python-is-not-java.html&quot;&gt;&lt;p&gt;Getters and setters are evil. Evil, evil, I say! Python objects are not Java beans. Do not write getters and setters. This is what the 'property' built-in is for. And do not take that to mean that you should write getters and setters, and then wrap them in 'property'. That means that until you prove that you need anything more than a simple attribute access, don't write getters and setters. They are a waste of CPU time, but more important, they are a waste of programmer time. Not just for the people writing the code and tests, but for the people who have to read and understand them as well.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;Writing getters and setters in Java has always bugged me, but I've never quite been able to articulate the reason until now. Python's &lt;a href=&quot;http://python.org/doc/2.2.3/whatsnew/sect-rellinks.html#SECTION000340000000000000000&quot;&gt;property  syntax&lt;/a&gt; (and Ruby's similar &lt;a href=&quot;http://www.rubycentral.com/book/tut_classes.html#S2&quot;&gt;attr_reader and attr_writer&lt;/a&gt; methods) are so much more elegant that writing those things by hand, or even auto-generating them with Eclipse, leaves a nasty taste in my mouth.&lt;/p&gt;</description>
  <link>http://simon.incutio.com/archive/2004/12/03/getters</link>
  <dc:subject>Python, Programming</dc:subject>
  <dc:date>2004-12-03T15:52:41-00:00</dc:date>
  <dc:creator>Simon Willison</dc:creator>
</item>
<item rdf:about="http://simon.incutio.com/archive/2004/09/28/modpydoc">
  <title>Running Pydoc under mod_python</title>
  <description>&lt;p id=&quot;p-0&quot;&gt;I've &lt;a href=&quot;http://simon.incutio.com/archive/2004/03/23/pydoc&quot;&gt;written about pydoc&lt;/a&gt; before. In my opinion it's one of Python's best kept secrets: a way of instantly browsing the properties, methods and documentation strings of any module available to the Python environment. It can even run a local HTTP server to allow for easy browsing of available documentation.&lt;/p&gt;

&lt;p id=&quot;p-1&quot;&gt;That's all well and good for code running on your local machine, but most developers won't want to run a Pydoc server on a remote machine. We ran in to this problem recently at work; we wanted to run Pydoc on our development server but didn't want it exposed to the world at large.&lt;/p&gt;

&lt;p id=&quot;p-2&quot;&gt;Initially we considered running the regular Pydoc server locally on some random port, blocking that port to external IPs with a firewall rule and then using Apache's &lt;a href=&quot;http://httpd.apache.org/docs-2.0/mod/mod_proxy.html&quot;&gt;mod_proxy&lt;/a&gt; to open it up to outside access in a controlled manner. The downside with this is that we would have to run a special process and a firewall rule just to enable a relatively minor function. Instead, I spent some time working through the &lt;samp&gt;pydoc.py&lt;/samp&gt; source code and came up with a &lt;a href=&quot;http://www.modpython.org/&quot;&gt;mod_python&lt;/a&gt; wrapper for the &lt;acronym title=&quot;HyperText Markup Langyage&quot;&gt;HTML&lt;/acronym&gt; documentation part of the module.&lt;/p&gt;

&lt;p id=&quot;p-3&quot;&gt;&lt;a href=&quot;http://simon.incutio.com/code/python/modpydoc.py&quot;&gt;modpydoc.py&lt;/a&gt;&lt;/p&gt;

&lt;p id=&quot;p-4&quot;&gt;(Aside: Safari will try to render the above as &lt;acronym title=&quot;HyperText Markup Langyage&quot;&gt;HTML&lt;/acronym&gt;, even though the Content-Type header says &lt;samp&gt;text/plain&lt;/samp&gt;. This is because &lt;a href=&quot;http://diveintomark.org/archives/2004/08/13/safari-content-sniffing&quot; title=&quot;Content sniffing considered harmful&quot;&gt;Safari is brain-dead&lt;/a&gt; - it inherited this particular grotesqueness from Internet Explorer. I still use it though.)&lt;/p&gt;

&lt;p id=&quot;p-5&quot;&gt;Since we were already running mod_python on our development server, adding this extra module required no extra server configuration or additional server processes. It also allowed us to tie authentication for the resulting Pydoc instance to our existing authentication database, using &lt;a href=&quot;http://www.giuseppetanzilli.it/mod_auth_pgsql/&quot;&gt;mod_auth_pgsql&lt;/a&gt;.&lt;/p&gt;

&lt;p id=&quot;p-6&quot;&gt;For the inquisitive, here's a rough approximation of the relevant parts of our &lt;samp&gt;httpd.conf&lt;/samp&gt; file for that server:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;apacheconf&quot;&gt;
LoadModule access_module modules/mod_access.so
LoadModule auth_module modules/mod_auth.so
LoadModule alias_module modules/mod_alias.so
LoadModule auth_pgsql_module modules/mod_auth_pgsql.so
LoadModule python_module modules/mod_python.so

RedirectMatch permanent /pydoc$ /pydoc/

&amp;lt;Location &quot;/pydoc/&quot;&amp;gt;
    SetHandler python-program
    PythonHandler utils.modpydoc
    PythonPath &quot;sys.path+['/path/to/our/codebase/']&quot;
    AuthName &quot;Code Browser&quot;
    AuthType basic
    Auth_PG_database ourdb
    Auth_PG_user dbuser
    Auth_PG_pwd_table users
    Auth_PG_uid_field username
    Auth_PG_pwd_field password_md5
    Auth_PG_pwd_whereclause &quot; AND can_browse_code = 't' &quot;
    Auth_PG_hash_type MD5
    require valid-user
&amp;lt;/Location&amp;gt;
&lt;/code&gt;&lt;/pre&gt;</description>
  <link>http://simon.incutio.com/archive/2004/09/28/modpydoc</link>
  <dc:subject>Python</dc:subject>
  <dc:date>2004-09-28T03:34:46-00:00</dc:date>
  <dc:creator>Simon Willison</dc:creator>
</item>
<item rdf:about="http://simon.incutio.com/archive/2004/09/21/python24">
  <title>Python2.4 highlights</title>
  <description>&lt;p id=&quot;p-0&quot;&gt;A.M. Kuchling's &quot;What's New in Python X&quot; documents are always a treat, and his &lt;a href=&quot;http://www.python.org/dev/doc/devel/whatsnew/whatsnew24.html&quot;&gt;guide to the forthcoming Python 2.4&lt;/a&gt; is no exception. Among other things, 2.4 &lt;a href=&quot;http://www.python.org/dev/doc/devel/whatsnew/node2.html&quot; title=&quot;1 PEP 218: Built-In Set Objects&quot;&gt;elevates sets to built in type status&lt;/a&gt;, dramatically &lt;a href=&quot;http://www.python.org/dev/doc/devel/whatsnew/node11.html&quot; title=&quot;10 Other Language Changes&quot;&gt;improves the usability of Python's list sort method&lt;/a&gt; (for easier application of &lt;acronym title=&quot;Decorate-Sort-Undecorate&quot;&gt;DSU&lt;/acronym&gt;, aka the &lt;a href=&quot;http://www.stonehenge.com/merlyn/UnixReview/col06.html&quot; title=&quot;Unix Review Column 6 (January 1996)&quot;&gt;Schwartzian transform&lt;/a&gt;), makes &lt;a href=&quot;http://www.python.org/dev/doc/devel/whatsnew/node7.html&quot; title=&quot;6 PEP 322: Reverse Iteration&quot;&gt;reverse iteration&lt;/a&gt; easier and introduces &lt;a href=&quot;http://www.python.org/dev/doc/devel/whatsnew/node5.html&quot; title=&quot;4 PEP 292: Simpler String Substitutions&quot;&gt;an alternative string substitution method&lt;/a&gt;.&lt;/p&gt;

&lt;p id=&quot;p-1&quot;&gt;All that's before you get on to the really exciting stuff: &lt;a href=&quot;http://www.python.org/dev/doc/devel/whatsnew/node4.html&quot; title=&quot;3 PEP 289: Generator Expressions&quot;&gt;generator expressions&lt;/a&gt;, the &lt;a href=&quot;http://www.python.org/dev/doc/devel/whatsnew/node8.html&quot; title=&quot;7 PEP 327: Decimal Data Type&quot;&gt;new decimal type&lt;/a&gt; (because floating point numbers are &lt;a href=&quot;http://docs.python.org/tut/node15.html&quot; title=&quot;B. Floating Point Arithmetic: Issues and Limitations&quot;&gt;such a nuisance&lt;/a&gt;) and the controversial &lt;a href=&quot;http://www.python.org/dev/doc/devel/whatsnew/node6.html&quot; title=&quot;5 PEP 318: Decorators for Functions, Methods and Classes&quot;&gt;function decorators&lt;/a&gt;.&lt;/p&gt;

&lt;p id=&quot;p-2&quot;&gt;I have to admit I didn't understand the significance of half of this stuff until I read about them in &quot;What's New&quot;, which explains the use-cases for the new features with great clarity.&lt;/p&gt;

&lt;p id=&quot;p-3&quot;&gt;Python seems to advance at just the right rate; new features are introduced fast enough to keep me interested (and keep the language feeling alive) but not so fast as to leave me feeling left behind.&lt;/p&gt;</description>
  <link>http://simon.incutio.com/archive/2004/09/21/python24</link>
  <dc:subject>Python</dc:subject>
  <dc:date>2004-09-21T02:36:47-00:00</dc:date>
  <dc:creator>Simon Willison</dc:creator>
</item>
<item rdf:about="http://simon.incutio.com/archive/2004/09/09/commandline">
  <title>Command line blacklisting</title>
  <description>&lt;p id=&quot;p-0&quot;&gt;Just over a year ago, &lt;a href=&quot;http://simon.incutio.com/archive/2003/09/02/blacklisting&quot; title=&quot;Blacklisting Comment Spam&quot;&gt;I started blacklisting&lt;/a&gt; domain names from links featured in comment spam. My idea then was that these blacklists could become a shared resource: people would publish their own blacklist and subscribe to those of people they trust, thus making it much harder for spammers to operate. While the sheer volume of spam domains meant that the technique was much less useful than I originally anticipated, I've continued to maintain my blacklist ever since as a preventative measure against repeat spammers.&lt;/p&gt;

&lt;p id=&quot;p-1&quot;&gt;I have a confession to make: all of my blog administration (with the exception of adding entries and blogmarks) is performed using &lt;a href=&quot;http://www.phpmyadmin.net/&quot;&gt;phpMyAdmin&lt;/a&gt;. The trouble with writing your own software is that it's very easy to skimp on the backend tools, since you're the only person who will ever see them. Incidentally, this is the main reason I plan to switch to &lt;a href=&quot;http://wordpress.org/&quot;&gt;WordPress&lt;/a&gt; just as soon as I find the inspiration to write the necessary import scripts. Comments are deleted in phpMyAdmin, and domains are blacklisted by manually editing the &lt;a href=&quot;http://simon.incutio.com/blacklist.txt&quot;&gt;blacklist.txt&lt;/a&gt; file via &lt;acronym title=&quot;File Transfer Protocol&quot;&gt;FTP&lt;/acronym&gt;.&lt;/p&gt;

&lt;p id=&quot;p-2&quot;&gt;This has been really bugging me, especially since I have so little other use for &lt;acronym title=&quot;File Transfer Protocol&quot;&gt;FTP&lt;/acronym&gt; that my only installed client is an unregistered version of &lt;a href=&quot;http://www.panic.com/transmit/&quot;&gt;Transmit&lt;/a&gt; (closes after ten minutes, won't save passwords along with account details). I've been muddling along with that for longer than I care to admit, but today I decided to take 10 minutes out to solve the problem once and for all. I could have put together a web interface for adding new domains but I wasn't really in the mood, so I decided to put time spent reading &lt;a href=&quot;http://www.faqs.org/docs/artu/&quot;&gt;&lt;cite&gt;The Art of Unix Programming&lt;/cite&gt;&lt;/a&gt; to good use and knock out a simple command line application.&lt;/p&gt;

&lt;p id=&quot;p-3&quot;&gt;The result (minus my login details) can be found &lt;a href=&quot;http://simon.incutio.com/code/python/blacklist.py&quot; title=&quot;blacklist.py&quot;&gt;here&lt;/a&gt;. Sample usage: &lt;samp&gt;./blacklist.py www.domain.org www.domain2.com&lt;/samp&gt;. It follows the Unix ideal of being the simplest-thing-that-could-possibly-work, and ended up taking longer to write than I expected thanks mainly to the craziness of Python's &lt;a href=&quot;http://www.python.org/doc/current/lib/module-ftplib.html&quot;&gt;ftplib&lt;/a&gt;. I've seen complaints about this before, and it thoroughly deserves its bad reputation.&lt;/p&gt;

&lt;p id=&quot;p-4&quot;&gt;Here's one example: &lt;code&gt;retrlines&lt;/code&gt; is the method used to retrieve ascii text from the server. Bizzarely, it doesn't actually return the text receieved; instead, it expects you to provide it with a callback function that will be fed each line in turn, minus the newline. Sounds like a job for &lt;a href=&quot;http://www.python.org/doc/current/lib/module-StringIO.html&quot;&gt;StringIO&lt;/a&gt;, but &lt;code&gt;StringIO&lt;/code&gt; objects don'y have a writeline method (required to add the newline back on). I ended up writing my own extension of the &lt;code&gt;StringIO2&lt;/code&gt; class and adding a writeline method just to preserve the newlines returned from the server!&lt;/p&gt;

&lt;p id=&quot;p-5&quot;&gt;Strange &lt;acronym title=&quot;Application Programming Interface&quot;&gt;API&lt;/acronym&gt;s aside, I'm pretty pleased with the final result. It follows a bunch of Unix design patterns (and skips others such as those related to configuration, but I'm not overly bothered about those) including the following:&lt;/p&gt;

&lt;ol&gt;
 &lt;li&gt;A usage note is displayed if no arguments are provided.&lt;/li&gt;
 &lt;li&gt;Multiple domains can be blacklisted at once, by providing them as multiple command line arguments.&lt;/li&gt;
 &lt;li&gt;Domains that are already in the blacklist are skipped, and a message is written to standard error.&lt;/li&gt;
 &lt;li&gt;If the script suceeds, it doesn't say anything at all.&lt;/li&gt;
&lt;/ol&gt;

&lt;p id=&quot;p-6&quot;&gt;It also uses the common Python idiom of wrapping the principle logic in a function and then calling that from a block that runs only if the file is executed directly (the &lt;a href=&quot;http://www.artima.com/weblogs/viewpost.jsp?thread=4829&quot; title=&quot;Guido van Rossum: Python main() functions&quot;&gt;&lt;code&gt;__name__ == '__main__'&lt;/code&gt; idiom&lt;/a&gt;) so that other Python code can import the module and reuse its functionality if required.&lt;/p&gt;

&lt;p id=&quot;p-7&quot;&gt;There's plenty of room for improvement: being able to pipe a list of domains in via standard input would be nice, and hard coding the (unencrypted) username and password is sloppy (as is expecting the blacklist.txt file to live in the &lt;acronym title=&quot;File Transfer Protocol&quot;&gt;FTP&lt;/acronym&gt; home directory). Even better, with &lt;acronym title=&quot;Secure SHell&quot;&gt;SSH&lt;/acronym&gt; access the whole thing could be replaced with an infinitely more secure one-liner: &lt;code class=&quot;bash&quot;&gt;echo www.domain-to-ban.org | ssh username@server &quot;cat - &gt;&gt; blacklist.txt&quot;&lt;/code&gt;. I'm happy though: an irritating task has become much less irritating and I have some example code to fall back on next time I need to get mucky with &lt;code&gt;ftplib&lt;/code&gt;.&lt;/p&gt;</description>
  <link>http://simon.incutio.com/archive/2004/09/09/commandline</link>
  <dc:subject>Python, Systems Administration</dc:subject>
  <dc:date>2004-09-09T05:59:46-00:00</dc:date>
  <dc:creator>Simon Willison</dc:creator>
</item>
<item rdf:about="http://simon.incutio.com/archive/2004/07/15/instant">
  <title>Instant authentication against an existing web application</title>
  <description>&lt;p id=&quot;p-0&quot;&gt;I was thinking today about the problem of querying an existing authentication database from a new application - exactly the kind of thing web services are useful for. Then I realised that any web application protected by &lt;acronym title=&quot;HyperText Transfer Protocol&quot;&gt;HTTP&lt;/acronym&gt; Basic authentication already provides a standard &lt;acronym title=&quot;Application Programming Interface&quot;&gt;API&lt;/acronym&gt; against which queries can be run. Here's the Python code to do exactly that:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;
def auth_against_url(url, username, password):
    import urllib2, base64
    request = urllib2.Request(url)
    b64 = base64.encodestring('%s:%s' % (username, password))[:-1]
    request.add_header('Authorization', 'Basic %s' % b64)
    try:
        urllib2.urlopen(request)
    except urllib2.HTTPError:
        return False
    return True
&lt;/code&gt;&lt;/pre&gt;

&lt;p id=&quot;p-1&quot;&gt;To check a username and password against an existing application's user database, just call the above function with the &lt;acronym title=&quot;Universal Republic of Love&quot;&gt;URL&lt;/acronym&gt; of a page within the existing application as the first argument. The function returns True if the username and password are valid, and False otherwise. It doesn't get much simpler than that.&lt;/p&gt;

&lt;p id=&quot;p-2&quot;&gt;A nice side effect of using Python's standard library modules is that they transparently support HTTPS, so authentication can take place over an encrypted channel provided the target application supports it.&lt;/p&gt;</description>
  <link>http://simon.incutio.com/archive/2004/07/15/instant</link>
  <dc:subject>Python</dc:subject>
  <dc:date>2004-07-15T00:12:14-00:00</dc:date>
  <dc:creator>Simon Willison</dc:creator>
</item>
<item rdf:about="http://simon.incutio.com/archive/2004/07/01/compileall">
  <title>Compile everything with a one-liner</title>
  <description>&lt;p&gt;The other day, we noticed that the .py files in our main mod_python application at work did not have corresponding compiled .pyc files. mod_python runs as the unprivileged apache user, which on our server doesn't have the required permissions to write the compiled .pyc files in to the directories in which our code lives.&lt;/p&gt;

&lt;p&gt;A bit of digging came up with the &lt;a href=&quot;http://www.python.org/doc/current/lib/module-compileall.html&quot;&gt;compileall&lt;/a&gt; module, which provides functions for byte-compiling Python files in bulk. We invoked it using the following shell one-liner, executed at the upper most directory of our code tree:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;python2.3 -c &quot;import compileall; compileall.compile_dir('.')&quot;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Executed as root, the result was a full set of .pyc bytecode files.&lt;/p&gt;</description>
  <link>http://simon.incutio.com/archive/2004/07/01/compileall</link>
  <dc:subject>Python</dc:subject>
  <dc:date>2004-07-01T17:59:39-00:00</dc:date>
  <dc:creator>Simon Willison</dc:creator>
</item>
<item rdf:about="http://simon.incutio.com/archive/2004/06/09/backporting">
  <title>Backporting from Python 2.3 to Python 2.2</title>
  <description>&lt;p id=&quot;p-0&quot;&gt;We have a home-grown templating system at work, which I intend to dedicate an entry to some time in the future. We originally wrote it in Python 2.2, but upgraded to Python 2.3 a while ago and have since been evolving our code in that environment. Today I found a need to load the most recent version of our templating system on to a small, long neglected application that had been running the original version ever since it had enough features to be usable.&lt;/p&gt;

&lt;p id=&quot;p-1&quot;&gt;Unfortunately, this application was running on a server that only had Python 2.2. Installing Python 2.3 would have been somewhat more painful here than on other servers we run for reasons I won't go in to, so I decided to have a go at getting our current code to run under the older Python version.&lt;/p&gt;

&lt;p id=&quot;p-2&quot;&gt;In the end, I only had to make three minor changes, all at the top of the file in question.&lt;/p&gt;

&lt;ol&gt;
 &lt;li&gt;&lt;p id=&quot;p-3&quot;&gt;I added &lt;code class=&quot;python&quot;&gt;from __future__ import generators&lt;/code&gt; as the very first line of the file. We use generators (with the &lt;code class=&quot;python&quot;&gt;yield&lt;/code&gt; statement) in a few places - this feature was only properly added in Python 2.3, but was made available in Python 2.2 as a &quot;future enhancement&quot; through the aforementioned obscure import.&lt;/p&gt;&lt;/li&gt;
 &lt;li&gt;&lt;p id=&quot;p-4&quot;&gt;I added &lt;code class=&quot;python&quot;&gt;True, False = 1, 0&lt;/code&gt; on the next line down. Surprisingly, Python 2.2 had no support for a boolean type and instead used a test for non-zero. The above line defines constants that behave enough like Python 2.3's True and False to avoid any problems.&lt;/p&gt;&lt;/li&gt;
 &lt;li&gt;&lt;p id=&quot;p-5&quot;&gt;I defined an &lt;code class=&quot;python&quot;&gt;enumerate&lt;/code&gt; function, which was introduced for real in Python 2.3. Here's the code I used:&lt;/p&gt;
 &lt;pre&gt;&lt;code class=&quot;python&quot;&gt;
def enumerate(obj):
    for i, item in zip(range(len(obj)), obj):
        yield i, item 
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p id=&quot;p-6&quot;&gt;All in all it only took around ten minutes to put the above together, after which the script worked just fine. It was interesting to see how our code had grown to rely on Python 2.3 features without us realising it.&lt;/p&gt;

&lt;p id=&quot;p-7&quot;&gt;&lt;strong&gt;Update:&lt;/strong&gt; Check this entry's comments for improvements to the above code snippets.&lt;/p&gt;</description>
  <link>http://simon.incutio.com/archive/2004/06/09/backporting</link>
  <dc:subject>Python, Systems Administration</dc:subject>
  <dc:date>2004-06-09T04:58:22-00:00</dc:date>
  <dc:creator>Simon Willison</dc:creator>
</item>
<item rdf:about="http://simon.incutio.com/archive/2004/05/07/switch">
  <title>Switch statements in Python</title>
  <description>&lt;p&gt;Python doesn't support a native switch statement. I've found myself using the following coding idiom instead recently which seems to work pretty well:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;{'option1': function1,
 'option2': function2,
 'option3': function3,
 'option4': function4}[value]()&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This works with lambdas as well, for inline calculations. Here's a switch statement that assigns to a variable in &lt;acronym title=&quot;PHP: Hypertext Preprocessor&quot;&gt;PHP&lt;/acronym&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;php&quot;&gt;switch ($value) {
    case 'a':
        $result = $x * 5;
        break;
    case 'b':
        $result = $x + 7;
        break;
    case 'c':
        $result = $x - 2;
        break;
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And here's the equivalent code in Python:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;result = {
  'a': lambda x: x * 5,
  'b': lambda x: x + 7,
  'c': lambda x: x - 2
}[value](x)&lt;/code&gt;&lt;/pre&gt;</description>
  <link>http://simon.incutio.com/archive/2004/05/07/switch</link>
  <dc:subject>Python</dc:subject>
  <dc:date>2004-05-07T02:43:14-00:00</dc:date>
  <dc:creator>Simon Willison</dc:creator>
</item>

</rdf:RDF>