<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" version="2.0">

<channel>
	<title>DevChix » Python</title>
	
	<link>http://www.devchix.com</link>
	<description>Boys can't have all the fun</description>
	<pubDate>Sat, 04 Jul 2009 06:18:34 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.7.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/devchix/mNrv" type="application/rss+xml" /><item>
		<title>I Love Python: ReSTful DB CRUD dispatching using CherryPy</title>
		<link>http://www.devchix.com/2009/04/19/i-love-python-restful-db-crud-dispatching-using-cherrypy/</link>
		<comments>http://www.devchix.com/2009/04/19/i-love-python-restful-db-crud-dispatching-using-cherrypy/#comments</comments>
		<pubDate>Sun, 19 Apr 2009 15:57:49 +0000</pubDate>
		<dc:creator>gloriajw</dc:creator>
		
		<category><![CDATA[Book]]></category>

		<category><![CDATA[Database]]></category>

		<category><![CDATA[Python]]></category>

		<category><![CDATA[Servers]]></category>

		<category><![CDATA[Thoughts]]></category>

		<guid isPermaLink="false">http://www.devchix.com/?p=230</guid>
		<description><![CDATA[CherryPy has been one of my favorite Python tools for several years. It should be mentioned here that a ReSTful dispatcher could easily be written in web.py, or pylons as well, and even comes for free in the latest TurboGears implementation. 
But if you&#8217;re looking for a small, easily manageable and extremely dynamic ReST dispatching [...]]]></description>
			<content:encoded><![CDATA[<p>CherryPy has been one of my favorite Python tools for several years. It should be mentioned here that a ReSTful dispatcher could easily be written in web.py, or pylons as well, and even comes for free in the latest TurboGears implementation. </p>
<p>But if you&#8217;re looking for a small, easily manageable and extremely dynamic ReST dispatching solution without the heft of an entire web framework, I&#8217;m about to show you how CherryPy can help you in three different ways, depending on your model.</p>
<p>Assuming this mapping:</p>
<p>HTTP GET or HEAD = DB Read<br />
HTTP POST = DB update<br />
HTTP PUT = DB insert<br />
HTTP DELETE = DB delete</p>
<p>Let&#8217;s also standardize on one common method across all examples, for determining the HTTP request type, and matching it to the function of the same name. Here is the full code snippet for accomplishing this task:</p>
<pre>
methods = ('OPTIONS','GET','HEAD','POST',
'PUT','DELETE','TRACE','CONNECT')

if cherrypy.request.method not in self.methods:
    raise cherrypy.HTTPError(400,'Bad Request')

# If request method is HEAD, return the page handler
# for GET, and let CherryPy take care of dropping
# the response body
method = cherrypy.request.method

if cherrypy.request.method == "HEAD":
    method = "GET"

http_method = getattr(self,method)

#print "HTTP Method: %s" % method

result=(http_method)(args,kwargs)
</pre>
<p>In our examples, we&#8217;re going to shorten this to:</p>
<pre>
http_method = getattr(self.m,cherrypy.request.method)
return (http_method)(args,kwargs)
</pre>
<p>All of this essentially determines how HTTP was called (GET/PUT/POST/DELETE), and calls the method in a class which exactly matches this name (self.GET(), self.PUT(), etc)<br />
When you see this code, know that it&#8217;s just the HTTP method resolving code. </p>
<p>Now for the fun. Let&#8217;s look at the dispatcher options we have. </p>
<h3>Way 1: A hard-coded URL pointing to fixed resources: </h3>
<p>CherryPy can be used in a manner similar to this to establish a fixed URL, and corresponding resources, driven from predefined classes instantiated in the &#8216;root&#8217; hierarchy:</p>
<pre>
import cherrypy

class ReSTPaths1:
	@cherrypy.expose
	def index(self):
		http_method = getattr(self,cherrypy.request.method)
		return (http_method)()

	def GET(self):
		return "In GET 1.."

class ReSTPaths2:
	@cherrypy.expose
	def index(self):
		http_method = getattr(self,cherrypy.request.method)
		return (http_method)()

	def GET(self):
		return "In GET 2.."

class ReSTPaths3:
	@cherrypy.expose
	def index(self,client_id=None):
		http_method = getattr(self,cherrypy.request.method)
		return (http_method)(client_id)

	def GET(self,client_id=None):
		return "IN Get 3, your client_id is %s\n" % (client_id)

cherrypy.server.socket_port=8081

root=ReSTPaths1()
root.client = ReSTPaths2()
root.client.address = ReSTPaths3()
cherrypy.quickstart(root)
</pre>
<p>Once this is running, the URL to invoke it looks like this:<br />
http://localhost:8081/<br />
http://localhost:8081/client/<br />
http://localhost:8081/client/address/<br />
http://localhost:8081/client/address/?client_id=34567<br />
http://localhost:8081/client/address/34567</p>
<p>Output looks something like this:</p>
<pre>
In GET 1..
In GET 2..
IN Get 3, your client_id is None
</pre>
<p>If you&#8217;re new to CherryPy or Python in general, I&#8217;ll reiterate for you how we are calling the GET method in our class. </p>
<p>When we issue this request, we&#8217;re issuing what HTTP calls a GET request:</p>
<p>http://localhost:8081/</p>
<p>The CherryPy service above, listening on port 8081, calls the index() method on the root class. The root class was set to:</p>
<p>root=ReSTPaths1()</p>
<p>at the bottom of that file. The index() method from the ReSTPaths1 Class looks like this, at the top of that file:</p>
<pre>
	def index(self):
		http_method = getattr(self,cherrypy.request.method)
		return (http_method)()
</pre>
<p>If we were to insert a print cherrypy.request.method statement before the return, we would see it set to &#8220;GET&#8221;. </p>
<p>getattr simply says: &#8220;get me the function name in self, matching the string &#8220;GET&#8221;.<br />
it returns a reference to self.GET(), which is set directly below the index:</p>
<pre>
	def GET(self):
		return "In GET 1.."
</pre>
<p>Notice that the index() method has a <strong>@cherrrypy.expose</strong> decorator above it. This makes the index method callable by the public. The GET method does not have it, which means we could never invoke the GET method by typing:</p>
<p>http://localhost:8081/GET</p>
<p>If you try this, you&#8217;ll get a 404 Not Found error, because it&#8217;s not visible through the CherryPy interface.</p>
<p>GET() has to be invoked through index(), which means GET can only be called if an HTTP GET request is issued. If we posted form data to this same URL from, say, a form entry asking people for data input, we would need to add a POST method to this ReSTPaths1() class, to receive the POST data entered in the form fields.</p>
<p>Now back to our example:</p>
<p>In this example, no part of the URL or associated resources are dynamic, in either initialization or run time. This is fine, and suits the needs of most ReSTful CRUD interfaces. </p>
<h3>Way 2: URL paths and associated components dynamically set once, upon dispatcher init/startup: </h3>
<p>Now let&#8217;s say we want to determine the contents of the root, and therefore the URLs and associated resources for our ReSTful interface, dynamically during initialization/startup. </p>
<p>We can assign the root setting by using a Python metaclass to generate classes in our CherryPy startup code, and set the root components to each generated class. This goes beyond the average needs for CRUD access, but it&#8217;s such a nice implementation that I must show it off:</p>
<pre>
import cherrypy

class MetaCRUD(type):
	@cherrypy.expose
	def index(cls):
		http_method = getattr(cls,cherrypy.request.method)
		return (http_method)()

	def GET(cls): return "In class ", cls.__name__, ', received a GET request.'

	def PUT(cls): return "In class ", cls.__name__, ', received a PUT request.'

	def POST(cls): return "In class ", cls.__name__, ', received a POST request.'

	def DELETE(cls): return "In class ", cls.__name__, ', received a DELETE request.'

baseCRUD = MetaCRUD('baseCRUD',(),{})
root = baseCRUD

dynamic_class = {}

for d in ['legacy_dbi','new_dbi','some_other_dbi']:
	dynamic_class[d] = MetaCRUD(d,(),{})
	setattr(root,d,dynamic_class[d])

cherrypy.server.socket_port=8081
cherrypy.quickstart(root)
</pre>
<p>Here we&#8217;re using a metaclass, with CherryPy exposed methods, to generate a dictionary of dynamic classes. We set the root.classname = the_new_class by using the setattr() method. </p>
<p>After initialization, URL components and resources are fixed in this model. But wow, the awesome power we have during initialization, in 28 lines really rocks. I wrote this in 30 minutes, and realized again why I am so head-over-heels in love with this language. </p>
<p>When we hit these URLs:</p>
<pre>
http://localhost:8081/
http://localhost:8081/legacy_dbi/
http://localhost:8081/new_dbi/
http://localhost:8081/some_other_dbi/
</pre>
<p>We see this output:</p>
<pre>
In class baseCRUD, received a GET request.
In class legacy_dbi, received a GET request.
In class new_dbi, received a GET request.
In class some_other_dbi, received a GET request.
</pre>
<p>Let&#8217;s issue a POST request via curl, on the command line. The response is returned:</p>
<pre>
[gloriajw@g-monster ~]$ curl http://localhost:8081/some_other_dbi/ -d ""
In class some_other_dbi, received a POST request.
</pre>
<p>This model could be used for, say, reading the contents of the Postgres template1 databases list or the mysql &#8217;show databases&#8217; command, and auto-generating a ReSTful CRUD interface for each. Access of each resources can be controlled via HTTP Auth methods. This is a great solution to providing, and restricting, legacy database access for new processes through a standard interface. </p>
<h3>Way 3: Live, ever-dynamic determination of URL and associated component: </h3>
<p>Some ReSTful URL models may need to be &#8216;run-time dynamic&#8217;, especially in the case where databases are dynamically created, and the associated resources per new database could vary. There is a simple example of a dynamic URL and resource model:</p>
<pre>
import cherrypy
import pprint

class ReSTPaths:
	@cherrypy.expose
	def __init__(self):
		pass

	@cherrypy.expose
	def client(self,*args,**kwargs):
		return "Your HTTP method was %s. Your args are: %s and your kwargs are: %s\n" \
		% (cherrypy.request.method, pprint.pformat(args), pprint.pformat(kwargs))

	@cherrypy.expose
	def address(self,*args,**kwargs):
		return "Your HTTP method was %s. Your args are: %s and your kwargs are: %s\n" \
		% (cherrypy.request.method, pprint.pformat(args), pprint.pformat(kwargs))

cherrypy.quickstart(ReSTPaths())
</pre>
<p>This allows for dynamic URLs such as:<br />
http://localhost:8080/client/address/34567<br />
http://localhost:8080/client/address?client_id=34567<br />
http://localhost:8080/address/client?client_id=34567<br />
http://localhost:8080/address/client/34567<br />
http://localhost:8080/address/anything/anything_else</p>
<p>The output from this code looks like this:</p>
<pre>
Your HTTP method was GET. Your args are: ('address', '34567') and your kwargs are: {}
Your HTTP method was GET. Your args are: ('address',) and your kwargs are: {'client_id': '34567'}
Your HTTP method was GET. Your args are: ('client',) and your kwargs are: {'client_id': '34567'}
Your HTTP method was GET. Your args are: ('client', '34567') and your kwargs are: {}
Your HTTP method was GET. Your args are: ('anything', 'anything_else') and your kwargs are: {}
</pre>
<p>Notice that we only have keyword args (kwargs) when we pass a named parameter, such as client_id=34567</p>
<p>Let&#8217;s try a POST request from curl, on the command line:</p>
<pre>
[gloriajw@g-monster ~]$ curl -d "something_else=whatever_i_want" http://localhost:8080/address/anything/anything_else
Your HTTP method was POST. Your args are: ('anything', 'anything_else') and your kwargs are: {'something_else': 'whatever_i_want'}
</pre>
<p>In this code, the sky is the limit. You can place whatever code you like in these methods, dynamically creating classes and resources as needed, letting them only persist until the result is returned. This may add some inefficiency, but in exchange offer more secure network resources.</p>
<p>Code is attached, Enjoy!</p>
<p>Gloria</p>
<p><a href="http://www.devchix.com/wp-content/uploads/2009/04/restfixedargs.py">http://www.devchix.com/wp-content/uploads/2009/04/restfixedargs.py</a></p>
<p><a href="http://www.devchix.com/wp-content/uploads/2009/04/restmeta.py">http://www.devchix.com/wp-content/uploads/2009/04/restmeta.py</a></p>
<p><a href="http://www.devchix.com/wp-content/uploads/2009/04/restvarargs.py">http://www.devchix.com/wp-content/uploads/2009/04/restvarargs.py</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.devchix.com/2009/04/19/i-love-python-restful-db-crud-dispatching-using-cherrypy/feed/</wfw:commentRss>
		</item>
		<item>
		<title>I Love Python: Twitter Feed/Content Auth and Scrape in One HTTP Request</title>
		<link>http://www.devchix.com/2009/02/21/i-love-python-twitter-feedcontent-auth-and-scrape-in-one-http-request/</link>
		<comments>http://www.devchix.com/2009/02/21/i-love-python-twitter-feedcontent-auth-and-scrape-in-one-http-request/#comments</comments>
		<pubDate>Sat, 21 Feb 2009 18:03:04 +0000</pubDate>
		<dc:creator>gloriajw</dc:creator>
		
		<category><![CDATA[Python]]></category>

		<category><![CDATA[Thoughts]]></category>

		<guid isPermaLink="false">http://www.devchix.com/?p=202</guid>
		<description><![CDATA[This is some lingering code from a GrrlCamp project, written by Gaba. It is such a handy, great little nugget of code.  It logs into a Twitter account and scrapes either the content or the RSS feed (your choice), in one fell swoop, using Base64 encoding of the login and password in the HTTP [...]]]></description>
			<content:encoded><![CDATA[<p>This is some lingering code from a GrrlCamp project, written by Gaba. It is such a handy, great little nugget of code.  It logs into a Twitter account and scrapes either the content or the RSS feed (your choice), in one fell swoop, using Base64 encoding of the login and password in the HTTP request header. Very clever:</p>
<pre>
import urllib2, base64
import sys
import feedparser
#import configuration

class Page:

    def __init__(self):
        self.data = {}
        self.data["url"] = 'http://www.twitter.com/gloriajw'
        self.data["username"] = 'gloriajw'
        self.data["password"] = 'XXXXXXXXXX'

        self.data["urlrss"] = 'http://twitter.com/statuses/user_timeline/18107956.rss'

    def __getitem__(self, key):
        return self.data[key]

    def __setitem__(self,key, value):
        self.data[key] = value

    def getContent(self):
        base64string = base64.encodestring('%s:%s' % (self.data['username'], self.data['password']))[:-1]
        authheader =  "Basic %s" % base64string

        req = urllib2.Request(self.data["url"])
        req.add_header("Authorization", authheader)
        try:
            handle = urllib2.urlopen(req)
        except IOError, e:                  # here we shouldn't fail if the username/password is right
            print "It looks like the username or password is wrong."
            sys.exit(1)

        return handle.read()

    def getRSS(self):
        base64string = base64.encodestring('%s:%s' % (self.data['username'], self.data['password']))[:-1]
        authheader =  "Basic %s" % base64string

        req = urllib2.Request(self.data["urlrss"])
        req.add_header("Authorization", authheader)
        try:
            handle = urllib2.urlopen(req)
        except IOError, e:                  # here we shouldn't fail if the username/password is right
            print "It looks like the username or password is wrong."
            sys.exit(1)

        return handle.read()

    def getData(self):
        """auth = urllib2.HTTPBasicAuthHandler()
        auth.add_password('BasicTest', 'twitter.com', self.data['username'], self.data['password'])

        return feedparser.parse('http://www.twitter.com/statuses/user_timeline/18107956.rss', handlers=[auth])
        """

        return feedparser.parse('http://%s:%s@twitter.com/statuses/user_timeline/18107956.rss' % (self.data['username'], self.data['password']))
</pre>
<p>To invoke it:</p>
<pre>
class Data:
    def __init__(self, entries):
        self.entries = entries

    def save(self):
        pass

    def parse(self):
        pass

    def imprimir(self):
        for item in self.entries:
            print item.title
</pre>
<p>And this:</p>
<pre>
def main():
    page = Page()    

    statuses = page.getData().entries

    data = Data(statuses)
    data.save()

    data.imprimir()    

if __name__ == "__main__":
    main()
</pre>
<p>This code will also be attached, in case of copy/paste mangling.</p>
<p>In both getContent() and getData(), Gaba constructs the HTTP response header so that the encoded username and password are passed in the Authorization section of the header. This is easier and more secure than making two requests, and maintaining session cookies. Very nice indeed. This can be used to sign into any web site which accepts HTTP Basic authentication headers (there are different types of HTTP authentication (BASIC, DIGEST, FORM, and CLIENT-CERT).</p>
<p>It is left as an exercise for you to get the content (not the feed) and use BeautifulSoup to extract the data portions. If you want to try this, and need help, post questions here. </p>
<p>Enjoy,<br />
Gloria</p>
]]></content:encoded>
			<wfw:commentRss>http://www.devchix.com/2009/02/21/i-love-python-twitter-feedcontent-auth-and-scrape-in-one-http-request/feed/</wfw:commentRss>
		</item>
		<item>
		<title>PyCon is coming soon, watch for us!</title>
		<link>http://www.devchix.com/2009/01/27/pycon-is-coming-soon-watch-for-us/</link>
		<comments>http://www.devchix.com/2009/01/27/pycon-is-coming-soon-watch-for-us/#comments</comments>
		<pubDate>Tue, 27 Jan 2009 18:08:53 +0000</pubDate>
		<dc:creator>gloriajw</dc:creator>
		
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://www.devchix.com/?p=197</guid>
		<description><![CDATA[I&#8217;ll be doing a tutorial on Kamaelia on Wednesday, March 25:
http://us.pycon.org/2009/tutorials/schedule/1AM7/
Alex McFerron is my assistant. 
The fee which I would normally collect to teach this tutorial at PyCon (something like $750) will be donated to Alex&#8217;s Math Circle Outreach for kids.
All tutorials will be videotaped and put somewhere on the net. Exciting, eh?  Watch [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ll be doing a tutorial on Kamaelia on Wednesday, March 25:</p>
<p>http://us.pycon.org/2009/tutorials/schedule/1AM7/</p>
<p>Alex McFerron is my assistant. </p>
<p>The fee which I would normally collect to teach this tutorial at PyCon (something like $750) will be donated to Alex&#8217;s Math Circle Outreach for kids.</p>
<p>All tutorials will be videotaped and put somewhere on the net. Exciting, eh?  Watch for us. We&#8217;re going to rock this out. </p>
<p>If you&#8217;re at PyCon, feel free to say hi and take me out for a beer, to which I&#8217;ll gladly reciprocate. I&#8217;m staying for all of the tutorials and code sprints. Woot! I can&#8217;t wait!</p>
<p>My email addy: gloriajw_66 at yahoo dot com</p>
<p>Gloria</p>
]]></content:encoded>
			<wfw:commentRss>http://www.devchix.com/2009/01/27/pycon-is-coming-soon-watch-for-us/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Hadoop Streaming and Python: No Jython necessary!</title>
		<link>http://www.devchix.com/2008/12/25/hadoop-streaming-and-python-no-jython-necessary/</link>
		<comments>http://www.devchix.com/2008/12/25/hadoop-streaming-and-python-no-jython-necessary/#comments</comments>
		<pubDate>Thu, 25 Dec 2008 23:25:27 +0000</pubDate>
		<dc:creator>gloriajw</dc:creator>
		
		<category><![CDATA[Design]]></category>

		<category><![CDATA[MySQL]]></category>

		<category><![CDATA[Python]]></category>

		<category><![CDATA[Thoughts]]></category>

		<guid isPermaLink="false">http://www.devchix.com/?p=192</guid>
		<description><![CDATA[Here is another jewel of an article, written by Michael Noll:
http://www.michael-noll.com/wiki/Writing_An_Hadoop_MapReduce_Program_In_Python
As hardware costs plummet and greater bandwidth becomes more affordable, cloud computing becomes even more alluring and feasible for the hobbyist. Working with large data sets is an interesting problem set, now attainable by the average developer with a free LINUX hard drive partition and [...]]]></description>
			<content:encoded><![CDATA[<p>Here is another jewel of an article, written by Michael Noll:<br />
<a href="http://www.michael-noll.com/wiki/Writing_An_Hadoop_MapReduce_Program_In_Python">http://www.michael-noll.com/wiki/Writing_An_Hadoop_MapReduce_Program_In_Python</a></p>
<p>As hardware costs plummet and greater bandwidth becomes more affordable, cloud computing becomes even more alluring and feasible for the hobbyist. Working with large data sets is an interesting problem set, now attainable by the average developer with a free LINUX hard drive partition and some spare time. </p>
<p>Hadoop is essentially a framework, written in Java, for accessing large data sets. For the average developer, it&#8217;s usually used in conjunction with HDFS which is a custom file system designed for stroing large data sets on cheaper hardware. HDFS data is usually stored in units of entire web pages written to disk &#8220;as-is&#8221;. Once stored, this large data set is accessible for parsing and analysis. </p>
<p>Indexing of this data is done via what is called a map-reduce algorithm. The easiest map-reduce algorithm to envision is the word count algorithm. Each word on a page is assigned the value &#8220;1&#8243; in the map portion, then all words are counted by sorting the words and adding their values. The result is a frequency count of each word in a page. This is the simplest of ten well known map-reduce algorithms, found in this white paper:</p>
<p><a href="http://www.cs.stanford.edu/people/ang//papers/nips06-mapreducemulticore.pdf">http://www.cs.stanford.edu/people/ang//papers/nips06-mapreducemulticore.pdf</a></p>
<p>The magic of Michael&#8217;s article is in how to prevent the stringent, often painful Jython interface to Hadoop. This trick is by streaming this data on the command line from his simpler, more Pythonic map-reduce algorithm directly to Hadoop, thereby avoiding the complex Jython interface. Very clever indeed! It would be wonderful to see all of the relatively standard map-reduce algorithms written in Python.</p>
<p>He has a couple of other great articles on exactly how to install and configure Hadoop on Ubuntu here:<br />
<a href="http://www.michael-noll.com/wiki/Running_Hadoop_On_Ubuntu_Linux_(Single-Node_Cluster)">http://www.michael-noll.com/wiki/Running_Hadoop_On_Ubuntu_Linux_(Single-Node_Cluster)</a></p>
<p>and here:</p>
<p><a href="http://www.michael-noll.com/wiki/Running_Hadoop_On_Ubuntu_Linux_(Multi-Node_Cluster)">http://www.michael-noll.com/wiki/Running_Hadoop_On_Ubuntu_Linux_(Multi-Node_Cluster)</a></p>
<p>On top of Hadoop is usually a metdata store, holding high level information about which page sets or data &#8220;chunks&#8221; can be found on which volumes, for efficiency. After attending a cloud computing conference in November, I realized that many companies have chosen to write their own metadata layer using <a href="http://www.hivedb.org/">HiveDB</a>, or custom metadata tools, and many distributed MySQL databases, rather than settling for the expensive commercial solutions. This great work is the primary cause of the proliferation of easily accessible Open Source cloud computing tools. </p>
<p>Another project to watch is called <a href="http://lucene.apache.org/mahout/">Mahout</a>, which is an attempt to make all of the well known map-reduce algorithms generally accessible across multicore Hadoop systems. </p>
<p>I run Fedora 10, and have a bit more work to do, but it is outstanding to see such an easily accessible installation for such a relatively complex set of tools. So many software tools and toys, so little time! </p>
<p>Gloria</p>
]]></content:encoded>
			<wfw:commentRss>http://www.devchix.com/2008/12/25/hadoop-streaming-and-python-no-jython-necessary/feed/</wfw:commentRss>
		</item>
		<item>
		<title>The Creative Commons license, and change.gov: Our new president gets it!</title>
		<link>http://www.devchix.com/2008/12/02/the-creative-commons-license-and-changegov-our-new-president-gets-it/</link>
		<comments>http://www.devchix.com/2008/12/02/the-creative-commons-license-and-changegov-our-new-president-gets-it/#comments</comments>
		<pubDate>Tue, 02 Dec 2008 20:23:58 +0000</pubDate>
		<dc:creator>gloriajw</dc:creator>
		
		<category><![CDATA[Book]]></category>

		<category><![CDATA[Introductions]]></category>

		<category><![CDATA[Python]]></category>

		<category><![CDATA[Thoughts]]></category>

		<guid isPermaLink="false">http://www.devchix.com/?p=189</guid>
		<description><![CDATA[I was really excited and moved to see this:
http://change.gov/newsroom/entry/towards_a_21st_century_government/
This copyright license affects most content on the website change.gov, guaranteeing transparency and the feedom to redistribute and discuss it&#8217;s content. 
All I can say is, wow. This president not only believes in transparency, but understands how to implement it using existing tools and conventions. He understands [...]]]></description>
			<content:encoded><![CDATA[<p>I was really excited and moved to see this:</p>
<p><a href="http://change.gov/newsroom/entry/towards_a_21st_century_government/">http://change.gov/newsroom/entry/towards_a_21st_century_government/</a></p>
<p>This copyright license affects most content on the website change.gov, guaranteeing transparency and the feedom to redistribute and discuss it&#8217;s content. </p>
<p>All I can say is, wow. This president not only believes in transparency, but understands how to implement it using existing tools and conventions. He understands the spirit of Open Source software development, and everything that has come about since this movement began. Imagine an &#8220;Open Government&#8221;, genuinely implemented and influenced by the people, and it&#8217;s hard not to want to get involved.</p>
<p>The change.gov web site has a very nice, simple form, requesting your ideas and suggestions. They already have proposals for nationwide fiber optic broadband, automation and transparency in the patent process, and automation of health insurance data to bring healthcare costs down. There are many more places where technology can automate away inefficient and error prone processes. </p>
<p>We here on DevChix all know how technology has changed our lives. Let them know how it can change a nation. Submit your ideas and suggestions, and let&#8217;s help educate and influence this new administration.</p>
<p>Gloria</p>
]]></content:encoded>
			<wfw:commentRss>http://www.devchix.com/2008/12/02/the-creative-commons-license-and-changegov-our-new-president-gets-it/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Shameless plug</title>
		<link>http://www.devchix.com/2008/11/24/shameless-plug/</link>
		<comments>http://www.devchix.com/2008/11/24/shameless-plug/#comments</comments>
		<pubDate>Mon, 24 Nov 2008 17:01:29 +0000</pubDate>
		<dc:creator>gloriajw</dc:creator>
		
		<category><![CDATA[Python]]></category>

		<category><![CDATA[Thoughts]]></category>

		<guid isPermaLink="false">http://www.devchix.com/?p=188</guid>
		<description><![CDATA[My article appears in this month&#8217;s Python Magazine.
This article was written months ago, and a few small utilities have been created since then, which would have made this article shorter. With the current 8.3 Postgresql distribution comes a new external db creation tool, which eliminates some of the documented weirdness of isolation level 0 DB [...]]]></description>
			<content:encoded><![CDATA[<p>My article appears in this month&#8217;s <a href=" http://www.pythonmagazine.com">Python Magazine</a>.<br />
This article was written months ago, and a few small utilities have been created since then, which would have made this article shorter. With the current 8.3 Postgresql distribution comes a new external db creation tool, which eliminates some of the documented weirdness of isolation level 0 DB creation and access. But other than that, the code associated with this article still serves as a great example of database agnostic ORM methodology in Python. </p>
<p>Please give the sample code a try, and feel free to ask any questions, etc.</p>
<p>Gloria </p>
]]></content:encoded>
			<wfw:commentRss>http://www.devchix.com/2008/11/24/shameless-plug/feed/</wfw:commentRss>
		</item>
		<item>
		<title>From Python 2.6 to PHP 5.2: A circuitous journey</title>
		<link>http://www.devchix.com/2008/11/20/from-python-26-to-php-52-a-circuitous-journey/</link>
		<comments>http://www.devchix.com/2008/11/20/from-python-26-to-php-52-a-circuitous-journey/#comments</comments>
		<pubDate>Thu, 20 Nov 2008 20:02:08 +0000</pubDate>
		<dc:creator>gloriajw</dc:creator>
		
		<category><![CDATA[Book]]></category>

		<category><![CDATA[Introductions]]></category>

		<category><![CDATA[PHP]]></category>

		<category><![CDATA[People]]></category>

		<category><![CDATA[Python]]></category>

		<category><![CDATA[Thoughts]]></category>

		<guid isPermaLink="false">http://www.devchix.com/?p=187</guid>
		<description><![CDATA[When I started heavily using PHP 5.2 (not by choice, I&#8217;ll admit), I was impressed, but I suffered from some incorrect assumptions about what PHP5 is and is not capable of doing. The good news is that it is more object oriented than it&#8217;s predecessor, but has some caveats to consider. Here are some things [...]]]></description>
			<content:encoded><![CDATA[<p>When I started heavily using PHP 5.2 (not by choice, I&#8217;ll admit), I was impressed, but I suffered from some incorrect assumptions about what PHP5 is and is not capable of doing. The good news is that it is more object oriented than it&#8217;s predecessor, but has some caveats to consider. Here are some things to be aware of when switching from a pure OO language to PHP5:</p>
<p>1: A nonexistent PHP array key generates no error or warning. When trying to iterate over a nonexistent array key, a warning occurs. In other languages, both of these conditions throw an exception.</p>
<p>Try this code for example:</p>
<pre>
&lt;?
$dictionary=array('one'=>'got one','two'=>'have two','four'=>'missing three?');
foreach (array_keys($dictionary) as $key)
{
	print "Key is:".$key.", value is:".$dictionary[$key]."\n";
}
print "Try undefined key three, no warning occurs:".$dictionary['three']."\n";
foreach ($dictionary['three'] as $value)
{
	print "Now we're iterating over a nonexistent key:";
	print "Key is: three, value is:".$dictionary['three']."\n";
}
?>
</pre>
<p>Running it results in this output:</p>
<pre>
php test.php
Key is:one, value is:got one
Key is:two, value is:have two
Key is:four, value is:missing three?
Try undefined key three, no warning occurs:

Warning: Invalid argument supplied for foreach() in /root/test.php on line 8
</pre>
<p>If it is vital to me to make sure I am aware of missing keys, I only have two choices. If I need a proactive solution, I have to use the array_key_exists() function to do existence checking before use. If I want a reactive solution, I  write a log scanner, to pick up on these warnings. In every other OO language I have used, an exception was thrown for this condition, and my exception handling determined if the error was vital enough to have to exit immediately or not. This seems like a more efficient way to handle this condition. I would imaging PHP5 does not do this because of it&#8217;s need to be backward compatible with PHP4, but this is a guess. </p>
<p>It would be wonderful to have a -OO flag for PHP, which gives you the option to run PHP and expect more standard, stricter OO behavior in these instances. </p>
<p>2: Warnings cannot be &#8220;caught&#8221; like exceptions. Exceptions and warnings are distinctly separate beasts, and never the twain shall meet. Fine, I thought, maybe I could detect warnings similar to how we detect errors. But it seems like warnings cannot be detected when they happen. There is no PHP code I know of which can check if a warning had occurred in runtime. I tried to detect it using array error_get_last() but to no avail. if you know how, post your trick here.</p>
<p>3: In PHP, &#8216;true&#8217; evaluates to an integer &#8216;1&#8242;. To get the boolean &#8216;true&#8217; value from a &#8216;true&#8217; statement, one needs to var_export() a true statement. Similarly, or maybe not, &#8216;false&#8217; evaluates to no output. Here is an example:</p>
<pre>
&lt;?
print "\nThe raw value of a true statement in PHP:".true;
print "\nThe raw value of a false statement in PHP:".false;
print "\nThe exported value of a true statement in PHP:".var_export(true,true);
print "\nThe exported value of a false statement in PHP:".var_export(false,true);
print "\n";
?>
</pre>
<p>And the output:</p>
<pre>
The raw value of a true statement in PHP:1
The raw value of a false statement in PHP:
The exported value of a true statement in PHP:true
The exported value of a false statement in PHP:false
</pre>
<p>This may not be noticeable to you in a standard expression. But if you&#8217;re doing funky stuff, like using the evaluated expression values as key references into the dictionary of a decision tree, for example, 1 does not equal &#8216;true&#8217;, and the difference matters quite a bit. </p>
<p>4: Long running processes with recursive circular references (such as Doctrine code) run out of memory. This is documented in many places, and the free() function works sometimes. A fix is coming in PHP 5.3. The foolproof solution for my code in production today (youch!) is to periodically restart the daemon. If you&#8217;re cringing right now, know that you&#8217;re not cringing alone. </p>
<p>There may be a part II to this article. Feel free to add your own PHP5 observations. </p>
<p>Gloria</p>
]]></content:encoded>
			<wfw:commentRss>http://www.devchix.com/2008/11/20/from-python-26-to-php-52-a-circuitous-journey/feed/</wfw:commentRss>
		</item>
		<item>
		<title>GEOPY: Rockin’ out geocoding for Python</title>
		<link>http://www.devchix.com/2008/11/12/geopy-rockin-out-geocoding-for-python/</link>
		<comments>http://www.devchix.com/2008/11/12/geopy-rockin-out-geocoding-for-python/#comments</comments>
		<pubDate>Thu, 13 Nov 2008 04:12:09 +0000</pubDate>
		<dc:creator>gloriajw</dc:creator>
		
		<category><![CDATA[Python]]></category>

		<category><![CDATA[python geocoding]]></category>

		<guid isPermaLink="false">http://www.devchix.com/?p=185</guid>
		<description><![CDATA[*waving*
I have a bit of a breather between contracts, so I&#8217;m back from a writing hiatus to show you more nifty Python tools and juicy goodness.
This is yet another great example of Python&#8217;s elegance and ease of use:
http://exogen.case.edu/projects/geopy/
It doesn&#8217;t just geocode. It gives you a common API to just about all of the publicly accessible [...]]]></description>
			<content:encoded><![CDATA[<p>*waving*</p>
<p>I have a bit of a breather between contracts, so I&#8217;m back from a writing hiatus to show you more nifty Python tools and juicy goodness.</p>
<p>This is yet another great example of Python&#8217;s elegance and ease of use:</p>
<p><a href="http://exogen.case.edu/projects/geopy/">http://exogen.case.edu/projects/geopy/</a></p>
<p>It doesn&#8217;t just geocode. It gives you a common API to just about all of the publicly accessible URL-based geocode services. The web page labels which ones require a key for access, and which ones do not. Beautiful!</p>
<p>The library is also able to calculate distances using several different distance approximation formulae, as well as parse out and reformat geographical data. Now this is some nifty <strong>py-candy</strong>, eh?</p>
<p>Nice Job <a href="http://blog.brianbeck.com/">Brian</a>, you rocked this out. </p>
<p>My only gripes are not with this tool at all, but with geocoding in general:</p>
<p>1: Where to get accurate, free IP address geocoding?</p>
<p>2: Why isn&#8217;t this data free for download, damn it? What if I want to use a cross section of it, and store it in my own database, without paying a fortune for it? One day, will Open Street Map be the source for Open Source geocode data which is freely downloadable, thus eliminating the 1000 queries per day limit? </p>
<p>Maybe we should all join forces, and store the results from 1000 queries per day per person, and build this database ourselves? Hmmm&#8230;</p>
<p>Gloria</p>
<p>PS: The geopy project has a code sprint scheduled for this Sunday, Nov. 16. Join in!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.devchix.com/2008/11/12/geopy-rockin-out-geocoding-for-python/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Rails Summit Latin America</title>
		<link>http://www.devchix.com/2008/10/16/rails-summit-latin-america/</link>
		<comments>http://www.devchix.com/2008/10/16/rails-summit-latin-america/#comments</comments>
		<pubDate>Thu, 16 Oct 2008 20:58:09 +0000</pubDate>
		<dc:creator>desi</dc:creator>
		
		<category><![CDATA[Events]]></category>

		<category><![CDATA[Introductions]]></category>

		<category><![CDATA[Presentation]]></category>

		<category><![CDATA[Python]]></category>

		<category><![CDATA[Rails]]></category>

		<category><![CDATA[Reviews]]></category>

		<category><![CDATA[Ruby]]></category>

		<category><![CDATA[Thoughts]]></category>

		<category><![CDATA[Tips and Tricks]]></category>

		<guid isPermaLink="false">http://www.devchix.com/?p=183</guid>
		<description><![CDATA[I am currently in Sao Paulo, Brazil at Rails Summit Latin America and the experience has been great thus far.
Ladies at the conference there is information at the end of this writeup about how to join. If you don&#8217;t feel like reading everything in this writeup that is fine but please do read about joining. [...]]]></description>
			<content:encoded><![CDATA[<p>I am currently in Sao Paulo, Brazil at <a href="http://www.locaweb.com.br/railssummit/default.asp?language=7">Rails Summit Latin America</a> and the experience has been great thus far.</p>
<p><b><i>Ladies at the conference there is information at the end of this writeup about how to join. If you don&#8217;t feel like reading everything in this writeup that is fine but please do read about joining.</i></b> </p>
<p>In contrast to many conferences I have been to recently I have been to just about every talk at this conference and I have thoroughly enjoyed them all. I say just about because there is a second track that is going on in another room but I haven&#8217;t been to those sessions. </p>
<p><b>The Organizers:</b><br />
<a href="http://www.akitaonrails.com/"> Fabio Akita and Gilberto Mautner Founder of <a href="http://www.locaweb.com.br/portal.html">locaweb </a> have done a great job with the conference and I would like to give them a special thanks. The lineup, venue and everything has been great. Obrigado!</p>
<p><b>Theme:</b><br />
I think most conferences, through the keynotes, some how seem to create a theme. The theme that I am picking up on at this conference is this: &#8220;Have No Fear&#8221; and &#8220;Just Do It&#8221;. No one actually said either of those two things but thats basically what I am taking away from most of the keynotes. They have all been especially encouraging for people to become involved. Contribute, create, and code. Give back to the community and get involved. Don&#8217;t be afraid .. put yourself out there and learn from the feedback you get.. learn from the experiences of creating.. do side projects.. basically be PASSIONATE.</p>
<p><b>The Talks:</b><br />
All the talks I have seen have been excellent. I give them an excellent rating because they have all had the qualities I look for in a talk.<br />
1. The content is good and interesting.<br />
2. The delivery of that content is entertaining or at least engaging.</p>
<p><b>Chad Fowler</b> - I really enjoyed Chad&#8217;s talk and as I sit here I am struggling to figure out a way to describe his talk and actually do it justice. He spoke about his background in music and how that has translated to his life as a developer. In addition, he spoke about being remarkable. He talked about many ways in which people are remarkable and many ways in which we ourselves can become remarkable people. He touched on many things and did so in such a way that I was able to stay engaged with him. There were pictures and video&#8217;s and graphs and fake numbers and.. anyway about the best I can say is that I personally really enjoyed his talk.</p>
<p><b>Dr. Nic Williams</b> - Dr. Nic&#8217;s presentation is a little easier to sum up but at the same time I can&#8217;t really do it justice. Dr. Nic is one of those speakers that if you ever have a chance to see him speak you should definitely take the opportunity. He is hilarious and has a good message. His talk was all about how to contribute back.. how to get involved.. how to participate. Make the future you proud of the you now.   <a href="http://drnicwilliams.com/2007/08/20/newgem-using-rubigen-for-generator-support/">Dr. Nic also talked about newgem</a></p>
<p><b>Chris Wanstrath</b> - Chris&#8217;s keynote started off being about the future of Ruby and RoR but in the end he took it back to the past and where we have come from. He went through a great deal of history on how we got here which I personally enjoyed especially when he pointed out the first ENAIC programmers were all women, unfortunately he was speaking quite fast so I think a lot of his talk was lost in translation. I think the primary thing Chris was trying to get across is to not be afraid. If you have an idea.. make time to get to it you never know where thats going to go. In the very least you gain experience and you gain knowledge. <a href="http://www.github.com">Chris has had many projects in the past but his current claim to fame is all about github.</a></p>
<p><b>Jay Fields</b> - Jay&#8217;s talk was about the immaturity of testing as a whole. While I agree with some of the things he said I also disagree with some of the things he said. I have had the luxury of getting to pair with Jay on projects before and its always interesting for me to see him speak because I have first hand experience with a lot of things he talks about. He described the problem of immaturity in testing as a whole first with the fact that we can&#8217;t even agree on common terminology. He then proceeded to talk about various tools and the pros and cons of each. He covered Selenium, Test:Unit, Rspec, Syntasis, and Expectations. The last two being the most immature of them all and bleeding edge. i.e. use at your own risk. He also answered a few questions about how to make your test suite fun faster and his response was basically that if you are willing to deal with the pain that goes along with it there are tools you can look into using such as null_db, unit_record, and ARBS. You can read about them on <a href="http://agilewebdevelopment.com/plugins/nulldb"> the null_db page on Agile Web Development site</a>. That page links out to the other plugins.  Jay also pointed out that all the things he was talking about are from his point of view. In other words its the context in which he works that causes him to have some of the testing beliefs he has.</p>
<p><b>David Chemlisky</b> - David&#8217;s first talk was about doing TDD and in my opinion he did an excellent job of demonstrating TDD. I have seen him give a talk similar in the past and of all the people I have heard try to describe TDD, David is one of the most skilled at it. He gave the talk from the point of view of a teacher which in my opinion is really the only way you can truly explain TDD. He went through the process step by step with us all to show us the way. :)</p>
<p>His second talk was more about Acceptance testing and story runner and the newest version of story runner which is being called cucumber. He demonstrated how it worked and made sure to give context around all the terminology such as user stories etc. Hopefully there will be some way of seeing this talk again maybe through a screen cast or something of that nature. I&#8217;ll be sure to ask him if he would be willing to do that. Or maybe there is one with cucumber? Not sure haven&#8217;t had a chance to look yet.<br />
Couple of links to stuff he talked about.<br />
<a href="http://github.com/aslakhellesoy/cucumber/wikis/home">Cucumber</a><br />
<a href="http://github.com/brynary/webrat/tree/master">webrat on github</a> and <a href="http://movesonrails.com/articles/2008/08/19/webrat-story-steps">a blog post on it here</a></p>
<p>On that last note I am actually interested to know if these talks are being recorded and if they will be available somewhere?  Anyone know the answer to that?</p>
<p><b>Obie Fernandez</b> - I haven&#8217;t actually seen Obie give his talk yet but I have seen the talk (insider information) so I am going to go ahead and give a recap.. I asked him to plug DevChix and wanted to have this write up already done before he did so.. ;-)  So Obie&#8217;s talk will be about the &#8220;Hashrocket Way&#8221;. He is basically giving up our secrets.. Like Dr. Nic said no secrets!  His main focus will be around how we work, the fact that we follow Agile Tenants and that we value fun, collaboration, and effectiveness. We achieve those things through certain practices such as pair programming, TDD, Story Carding, launch parties etc. <a href="http://blog.obiefernandez.com">Again you should check out his blog.</a></p>
<p><b>Ninh Bui and Hongli Lai a.k.a The Phusion Guys</b> - I woke up late so I didn&#8217;t catch all of the talk from the Phusion guys but the part that I did catch was hilariously funny and explained things like caching and database sharding. Additionally, they gave a demo of <a href="http://github.com/FooBarWidget/yuumius_comments/tree/master"> yuumis_comments..</a> and <a href="http://blog.phusion.nl/">here is also a link to their blog</a> </p>
<p>I call out all of these guys because they are some of the best speakers I have ever seen and I actually saw them speak at this particular event. </p>
<p><b>Phillippe Hanrigou</b> - Phillippe is going to be giving a talk on how to effectively do acceptance testing which I am looking forward to but I won&#8217;t be able to cover that here because I haven&#8217;t seen it and since I don&#8217;t have insider info on that one I&#8217;ll just have to wait like everyone else. I do know that he will be talking about one tool I hadn&#8217;t heard of before called <a href="http://deep-test.rubyforge.org/">Deep Test</a>. <a href="http://ph7spot.com">You should check Phillippe&#8217;s blog as well</a></p>
<p><b>Luis Lavena</b> - Luis will also be giving a talk about surviving with RoR and Ruby as a windows user.. again I think the talk is going to be awesome but its in the future so I can&#8217;t really talk about that yet. <a href="http://blog.mmediasys.com/">You should check out his blog!</a></p>
<p><b>The Venue:</b><br />
The venue is quite nice. The main auditorium is very well arranged and has plenty of room despite the fact that there are a lot of people here. There is a very large screen making it easy for everyone to see the slides as well as the speakers. The lighting on the actual speakers is a little weird but other than that the actual conference room is great. The audio is fantastic and the actual hang out area is quite nice as well (other than the lack of air conditioning but thats just me being a little whiny its not really that hot). One other really important point that I want to bring up is the translators. You can get a headset at the checkin area that will translate the talks from English to Spanish and Portuguese and from what I understand the translators have been doing a kick ass job so a special thanks to all those ladies in the booths translating for us. </p>
<p><b>The Community:</b><br />
I was very encouraged by the number of people at the conference, the number of people using github (vast majority) and the number of people doing Ruby and RoR development on a day to day basis. It is always an exciting moment for me when I realize it is gaining in support because how much I love the language. In addition, everyone has been extremely helpful and friendly. We meet <a href="http://www.karmacrash.com/">Tim Case</a> the first day and he was more than willing to take us under his wing and show us around. </p>
<p>One thing that was both encouraging and discouraging is the number of women at the conference. There were women, thats the good news, the bad news is that I think from a ratio point of view the number of women at the conference is on par with what I have experienced at Ruby and RoR conferences in the US. That is to say its pretty small. Usually at conferences since there are so few women I can manage to talk to most of them and but here I have been some what intimidated by the language barrier. One other thing to point out is that there were no women speakers but hey that isn&#8217;t really that uncommon. I am hoping that when Obie does his talk and plugs DevChix for us that many of those women who were at the conference that I didn&#8217;t get to meet will come to the site and join.</p>
<p><b>Ladies Please Read</b><br />
For those women who do happen to come to the site from Brazil and other countries. I would like to say that we have members world wide who can speak a number of different languages so please don&#8217;t let that discourage you from joining and participating. We would LOVE to have you all as part of the group. Also encourage other female developers you know.</p>
<p>If you are a women, a developer, interested in joining and/or contributing to DevChix, please contact Desi McAdam at info(-at-)devchix.com with your:</p>
<p>   1. Name<br />
   2. Email<br />
   3. Do you know any one from DevChix?<br />
   4. A short 2 sentence bio describing your development background/experience (or what you hope to learn) and a link to your blog if you happen to have one.</p>
<p>Obrigado! :) </p>
]]></content:encoded>
			<wfw:commentRss>http://www.devchix.com/2008/10/16/rails-summit-latin-america/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Kamaelia: The future of Python Frameworks looks promising.</title>
		<link>http://www.devchix.com/2008/05/10/kamaelia-the-future-of-python-frameworks-looks-promising/</link>
		<comments>http://www.devchix.com/2008/05/10/kamaelia-the-future-of-python-frameworks-looks-promising/#comments</comments>
		<pubDate>Sat, 10 May 2008 22:42:38 +0000</pubDate>
		<dc:creator>gloriajw</dc:creator>
		
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://www.devchix.com/?p=154</guid>
		<description><![CDATA[Kamaelia is a general purpose Python framework developed by BBC Research.
http://kamaelia.sourceforge.net/Home
It is what I would consider a second generation framework. It has a mature level of feature and plug-in support, and a naturally extensible model, two things which are either rare in most frameworks, or too difficult to be practical. Audio and video plug-in support [...]]]></description>
			<content:encoded><![CDATA[<p>Kamaelia is a general purpose Python framework developed by BBC Research.<br />
<a href="http://kamaelia.sourceforge.net/Home">http://kamaelia.sourceforge.net/Home</a></p>
<p>It is what I would consider a second generation framework. It has a mature level of feature and plug-in support, and a naturally extensible model, two things which are either rare in most frameworks, or too difficult to be practical. Audio and video plug-in support is amazingly clean in the Kamaelia examples. The Kamaelia kernel, named Axon, is the core component for module execution. Module intercommunication happens via pipes, so the issue of the context switch slowness for threaded apps is not an issue here. </p>
<p>Kamaelia also supports OS level threading, but this support seems to be nested down into the TCP protocol module. Nevertheless, the snap-together pipe model is tempting for any app, since it&#8217;s quite easy to grok. The code examples are exactly what Python enthusiasts have come to expect: clean, short, and almost intuitive. </p>
<p>Like many great tools, it comfortably straddles the line between tool and toy, with clean integration of pygame, as well as the support of many common protcols (HTTP, Torrent, etc.) and audio and video codecs (Vorbis, Wav, etc.) supplemented by a solid engine. </p>
<p>The component list for Kamaelia is called the Component Toybox, setting the tone for this project. We are encouraged to play, and novice contributors are encouraged to join and contribute. This is what I love the most about this project. It is unpretentious, approachable by anyone who wants to learn and contribute, and it is well organized and well designed. The documentation flows smoothly, although I&#8217;d love to see more detail on helping newbies find, install and configure all of the dependencies for the dependencies for each architecture. Pygame, for example, needs SDL development libs to run the provided examples. But newbies are stuck calling friends like me to explain this to them and help them past the installation hump. This is a difficult problem to resolve in any toolset dependent on many external toolsets, having their own development paths and practices. Maybe the Python buildout tool, plus some additional scripting could resolve this issue? </p>
<p>This framework is exciting. It opens the possibilities of faster web and app based integration of tools and tricks. It makes you ponder the infinite possibilities of nested protocol support, not just encapsulation of protocols within HTTP. Python development just keeps getting better and more fun, and this is most certainly a project to watch for ideas and possibilities of things to come. </p>
<p>Gloria</p>
]]></content:encoded>
			<wfw:commentRss>http://www.devchix.com/2008/05/10/kamaelia-the-future-of-python-frameworks-looks-promising/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
