<?xml version="1.0"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">

<channel>
	<title>Planet Turbogears</title>
	<link>http://planet.turbogears.org/</link>
	<language>en</language>
	<description>Planet Turbogears - http://planet.turbogears.org/</description>

<item>
	<title>Compound Thinking: TurboGears 2.0.1 now available on pypi</title>
	<guid>http://compoundthinking.com/blog/?p=672</guid>
	<link>http://compoundthinking.com/blog/index.php/2009/06/22/turbogears-201-now-available-on-pypi/</link>
	<description>&lt;p&gt;Since the beginning (nearly) of TurboGears 2.x development we use a &lt;a title=&quot;TurboGears 2 private index&quot; href=&quot;http://www.turbogears.org/2.0/downloads/2.0.1/&quot; target=&quot;_blank&quot;&gt;private index&lt;/a&gt; to store all our dependencies and &lt;a title=&quot;Install docs&quot; href=&quot;http://www.turbogears.org/2.0/docs/main/DownloadInstall.html#install-turbogears-2&quot; target=&quot;_blank&quot;&gt;point people to it for installation&lt;/a&gt;. This was nice because it helped us control our dependency tree and make sure installation of our unstable software was as easy as possible.&lt;/p&gt;
&lt;p&gt;Since we had released a stable 2.0 version, followed by a 2.0.1 bugfix, we really were lacking a real pypi install mechanism. This is now a thing of the past! You can install a full blown TurboGears2 environment in one simple command:&lt;/p&gt;
&lt;p&gt;easy_install tg.devtools&lt;/p&gt;
&lt;p&gt;and this will fetch everything using normal lookups from the pypi. I hope this will help people out there.&lt;/p&gt;
&lt;p&gt;At the same time I&amp;#8217;d like to ask for help in that domain: If you are using TurboGears2 and find out that some dependency that needs compilation is not found in a compiled state (either on &lt;a title=&quot;PYthon Package Index&quot; href=&quot;http://pypi.python.org/pypi&quot; target=&quot;_blank&quot;&gt;pypi&lt;/a&gt; or on &lt;a title=&quot;TurboGears 2.0.1 index page&quot; href=&quot;http://www.turbogears.org/2.0/downloads/2.0.1/&quot; target=&quot;_blank&quot;&gt;our index&lt;/a&gt;), please help us:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;By sending a compiled version of the egg to me (florent aide, you&amp;#8217;ll find me on the mailing list easily)&lt;/li&gt;
&lt;li&gt;By pointing us the missing dependency (send a mail in the &lt;a title=&quot;TurboGears Mailing List&quot; href=&quot;http://groups.google.com/group/turbogears&quot; target=&quot;_blank&quot;&gt;turbogears&lt;/a&gt; or &lt;a title=&quot;TurboGears-Trunk Mailing List&quot; href=&quot;http://groups.google.com/group/turbogears-trunk&quot; target=&quot;_blank&quot;&gt;turbogears-trunk&lt;/a&gt; mailing list)&lt;/li&gt;
&lt;li&gt;Or even better: try to become a maintainer for the specific dependency, that you know will always be missing for your architecture, and let us know about that great news. The whole open source community will become better, your karma (the real one, not the one you can admire on &lt;a title=&quot;My false Karma&quot; href=&quot;http://www.ohloh.net/accounts/faide&quot; target=&quot;_blank&quot;&gt;ohloh&lt;/a&gt;) will bump-up and you&amp;#8217;ll be forever remembered on &lt;a title=&quot;not!&quot; href=&quot;http://starwars.com/databank/location/endor/index.html&quot; target=&quot;_blank&quot;&gt;endor&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Now this leaves us with one more thing to do: finish &lt;a title=&quot;Next TG website powered by TG&quot; href=&quot;http://beta.turbogears.org/&quot; target=&quot;_blank&quot;&gt;the web site for turbogears that is currently in a poor state&lt;/a&gt;. If you would like to help us on the &lt;a title=&quot;TurboGears website engine&quot; href=&quot;http://bitbucket.org/faide/turbogearsorg/overview/&quot; target=&quot;_blank&quot;&gt;engine&lt;/a&gt;, please let us know in the mailing lists or via private message. If you want to help-out with content, please let us know also and we&amp;#8217;ll be more than glad to give you an editor account and some directions to get some content online in this new website.&lt;/p&gt;
&lt;p&gt;Cheers all,&lt;/p&gt;
&lt;p&gt;Florent.&lt;/p&gt;</description>
	<pubDate>Mon, 22 Jun 2009 20:21:32 +0000</pubDate>
</item>
<item>
	<title>Compound Thinking: TurboGears 2.0 presentation video</title>
	<guid>http://compoundthinking.com/blog/?p=668</guid>
	<link>http://compoundthinking.com/blog/index.php/2009/06/15/turbogears-20-presentation-video/</link>
	<description>&lt;p&gt;In the last post I said we presented TurboGears 2.0 at the Pycon FR event. We have received the &lt;a title=&quot;TurboGears 2.0 presentation - French&quot; href=&quot;http://video.pycon.fr/videos/free/63/&quot; target=&quot;_blank&quot;&gt;video feeds&lt;/a&gt; from the organization. This is a French presentation, sorry for the non-french speakers.&lt;/p&gt;
&lt;p&gt;As a reminder the code of application we presented is &lt;a title=&quot;TGdo - TurboGears 2.0 demo application&quot; href=&quot;http://bitbucket.org/zaf/tgdo/&quot; target=&quot;_blank&quot;&gt;available on bitbucket&lt;/a&gt;.&lt;/p&gt;</description>
	<pubDate>Mon, 15 Jun 2009 08:29:50 +0000</pubDate>
</item>
<item>
	<title>Compound Thinking: TurboGears 1.x to Turbogears 2.0</title>
	<guid>http://compoundthinking.com/blog/?p=651</guid>
	<link>http://compoundthinking.com/blog/index.php/2009/06/12/turbogears-1x-to-turbogears-20/</link>
	<description>&lt;p&gt;Two weeks ago we (&lt;a href=&quot;http://www.linkedin.com/pub/jonathan-schemoul/2/603/b92&quot; target=&quot;_blank&quot;&gt;Jonathan Schemoul&lt;/a&gt;, &lt;a href=&quot;http://www.linkedin.com/pub/thomas-zaffran/5/377/951&quot; target=&quot;_blank&quot;&gt;Thomas Zaffran&lt;/a&gt; and &lt;a href=&quot;http://www.linkedin.com/in/florentaide&quot; target=&quot;_blank&quot;&gt;me&lt;/a&gt;) animated a &lt;a title=&quot;French: PyconFR 2009 - TurboGears 2.0 Presentation&quot; href=&quot;http://compoundthinking.com/blog/wp-content/uploads/2009/06/pycon-tg.pdf&quot;&gt;TurboGears 2.0 presentation (in french)&lt;/a&gt; and workshop at &lt;a title=&quot;Pycon FR 2009&quot; href=&quot;http://fr.pycon.org/&quot; target=&quot;_blank&quot;&gt;PyconFR&lt;/a&gt; 2009. PyconFR is an annual French Python event organized  by the &lt;a href=&quot;http://www.afpy.org&quot; target=&quot;_blank&quot;&gt;AFPY&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The presention was separated in two phases. The first part covered an history of the project and a technical overview. The second part was a live coding session during which we created a &lt;a title=&quot;TODO list in TurboGears 2.0 - repository&quot; href=&quot;http://bitbucket.org/zaf/tgdo/&quot; target=&quot;_blank&quot;&gt;small todolist application&lt;/a&gt; to show-off the new TurboGears 2.0 features.&lt;/p&gt;
&lt;p&gt;&lt;img class=&quot;alignnone&quot; src=&quot;http://compoundthinking.com/blog/wp-content/uploads/2009/06/tgjon1.jpg&quot; alt=&quot;Jon is hacking on turbogears 2&quot; width=&quot;490&quot; height=&quot;304&quot; /&gt;&lt;/p&gt;
&lt;p&gt;At the end of this presentation, one of the attendees came to us and gave us a nice remark that I would like to share with you here: &amp;#8220;I did not remark any changes in TG2 since my TG1 days, did you change something?&amp;#8221;&lt;/p&gt;
&lt;p&gt;This was a pleasant surprise to me. This means one thing: we changed the whole underlying layers, rewrote authentication and authorization, switched tgwidgets with ToscaWidgets, based our Framework on Pylons instead of CherryPy &amp;#8212; and yet this person, looking at the controller&amp;#8217;s code of our todolist application felt &amp;#8220;at home like if it was a TurboGears 1.0 application&amp;#8221;.&lt;/p&gt;
&lt;p&gt;As we already stated, we want to ease-out the tg1&amp;#8211;&amp;gt;tg2 transitions as much as possible. We know there is some room for improvement in that quarter! But since we (core devs) have live and running tg1 applications out there the itch is already there and we&amp;#8217;ll make sure to scratch it.&lt;/p&gt;
&lt;p&gt;As an example, &lt;a title=&quot;Paris Envies&quot; href=&quot;http://www.parisenvies.com/&quot; target=&quot;_blank&quot;&gt;Paris Envies&lt;/a&gt; is a TurboGears 1.1 application, coming from an 1.0 background, using Genshi, SQLObject and TGWidgets. And I know for sure that Jon has a real incentive to move to TG2 and get SO support for it :)&lt;/p&gt;
&lt;p&gt;Stay tuned people, TurboGears is live and well!&lt;/p&gt;</description>
	<pubDate>Fri, 12 Jun 2009 10:50:56 +0000</pubDate>
</item>
<item>
	<title>Christopher Perkins: Sprox 0.6.1 released</title>
	<guid>http://percious.com/blog/archives/29</guid>
	<link>http://percious.com/blog/archives/29</link>
	<description>&lt;p&gt;Well, it&amp;#8217;s been longer than I wanted since the last release.  (almost 4 months)  I was holding out because I wanted to get a few more features working, but I realized this week that there was a lot of new functionality, and so it was time to cut a new release.  It turns out, the codebase grew by almost 20% with this release.  I see this as a very stable release because I use almost every new feature at my day job.  Here&amp;#8217;s a rundown on what is new.&lt;/p&gt;
&lt;p&gt;* TableFiller can provide field_methods for customization of output.&lt;br /&gt;
* You can now customize the query TableFiller uses.&lt;br /&gt;
* TableBase now has __xml_field__ modifier that un-escapes the data provided by the given list of fields.&lt;br /&gt;
* There is a new tutorial for TableFiller: http://www.sprox.org/tutorials/table.html .&lt;br /&gt;
* Sqashed #8: Synonym Properties causing Tracebacks.&lt;br /&gt;
* Added Mako Templates for every sprox widget. (SPEED!)&lt;br /&gt;
* Fixed the way relation form fields render.&lt;br /&gt;
* Brandon Rhodes provided a fix for TableBase that allows fields to render with any Widget type.&lt;br /&gt;
* Teajay Bernard provided *experimental* support for Editable Dojo Grid.&lt;br /&gt;
* Test framework fixed to be more forgiving of XML.&lt;br /&gt;
* Declarative Validation overrides now work properly.&lt;br /&gt;
* Field Class added so that you may override both the Widget _and_ a Validator for a field (documentation pending).&lt;/p&gt;
&lt;p&gt;Special thanks to Brandon Rhodes and Teajay Bernard for their contributions.&lt;/p&gt;
&lt;p&gt;You can get sprox from pypi at: http://pypi.python.org/packages/source/s/sprox/sprox-0.6.1.tar.gz&lt;/p&gt;</description>
	<pubDate>Fri, 05 Jun 2009 19:28:21 +0000</pubDate>
</item>
<item>
	<title>Jorge Vargas: “Everything” and Wave</title>
	<guid>http://www.maetico.com/everything-and-wave/</guid>
	<link>http://www.maetico.com/everything-and-wave/</link>
	<description>&lt;p&gt;Outline: I talk a little about what is wave, then what I think of wave and last about &amp;#8220;everything&amp;#8221; which was my idea/prototype of what it should be.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;So What is wave?&lt;/strong&gt;&lt;/em&gt;&lt;br /&gt;
Apparently most of the people on the &amp;#8220;blogosphere&amp;#8221; have no clue. And currently the best source (other than &lt;a href=&quot;http://wave.google.com/&quot; target=&quot;_blank&quot;&gt;the video&lt;/a&gt;, go watch that first) is at the 2 google groups. I&amp;#8217;ll start with a brief explanation. Wave is actually 3 totally separate things.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;A communication protocol&lt;/li&gt;
&lt;li&gt;A very efficient client&lt;/li&gt;
&lt;li&gt;A set of extensions to that client.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;What most people miss is that wave is a protocol (apparently a set of extensions to XMPP), now be careful! this protocol is ONLY for server-server communications, which means this is how waves travel across the interwebs and has nothing to do with posting to the wave or reading them. The real advantage of this is that synchronization happens at a very fast level which means thin clients, With something they call &amp;#8220;operational transformation&amp;#8221; as this guy explains in &lt;a href=&quot;http://www.youtube.com/watch?v=3ykZYKCK7AM&quot; target=&quot;_blank&quot;&gt;this video&lt;/a&gt;. And the other really interesting thing is that it enables private servers with private waves, without creating walls.&lt;/p&gt;
&lt;p&gt;Then we have the client which is what everyone is drooling about, which is simply a realllly cool editor and collector. It is build with GWT and apparently comet. This seems to implement the realtime typing, search, the playback and drag &amp;amp; drop goodness we saw. It is a remarkable webapp and I can&amp;#8217;t wait for them to release it.&lt;/p&gt;
&lt;p&gt;The third component which is the most interesting part for me to play with. Is actually 3 different things Robots, Embed, and Gadgets.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;em&gt;gadgets&lt;/em&gt; are nothing new, we all know how you can add a youtube video in a site that is not youtube and do stuff with it, same with a google map, etc. The only innovation here is that the gadget can access the data from the wave.&lt;/li&gt;
&lt;li&gt;The &lt;em&gt;Embed&lt;/em&gt; api is pretty much a &amp;#8220;viral tool&amp;#8221;, the goal is to take waves to non-wave environments. Which gets you several bridges to pretty much everything out there. I call this viral because it is what is going to make this a huge thing. After someone sees that my &amp;#8220;blog&amp;#8217;s comments&amp;#8221; are in this super cool system, they will track that system and say ohhhh wave is cool!&lt;/li&gt;
&lt;li&gt;The part I&amp;#8217;m most exited about is the &lt;em&gt;robots&lt;/em&gt;, simply because they are first class citizens. And that means that anyone with a little knowledge of how the system works is going to be able to create automatization, and this is so powerful that it is scary. In the good uses of this I can see (and will write) 100s of really useful tools. Just think about it for a second, the robot will know everything the people will know about the wave. Now the scary part is when someone takes this freedom and applies it to evil.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That pretty much covers it, how is this different from anything else out there. It&amp;#8217;s goal is to unify not subdivide the fact that they are releasing the protocol means you will be able to run your own wave server, which means private really private waves. This is totally useless for &amp;#8220;where are we going to eat?&amp;#8221; but it&amp;#8217;s very important for &amp;#8220;We are broke and only have 3 million dollars left on the bank account, what shall we do?&amp;#8221;. The other really cool thing is that they are going to open source everything (let&amp;#8217;s hope that&amp;#8217;s true) which means the client will solve the &amp;#8220;how to build a real time system&amp;#8221; problem, and developers can focus on their tools.&lt;/p&gt;
&lt;p&gt;But this is not a me-too post. In fact someone recommended me not to post this but I have to. I have been thinking of a system like this for a long time, seriously I have chatlogs, trac tickets, svn repositories (yes that long!), a prototype on appengine, another in mercurial and another as a TG2 app with first had a zodb backend and recently a mongodb. I also have some work on the frontend but I wasn&amp;#8217;t thinking real time. So all in all it has to be at least 5 years of working around this idea. This is also on the planned roadmap for &amp;#8220;codemill&amp;#8221; and &amp;#8220;DVDev&amp;#8221; (a totally different post). And my last prototype of this idea is named &amp;#8220;everything&amp;#8221;, hence the title of this post. I though it was a little cocky at first but I think I was right, wave is indeed about everything.&lt;/p&gt;
&lt;p&gt;Of course as the famous quote &amp;#8220;There is someone smarter than you outside of your organization&amp;#8221;, I have not been able to lift off my idea as I&amp;#8217;m pretty much a one man team with no resources, and I&amp;#8217;m not smarter than the wave team. Which means I&amp;#8217;m going to be an early adopter here and build &amp;#8220;everything&amp;#8221; on top of wave.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Analysis of Wave &lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What they got really right.&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Robots as first class citizens
&lt;ul&gt;
&lt;li&gt;This means they realize the potential behind having computer helpers on your day to day tasks. With the correct set of bots you should be able to enhance your writing to scary levels of enlightenment.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;One instance of the wave
&lt;ul&gt;
&lt;li&gt;I think this the most important part of the system (but I put robots first because I&amp;#8217;m so exited about them!), the web today is too fragmented, just as an example try to search for the first public non-official announcement of wave. This is practically impossible because the web is a huge copy&amp;amp;paste fiasco. The wave format is something to unify all the systems under the same data structure but it keeps them all independent.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Server-Server replication
&lt;ul&gt;
&lt;li&gt;The beauty of this is that all the wave servers take care of the heavy lifting which means the clients are very simple (in coding). This is probably going to be a key feature for the adoption of the system. Most existing clients (mail,IM,GUIs,webpages) and forms of presenting the data (websites,phones,native clients,etc) simply need to learn how to read and write from the wave format.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Plugable as hell
&lt;ul&gt;
&lt;li&gt;you can write your own client, your own bits (gadgets), your own functions (robots) and your own server&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;one data structure to rule them all
&lt;ul&gt;
&lt;li&gt;IF wave-protocol gets to be the success I hope it will be, this is probably as big as XML. Before XML each system/company/app/team used their own little format for moving data across applications (most binary, but a lot text). So back then you will have to code something to talk to each one of the applications you wanted to talk to. Why XML was so big? It lifted the barriers on the data. How wave-protocol is like XML, it&amp;#8217;s going to lift barriers on the data.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;It&amp;#8217;s a messaging system
&lt;ul&gt;
&lt;li&gt;Which coincidentally is how people communicate. All the old messaging system share one fundamental flaw they are synchronous you can measure when a message starts and when it ends. In wave the message is one character long which is as close to speaking as we can get, in fact it&amp;#8217;s better because it&amp;#8217;s not noisy &lt;img src=&quot;http://www.maetico.com/wp-includes/images/smilies/icon_smile.gif&quot; alt=&quot;:)&quot; class=&quot;wp-smiley&quot; /&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;A solution to the &amp;#8220;where&amp;#8221;
&lt;ul&gt;
&lt;li&gt;today you need to answer where shall we discuss this, should I call you, email, write to the mailing list, IM, twitter, bah! wave&amp;#8217;s answers: &amp;#8220;everywhere&amp;#8221;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;What they got almost right&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;XML, to be honest they have a very good and clean xml file. But why not json or even yaml? Although &lt;a href=&quot;http://metajack.im/2009/03/09/xmpp-complexity-versus-sophistication/&quot; target=&quot;_blank&quot;&gt;this post is enlightening&lt;/a&gt;.  I honestly think they didn&amp;#8217;t choose XML, XMPP did that for them. Maybe json is a better storage and transfer system but they will probably make them have to sit and re-write XMPP and I&amp;#8217;ll be writting this post in 2012 or later.&lt;/li&gt;
&lt;li&gt;One true editor, I&amp;#8217;m not sold to the idea of having one editor. I really think we&amp;#8217;ll need several specialized editors for the different content we&amp;#8217;ll like to create on waves.&lt;/li&gt;
&lt;li&gt;Appengine only bots. I assume this is either because of
&lt;ul&gt;
&lt;li&gt;a) to be able to kill an offensive bot&lt;/li&gt;
&lt;li&gt;b) to protect wave with the sandbox (you can&amp;#8217;t compile a worn on appengine)&lt;/li&gt;
&lt;li&gt;c) to give appengine popularity.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In any case I hope this is lifted at some point, or I&amp;#8217;ll just use a comunity server &lt;img src=&quot;http://www.maetico.com/wp-includes/images/smilies/icon_smile.gif&quot; alt=&quot;:)&quot; class=&quot;wp-smiley&quot; /&gt; &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;The biggest challenges&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;spam&lt;/em&gt;: I think this is the most important aspect of the system. will it die like usenet? could the protocol be spam-proof? how can you prevent spam without coercing the users?&lt;/li&gt;
&lt;li&gt;&lt;em&gt;robots&lt;/em&gt;: leaving spammy out. Where is the line between helper robots and annoying robots, how can you trust a robot? how will you identify the evil robots?&lt;/li&gt;
&lt;li&gt;&lt;em&gt;uncooperative behavior&lt;/em&gt;: this is similar to the robots problem, and in fact it&amp;#8217;s tied to it. How do you deal with people that where added to the wave and are against it&amp;#8217;s usefulness.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;authorization&lt;/em&gt;: Who should be allowed to edit the wave? some waves need to have ACL, should this be at the protocol level?&lt;/li&gt;
&lt;li&gt;&lt;em&gt;some readonly parts&lt;/em&gt;: how and who should declare what is &amp;#8220;set in stone&amp;#8221;?&lt;/li&gt;
&lt;li&gt;&lt;em&gt;massive forking/endless hours finding the important waves&lt;/em&gt;: if we give too much power to the owner of the wave then we risk fragmenting the conversation and having 100s of &amp;#8220;missed update&amp;#8221; where you could be useful. If we give too little power caos will take over.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;ownership&lt;/em&gt;: who owns the content? who owns the wave? up to which point my original wave is really mine?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;The future of &amp;#8220;Everything&amp;#8221;&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;So as I said above I am/was writing &amp;#8220;everything&amp;#8221;. And I think it is still a viable project. I&amp;#8217;m just going to retarget it to be wave-compliant.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;how is &amp;#8220;everything&amp;#8221; different from wave?&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;specialized editors&lt;/em&gt;: I am really thinking of having editors for each type of data. For example a ticket editor, code review editor or the more traditional rest,html,plain editors. Since this is pure javascript I&amp;#8217;ll probably retrofit them to be gadgets ones the client is release, or they could evolved into their own client.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Per server robots&lt;/em&gt;: To be honest I&amp;#8217;m a bit scared about the robots in the wave, I think the wave team went too far with robots and I&amp;#8217;m really interested in knowing how they plan to keep them at bay. In my idea the robots where local and I was thinking of them as helpers rather than contributors, in wave terms my robots where limited to the blip, and I think this is a good idea for your own set of minions you don&amp;#8217;t want other people to use. I&amp;#8217;m going to push this idea forward and I&amp;#8217;ll code them in wave terms so they are compatible and most likely useable as google&amp;#8217;s wave-client bots. From the source it seems you can build a standalone robot server with what they released.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;publishing system&lt;/em&gt;. I originally though of &amp;#8220;everything&amp;#8221; as a publishing system. But in the form of editorial reviews rather than wiki-style. My idea was to have one true editor to a website with the means for a proper feedback. And I&amp;#8217;ll push this to happen on the wave. I really think we need a two tier system for some waves, where you have a set of authors and a massive set of feedback. In the simplest way this will be used to write a blog. In a more complex case it will be a mailing list to discuss a project/product/idea. In a even more complex case it will serve to write a paper or a book. And in the most complex case it will serve to record your live and thoughts.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So that&amp;#8217;s about it. Sorry for the huge ass wave but I think this is a topic that deserves a lot of thought I&amp;#8217;ll leave you with what I think is the &lt;a href=&quot;http://groups.google.com/group/wave-protocol/browse_thread/thread/fe626de702762ecb&quot;&gt;most inspiring message&lt;/a&gt; currently at any of the google groups regarding wave.&lt;/p&gt;</description>
	<pubDate>Mon, 01 Jun 2009 02:58:02 +0000</pubDate>
</item>
<item>
	<title>Compound Thinking</title>
	<guid>http://compoundthinking.com/blog/?p=639</guid>
	<link>http://compoundthinking.com/blog/index.php/2009/05/27/639/</link>
	<description>&lt;p&gt;The long wait is finally over!&lt;/p&gt;
&lt;p&gt;I am happy to announce the release of TurboGears 2.0 final. This release is the product of a lot of work by the whole TurboGears team, and we&amp;#8217;re very happy to have a final stable release. TurboGears 2.0 final includes all kinds of goodies for those making web applications, from one of the most powerful and flexible Object Relational Mappers available in any language, to a powerful and flexible template system. But just as important as the quality of the parts, is the out-of-the-box integration to help get you started quickly:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;We have quickstart template that helps get you going quickly with everything you need: from sample templates, to sample controllers and tests.&lt;/li&gt;
&lt;li&gt;We have an extensible user/groups/permission system that you can easily configure into your app when quickstarting a project.&lt;/li&gt;
&lt;li&gt;We have zero config needed support for development database backed by SQLite.&lt;/li&gt;
&lt;li&gt;We have a working admin system for editing your database while your app is in development.&lt;/li&gt;
&lt;li&gt;Our admin system is extensible and reusable as a component of your application.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There&amp;#8217;s lots more. But equally important, we don&amp;#8217;t think that out of the box defaults should be constraints on our users. So, a trivial configuration change lets you use DB2, or Oracle, or SQLServer, and everything we&amp;#8217;ve wired up for you is easy enough to customize or replace. For example, we support configs for three major python template engines out of the box, and you can easily make your own render function to handle anything else you want.&lt;/p&gt;
&lt;p&gt;One of the goals of TurboGears 2 is to use standard python components, that are valuable in all kinds of other contexts, so you are not tied into one monolythic system. Learning SQLAlchemy can help you write command line tools, GUI apps, web-services that don&amp;#8217;t use a framework; Genshi is valuable when generating all kinds of xml data for interchange between systems; the beaker is a great caching system that&amp;#8217;s valuable in all kind of web contexts, etc.&lt;/p&gt;
&lt;p&gt;TurboGears 2 final is just now comming out, but it&amp;#8217;s already in production use at places like ShootQ, RedHat? (for a large set of Fedora infrastructure projects) and many other places. And we&amp;#8217;re already looking forward to a few more high profile TG2 deployments in the next few weeks.&lt;/p&gt;</description>
	<pubDate>Wed, 27 May 2009 18:21:29 +0000</pubDate>
</item>
<item>
	<title>Jorge Vargas: TurboGears and the Google Summer of Code 09</title>
	<guid>http://www.maetico.com/turbogears-and-the-google-summer-of-code-09/</guid>
	<link>http://www.maetico.com/turbogears-and-the-google-summer-of-code-09/</link>
	<description>&lt;p&gt;The GSOC started officially yesterday. For those of you that don&amp;#8217;t know it it&amp;#8217;s a program from google to get university student involved in open source, google it for more info.&lt;/p&gt;
&lt;p&gt;TurboGears got accepted for 3 projects this year! You can read the proposals &lt;a href=&quot;http://socghop.appspot.com/org/home/google/gsoc2009/turbogears&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The first one (in points) is by a second time student with us. His name is Sanjiv and he is from India, in his last GSOC he created a bunch of ToscaWidgets for a big set of libraries, and since he was so good at it he started to work on &lt;a href=&quot;http://pypi.python.org/pypi/tgext.geo&quot; target=&quot;_blank&quot;&gt;tgext.geo&lt;/a&gt; which is an extension to TurboGears to provide geospatial libraries support. We liked that so much that he now has the full summer to get that going, and I&amp;#8217;m really looking forward for his work.&lt;/li&gt;
&lt;li&gt;Our second project is going to be developed by Jesse Howarth and it is something I have been expecting from quite some time. And it&amp;#8217;s actually two small projects and I love both of them. The first one (in order of appearance) is to finish up our last year GSOC project to provide a webUI for Builbot, for those that don&amp;#8217;t know it buildbot is a &amp;#8220;integration testing tool&amp;#8221; it will checkout, build, run tests, run your project and yell at you if you break the tip, together with a webUI to manage it, that rocks! The second is a very interesting tool for building online documentation based on sphinx, there is little to know about how it&amp;#8217;s going to work but it will be awesome if we could get something that will allow people to manage documentation just as if it where code with a web based review interface.&lt;/li&gt;
&lt;li&gt;And the third it&amp;#8217;s a problem I have been wanting to work on for quite some time. I won&amp;#8217;t lie to you. I wrote the idea and Alexandru Marinescu is going to step up and code it, and in the process we are going to leave a ton of very useful tgext to be used by the community. The project is currently split into 3 areas,
&lt;ol&gt;
&lt;li&gt;User management, we are building tgext.registration, tgext.profile and maybe tgext.oath and tgext.openid, those last two should probably be repoze.who plugins instead. The idea is that tgext.registration will provide everything that is needed so no one will ever need to write a registration module again &lt;img src=&quot;http://www.maetico.com/wp-includes/images/smilies/icon_smile.gif&quot; alt=&quot;:)&quot; class=&quot;wp-smiley&quot; /&gt; Profile on the other hand is a very nice tool to manage users it will provide a custom admin for &amp;#8216;administrators&amp;#8217; to manage their users, as well as password reset forms and more&lt;/li&gt;
&lt;li&gt;A complete web based frontend for mercurial, to view a repository. This is in spirit a rewrite of hgweb with the goals of making it more flexible and to provide some additional features&lt;/li&gt;
&lt;li&gt;And this is where the cool stuff starts, a web based repository management tool for mercurial. This part of the project is a bit fusy but it it&amp;#8217;s initial feature set is support for &amp;#8216;create repo&amp;#8217;, &amp;#8216;fork&amp;#8217; and &amp;#8216;pull request&amp;#8217;, after that it&amp;#8217;s open to adding as many features as people need.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I have great hopes for us students and I&amp;#8217;m looking forward for their work. If you want to follow you should join us on the mailing list &lt;a href=&quot;http://groups.google.com/group/turbogears-gsoc&quot; target=&quot;_blank&quot;&gt;turbogears-gsoc@googlegroups.com&lt;/a&gt; and check out the site we have put up for this &lt;a href=&quot;http://gsoc.turbogears.org/&quot;&gt;http://gsoc.turbogears.org/&lt;/a&gt;&lt;/p&gt;</description>
	<pubDate>Mon, 25 May 2009 03:02:26 +0000</pubDate>
</item>
<item>
	<title>Matthew Wilson: Need help with data files and setup.py</title>
	<guid>http://blog.tplus1.com/?p=337</guid>
	<link>http://blog.tplus1.com/index.php/2009/04/21/need-help-with-data-files-and-setuppy/</link>
	<description>&lt;p&gt;I&amp;#8217;m working on a package that includes some files that are meant to be copied and edited by people using the package.&lt;/p&gt;
&lt;p&gt;My project is named &amp;#8220;pitz&amp;#8221; and it is a bugtracker.  Instead of using a config file to set the options for a project, I want to use python files.&lt;/p&gt;
&lt;p&gt;When somebody installs pitz, I want to save some .py files somewhere so that when they run my pitz-setup script, I can go find those .py files and copy them into their working directory.&lt;/p&gt;
&lt;p&gt;I have two questions:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Do I need to write my setup.py file to specify that the .py files in particular directory need to be treated like data, not code?  For example, I don&amp;#8217;t want the installer to hide those files inside an egg.&lt;/li&gt;
&lt;li&gt;How can I find those .py files later and copy them?&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Here&amp;#8217;s my setup.py so far:&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;
from setuptools import setup, find_packages
version = &amp;#039;0.1&amp;#039;
setup(name=&amp;#039;pitz&amp;#039;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;version=version,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;description=&amp;quot;Python to-do tracker inspired by ditz (ditz.rubyforge.org)&amp;quot;,

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;long_description=&amp;quot;&amp;quot;&amp;quot;
ditz (http://ditz.rubyforge.org) is the best distributed ticketing
system that I know of.&amp;nbsp;&amp;nbsp;There&amp;#039;s a few things I want to change, so I
started pitz.&amp;quot;&amp;quot;&amp;quot;,

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;classifiers=[],
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;keywords=&amp;#039;ditz&amp;#039;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;author=&amp;#039;Matt Wilson&amp;#039;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;author_email=&amp;#039;matt@tplus1.com&amp;#039;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;url=&amp;#039;http://tplus1.com&amp;#039;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;license=&amp;#039;&amp;#039;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;packages=find_packages(exclude=[&amp;#039;ez_setup&amp;#039;, &amp;#039;examples&amp;#039;, &amp;#039;tests&amp;#039;]),

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;include_package_data=True,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;package_dir={&amp;#039;pitz&amp;#039;:&amp;#039;pitz&amp;#039;},

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;data_files=[(&amp;#039;share/pitz&amp;#039;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#039;pitz/pitztypes/agilepitz.py.sample&amp;#039;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#039;pitz/pitztypes/tracpitz.py.sample&amp;#039;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;])],

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;zip_safe=False,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;install_requires=[
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;# &amp;#039;PyYAML&amp;#039;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;# &amp;#039;sphinx&amp;#039;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;# &amp;#039;nose&amp;#039;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;# &amp;#039;jinja2&amp;#039;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;# -*- Extra requirements: -*-
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;],

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;# I know about the much fancier entry points, but I prefer this
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;# solution.&amp;nbsp;&amp;nbsp;Why does everything have to be zany?
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;scripts = [&amp;#039;scripts/pitz-shell&amp;#039;],

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;test_suite = &amp;#039;nose.collector&amp;#039;,
)
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;When I run python setup.py install, I do get those .sample files copied, but they get copied into a folder way inside of my pitz install:&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;
$ cd ~/virtualenvs/scratch/lib/
$ find -type f -name &amp;#039;*.sample&amp;#039;
./python2.6/site-packages/pitz-0.1dev-py2.6.egg/share/pitz/tracpitz.py.sample
./python2.6/site-packages/pitz-0.1dev-py2.6.egg/share/pitz/agilepitz.py.sample
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;I don&amp;#8217;t know how I can write a script to copy those tracpitz.py.sample files out.  Maybe I can ask pitz what its version is, and then build a tring and use os.path.join, but that doesn&amp;#8217;t look like any fun at all.&lt;/p&gt;
&lt;p&gt;So, what should I do instead?&lt;/p&gt;</description>
	<pubDate>Wed, 22 Apr 2009 03:00:28 +0000</pubDate>
</item>
<item>
	<title>Compound Thinking: Working at SourceForge</title>
	<guid>http://compoundthinking.com/blog/?p=621</guid>
	<link>http://compoundthinking.com/blog/index.php/2009/04/09/working-at-sourceforge/</link>
	<description>&lt;p&gt;I&amp;#8217;ve been at SourceForge for a couple of months now, it&amp;#8217;s been great, the work is surprisingly fun and rewarding.   There&amp;#8217;s a local office, and so I actually get to g and hang out with smart people whenever I want.  I can still work from home, but having someplace to go in to has been a refreshing change. &lt;/p&gt;
&lt;p&gt;I haven&amp;#8217;t gotten to know many people outside the engineering team in Dexter, but they are great guys. &lt;/p&gt;
&lt;p&gt;There&amp;#8217;s lots of good stuff happening here, support for bazar, mercurial, git, trac, and other options on SourceForge itself, improved feeds, and other API&amp;#8217;s for getting at SF data, etc.   But I&amp;#8217;m only peripherally  aware of all that at the moment because I was hired to work on &amp;#8220;totally new stuff&amp;#8221; which is written in Python. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What I&amp;#8217;m working on&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Our first new project is a site called &lt;a href=&quot;http://fossfor.us&quot;&gt;FossFor.Us&lt;/a&gt;, and it was the vision for this site, and the team that is working on this and other new stuff, that sold me on the coming to work for Sourceforge.     It&amp;#8217;s written in Django, and it&amp;#8217;s been my first really large Django project, and while the experience has been pretty positive, there have been a number of things that have renewed my commitment to TurboGears development &amp;#8212; but that&amp;#8217;s a blog post for another day.  &lt;/p&gt;
&lt;p&gt;The backstory to the FossFor.Us site is that open source project hosting providers (Sourceforge and it&amp;#8217;s recent competitors) have traditionally been pulled in two very different directions by  two very different sets of users: &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;developers of open source software&lt;/li&gt;
&lt;li&gt;and people who just want to&lt;em&gt;&lt;/em&gt;.&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;And that tension has held us back in the past, we have to serve everybody with the same portal, and it ends up not serving either community as well as it should.   But since developers are the most vocal users, it&amp;#8217;s been the second class of user that&amp;#8217;s been most neglected.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://fossfor.us&quot;&gt;&lt;img src=&quot;http://compoundthinking.com/blog/wp-content/uploads/2009/04/foss_blog_image.jpg&quot; alt=&quot;foss_blog_image&quot; title=&quot;foss_blog_image&quot; width=&quot;400&quot; height=&quot;229&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;These people are just looking to get things done, and don&amp;#8217;t care about the &amp;#8220;project&amp;#8221; part of open source software, they are, at least at first, only interested in the &amp;#8220;product.&amp;#8221;   In many ways the Free and Open Source Software community has not served these people well. &lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://fossfor.us&quot;&gt;Fossfor.us&lt;/a&gt; is in it&amp;#8217;s first incarnation an attempt to create a window on the free software world, that&amp;#8217;s just about finding and using software.   But in a larger sense it&amp;#8217;s an attempt to help us as a community to connect with potential users better. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;I think connecting FOSS geeks and users is  actually &lt;em&gt;important&lt;/em&gt;&lt;br /&gt;
&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s important because people aren&amp;#8217;t aware that there are free options, and are paying for software they can&amp;#8217;t afford.   There&amp;#8217;s a prototypical user (based on a real person) that we talk about a lot, who&amp;#8217;s a single mom, has an old laptop, and struggles week to week to pay her bills, but who bought Photoshop, because &amp;#8220;that&amp;#8217;s how you edit photos.&amp;#8221;    Her family could have used that money to more productive ends, but because she needed to edit photos, and didn&amp;#8217;t know about the free alternatives all those opportunities are just lost.    &lt;/p&gt;
&lt;p&gt;Of course the same thing is true of small business owners, who could use free software to reduce their &amp;#8220;overhead&amp;#8221; costs, and actually spend money on creating things people love.   Free software has the potential to lubricate the wheels of the economy, encourage entrepreneurial activity, and enrich people&amp;#8217;s lives.    &lt;/p&gt;
&lt;p&gt;All of this is to say I think &lt;a href=&quot;http://fossfor.us&quot;&gt;fossfor.us&lt;/a&gt; is a way to serve the world by making the product of all the open source developer&amp;#8217;s labor more easily available and more accessible to real people.   And when my mom actually used it to find some software a couple weeks ago, I knew we&amp;#8217;d done something right.&lt;/p&gt;</description>
	<pubDate>Thu, 09 Apr 2009 14:20:53 +0000</pubDate>
</item>
<item>
	<title>Christopher Perkins: Pycon 2009 Recap</title>
	<guid>http://percious.com/blog/archives/28</guid>
	<link>http://percious.com/blog/archives/28</link>
	<description>&lt;p&gt;It felt like this year Pycon was executed to near perfection. Many struggles I had with last years Pycon were addressed both by the organizers, and some creative thinking.&lt;br /&gt;
In this post I will recap everything that happened from my perspective.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;WSGI House&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I gathered a few close friends from the TG team and a couple of wildcards for perspective to share a house for the continuum of the conference.  Having a house gave us a place to go home to at night and meet with friends, often staying up late talking about issues surrounding our favorite software.  Having a focused group I feel is important because you spend less time off on wild tangents.  The first (and pretty much only) rule of the house was that you pay the same amount whether you stay one night or nine.  At least one of our members was encouraged by this rule to stay for the sprints which he hadn&amp;#8217;t done before. Success!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tutorials&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;For me, tutorials got off to a shaky start, but we seemed to recover nicely.  TurboGears has a lot of momentum right now, and it makes it hard to come up with a succinct tutorial when there is so much functionality to cover.  I think we were able to recover and that our students managed to soak in enough knowledge from our proverbial fire hose to create some useful applications.  I think we have a good start on a &lt;a href=&quot;http://groups.google.com/group/turbogears/browse_thread/thread/27eaffa49a6e7d79&quot;&gt;new book&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I was extremely impressed with the quality of students who were attending my ToscaWidgets tutorial.  Every single student finished every example.  I chose Pylons to give the tutorial, and although it is a little harder to integrate TW in the stream than does TurboGears2, it installed quickly and flawlessly.  Overall, I think the tutorial was a &lt;a href=&quot;http://ygingras.net/b/2009/3/pycon-part-2&quot;&gt;success&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Talks&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This year I did not focus on attending the talks, but instead chose wisely based on speaker and topic and allowed my feet to do the walking if the talk became uninteresting.  I definitely missed some talks, but the AV team has done an incredible job putting the talks up on &lt;a href=&quot;http://pycon.blip.tv/posts?view=archive&amp;amp;nsfw=dc&quot;&gt;blip.tv&lt;/a&gt; so that I can review them later.&lt;/p&gt;
&lt;p&gt;This year I did not miss Raymond Hettinger&amp;#8217;s &lt;a href=&quot;http://blip.tv/file/1947373/&quot;&gt;talk&lt;/a&gt; on AI in python and was enthralled by a speaker who could successfully put a page of code on the screen and keep my interest.  I showed up to support Philip Jenvey in his talk on Pylons on Jython but was impressed by his ability to provide a succinct example on where Jython really shines.  I am hoping that more people take a second look at this really well done presentation.&lt;/p&gt;
&lt;p&gt;Now, I am a SQLAlchemy supporter through and through, but find the domain of database mapping an interesting echosystem.  While the ORM panel was littered by advertising chatter from one of the panelists who did not even write an ORM, an obvious dis-inclusion was &lt;a href=&quot;http://www.aminus.org/blogs/index.php/fumanchu&quot;&gt;Robert Brewer&lt;/a&gt; who wrote Dejavu, a very nice way to map persistent resources of different types for use in an &amp;#8220;objecty&amp;#8221; way.  Bob&amp;#8217;s &lt;a href=&quot;http://blip.tv/file/1949237/&quot;&gt;talk&lt;/a&gt; was especially interesting and makes me wonder if SQLAlchemy could leverage some of the work with AST that Bob beautifully displayed with some of the most amazing one-handed keyboarding I have ever seen.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Open Space&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Well, I said I was going to give a talk at the Open Space, and ended up not doing so.  Part of the problem was the utter lack of projectors in the OS rooms, and part of it was a reluctance to break up the collaborative/discussive vibe that was going on in these sessions.  WSGIers hammered out a 2.0 spec, which involved a discussion I only monitored in passing.  I was disappointed by the lack of people who showed up for the GSoC BOF, but I think the economy held back a lot of students from attending Pycon.  It was also nice to allow my feet to walk around and see what was up in different projects.  I met one guy who took REST way to far and got to express some of my dissatisfaction with one of the available tools.  On a more positive note, the TG BOF was well-attended  and it was nice to see so many users wondering what was up in TG land.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Sprints&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This year I refused to let the noobs get me down and actually wrote some code.  I am sorry if I did not act as a good host of the TG project, but we have some important milestones coming up and I just wanted to get work done on that.  Sprinting remains a cornerstone of our development process and I will see if we can&amp;#8217;t get our monthly&lt;br /&gt;
sprints happening again in 2009.  I was however able to completely &lt;a href=&quot;http://bitbucket.org/percious/tg-21/&quot;&gt;re-engineer&lt;/a&gt; our dispatch system, and while it is not currently 100% complete, it should be finished in a matter of days.  RestController now supports variable arguments for get_one, delete, and put, as well as supporting lookup and default.  Anyone can actually now create their own dispatch mechanism, since this functionality has been generalized.  Simply subclass Dispatcher, override _dispatch() and go to town.  I look forward&lt;br /&gt;
to seeing what kind of crazy code this brings to TG land.  A lot of discussion has been had on how to make &amp;#8220;plugins&amp;#8221; or &amp;#8220;extensions&amp;#8221; for TG, and you can rest assured that we will have this functionality soon.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Thanks&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Thanks to all of my house mates who put up with my &amp;#8220;mothering&amp;#8221;.  Thanks to all of you who tolerated my &amp;#8220;um&amp;#8221;s at my talk on Sphinx, and especially to Georg Brandl who answered some questions.  Thanks to the organizers, volunteers and staff that came together to create what has been my best Pycon to date.&lt;/p&gt;</description>
	<pubDate>Sat, 04 Apr 2009 00:08:31 +0000</pubDate>
</item>
<item>
	<title>Compound Thinking: Turbogears 2.0 RC1 Release</title>
	<guid>http://compoundthinking.com/blog/?p=619</guid>
	<link>http://compoundthinking.com/blog/index.php/2009/03/29/turbogears-20-rc1-release/</link>
	<description>&lt;p&gt;I missed the boat by a few days here, but I posted up the first Release Candidate for TG2 earlier this week before pycon.   And given the interest in the sprints, it&amp;#8217;s very likely that we&amp;#8217;ll have a 2.0 final release avalable by the end of next week. &lt;/p&gt;</description>
	<pubDate>Sun, 29 Mar 2009 18:46:43 +0000</pubDate>
</item>
<item>
	<title>Jorge Vargas: TG2: after 3 and a half months and 6 beta releases</title>
	<guid>http://www.maetico.com/tg2-after-35-months-and-6-beta-releases/</guid>
	<link>http://www.maetico.com/tg2-after-3-and-a-half-months-and-6-beta-releases/</link>
	<description>&lt;p&gt;Last time I wrote about TG here I said I was committed to get  TGb1 out of the door and that was December 15th, 2008, wow time runs by when you are having fun. Lets see, today is March 1 that&amp;#8217;s 3.5 months exactly or 76 days according to python.&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; datetime.date.today()-datetime.date(2008,12,15)&lt;br /&gt;
datetime.timedelta(76)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Since then we have had &lt;a href=&quot;http://trac.turbogears.org/timeline?from=03%2F01%2F09&amp;amp;daysback=80&amp;amp;milestone=on&amp;amp;update=Update&quot;&gt;TG2b1, TG2b2, TG2b3, TG2b4, TG2b5 and TG2b6&lt;/a&gt; which averages us to one release every 12 days! that&amp;#8217;s a lot of work!, to be fair it&amp;#8217;s more like 15 days each as b4 was short lived due to &amp;#8230;. that&amp;#8217;s in the pass who cares &lt;img src=&quot;http://www.maetico.com/wp-includes/images/smilies/icon_smile.gif&quot; alt=&quot;:)&quot; class=&quot;wp-smiley&quot; /&gt; &lt;/p&gt;
&lt;p&gt;TG2b1 had &lt;a href=&quot;http://trac.turbogears.org/query?status=closed&amp;amp;milestone=2.0b1&amp;amp;order=priority&quot;&gt;47 tickets&lt;/a&gt; It was basically a cleanup release and we applied a ton of patches from trac, the most notable thing is the upgrades for &lt;a href=&quot;http://pypi.python.org/pypi/repoze.what&quot;&gt;repoze.what&lt;/a&gt;, with &lt;a href=&quot;http://gustavonarea.net/&quot;&gt;Gustavo&lt;/a&gt; making a clear goal to get this package in shape for real world usage.&lt;/p&gt;
&lt;p&gt;TG2b2 had &lt;a href=&quot;http://trac.turbogears.org/query?status=closed&amp;amp;milestone=2.0b2&amp;amp;order=priority&quot;&gt;12 tickets&lt;/a&gt; Was mainly &lt;a href=&quot;http://compoundthinking.com&quot;&gt;Marks&lt;/a&gt; work, He fixed our &lt;a href=&quot;http://pypi.python.org/pypi/WebError&quot;&gt;WebError&lt;/a&gt; to look nice and fixed the error controller (after I failed at understanding it) then he fixed tg.url to work with the newest pylons.url (&lt;a href=&quot;http://pypi.python.org/pypi/Pylons&quot;&gt;pylons&lt;/a&gt; 0.9.7b4 I think) which was 15% faster (or some nice number) due to some optimizations from &lt;a href=&quot;http://groovie.org/&quot;&gt;benbangert&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Tg2b3 had &lt;a href=&quot;http://trac.turbogears.org/query?status=closed&amp;amp;milestone=2.0b3&amp;amp;order=priority&quot;&gt;16 tickets&lt;/a&gt; and was probably the most important of the betas, even though it had such a small ticket count, as it gave us a ton of features mostly from the hand of &lt;a href=&quot;http://percious.com/blog/&quot;&gt;Christopher Perkins&lt;/a&gt;,&lt;/p&gt;
&lt;p&gt;He gave us the very cool content type request dispatch, which despite the name it&amp;#8217;s something not that scary and very powerful. You simply add .json to a url that&amp;#8217;s behind a controller with @expose(&amp;#8217;json&amp;#8217;) and it will give you &amp;#8216;application/json&amp;#8217;, this works with minetypes so it will allow you to build any type of file on the fly. Or simply serve different requests from the same controller, for example .xml, .json and.html could serve as legacy API, ajax and  browser, all from the same controller!&lt;/p&gt;
&lt;p&gt;The other very nice feature by &lt;a href=&quot;http://www.ohloh.net/accounts/percious&quot;&gt;Chris&lt;/a&gt; is the RestController (RC) and it&amp;#8217;s extension CrudRestController (CRC) (in the package &lt;a href=&quot;http://pypi.python.org/pypi/tgext.crud&quot;&gt;tgext.crud&lt;/a&gt;) which is the base for &lt;a href=&quot;http://pypi.python.org/pypi/tgext.admin&quot;&gt;tgext.admin&lt;/a&gt; and &lt;a href=&quot;http://pypi.python.org/pypi/Catwalk&quot;&gt;Catwalk2&lt;/a&gt;. Wow that&amp;#8217;s a lot of names. I saved this from IRC which I think explains it nicely.&lt;/p&gt;
&lt;p&gt;1 percious_: Sprox = SA + TW&lt;br /&gt;
2 percious_: RC = Restful Dispatch&lt;br /&gt;
3 jon1012: hey guys&lt;br /&gt;
4 percious_: CRC = Forms/Fillers/Tables + RC&lt;br /&gt;
5 percious_: Admin = CRC + config + index page&lt;br /&gt;
6 elpargo: hi jon1012&lt;br /&gt;
7 percious_: Catwalk = Admin + TG-quickstart-specific Config&lt;br /&gt;
8 percious_: hi jon1012&lt;br /&gt;
9 elpargo: awesome I&amp;#8217;ll turn that into a doc soon TM&lt;br /&gt;
10 percious_: catwalk is a dumb name we should probably eliminate&amp;#8230;&lt;br /&gt;
11 pjenvey_: holy acronyms, batman&lt;br /&gt;
12 percious_: sounds awesome&lt;br /&gt;
13 percious_: AC = Admin Controller&lt;br /&gt;
14 percious_: CRC = CrudRestController&lt;br /&gt;
15 percious_: RC = RestController&lt;br /&gt;
16 percious_: SA = SqlAlchemy&lt;br /&gt;
17 percious_: TW = ToscaWidgets&lt;/p&gt;
&lt;p&gt;still too cryptic? ok, here are some words. You start with the very basic &lt;a href=&quot;http://sqlalchemy.org/&quot;&gt;SQLAlchemy&lt;/a&gt; definitions and &lt;a href=&quot;http://toscawidgets.org/&quot;&gt;ToscaWidgets&lt;/a&gt; then you have &lt;a href=&quot;http://sprox.org/&quot;&gt;sprox&lt;/a&gt; which links one to the other with some very nice basic Widgets, then you take a &lt;a href=&quot;http://microformats.org/wiki/rest&quot;&gt;rest&lt;/a&gt; controller and make available over the web as a &lt;a href=&quot;http://en.wikipedia.org/wiki/Resource_(Web)&quot;&gt;resource&lt;/a&gt;, then you take a group of resources and transform it into a &lt;a href=&quot;http://en.wikipedia.org/wiki/Create,_read,_update_and_delete&quot;&gt;CRUD&lt;/a&gt; with CrudRestController, then you take a group of CRCs and transform them into an AdminController, or you could just skip all that and let Catwalk2 give you a very nice set of defaults. From all this I find CRC to be the best for most applications it&amp;#8217;s a very nice sweet spot between fully automatic and fully by hand. And I strongly think this is the best tool TG2 has to offer for database driven applications (sorry &lt;a href=&quot;http://python-rum.org/&quot;&gt;Rum&lt;/a&gt; I know you are very good but I just can&amp;#8217;t customize you)&lt;/p&gt;
&lt;p&gt;The other important change in TGb3 was the new &lt;a href=&quot;http://pypi.python.org/pypi/WebFlash&quot;&gt;flash&lt;/a&gt; based on a cookie, instead of the session and this was done by &lt;a href=&quot;http://albertovalverde.es/&quot;&gt;Alberto Valverde&lt;/a&gt; (don&amp;#8217;t be fool by his blog, he is very active coding). This is a rather interesting feature mainly because it will allow you to cache your application. And in the best of WSGI spirit this was released as a separate package.&lt;/p&gt;
&lt;p&gt;The last important change here was a small project started by &lt;a href=&quot;http://www.ohloh.net/accounts/albertov&quot;&gt;Alberto&lt;/a&gt; and &lt;a href=&quot;http://www.maetico.com&quot;&gt;your trully&lt;/a&gt;, it&amp;#8217;s a base class inside TurboGears named WSGIAppController and a package named tgext.wsgiapps (yet unreleased, although it&amp;#8217;s hg is public). The idea behind WSGIAppController is to prepare TG to serve a downstream application. The purpose of wsgiapps is to make controllers for the most popular apps out there (we have &lt;a href=&quot;http://pypi.python.org/pypi/Trac&quot;&gt;Trac&lt;/a&gt;, &lt;a href=&quot;http://pypi.python.org/pypi/Mercurial&quot;&gt;Mercurial&lt;/a&gt;, Zine (no link as a vote of protest as it has no setup.py file), and &lt;a href=&quot;http://pypi.python.org/pypi/TileCache&quot;&gt;TileCache&lt;/a&gt;) and fix all the small little details you will encounter. This is all heavily under-documented but I&amp;#8217;ll get around to it ones I have a proper alpha for codemill (but codemill is another post).&lt;/p&gt;
&lt;p&gt;The next feature (I believe this was here correct me if I&amp;#8217;m wrong).  &lt;a href=&quot;http://jondesign.net/&quot;&gt;jon1012&lt;/a&gt; and &lt;a href=&quot;http://www.ohloh.net/accounts/faide&quot;&gt;florent&lt;/a&gt; (hi french people) sat down and gave the TG quickstart a totally fresh look and not conformed with that they made a very nice tutorial for new people. The new CSS is very nice and clean and will serve as a nice base for any project.&lt;/p&gt;
&lt;p&gt;TG2b4 was another bugfix release and it had a very small ticket count (&lt;a href=&quot;http://trac.turbogears.org/query?status=closed&amp;amp;milestone=2.0b4&amp;amp;order=priority&quot;&gt;just 2&lt;/a&gt;) this was because most of the work happen outside of TG, and it was a bugfix release, with so many feature in b3 we had to find some bugs didn&amp;#8217;t we?&lt;/p&gt;
&lt;p&gt;TG2b5 was another biggiee (&lt;a href=&quot;http://trac.turbogears.org/query?status=closed&amp;amp;milestone=2.0b5&amp;amp;order=priority&quot;&gt;21 tickets&lt;/a&gt;) and it saw many more enhancements to the auth &amp;amp; auth stack, with the last set of features from &lt;a href=&quot;http://www.ohloh.net/accounts/Gustavo&quot;&gt;Gustavo&lt;/a&gt; to make this super configurable, we also had the __before__ added to TG which is a very nice feature from people comming from pylons and the error controller now has a nice styling (again thanks &lt;a href=&quot;http://www.ohloh.net/accounts/MarkRamm&quot;&gt;Mark&lt;/a&gt;!)&lt;/p&gt;
&lt;p&gt;And last but not least TG2b6 which was a little overdue (mainly because mramm has a life and couldn&amp;#8217;t cut us a release). This was another rather big release as everyone was rushing to get their fixes in before feature freeze and made a total &lt;a href=&quot;http://trac.turbogears.org/query?status=closed&amp;amp;milestone=2.0b6&amp;amp;order=priority&quot;&gt;ticket count of 27&lt;/a&gt; I&amp;#8217;m a little bias here so I&amp;#8217;ll say what I did first. We now have a new (and awesome) default model unit test class which was originally given to me (for private code) by percious and I finally manage to sneak into TG2, it makes testing your model as simple as creating an instance of each class with such a nice api that it doesn&amp;#8217;t even needs docs (yes I know I&amp;#8217;ll write them), on top of that I commited a cleanup of the dependencies which makes the installer a lot smaller and made TG2 pip compatible, you know because everyone loves pip. On the auth front Gustavo&amp;#8217;s work was so good that people from pylons wanted to use his repoze.what package so he split TG&amp;#8217;s functionality into &lt;a href=&quot;http://code.gustavonarea.net/repoze.what-pylons/&quot; class=&quot;ext-link&quot;&gt;&lt;span class=&quot;icon&quot;&gt;repoze.what-pylons&lt;/span&gt;&lt;/a&gt; and also enhanced the whole thing to look a little more like TG1 identity which allows a far better use with less surprises.&lt;/p&gt;
&lt;p&gt;Also here (I believe) one of our &amp;#8216;08 google summer of code students (now active contributor) all the way from India Mr. &lt;a href=&quot;http://www.ohloh.net/accounts/sanjiv&quot;&gt;Sanjiv Singh&lt;/a&gt; (ok that was too much of an intro) , updated the &lt;a href=&quot;http://pypi.python.org/pypi/tgext.geo&quot;&gt;tgext.geo&lt;/a&gt; package to be a flag in quickstart. So now you can enjoy all his geo goodness with 5 keystrokes (&amp;#8211;geo)&lt;/p&gt;
&lt;p&gt;So there you have it that&amp;#8217;s the super small summary of what We (TurboGears people) have been up to in the last&amp;#8230; wow I still can&amp;#8217;t believe it&amp;#8217;s been 3.5 months.&lt;/p&gt;
&lt;p&gt;What&amp;#8217;s next? of course TG2.1! We are already &lt;a href=&quot;http://trac.turbogears.org/query?status=new&amp;amp;status=assigned&amp;amp;status=reopened&amp;amp;milestone=2.1&amp;amp;order=priority&quot;&gt;building up on tickets&lt;/a&gt; for that. But before we get our hands on the coding we need to get the rc and final out and write &lt;a href=&quot;http://trac.turbogears.org/query?status=new&amp;amp;status=assigned&amp;amp;status=reopened&amp;amp;type=documentation&amp;amp;order=priority&quot;&gt;some documentation&lt;/a&gt; and some more &lt;a href=&quot;http://trac.turbogears.org/query?status=new&amp;amp;status=assigned&amp;amp;status=reopened&amp;amp;component=Documentation&amp;amp;order=priority&quot;&gt;documentation&lt;/a&gt; yes that is confusing we are moving from a &amp;#8220;component documentation&amp;#8221; to a &amp;#8220;type documentation&amp;#8221; but most tickets are still in the wrong slot. Anyway it&amp;#8217;s all work to be done and needs reviews as well as comments from newbies and pros alike. TG2 is here and ready to rock now lets test it in the wild so we can write docs, posts and patches, to get a TG2.0!&lt;/p&gt;
&lt;p&gt;Oh and see you at pycon!&lt;/p&gt;</description>
	<pubDate>Mon, 02 Mar 2009 05:09:47 +0000</pubDate>
</item>
<item>
	<title>Compound Thinking: TurboGears 2 Beta 6 released</title>
	<guid>http://compoundthinking.com/blog/?p=609</guid>
	<link>http://compoundthinking.com/blog/index.php/2009/02/27/turbogears-2-beta-6-released/</link>
	<description>&lt;p&gt;TurboGears 2.0 beta 6 comes with lots of fixes, and a total feature freeze in preparation for the first Release Candidate. From here on out to 2.0, we&amp;#8217;ll only be doing bugfixes and improving our Docs. Speaking of Docs, Beta 6 comes on the heals of this last weekend&amp;#8217;s doc sprint, so it already comes with new and improved documentation.&lt;/p&gt;
&lt;p&gt;One thing which you should be aware of in Beta 6 is that after you install tg.devtools and quickstart a new application you have to do  python setup.py develop  on your quickstarted app because some of the dependencies for the app are not installed until that time. This allows you to remove optional dependencies from your application if you&amp;#8217;re not using them.&lt;/p&gt;
&lt;p&gt;Jorge Vargas has &lt;a href=&quot;http://www.turbogears.org/2.0/docs/main/DownloadInstall.html&quot;&gt;completely rewritten&lt;/a&gt; the Install doc.   Anita has done great work on &lt;a href=&quot;http://www.turbogears.org/2.0/docs/main/Wiki20/wiki20.html&quot;&gt;the Wiki 20 doc&lt;/a&gt;, which is providing an ever improving introduction to TG2. &lt;/p&gt;
&lt;p&gt;Christoph Zwerschke has update the &lt;a href=&quot;http://www.turbogears.org/2.0/docs/main/ToscaWidgets/forms.html&quot;&gt;ToscaWidgets&lt;/a&gt; forms doc, Chris Perkins has documented the &lt;a href=&quot;http://www.turbogears.org/2.0/docs/main/RestControllers.html&quot;&gt;new RestController stuff&lt;/a&gt; which simplifies common Create, Read, Update, and Delete operations. And I  created an&lt;a href=&quot;http://www.turbogears.org/2.0/docs/main/RequestFlow.html&quot;&gt; overview of the TurboGears 2 stack&lt;/a&gt;.  There are also new docs on the&lt;a href=&quot;http://www.turbogears.org/2.0/docs/main/Templates/Alternative.html&quot;&gt; alternative template engines&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt;And of course there were also many, many smaller updates spread across the TG2 docs.&lt;/p&gt;
&lt;p&gt;We are nowhere near where we want to be with the TG2 docs, but they are shaping up quite nicely.  And we&amp;#8217;re getting very close to the final release.   &lt;/p&gt;
&lt;p&gt;It&amp;#8217;s been a great ride, and I&amp;#8217;m already looking forward to some of the &lt;a href=&quot;http://trac.turbogears.org/query?status=new&amp;#038;status=assigned&amp;#038;status=reopened&amp;#038;milestone=2.0rc1&quot;&gt;great things in store&lt;/a&gt; for 2.1. &lt;/p&gt;</description>
	<pubDate>Fri, 27 Feb 2009 02:07:03 +0000</pubDate>
</item>
<item>
	<title>Compound Thinking: TG2 doc sprint this weekend</title>
	<guid>http://compoundthinking.com/blog/?p=601</guid>
	<link>http://compoundthinking.com/blog/index.php/2009/02/20/tg2-doc-sprint-this-weekend/</link>
	<description>&lt;p&gt;We&amp;#8217;ve declared a final feature-freeze on TurboGears in the runnup to the 2.0 release. &lt;/p&gt;
&lt;p&gt;But that doesn&amp;#8217;t mean that there&amp;#8217;s not still lots of work to do.   We&amp;#8217;re working on a updates to the TG website, radically improved documentation, and better marketing materials.   So, we&amp;#8217;re having another TG2 sprint this weekend, but this sprint will be focused on infrastructure documentation, and will be the most newbie friendly sprint ever since one of the primary tasks is to make sure that the docs make good sense to new users. &lt;/p&gt;
&lt;p&gt;Documentation is hard because the people who write it generally are experts, and have forgotten what&amp;#8217;s complicated/confusing to new users.   So we really, really need fresh eyes and fresh perspectives.&lt;/p&gt;
&lt;p&gt;And one of the most useful things you can do is read and comment on our docs: &lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.turbogears.org/2.0/docs/index.html&quot;&gt;http://www.turbogears.org/2.0/docs/index.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt; If you have a few hours, please join us in #turbogears on IRC on freenode (see &lt;a href=&quot;https://wiki.mozilla.org/HowTo:IRC&quot;&gt;this tutorial&lt;/a&gt; if you&amp;#8217;re new to IRC) and sign up for the sprint here: &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;</description>
	<pubDate>Fri, 20 Feb 2009 03:03:30 +0000</pubDate>
</item>
<item>
	<title>Compound Thinking: NGINX+SSI+TG2/Pylons</title>
	<guid>http://compoundthinking.com/blog/?p=556</guid>
	<link>http://compoundthinking.com/blog/index.php/2009/02/12/nginxssitg2pylons/</link>
	<description>&lt;p&gt;&lt;a href=&quot;http://www.reshetseret.com/app/blog/?p=3&quot;&gt;Interesting stuff &lt;/a&gt;here.   This came up again at my new job, and I remembered that I&amp;#8217;d forgotten to blog about it when I first saw this blog-post. &lt;/p&gt;
&lt;p&gt;NGINX is an amazingly fast lightweight web server, and Server Side Includes (SSI) seem to be making a comeback as &amp;#8220;composed&amp;#8221; pages become more popular and traffic levels go up.  &lt;/p&gt;
&lt;p&gt;This is interesting because it lets NGINX provide super-fast and easy to use access to memcachd cached pages, and with SSI you can restrict the dynamic portions that have to be handled by python to the smallest possible portion of the page.   If the pattern fits your application really well, you can see very significant increases in the number of requests-per-second you can achieve this way. &lt;/p&gt;
&lt;p&gt;I&amp;#8217;ve been fooling around with SSI+nginx too for another project, but and have been meaning to blog about it but  haven&amp;#8217;t had time to get anything ready to publish.   I do intend to write a detailed tutorial on this setup someday, but for know &lt;a href=&quot;http://www.reshetseret.com/app/blog/?p=3&quot;&gt;this&lt;/a&gt; is a great if super-high velocity  introduction to the how of SSI+Memcached+Pylons.  And of course you can use TG2 with this in exactly the same way. &lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.reshetseret.com/app/blog/?p=3&quot;&gt;http://www.reshetseret.com/app/blog/?p=3&lt;/a&gt;&lt;/p&gt;</description>
	<pubDate>Thu, 12 Feb 2009 01:41:07 +0000</pubDate>
</item>
<item>
	<title>Compound Thinking: TurboGears 2 tutorials at PyCon</title>
	<guid>http://compoundthinking.com/blog/?p=572</guid>
	<link>http://compoundthinking.com/blog/index.php/2009/02/11/turbogears-2-tutorials-at-pycon/</link>
	<description>&lt;p&gt;This year at PyCon we&amp;#8217;ll be using turbogears 2.0 final in the beginning and intermediate TG &lt;a href=&quot;http://pycon.org/2009/tutorials/schedule/&quot;&gt;tutorials&lt;/a&gt;, and there&amp;#8217;s lots of great stuff to cover: &lt;/p&gt;
&lt;p&gt; * A new &amp;#8220;admin&amp;#8221; system&lt;br /&gt;
 * New REST support in controllers&lt;br /&gt;
 * Improved automatic form generation via sprox&lt;br /&gt;
 * Built in user/groups/permissions system&lt;/p&gt;
&lt;p&gt;This year&amp;#8217;s tutorial will be much more interactive than last, and will be focused on TurboGears more narrowly than last year when we did TG2+Pylons.   We&amp;#8217;ll be covering lots of stuff that can be used in Pylons, but since TG2 configures all this for us, we&amp;#8217;ll be doing it the TG2 way. &lt;/p&gt;
&lt;p&gt;In addition to the beginning and intermediate TG tutorials, there will also be a full day of SQLAlchemy tutorials, and a ToscaWidgets tutorial. &lt;/p&gt;
&lt;p&gt;If you really want to maximize your learning experience, I&amp;#8217;d recommend this list of tutorials: &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://pycon.org/2009/tutorials/schedule/1AM5/&quot;&gt;Beginning TurboGears&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://pycon.org/2009/tutorials/schedule/1PM5/&quot;&gt;Intermediate TurboGears&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://pycon.org/2009/tutorials/schedule/2AM3/&quot;&gt;ToscaWidgets&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://pycon.org/2009/tutorials/schedule/2PM4/&quot;&gt;Advanced SQLAlchemy&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you haven&amp;#8217;t used SQLAlchemy before and want more introduction than the TG tutorials provide, you might want to switch out the ToscaWidgets tutorial for the &lt;a href=&quot;http://pycon.org/2009/tutorials/schedule/2AM4/&quot;&gt;Introduction to SQLAlchemy&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;And if you really want to maximize your TG experience, there will be a couple of TG experts that will work with you on some open source TurboGears applications at the sprints after the conference.   I think working with the core TG team on real application code is a great way to round out the Tutorials and maximizing your learning. &lt;/p&gt;
&lt;p&gt;This is an incredibly great two day learning experience at an incredible price. I&amp;#8217;m really excited about how much PyCon in general and the tutorials specifically have to offer TurboGears users this year.  I think the  two full days TG related tutorial, opens up the possibility go go into much greater depth, and when coupled with the sprints, provides a great way to learn more about turbogears.&lt;/p&gt;</description>
	<pubDate>Wed, 11 Feb 2009 01:40:36 +0000</pubDate>
</item>
<item>
	<title>Compound Thinking: Database Migrations</title>
	<guid>http://compoundthinking.com/blog/?p=579</guid>
	<link>http://compoundthinking.com/blog/index.php/2009/02/09/database-migrations/</link>
	<description>&lt;p&gt;SQLAlchemy Migrate 0.5 was released last week, and it got me thinking about how important it is. &lt;/p&gt;
&lt;p&gt;Evolutionary Database design and &lt;a href=&quot;http://www.amazon.com/Refactoring-Databases-Evolutionary-Addison-Wesley-Signature/dp/0321293533/pragmaticsyst&quot;&gt;data schema refactoring&lt;/a&gt; critical to most projects these days, and pretty much everywhere I&amp;#8217;ve worked over the past 10 years, we&amp;#8217;ve handled database upgrades via a set of sql upgrade and downgrade scripts, a db version number in the db, and a upgrader/downgrader python thingamabober. &lt;/p&gt;
&lt;p&gt;A few years ago I did a couple projects in Rails, and Rails &lt;a href=&quot;http://api.rubyonrails.org/classes/ActiveRecord/Migration.html&quot;&gt;Migrations&lt;/a&gt; made this easier, by providing a standard API.   There were limitations, and worries about lost data, and sometimes it wasn&amp;#8217;t clear what SQL would be generated &amp;#8212; but it was good enough, and worked well enough, that everybody used it. &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://compoundthinking.com/blog/wp-content/uploads/2008/07/104271343_957605dcd2-300x300.jpg&quot; alt=&quot;104271343_957605dcd2&quot; title=&quot;104271343_957605dcd2&quot; width=&quot;300&quot; height=&quot;300&quot; align=&quot;right&quot; class=&quot;alignnone size-medium wp-image-339&quot; /&gt;But what I don&amp;#8217;t like about ActiveRecord, and other ORMs like it is that every object-property change ultimately requires an underlying database change.   On large projects I really want the flexiblity of a data-mapper to insulate some of my OO code and OO design decisions from the need for database level changes.   I think this is incredibly important on very complex projects where the &amp;#8220;data model&amp;#8221; needs to change quite frequently, but the underlying database schema needs to change less frequently.    SQLAlchemy on the other hand provides a clear, simple, elegant solution to that problem by decoupling the Objects from the Relations by providing an explicit Mapper.   &lt;/p&gt;
&lt;p&gt;But even with the flexibility of a Data Mapper based ORM, you still need to update your database schema sometimes.  And that&amp;#8217;s where SQLAlchemy-Migrate comes in.   I think it or something like it is an indispensable tool in the SA user&amp;#8217;s toolkit. &lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://turbogears.org/2.0/&quot;&gt;TG2&lt;/a&gt; ships with both &lt;a href=&quot;http://sqlalchemy.org&quot;&gt;SQLALchemy&lt;/a&gt; and &lt;a href=&quot;http://code.google.com/p/sqlalchemy-migrate/&quot;&gt;SQLALchemy-Migrate&lt;/a&gt;.   And provides &lt;a href=&quot;http://turbogears.org/2.0/docs/main/DatabaseMigration.html&quot;&gt;a little bit of help&lt;/a&gt; to make migration development even easier. &lt;/p&gt;
&lt;p&gt;There&amp;#8217;s more we can do to integrate Migrations into TG2, mainly by documenting it better, and setting it up a bit more in quickstart.   I know there&amp;#8217;s a trade-off there too, because for a lot of smaller applications migrations are too much overhead at the beginning, you can more easily wipe and recreate your database as you make changes, and we should support that way of working &amp;#8212; so nothing we do should make that harder.  &lt;/p&gt;
&lt;p&gt;With that said, I&amp;#8217;ll know we have arrived at the right place when we&amp;#8217;ve made evolutionary database development or database schema refactoring easy enough that it feels natural and easy, and not doing it feels uncomfortable.&lt;/p&gt;</description>
	<pubDate>Mon, 09 Feb 2009 02:53:51 +0000</pubDate>
</item>
<item>
	<title>Christopher Perkins: Pycon 2009</title>
	<guid>http://percious.com/blog/archives/27</guid>
	<link>http://percious.com/blog/archives/27</link>
	<description>&lt;p&gt;&lt;img src=&quot;http://us.pycon.org/common/img/logo-sitemasthead.gif&quot; height=&quot;120&quot; width=&quot;328&quot; /&gt;&lt;/p&gt;
&lt;p&gt;So, Pycon registration has been up for a few days, I will be speaking both on and off-podium (read: open space) and providing assistance to and presenting tutorials.  Here is a run down of what I am planning in case you wanted a little bit more in-depth information.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Tutorials:&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Turbogears2 &lt;a href=&quot;http://us.pycon.org/2009/tutorials/schedule/1AM5&quot;&gt;Beginner&lt;/a&gt; and &lt;a href=&quot;http://us.pycon.org/2009/tutorials/schedule/1PM5&quot;&gt;Intermediate&lt;/a&gt;&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;I will be assisting &lt;a href=&quot;http://compoundthinking.com/blog/&quot;&gt;Mark Ramm&lt;/a&gt; by giving individuals help installing and using the new TurboGears2 framework.  Mark is an experienced tutorial presenter, an expert in the technology, and in general a fun character to spend a few hours with.  When you leave his tutorials you should expect to have a working version of TG2 on your machine, along with an understanding of Model, View, and Controller paradigms.  Middleware, Forms, and REST will also be covered.  One note, if you are getting started with TG2, it&amp;#8217;s best to have it installed and running if you plan to attend only the Intermediate Section.  We will not be going over installation in the second-half.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://us.pycon.org/2009/tutorials/schedule/2AM3&quot;&gt; &lt;/a&gt;&lt;strong&gt;&lt;a href=&quot;http://us.pycon.org/2009/tutorials/schedule/2AM3&quot;&gt;Toscawidgets: Test Driven Modular Ajax&lt;/a&gt;:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I am presenting this tutorial which will describe how to use the valuable Toscawidgets package to create web content.  If you are currently use WSGI technology, and are interested in creating reusable, modular web content, this is a perfect way to get started.  I will show you how to configure TW middleware to work with pylons (which is applicable to other frameworks like repoze.bfg, paste, or even plone/Grok).  I will then describe how you might use this middleware to generate web forms.  The last few hours of class will be devoted to using the JavaScript utilities of TW to create an Ajaxified website, and test it using YUITest.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://us.pycon.org/2009/tutorials/schedule/2PM5&quot;&gt;&lt;strong&gt;The Big F&amp;#8217;ing Tutorial: Development Using the &lt;tt class=&quot;docutils literal&quot;&gt;&lt;span class=&quot;pre&quot;&gt;repoze.bfg&lt;/span&gt;&lt;/tt&gt; Web Framework&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I will assist/present with &lt;a href=&quot;http://blog.repoze.org/&quot;&gt;Chris McDonough&lt;/a&gt; about this up-and-coming framework who&amp;#8217;s goals are to utilize bits of the zope 3 framework, wsgi, and new technologies to make a lighting-fast web server.  Those of you who are familiar with Zope technologies may be interested to find how nicely some of the familiar bits of zope are integrated with wsgi with repoze.bfg.&lt;/p&gt;
&lt;p&gt;&lt;em&gt; Presentations:&lt;/em&gt;&lt;span id=&quot;proposal_link_92&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span id=&quot;proposal_link_92&quot;&gt;&lt;span&gt;Using Sphinx and Doctests to provide Robust Documentation&lt;/span&gt;&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This is a 1/2 hour slot which describes how you can integrate tested documentation with your source code&amp;#8230; with sanity!  I go over a quick install of &lt;a href=&quot;http://sphinx.pocoo.org/&quot;&gt;Sphinx&lt;/a&gt;, and use some screencasts to demenstrate how to add, run, and display doctests using it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Open Space:&lt;span&gt;Agile Development with&lt;a href=&quot;http://www.sqlalchemy.org&quot;&gt; SQLAlchemy&lt;/a&gt; and Python Testing Tools&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I really enjoy giving this talk, and even though it was not accepted as a formal talk, I will find a venue by way of Open Space to express my knowledge of Testing, SA, and Nose.  I have given this talk a few times now, and it&amp;#8217;s fairly polished.  My presentation, while on some dry topics, won&amp;#8217;t put you to sleep.  Carefully prepared screencasts and photograph-punctuated slides makes the 45 minutes breeze by.  Questioneers/Hecklers welcome!&lt;/p&gt;
&lt;p&gt;&lt;em&gt; Sprint Topics&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I want to spend some time with the Dispatch of TG2, and probably push Sprox further a bit.  If you are just starting with TG, please feel free to contribute.  Sprinting is a great way to learn a lot from the experts in the domain.  We usually do a meet-greet-install the night before the sprints.  Oh, and I&amp;#8217;ve been known to provide refreshments to all of our sprinting hordes (read: FREE BEER).&lt;/p&gt;
&lt;p&gt;So, I hope to see all of you there!  If you see me in the hall, feel free to introduce yourself and tell me what you are using Python for!&lt;/p&gt;</description>
	<pubDate>Wed, 04 Feb 2009 23:33:42 +0000</pubDate>
</item>
<item>
	<title>Compound Thinking: WSGI and cooperation</title>
	<guid>http://compoundthinking.com/blog/?p=562</guid>
	<link>http://compoundthinking.com/blog/index.php/2009/02/04/wsgi-and-cooperation/</link>
	<description>&lt;p&gt;Wow, lots of i&lt;a href=&quot;http://compoundthinking.com/blog/index.php/2009/01/21/django-developer-discovers-wsgi/#comments&quot;&gt;nteresting discussion&lt;/a&gt; based on &lt;a href=&quot;http://compoundthinking.com/blog/index.php/2009/01/21/django-developer-discovers-wsgi/&quot;&gt;my last post&lt;/a&gt; about a Django developer discovering how rich the WSGI middleware ecosystem has become.  And I actually think that the discussion there is very enlightening.   &lt;/p&gt;
&lt;p&gt;But I think those who criticize WSGI often miss the real point. I think WSGI is interesting not because of how amazing it&amp;#8217;s API is, but because it&amp;#8217;s provided a clear way for the many python web development communities to work together, and to swap and trade technologies.    &lt;/p&gt;
&lt;p&gt;Many things that used to be part of the Zope application framework, have been turned into WSGI middleware by the repoze folks (&lt;a href=&quot;http://svn.repoze.org/repoze.profile/trunk/README.txt&quot;&gt;repoze.profile&lt;/a&gt;, &lt;a href=&quot;http://svn.repoze.org/repoze.tm2/trunk/README.txt&quot;&gt;repoze.tm&lt;/a&gt;, &lt;a href=&quot;http://svn.repoze.org/repoze.retry/trunk/README.txt&quot;&gt;repoze.retry&lt;/a&gt;, etc) while things that used to be TurboGears framework specific have moved out to become libraries with middleware components (&lt;a href=&quot;http://toscawidgets.org/&quot;&gt;ToscaWidgets&lt;/a&gt;, &lt;a href=&quot;http://pypi.python.org/pypi/repoze.what/1.0&quot;&gt;repoze.what&lt;/a&gt;, etc).   &lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.pylonshq.com/&quot;&gt;Pylons&lt;/a&gt; was built from the ground up using WSGI Components, and has contributed a bunch of great components.  &lt;/p&gt;
&lt;p&gt;And then there&amp;#8217;s Ian Bicking who has contributed a huge array of tools for working with WSGI stacks paste contains all kinds of stuff like the &lt;a href=&quot;http://pythonpaste.org/modules/cascade.html&quot;&gt;paste cascade app&lt;/a&gt;, &lt;a href=&quot;http://pythonpaste.org/script/&quot;&gt;paste script&lt;/a&gt;, and most importantly &lt;a href=&quot;http://pythonpaste.org/webob/&quot;&gt;webob&lt;/a&gt;.   WebOb is very lightweight, just an OO proxy over the environ, and a few helper methods, but it makes writing WSGI middleware and WSGI applications much easier.&lt;/p&gt;
&lt;p&gt;The point of all this is that the wider python web world is seeing a huge increase in cross-polination of ideas, of working together on projects, and sharing code across major frameworks from TurboGears to Zope, to Pylons.   And at the core of all this is the WSGI specification.   WSGI may not be pefect, but it&amp;#8217;s still great, because it provides a defined way for web framework developers to work together.   And, that coupled with the fact that we&amp;#8217;re all pretty friendly people, and we all like each other and want to work together on things, has created a renasance of sorts in python web tools world.&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s now easy enough to pull tools together and make your own webframework that I know a couple people folks who&amp;#8217;ve created 2-3 specialized frameworks for various projects in the last year.    This is great because they can take only what they need, and also because they have contributed back inovative bits and pieces, and have also helped improve some of existing pieces at the same time.&lt;/p&gt;
&lt;p&gt;Sure, it&amp;#8217;s a little bit messy and chaotic when compared to more centrally controlled framework development, but it&amp;#8217;s also a whole heck of a lot more interesting, flexible, and fun.  And there&amp;#8217;s a whole lot of interesting new ideas getting tried out. &lt;/p&gt;
&lt;p&gt;TG2&amp;#8217;s goal is to provide an opinionated, coherent, facade across this complexity.  We want to be coherent, without being monolythic, to be full-stack, while allowing the user control over the stack.  &lt;/p&gt;
&lt;p&gt;Django developers sometimes criticize the wsgi world for not providing a complete and integrated toolset.  And that&amp;#8217;s exactly the problem that TG2 is determined to solve.  If we&amp;#8217;re doing our jobs right TG2 will  provide what we think are best of breed components, put together in a coherent, and easy-to-use way.  We want users to be able to depend on the stack and to be able to build reusable applications on top of it. And that requires being opinionated.   But we also want to make it possible for users with different needs to make different choices when and where the need arises.&lt;/p&gt;
&lt;p&gt;One TG2 developer said it this way &amp;#8220;We want TG2 to have strong opinions, loosely held,&amp;#8221; and I think that&amp;#8217;s about right.  We want to provide a clear path that works and works well, with a solid foundation, but we also want to have the humility to know that the opinions we bake into our framework are not always right for every web-app.   And we want to trust our development community to know when to stay one the easy path, and when to try out new ways of doing things, or use WSGI components that work better for their apps.  &lt;/p&gt;</description>
	<pubDate>Wed, 04 Feb 2009 04:49:47 +0000</pubDate>
</item>
<item>
	<title>Jonathan LaCour: Buy My Expertise and Save Lives!</title>
	<guid>http://cleverdevil.org/computing/79/</guid>
	<link>http://cleverdevil.org/computing/79/</link>
	<description>&lt;p&gt;&lt;center&gt;&lt;div&gt;&lt;/div&gt;&lt;/center&gt;&lt;/p&gt;
 &lt;img src=&quot;http://thirstrelief.shootq.com/img/shootq_thirstrelief_logo.png&quot; /&gt;&lt;br /&gt;


	&lt;p&gt;I&amp;#8217;m proud to report that my employer, &lt;a href=&quot;http://web.shootq.com&quot;&gt;ShootQ&lt;/a&gt; is sponsoring the &lt;a href=&quot;http://thirstrelief.shootq.com&quot;&gt;ThirstRelief Mentor Auction&lt;/a&gt; to benefit &lt;a href=&quot;http://thirstrelief.org&quot;&gt;ThirstRelief International&lt;/a&gt;. Bidding starts tonight, Thursday, January 29 at 10 p.m. EST. If you have any interest in photography, I&amp;#8217;d encourage you to participate in the auction, as there are some great opportunities available to interact with some of the best in the world.&lt;/p&gt;

	&lt;p&gt;One of the auctions available to bid on is a 90-minute mentor session with the ShootQ development team, including yours truly. While we may not be as glitzy as some of the other folks up for auction, I&amp;#8217;d like to think that we could still fetch a nice sum. So &lt;a href=&quot;http://thirstrelief.shootq.com&quot;&gt;join in the cause, and start bidding&lt;/a&gt; tonight!&lt;/p&gt;

	&lt;p&gt;Its a joy to be a part of a business that puts such an emphasis on making a difference in the world, and I am excited to be able to chip in a bit myself.&lt;/p&gt;</description>
	<pubDate>Thu, 29 Jan 2009 16:00:17 +0000</pubDate>
</item>
<item>
	<title>Christopher Perkins: Coding Binge</title>
	<guid>http://percious.com/blog/archives/18</guid>
	<link>http://percious.com/blog/archives/18</link>
	<description>&lt;p&gt;    &lt;/p&gt;
&lt;p&gt;I haven&amp;#8217;t written to the blog in a while.  Quite frankly, I&amp;#8217;ve been busy.  In the last 30 days, I have released 3 software new packages, updated 1, deprecated 1, participated in a sprint that lasted a virtual 2 weeks, closed countless tickets, and pushed forward TG2 functionality.&lt;/p&gt;
&lt;p&gt;TG2b4 was released last Saturday.  This was mostly a bug-fix release, but b3 is where the new functionality really came into the scene.  TG2b3 is the first build to include &lt;a href=&quot;http://sprox.org&quot;&gt;Sprox&lt;/a&gt;, a new library for schema-generated widget generation.  Sprox is the offspring of DBSprockets.  I decided I liked the declarative part of DBSprockets so much I wanted to spin it off as it&amp;#8217;s own entity.  Sprox looses DBSprocket&amp;#8217;s table-based dependency, utilizing the mapping provided by SQLAlchemy.  I realized that much of DBSprocket&amp;#8217;s code was doing precisely what SQLSoup was designed to do, and decided to focus my efforts on making and extremely configurable widget base.  The result was a considerable removal of the cruft that was associated with DBSprockets.  Sprox releases with an excellent documentation base provided by Sphinx.&lt;/p&gt;
&lt;p&gt;There has been a bit of resistance to Sprox, people were/are confused/upset about my providing yet more options for schema based widget generation.  The fact is I have yet to find anything that performs as well as Sprox from a developer/speed standpoint, and I needed to provide our TurboGears user base with a better way to administrate their site, and also allow them to use that tool component-wise in their system.  I think this method for developing widgets is well done in other frameworks, and we need a solid answer to this problem.  &lt;a href=&quot;http://sprox.org&quot;&gt;Sprox&lt;/a&gt; is just that.&lt;/p&gt;
&lt;p&gt;The next step was to re-work Catwalk to use Sprox.  This took a little effort, and I put in RESTful URLs while I was at it, but struggled with making the URLs work within TG2&amp;#8217;s dispatch system.  The result was as close to REST as you can get without conforming to a set &lt;a href=&quot;http://microformats.org/wiki/rest/urls&quot;&gt;standard&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The result of hacking REST into Catwalk got me thinking, and I decided to implement content-type dispatch as well as RESTful dipatch in TG2.  I went back for another round on Catwalk, and converted it over to the standard.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;ve also been toying around with &lt;a href=&quot;http://www.dojotoolkit.org&quot;&gt;Dojo&lt;/a&gt; at NREL.  I&amp;#8217;m pretty much done with ExtJS due to licensing issues, a not-so-hot codebase, and weak support from IRC.  It&amp;#8217;s bad when you go on to ask a question on the channel as a 6 month-user of a software project and end up spending all your time answering everyone else&amp;#8217;s questions (as the most experienced person in the room).  Something must be said for an organization that does not push paid consulting as a primary focus on their website&amp;#8230;  #dojo has been an exceptional resource for getting my work done.  Those guys know their software, and lend a great hand to help you with it.&lt;/p&gt;
&lt;p&gt;Back to the topic at hand&amp;#8230; I was able to shoe-horn Dojo into Sprox with little effort, and implemented DojoCatwalk, which worked, but was ultimately not what I wanted.  What I really wanted was configurability.  I started work on tgext.admin, which was supposed to provide enough functionality to replace tgcrud, a command to auto-create crud in your own TG application.  To support &lt;a href=&quot;http://http://www.turbogears.org/2.0/docs/main/Extensions/Admin/index.html?highlight=configuration&quot;&gt;tgext.admin&lt;/a&gt;, I created a new package called tgext.crud, which provided a &lt;a href=&quot;http://code.google.com/p/tgtools/source/browse/projects/tgext.crud/trunk/tgext/crud/controller.py&quot;&gt;CrudRestController&lt;/a&gt;, which is a simple way of providing crud for any object in your model.  AdminController combines this functionality with that of Mark&amp;#8217;s &lt;a href=&quot;http://www.turbogears.org/2.0/docs/main/Controllers.html?highlight=lookup&quot;&gt;lookup&lt;/a&gt; code to provide a fast, configurable set of tables/forms/etc for all objects in your model.  AdminController takes a declarative AdminConfig as input which provides a consistent way to create your administrative toolset.  Did I mention it does Dojo tables with ajax loading?  Yeah.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;m not done with this binge yet.  Catwalk is going to mutate one more time before I&amp;#8217;m through with it.  It is going to become a default-configured AdminController specifically designed to work within the context of a quickstarted TG2 application.  I had one blocker ticket which was solved last weekend, so it&amp;#8217;s time to get Catwalk good and finished.&lt;/p&gt;</description>
	<pubDate>Tue, 27 Jan 2009 23:20:40 +0000</pubDate>
</item>
<item>
	<title>Jonathan LaCour: Metaclasses Demystified [5]</title>
	<guid>http://cleverdevil.org/computing/78/</guid>
	<link>http://cleverdevil.org/computing/78/</link>
	<description>&lt;p&gt;&lt;i&gt;This article originally appeared in the July 2008 issue of &lt;a href=&quot;http://pymag.phparch.com/&quot;&gt;Python
Magazine&lt;/a&gt; and was adapted from Jonathan LaCour&amp;#8217;s
&lt;a href=&quot;http://cleverdevil.org/train&quot;&gt;CLEVERtrain&lt;/a&gt; professional Python training services.&lt;/i&gt;&lt;/p&gt;


	&lt;p&gt;The word &amp;#8220;metaclass&amp;#8221; often strikes fear into the hearts of Python
programmers. This article explores metaclasses in an approachable way, in
order to take the mystery out of metaclasses, and enable you to leverage
metaprogramming techniques to solve real problems.&lt;/p&gt;


	&lt;p&gt;There are few things in the Python world that are so misunderstood and
feared as metaclasses. In fact, when I recently was training a group of
seasoned programmers about metaclasses, I asked the room what sprung to mind
when they heard the word &amp;#8220;metaclass.&amp;#8221; The students shouted out their feelings
in chorus – &amp;#8220;confusing,&amp;#8221; &amp;#8220;magical,&amp;#8221; and worst of all, &amp;#8220;difficult.&amp;#8221;&lt;/p&gt;


	&lt;p&gt;Well, as I told my students that day, when it comes to metaclasses, I&amp;#8217;d
recommend that we called upon the wise words of Douglas Adams in his famed
book &amp;#8220;The Hitchhiker&amp;#8217;s Guide to the Galaxy.&amp;#8221;&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;&amp;#8220;Don&amp;#8217;t panic!&amp;#8221;&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;Once you take a closer look at how object-oriented programming works in
Python, you&amp;#8217;ll quickly discover that not only are metaclasses easy, they&amp;#8217;re
also extremely useful. Here, we&amp;#8217;ll do our best to take all of the mystery out
of metaclasses, and show you that there&amp;#8217;s nothing to be afraid of!&lt;/p&gt;


	&lt;h2&gt;Revisiting Classes&lt;/h2&gt;


	&lt;p&gt;Most Python programmers are familiar with creating classes, and might even
create or modify their own classes several times a week in the course of their
work. Many of us were even taught about classes and object-oriented
programming in the course of our education. But, when was the last time any of
us really thought about classes in depth since we were first introduced to the
concept? I&amp;#8217;d wager that most of us take classes for granted, and don&amp;#8217;t really
think about what they are providing for us, and more importantly, &lt;em&gt;how&lt;/em&gt; they
provide it to us.&lt;/p&gt;


	&lt;p&gt;Understanding metaclasses can be greatly simplified by taking another look
at Python classes, from a slightly different perspective. In order to do this,
lets pose a simple question. What exactly does a class &lt;em&gt;do&lt;/em&gt;?&lt;/p&gt;


	&lt;p&gt;My first instinct when attempting to answer this question is to rely on my
education, which unearths big, fancy, computer-sciency words like
&amp;#8220;encapsulation&amp;#8221; and &amp;#8220;abstraction.&amp;#8221; Its tempting to allow this to cloud our
thinking, so lets do our best to think at a much simpler level when
considering this question. So, I ask again – what does a class do?&lt;/p&gt;


	&lt;p&gt;Fundamentally, a class is used to construct objects called &lt;em&gt;instances&lt;/em&gt;.
This is essentially all a class does – creates instances. The process of
creating instances using a class is called &lt;em&gt;instantiation&lt;/em&gt;. For example, given
a class &lt;code&gt;Person&lt;/code&gt;, we can instantiate it to create an &amp;#8220;instance&amp;#8221; of that
&lt;code&gt;Person&lt;/code&gt; class.&lt;/p&gt;


&lt;code&gt;&lt;pre&gt;
    class Person(object):
        pass

    jonathan = Person()
&lt;/pre&gt;&lt;/code&gt;

	&lt;p&gt;This instance is related back to its class in that the class is what
&lt;em&gt;constructs&lt;/em&gt; the instance. What do we mean by &amp;#8220;construct&amp;#8221;? Well, when a class
is instantiated, it constructs an instance by providing it with its
&amp;#8220;namespace.&amp;#8221; We all know from Tim Peters&amp;#8217; &amp;#8220;The Zen of Python&amp;#8221; that namespaces
are a &amp;#8220;honking great idea,&amp;#8221; and classes are a great example of why! The
attributes in the namespace of a class are used to define the namespace of its
instances, thus providing those instances with behavior and state. Lets
enhance our &lt;code&gt;Person&lt;/code&gt; class, to see how this works.&lt;/p&gt;


&lt;code&gt;&lt;pre&gt;
    &amp;gt;&amp;gt;&amp;gt; class Person(object):
    ...    greeting = 'Hello'
    ...    
    ...    def greet(self, who):
    ...        print self.greeting, who

    &amp;gt;&amp;gt;&amp;gt; jonathan = Person()
    &amp;gt;&amp;gt;&amp;gt; jonathan.greet('Readers')
    'Hello Readers'
&lt;/pre&gt;&lt;/code&gt;

	&lt;p&gt;The &lt;code&gt;Person&lt;/code&gt; class now has two attributes in its namespace – &lt;code&gt;greeting&lt;/code&gt; and
&lt;code&gt;greet&lt;/code&gt;. When we instantiate our &lt;code&gt;Person&lt;/code&gt; class, our instance is given both
state, in the form of the &lt;code&gt;greeting&lt;/code&gt; attribute, and behavior, in the form of
the &lt;code&gt;greet&lt;/code&gt; method. In this way, a class is of critical and primary importance
in defining how its instances will behave.&lt;/p&gt;


	&lt;p&gt;So, what does a class do? Lets summarize. In a nutshell, a class is an
object with constructs instances through a process called instantiation,
therefore defining the namespace, behavior, and state of that instance.&lt;/p&gt;


	&lt;h2&gt;Defining Metaclasses&lt;/h2&gt;


	&lt;p&gt;Now that we&amp;#8217;ve established clearly what a class is, we can confidently pose
the question – what exactly is a metaclass? When sifting through
documentation, the most common answer you&amp;#8217;ll find to that question is short,
but often difficult to unpack:&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;A metaclass is the class of a class.&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;While this answer is certainly correct and concise, and tells us what a
metaclass &lt;em&gt;is&lt;/em&gt;, it still doesn&amp;#8217;t tell us what a metaclass &lt;em&gt;does&lt;/em&gt;. Lets look
at an alternate answer to the question:&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;A metaclass is a class whose instances are classes.&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;I will concede that this answer is just as much of a mouthful as its
counterpart, but it has the benefit of giving us a clue as to what a metaclass
&lt;em&gt;does&lt;/em&gt;! In short, a metaclass constructs classes. We also know that a
metaclass is just another class, and we&amp;#8217;ve just spent some time outlining what
a class does. As a result, we should be able to build upon what we&amp;#8217;ve learned
about classes earlier to determine a bit more about metaclasses.&lt;/p&gt;


	&lt;p&gt;Recall that a class helps define the behavior and state of its instances.
Metaclasses provide the same basic capability to classes, giving you the
ability to change the way a class will behave at runtime. This technique is
commonly referred to as &amp;#8220;metaprogramming.&amp;#8221;&lt;/p&gt;


	&lt;p&gt;Having a definition of metaclasses and metaprogramming is useful, but lets
take a deeper look by investigating an existing metaclass.&lt;/p&gt;


	&lt;h2&gt;The &lt;code&gt;type&lt;/code&gt; Metaclass&lt;/h2&gt;


	&lt;p&gt;In Python, classes which inherit from &lt;code&gt;object&lt;/code&gt; are called &amp;#8220;new-style
classes.&amp;#8221; All such new-style classes have a default metaclass called &lt;code&gt;type&lt;/code&gt;.
We can prove that &lt;code&gt;type&lt;/code&gt; is the metaclass of &lt;code&gt;object&lt;/code&gt; through simple
introspection in the Python interpreter. Recall, a metaclass is the class of a
class, so what is the class of &lt;code&gt;object&lt;/code&gt;:&lt;/p&gt;


&lt;code&gt;&lt;pre&gt;
    &amp;gt;&amp;gt;&amp;gt; print object.__class__
    &amp;lt;type 'type'&amp;gt;
&lt;/pre&gt;&lt;/code&gt;

	&lt;p&gt;Just as we expected! The metaclass of &lt;code&gt;object&lt;/code&gt; is &lt;code&gt;type&lt;/code&gt;, and thus all
classes which inherit from &lt;code&gt;object&lt;/code&gt; will be provided with this metaclass by
default. Classes that do not inherit from &lt;code&gt;object&lt;/code&gt; are called &amp;#8220;old-style
classes&amp;#8221; and will disappear in Python 3.0. While old-style classes also
support metaclasses and metaprogramming, we&amp;#8217;ll focus on new-style classes in
this article for the sake of simplicity.&lt;/p&gt;


	&lt;p&gt;Typically, classes are defined using the &lt;code&gt;class&lt;/code&gt; statement in Python, as
we saw in our earlier &lt;code&gt;Person&lt;/code&gt; example. However, we have just learned that
metaclasses create classes when they are instantiated. This means that we
should be able to define a class by instantiating the &lt;code&gt;type&lt;/code&gt; metaclass
manually.&lt;/p&gt;


	&lt;p&gt;Lets define our original &lt;code&gt;Person&lt;/code&gt; class again, but this time, lets do it
without using the &lt;code&gt;class&lt;/code&gt; statement by instantiating the &lt;code&gt;type&lt;/code&gt; metaclass:&lt;/p&gt;


&lt;code&gt;&lt;pre&gt;
    &amp;gt;&amp;gt;&amp;gt; def greet(self, who):
    ...    print self.greeting, who

    &amp;gt;&amp;gt;&amp;gt; Person = type(
    ...    'Person', 
    ...    (object,),
    ...    {'greet': greet, 'greeting': 'Hello'}
    ... )
    &amp;gt;&amp;gt;&amp;gt;
    &amp;gt;&amp;gt;&amp;gt; jonathan = Person()
    &amp;gt;&amp;gt;&amp;gt; jonathan.greet('Readers')
    'Hello Readers'
&lt;/pre&gt;&lt;/code&gt;

	&lt;p&gt;This method of creating classes is equivalent to using the &lt;code&gt;class&lt;/code&gt;
statement, and reveals quite a bit about how metaclasses work. The constructor
for a metaclass expects very specific arguments:&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;The first argument is the name of the class.&lt;/li&gt;
		&lt;li&gt;The second argument is a tuple of the base classes for the class.&lt;/li&gt;
		&lt;li&gt;The last argument is a dictionary representing the namespace of the class.
  This dictionary contains all of the attributes that would typically appear
  within the body of a class statement.&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;Now, we&amp;#8217;ve seen a metaclass in action, and we know how to instantiate them
to create classes. Armed with this knowledge of the default &lt;code&gt;type&lt;/code&gt; metaclass,
we can now tackle the much more interesting problem of creating our own
metaclasses.&lt;/p&gt;


	&lt;h2&gt;Defining Metaclasses&lt;/h2&gt;


	&lt;p&gt;Defining metaclasses in Python is as simple as creating a class that
inherits from the built-in &lt;code&gt;type&lt;/code&gt; metaclass. The constructor for our metaclass
will take the same arguments as the constructor for the &lt;code&gt;type&lt;/code&gt; metaclass:&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;The class name.&lt;/li&gt;
		&lt;li&gt;A tuple of the class bases.&lt;/li&gt;
		&lt;li&gt;A dictionary representing the namespace of the class.&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;Constructors typically perform some action on their instances, so lets make
our constructor set a flag on the instance that we can inspect to make sure
that our metaclass is being used.&lt;/p&gt;


&lt;code&gt;&lt;pre&gt;
    class MyFirstMeta(type):
        def __init__(cls, name, bases, ns):
            cls.uses_my_metaclass = True
&lt;/pre&gt;&lt;/code&gt;

	&lt;p&gt;One important thing to note here is that the first argument to the
constructor of a class is typically called &lt;code&gt;self&lt;/code&gt;, as it refers to the
instance being constructed. It is conventional to name the first argument of a
metaclass constructor &lt;code&gt;cls&lt;/code&gt; as the metaclass instance is actually a &lt;em&gt;class&lt;/em&gt;.&lt;/p&gt;


	&lt;p&gt;Now that we&amp;#8217;ve defined our metaclass, we know that we can construct a new
class called &lt;code&gt;MyClass&lt;/code&gt; simply by instantiating the metaclass:&lt;/p&gt;


&lt;code&gt;&lt;pre&gt;
    &amp;gt;&amp;gt;&amp;gt; MyClass = MyFirstMeta('MyClass', (object,), {})
    &amp;gt;&amp;gt;&amp;gt; print MyClass.uses_my_metaclass
    True
&lt;/pre&gt;&lt;/code&gt;

	&lt;p&gt;This very simple metaclass has given us our first glimpse into the power of
metaclasses. Within our metaclass constructor, we gave our class some state in
the form of a boolean attribute &lt;code&gt;uses_my_metaclass&lt;/code&gt;. Metaclasses have the
power to add, remove, or modify any attribute of the class being constructed.
Metaclasses will frequently add or replace methods on their instances, based
upon the data in the namespace of the class. Many Python object-relational
mappers use metaclasses to transform the attributes of a class into database
table definitions, for example.&lt;/p&gt;


	&lt;p&gt;While you can certainly construct classes by manually instantiating custom
metaclasses, it is much more convenient to use the &lt;code&gt;class&lt;/code&gt; statment to create
your classes. Python allows you to define the metaclass for a class by using
the special &lt;code&gt;__metaclass__&lt;/code&gt; attribute in your class statement:&lt;/p&gt;


&lt;code&gt;&lt;pre&gt;
    class MyClass(object):
        __metaclass__ = MyFirstMeta
&lt;/pre&gt;&lt;/code&gt;

	&lt;p&gt;This is the preferred method of attaching metaclasses to your classes. An
important thing to note about this syntax is that while you are not manually
instantiating the metaclass when defining your classes this way, the Python
interpeter &lt;em&gt;will&lt;/em&gt; instantiate the metaclass. The metaclass instantiation
will occur immediately after the class statement has been fully executed. As a
result, bugs in metaclasses often are triggered during imports. In a way, the
class statement is simply syntactic sugar for instantiating metaclasses!&lt;/p&gt;


	&lt;h2&gt;Mystery Metaclass Methods&lt;/h2&gt;


	&lt;p&gt;Before we move onto some practical examples of metaclasses, lets
investigate metaclass definition a bit further. Our &lt;code&gt;Person&lt;/code&gt; class defines a
method called &lt;code&gt;greet&lt;/code&gt; within its namespace. Instances of &lt;code&gt;Person&lt;/code&gt; will thus
have an &amp;#8220;instance method&amp;#8221; called &lt;code&gt;greet&lt;/code&gt;. We know what happens when we define
methods on a class, but what happens if we define a method on a &lt;em&gt;metaclass&lt;/em&gt;?&lt;/p&gt;


	&lt;p&gt;Methods defined on a class become &lt;em&gt;instance methods&lt;/em&gt;. Since instances of
metaclasses are &lt;em&gt;classes&lt;/em&gt;, methods defined on metaclasses become _class
methods_. Lets take a look at this in practice:&lt;/p&gt;


&lt;code&gt;&lt;pre&gt;
    &amp;gt;&amp;gt;&amp;gt; class MysteryMeta(type):
    &amp;gt;&amp;gt;&amp;gt; ... def mystery_method(cls):
    &amp;gt;&amp;gt;&amp;gt; ...     return 'I am a class method!'
    &amp;gt;&amp;gt;&amp;gt; 
    &amp;gt;&amp;gt;&amp;gt; class Mystery(object):
            __metaclass__ = MysteryMeta
    &amp;gt;&amp;gt;&amp;gt; 
    &amp;gt;&amp;gt;&amp;gt; print Mystery.mystery_method()
    I am a class method!
&lt;/pre&gt;&lt;/code&gt;

	&lt;p&gt;This revelation often surprises people, but is a logical outcome of the
fact that metaclasses are simply classes which produce classes. Many
metaclasses utilize this capability of defining class methods, but it is often
preferable to define such class methods on a base class, which is easier to
document and understand.&lt;/p&gt;


	&lt;p&gt;We&amp;#8217;ve now established what metaclasses are, how they work, and how we can
define our own by inheriting from &lt;code&gt;type&lt;/code&gt;. But, what about practical use
cases for metaclasses? Lets take a look at several examples of how we might
come to use metaprogramming in practice.&lt;/p&gt;


	&lt;h2&gt;Example: The Enforcer&lt;/h2&gt;


	&lt;p&gt;When I am teaching Python to programmers with strong backgrounds in
&amp;#8220;bondage and discipline&amp;#8221; languages like Java, I frequently hear the same
complaints about Python. One such complaint is that class definitions are
&amp;#8220;loose&amp;#8221; and you cannot enforce the type of variables by declaring them
up-front. In order to illustrate how to use metaclasses, lets define a little
library that will address this particular complaint.&lt;/p&gt;


	&lt;p&gt;Our goal is to create a base class called &lt;code&gt;Enforcer&lt;/code&gt; that will enforce the
types of attributes on its subclasses. Lets say we wanted to enforce that the
&lt;code&gt;name&lt;/code&gt; attribte of our &lt;code&gt;Person&lt;/code&gt; class was a string, and that the &lt;code&gt;age&lt;/code&gt;
attribute was an integer. Attempting to set attribtues with the wrong type
should trigger a &lt;code&gt;TypeError&lt;/code&gt; to be raised, just like the Java compiler would
catch such errors.&lt;/p&gt;


&lt;code&gt;&lt;pre&gt;
    class Person(Enforcer):
        name = Field(str)
        age = Field(int)
&lt;/pre&gt;&lt;/code&gt;

	&lt;p&gt;The first thing we need to do is define the &lt;code&gt;Field&lt;/code&gt; class, which we will
use to hold onto the type of the variable we&amp;#8217;re attempting to restrict. Lets
also give it the ability to validate whether or not a value is of the right
type for that particular attribute:&lt;/p&gt;


&lt;code&gt;&lt;pre&gt;
    class Field(object):
        def __init__(self, ftype):
            self.ftype = ftype

        def is_valid(self, value):
            return isinstance(value, self.ftype)
&lt;/pre&gt;&lt;/code&gt;

	&lt;p&gt;Now that we have our &lt;code&gt;Field&lt;/code&gt; class, we need to create a metaclass that will
look at the namespace of our class, searching for &lt;code&gt;Field&lt;/code&gt; definitions, and
then storing them in a dictionary for later use. Recall that the last argument
to the constructor of a metaclass is a dictionary containing the namespace of
the class. We can loop through this namespace to find &lt;code&gt;Field&lt;/code&gt; definitions:&lt;/p&gt;


&lt;code&gt;&lt;pre&gt;
    class EnforcerMeta(type):
        def __init__(cls, name, bases, ns):
            # store the field definitions on the class as a dictionary 
            # mapping the field name to the Field instance.
            cls._fields = {}

            # loop through the namespace looking for Field instances
            for key, value in ns.items():
                if isinstance(value, Field):
                    cls._fields[key] = value
&lt;/pre&gt;&lt;/code&gt;

	&lt;p&gt;Our metaclass first attaches a &lt;code&gt;_fields&lt;/code&gt; dictionary to the class itself.
This data structure is where we will store &lt;code&gt;Field&lt;/code&gt; definitions for later
use. We then loop through the items in the namespace looking for &lt;code&gt;Field&lt;/code&gt;
instances, and finally we store them in our &lt;code&gt;_fields&lt;/code&gt; dictionary.&lt;/p&gt;


	&lt;p&gt;Next up is the &lt;code&gt;Enforcer&lt;/code&gt; base class itself. The &lt;code&gt;Enforcer&lt;/code&gt; base class
first needs to attach the &lt;code&gt;EnforcerMeta&lt;/code&gt; metaclass we&amp;#8217;ve just defined. This is
a very common way for libraries to distribute their metaclasses, by defining a
base class to inherit from, rather than requiring users to even know that a
metaclass is being used, or how to attach the metaclass to their classes.&lt;/p&gt;


	&lt;p&gt;The second thing the &lt;code&gt;Enforcer&lt;/code&gt; base class needs to do is to override the
&lt;code&gt;__setattr__&lt;/code&gt; method. This is a special method on Python classes that allows
you to override the default attribute setting behavior on your Python objects.
The &lt;code&gt;__setattr__&lt;/code&gt; method takes in the name of the attribute being set, and the
value being set.&lt;/p&gt;


&lt;code&gt;&lt;pre&gt;
    class Enforcer(object):
        # attach the metaclass
        __metaclass__ = EnforcerMeta

        def __setattr__(self, key, value):
            if key in self._fields:
                if not self._fields[key].is_valid(value):
                    raise TypeError('Invalid type for field!')
            super(Enforcer, self).__setattr__(key, value)
&lt;/pre&gt;&lt;/code&gt;

	&lt;p&gt;Our &lt;code&gt;Enforcer&lt;/code&gt; class first attaches the metaclass. Then, it overrides the
&lt;code&gt;__setattr__&lt;/code&gt; method so that it can watch for field assignments. First, we
check to see if the attribute being set is one of our defined fields. Then, we
ask the field definition if the value that is being passed is valid for the
field definition. If it is not a valid type for the field, we raise a
&lt;code&gt;TypeError&lt;/code&gt;.&lt;/p&gt;


	&lt;p&gt;The last line of the &lt;code&gt;Enforcer&lt;/code&gt; class is extremely important. This line is
instructing the Python interpreter to call the &lt;code&gt;__setattr__&lt;/code&gt; implementation
on the appropriate superclass definition, in this case &lt;code&gt;object&lt;/code&gt;. Without
this line, attribute setting would fail on all &lt;code&gt;Enforcer&lt;/code&gt; subclasses.&lt;/p&gt;


	&lt;p&gt;Lets try out our new creation from the Python interactive prompt:&lt;/p&gt;


&lt;code&gt;&lt;pre&gt;
    &amp;gt;&amp;gt;&amp;gt; class Person(Enforcer):
    ...    name = Field(str)
    ...    age = Field(int)
    ... 
    &amp;gt;&amp;gt;&amp;gt; jonathan = Person()
    &amp;gt;&amp;gt;&amp;gt; jonathan.name = 3
    TypeError: Invalid type
    &amp;gt;&amp;gt;&amp;gt; jonathan.age = 'Old'
    TypeError: Invalid type
    &amp;gt;&amp;gt;&amp;gt; jonathan.name = 'Jonathan'
    &amp;gt;&amp;gt;&amp;gt; jonathan.age = 28
&lt;/pre&gt;&lt;/code&gt;

	&lt;p&gt;Our metaclass has completely changed the way that our class behaves,
transforming it into a more rigid class definition that keeps our Java-loving
friends happy. While such restrictive enforcement is atypical in Python, it
certainly shows how powerful metaclasses can be.&lt;/p&gt;


	&lt;p&gt;This example also illustrates a common pattern for metaclasses, in which a
class describes how it wants to behave in a &amp;#8220;declarative&amp;#8221; way without actually
writing any code to implement that behavior. The metaclass subsequently takes
that metadata, and uses it to &amp;#8220;reprogram&amp;#8221; the class. This is the essence of
what metaprogramming brings to the table, and is the most popular use-case for
metaclasses.&lt;/p&gt;


	&lt;h2&gt;Example: Auto Decorator&lt;/h2&gt;


	&lt;p&gt;Since being given a special syntax in Python 2.4, decorators have become a
very commonly used feature. A decorator is essentially a wrapper around a
function or method. In versions of Python prior to 2.4, decorators were
applied by manually replacing the method definition with a &amp;#8220;decorated&amp;#8221; version
of the method. Starting in Python 2.4, decorators could be applied using the
now popular &lt;code&gt;@decorator&lt;/code&gt; syntax.&lt;/p&gt;


	&lt;p&gt;Sometimes, I find myself in the situation where I need to decorate all of
the methods of a class with the same decorator. Lets create a metaclass that
will simplify this process by automatically applying a decorator that is
declared in the namespace of the class:&lt;/p&gt;


&lt;code&gt;&lt;pre&gt;
    import inspect

    class AutoDecorateMeta(type):
        def __init__(cls, name, bases, ns):
            deco = ns.get('decorator', lambda f: f)
            for key, value in ns.items():
                # skip the decorator and constructor
                if key in ('decorator', '__init__'): continue

                # skip objects in the namespace that aren't methods
                if not inspect.isfunction(value): continue

                # apply the decorator
                setattr(cls, key, deco(value))
&lt;/pre&gt;&lt;/code&gt;

	&lt;p&gt;Our metaclass first looks up an attribute named &lt;code&gt;decorator&lt;/code&gt; in the
namespace of the class. This is the decorator that we will apply to every
method of the class. Note that if such a decorator cannot be found in the
namespace of the class, we define a fake decorator that will simply return the
existing method definition.&lt;/p&gt;


	&lt;p&gt;Next, we loop through the namespace of the class looking for methods. If we
encounter the decorator or the constructor, we skip them, as we don&amp;#8217;t want to
decorate our constructor or the decorator itself. We then make use of the
&lt;code&gt;inspect&lt;/code&gt; module to determine if the value is a method, and if it is, we
replace the method definition with a decorated version of that method.&lt;/p&gt;


	&lt;p&gt;Lets put our metaclass to the test by creating a class that defines several
properties. Typically, we&amp;#8217;d have to decorate every method with the
&lt;code&gt;@property&lt;/code&gt; decorator, which could add a lot of verbosity to our class,
depending on the number of methods we&amp;#8217;d have to decorate.&lt;/p&gt;


&lt;code&gt;&lt;pre&gt;
    class Person(object):
        __metaclass__ = AutoDecorateMeta
        decorator = property

        def __init__(self, first, middle, last):
            self.first = first
            self.middle = middle
            self.last = last

        def name(self):
            return '%s %s' % (self.first, self.last)

        def full_name(self):
            return '%s %s %s' % (self.first, self.middle, self.last)

        def initials(self):
            return '%s%s%s' % (self.first[0], self.middle[0], self.last[0])
&lt;/pre&gt;&lt;/code&gt;

	&lt;p&gt;Now that we&amp;#8217;ve created our class, we should be able to try it out from our
Python interactive prompt to see if all of our methods were transformed into
properties:&lt;/p&gt;


&lt;code&gt;&lt;pre&gt;    
    &amp;gt;&amp;gt;&amp;gt; mlk = Person('Martin', 'Luther', 'King')
    &amp;gt;&amp;gt;&amp;gt; print mlk.name
    Martin King
    &amp;gt;&amp;gt;&amp;gt; print mlk.full_name
    Martin Luther King
    &amp;gt;&amp;gt;&amp;gt; print mlk.initials
    MLK
&lt;/pre&gt;&lt;/code&gt;

	&lt;p&gt;Not only is this example useful in practice, it also illustrates another
use case for metaclasses and metaprogramming – automating repetitive tasks
that occur in class definition. This metaclass could be used to wrap every
method of a class in a transaction, to add debugging hooks, or even to
synchronize all of the methods using a thread lock.&lt;/p&gt;


	&lt;h2&gt;Cautionary Notes&lt;/h2&gt;


	&lt;p&gt;Metaclasses are fantastically cool, and as we&amp;#8217;ve seen, they can be pretty
useful. The rise of object-relational mappers and web frameworks have put
metaclasses into use by an increasing number of Python users, and has
increased the visibility of metaclasses substantially. That being said,
metaclasses are a feature of Python that must be used carefully. Because
metaclasses do their work at class definition time, bugs in your metaclasses
can result in errors that are triggered at import time. In addition,
metaclasses are often hidden from the programmer behind a base class, which
can cause confusion.&lt;/p&gt;


	&lt;p&gt;Applied judiciously, metaclasses can be a great tool for solving problems,
and give Python programmers the ability to take advantage of metaprogramming
techniques in their own code. I hope that this article has shed some light on
what metaclasses are, and has taken some of the mystery out of metaclasses.&lt;/p&gt;</description>
	<pubDate>Sat, 10 Jan 2009 19:00:12 +0000</pubDate>
</item>
<item>
	<title>Andrew Grover: Moving to TG2, Part 1</title>
	<guid>tag:blogger.com,1999:blog-6972144554804670310.post-318372080315746183</guid>
	<link>http://bandradar.blogspot.com/2009/01/moving-to-tg2-part-1.html</link>
	<description>&lt;div&gt;This is the start of a series on the work we're doing upgrading BandRadar's components. BandRadar's development started in 2006, and used the default components of TurboGears at the time: SQLObject for ORM, kid for templating, tgwidgets for widgeting, mochikit for js library, and CherryPy as appserver.&lt;br /&gt;&lt;br /&gt;Basically all of these components are now obsolete, or at least no longer recommended for new TG/TG2 projects. But they still work fine, so why change?&lt;br /&gt;&lt;br /&gt;Good question. I'm hoping that re-examining the choices we made in implementing BandRadar version 1 will bear dividends in terms of simplifying the code or making it easier to add new functionality, but honestly it's not clear at this point whether time spent on this work will have more value than spending it on extending the current code. It also depends on how hard moving to the new components is. Thankfully, TurboGears will let us transition to new components in stages, instead of all at once.&lt;br /&gt;&lt;br /&gt;The plan:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;SQLObject to SQLAlchemy (Elixir)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;kid to Genshi&lt;/li&gt;&lt;li&gt;tg.widgets to ToscaWidgets&lt;/li&gt;&lt;li&gt;CherryPy to Pylons/mod_wsgi&lt;/li&gt;&lt;/ol&gt;Currently working on #1. Converting classes derived from class SQLObject to class Entity and defining the relationships has been relatively painless. All our table names are not what Elixir is expecting, but it's easy to tell it what they should be. The first little bit of trouble is that SQLObject did not create db constraints for required fields, it keeps track of these itself and throws an error if a required field is omitted when creating an object. SA appears to rely on the database for this (which makes sense) but our existing db schema (originally created by SO) will need to be updated by hand for the new not-NULL constraints. We've also added a fair number of additional methods to the objects on model.py, and these will need to be reimplemented in SA-ese. Finally, our SO model includes a feature where all modifications to some tables are logged to a separate table (so we could recover from vandalism if necessary)... this will need to be reimplemented in SA, or we need to jump to versioned objects. I'd prefer the former, frankly, but I don't know if SA has a feature equivalent to sqlobject.events, or if I could just override __setattr__() in my model objects.&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img width=&quot;1&quot; height=&quot;1&quot; src=&quot;https://blogger.googleusercontent.com/tracker/6972144554804670310-318372080315746183?l=bandradar.blogspot.com&quot; /&gt;&lt;/div&gt;</description>
	<pubDate>Mon, 05 Jan 2009 14:12:39 +0000</pubDate>
</item>
<item>
	<title>Jorge Vargas: TurboGears2 and ExtJS tutorial app</title>
	<guid>http://www.maetico.com/turbogears2-and-extjs-tutorial-app/</guid>
	<link>http://www.maetico.com/turbogears2-and-extjs-tutorial-app/</link>
	<description>&lt;p&gt;For some time someone has been asking me, actually saying near me &amp;#8220;We should write a tutorial on how to use ExtJS with TurboGears&amp;#8221;, this morning someone on IRC was having big troubles getting it to work and I figured out that it will take me less time to write it than to sit down and explain, I was wrong but I did it anyway.&lt;/p&gt;
&lt;p&gt;The example is very simple. It takes &lt;a href=&quot;http://www.extjs.com/deploy/dev/examples/grid/array-grid.html&quot;&gt;one basic&lt;/a&gt; ExtJS tutorial which originally was a locally loaded grid and transforms it into a remote(&amp;#8221;Ajaxy&amp;#8221;) grid with the same data, so even though it looks the same this is loaded from the Database. I wrote it with TurboGears trunk mainly because that is what I had around but also I wanted to test the new quickstart template in it&amp;#8217;s non-auth version, in theory it should run on TG1.9.7b2 but I haven&amp;#8217;t tested it. You can get a copy from the temporal mercurial repositiory &lt;a href=&quot;http://freehg.org/u/jorgevargas/tg-extjs-sample/&quot;&gt;here&lt;/a&gt;, I say temporal becuase I&amp;#8217;m going to finally enable hg.maetico.com soonTM.&lt;/p&gt;
&lt;p&gt;Back to the tutorial, you can follow the changesets as they explain each step in detail, (together with mistakes!)  the steps are simple&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt; quickstart a TG2 project&lt;/li&gt;
&lt;li&gt;Add extjs to the public/javascript folder&lt;/li&gt;
&lt;li&gt;Create the model and copy the &amp;#8216;myData&amp;#8221; variable, notice how much JS looks like python, all I had to do was delete the var and the ;&lt;/li&gt;
&lt;li&gt;Then we take advantage of one of the great features of turbogears, automagical json from the ORM. Don&amp;#8217;t believe me? take a look at &lt;a href=&quot;http://freehg.org/u/jorgevargas/tg-extjs-sample/rev/cc7e96e71110&quot;&gt;this changeset&lt;/a&gt;. 3 lines will take all objects from the dband output json. And the exact same code works for any SQLAlchemy object.&lt;/li&gt;
&lt;li&gt;copy over the rest of the extjs sample to a JS file, and modify it to have a JsonStore (http+json reader) instead of the SimpleStore(local array reader)&lt;/li&gt;
&lt;li&gt;Add all your JS to the template and your done! well except one detail.&lt;/li&gt;
&lt;li&gt;EXTJS likes to send a _dc parameter I really don&amp;#8217;t know why I believe it&amp;#8217;s to prevent proxy&amp;#8217;s cache or something, therefore we need to tell TG about it and then simple don&amp;#8217;t do anything with it.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;So what are you waiting for? go get the trunk we need lots of testing before our &lt;a href=&quot;http://trac.turbogears.org/milestone/2.0b1&quot;&gt;2.0b1&lt;/a&gt; release! since you already clicked on that link, why don&amp;#8217;t you take a look at the remaining tickets, they are mostly documentation and tests, easy things &lt;img src=&quot;http://www.maetico.com/wp-includes/images/smilies/icon_smile.gif&quot; alt=&quot;:)&quot; class=&quot;wp-smiley&quot; /&gt; &lt;/p&gt;
&lt;p&gt;Peace out.&lt;/p&gt;</description>
	<pubDate>Wed, 17 Dec 2008 09:16:29 +0000</pubDate>
</item>
<item>
	<title>Jorge Vargas: TurboGears 2 and I</title>
	<guid>http://www.maetico.com/turbogears-2-and-i/</guid>
	<link>http://www.maetico.com/turbogears-2-and-i/</link>
	<description>&lt;p&gt;This is no news to the people close to the project but it will be for everyone else.&lt;/p&gt;
&lt;p&gt;I have decided to exercise my committer rights, and actually give back to the project, in terms of code. I have been giving a lot back in terms of help, if you don&amp;#8217;t believe me check &lt;a href=&quot;http://groups.google.com/group/turbogears/about&quot;&gt;this&lt;/a&gt; and &lt;a href=&quot;http://groups.google.com/group/turbogears-trunk/about&quot;&gt;this&lt;/a&gt;, on the &amp;#8220;top posters part&amp;#8221;. And yes I have had SVN checking privileges for a long time, several years actually, I just never made it public until now.&lt;/p&gt;
&lt;p&gt;What I plan (actually been doing for at least a week) to do in the short term.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Get TG2 b1 out of the door, we did a lot of work this weekend and cut the pending tickets more than half, we started with around 40 and at this moment at 11, which by the way are almost all documentation tickets&lt;/li&gt;
&lt;li&gt;Finish my TG1.1 to TG2 migration guide, the first &lt;a href=&quot;http://docs.turbogears.org/2.0/RoughDocs/1.1Migration&quot;&gt;draft is here&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Work on my Widgets 3.0 idea, search the trunk list of it, I need a name by the way, so suggestions are welcome&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In the mid term&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Work on a TWsite code, to make it usable for www.turbogears.org&lt;/li&gt;
&lt;li&gt;Work on finally getting TurboGears on mercurial&lt;/li&gt;
&lt;li&gt; writing and rewriting several apps I have and launching them on top of TG2.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Anyway enough talk back to the tickets.&lt;/p&gt;
&lt;p&gt;Long term&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;TurboGears 2.1&lt;/li&gt;
&lt;/ul&gt;</description>
	<pubDate>Mon, 15 Dec 2008 21:50:03 +0000</pubDate>
</item>
<item>
	<title>Luke Macken: &gt;&gt;&gt; from fedora.client import Wiki</title>
	<guid>http://lewk.org/blog/tags/wiki</guid>
	<link>http://lewk.org/blog/wiki.html</link>
	<description>&lt;p&gt;
I created a simple Python API for interacting with &lt;a href=&quot;http://fedoraproject.org/wiki&quot;&gt;Fedora's MediaWiki&lt;/a&gt; a while back, in an attempt to gather various metrics.  I just went ahead and committed it to the &lt;a href=&quot;http://fedorahosted.org/python-fedora&quot;&gt;python-fedora&lt;/a&gt; modules.  Here is how to use it:
&lt;/p&gt;

&lt;blockquote&gt;&lt;code&gt;
&lt;font&gt;
&amp;gt;&amp;gt;&amp;gt; &lt;font color=&quot;#cd00cd&quot;&gt;from&lt;/font&gt;&amp;nbsp;fedora.client &lt;font color=&quot;#cd00cd&quot;&gt