<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>blog.teemu.im &#187; Python</title>
	<atom:link href="http://blog.teemu.im/topics/python/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.teemu.im</link>
	<description>i'm teemu and this is my weblog</description>
	<lastBuildDate>Mon, 31 Oct 2011 08:44:53 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
<atom:link rel="hub" href="http://pubsubhubbub.appspot.com"/><atom:link rel="hub" href="http://superfeedr.com/hubbub"/>		<item>
		<title>Playing Around With Openstack&#8217;s Object Storage</title>
		<link>http://blog.teemu.im/2010/10/22/playing-around-with-openstacks-object-storage/</link>
		<comments>http://blog.teemu.im/2010/10/22/playing-around-with-openstacks-object-storage/#comments</comments>
		<pubDate>Fri, 22 Oct 2010 01:51:56 +0000</pubDate>
		<dc:creator>Teemu Harju</dc:creator>
				<category><![CDATA[Erlang]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Openstack]]></category>
		<category><![CDATA[Swift]]></category>

		<guid isPermaLink="false">http://blog.teemu.im/?p=342</guid>
		<description><![CDATA[Couple of weeks ago I found out about the Openstack project and I found it immediately to be very interesting. What I&#8217;ve been playing around with the most is the object storage part of Openstack called Swift. I&#8217;ll show here how you can use Swift with a couple of different libraries. The nice thing about [...]]]></description>
			<content:encoded><![CDATA[<p>Couple of weeks ago I found out about the <a href="http://openstack.org">Openstack project</a> and I found it immediately to be very interesting. What I&#8217;ve been playing around with the most is the <a href="http://www.openstack.org/projects/storage/">object storage</a> part of Openstack called <a href="http://swift.openstack.org/">Swift</a>. I&#8217;ll show here how you can use Swift with a couple of different libraries. The nice thing about Swift is that it is basically the <a href="http://www.rackspacecloud.com/cloud_hosting_products/files">Rackspace Cloudfiles</a> storage, so the same libraries that work with Cloudfiles, should work with Swift as well. Well, they require some small modifications. But, I&#8217;ll show you here two libraries that I know are working already. Of course, you will need a Swift instance running somewhere and instructions on how to setup one you can read the <a href="http://swift.openstack.org/development_saio.html">&#8220;Swift All In One&#8221;</a> document that shows how you can run Swift on a single server.</p>
<p>The first library I&#8217;ll show here is the <a href="http://github.com/rackspace/python-cloudfiles">python-cloudfiles</a>. I recommend using the latest one from Github, since the one that you can get for example from Ubuntu repositories does not support Swift and the one you can get from <a href="http://pypi.python.org/pypi/python-cloudfiles/1.7.0">Python Package Index</a> had a bug that made it not work with Swift.</p>
<p>Here I&#8217;ll show you how you can connect to your local Swift instance using the <code>authurl</code> parameter and how you can create containers and objects using <code>python-cloudfiles</code>.</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">from</span> cloudfiles.<span style="color: black;">connection</span> <span style="color: #ff7700;font-weight:bold;">import</span> Connection
&nbsp;
conn = Connection<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;test:test&quot;</span>, <span style="color: #483d8b;">&quot;test&quot;</span>, authurl=<span style="color: #483d8b;">&quot;http://127.0.0.1:11000/v1.0&quot;</span><span style="color: black;">&#41;</span>
&nbsp;
container = conn.<span style="color: black;">create_container</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;test&quot;</span><span style="color: black;">&#41;</span>
&nbsp;
obj = container.<span style="color: black;">create_object</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;test.txt&quot;</span><span style="color: black;">&#41;</span>
obj.<span style="color: black;">content_type</span> = <span style="color: #483d8b;">&quot;text/plain&quot;</span>
obj.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;test&quot;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>Pretty straightforward&#8230; right?</p>
<p>Next, I&#8217;ll show you another library that works with Swift called <a href="http://github.com/ddossot/cferl">cferl</a>. It&#8217;s a Erlang library for Cloudfiles and I made some <a href="http://github.com/ddossot/cferl/commit/38689bebcc0f229b3c75d113aed9532da745667d">simple patches</a> to it to make it work with Swift.</p>
<p>Here&#8217;s how you can do the same things as in previous example using <code>cferl</code>.</p>

<div class="wp_syntax"><div class="code"><pre class="erlang" style="font-family:monospace;">ibrowse:<span style="color: #ff3c00;">start</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
<span style="color: #109ab8;">&#123;</span>ok<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Connection</span><span style="color: #109ab8;">&#125;</span> <span style="color: #014ea4;">=</span> cf<span style="color: #ff4e18;">erl</span>:<span style="color: #ff3c00;">connect</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff7800;">&quot;test:test&quot;</span><span style="color: #6bb810;">,</span> <span style="color: #ff7800;">&quot;test&quot;</span><span style="color: #6bb810;">,</span> <span style="color: #ff7800;">&quot;http://127.0.0.1:11000/v1.0&quot;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #109ab8;">&#123;</span>ok<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Container</span><span style="color: #109ab8;">&#125;</span> <span style="color: #014ea4;">=</span> <span style="color: #45b3e6;">Connection</span>:<span style="color: #ff3c00;">create_container</span><span style="color: #109ab8;">&#40;</span><span style="color: #ee3800;">&lt;&lt;</span><span style="color: #ff7800;">&quot;test&quot;</span><span style="color: #ee3800;">&gt;&gt;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #109ab8;">&#123;</span>ok<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Object</span><span style="color: #109ab8;">&#125;</span> <span style="color: #014ea4;">=</span> <span style="color: #45b3e6;">Container</span>:<span style="color: #ff3c00;">create_object</span><span style="color: #109ab8;">&#40;</span><span style="color: #ee3800;">&lt;&lt;</span><span style="color: #ff7800;">&quot;test.txt&quot;</span><span style="color: #ee3800;">&gt;&gt;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
ok <span style="color: #014ea4;">=</span> <span style="color: #45b3e6;">Obje</span><span style="color: #ff4e18;">ct</span>:<span style="color: #ff3c00;">write_data</span><span style="color: #109ab8;">&#40;</span><span style="color: #ee3800;">&lt;&lt;</span><span style="color: #ff7800;">&quot;test&quot;</span><span style="color: #ee3800;">&gt;&gt;</span><span style="color: #6bb810;">,</span> <span style="color: #ee3800;">&lt;&lt;</span><span style="color: #ff7800;">&quot;text/plain&quot;</span><span style="color: #ee3800;">&gt;&gt;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span></pre></div></div>

<p>Ok, that&#8217;s it. Now you can start playing with Swift and storing petabytes of data in it.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.teemu.im/2010/10/22/playing-around-with-openstacks-object-storage/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Exercise in Python Decorators</title>
		<link>http://blog.teemu.im/2010/10/03/exercise-in-python-decorators/</link>
		<comments>http://blog.teemu.im/2010/10/03/exercise-in-python-decorators/#comments</comments>
		<pubDate>Sun, 03 Oct 2010 05:52:45 +0000</pubDate>
		<dc:creator>Teemu Harju</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.teemu.im/?p=311</guid>
		<description><![CDATA[Recently, I found myself in need of a web server that I can use to simulate a behavior of a certain website. I wanted to just copy the output of that website and deliver it using this web server. The problem was that serving static content is naturally way faster than serving dynamic web application, [...]]]></description>
			<content:encoded><![CDATA[<p>Recently, I found myself in need of a web server that I can use to simulate a behavior of a certain website. I wanted to just copy the output of that website and deliver it using this web server. The problem was that serving static content is naturally way faster than serving dynamic web application, so for my simulation I needed to make the web server wait for a certain period of time before returning the static file. Being a Python fan I decided to use <a href="http://www.tornadoweb.org">Tornado</a> as the web server. Now, all I needed to do is slow it down.</p>
<p>Ok, I could just simply do this&#8230;</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #dc143c;">time</span>.<span style="color: black;">sleep</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0.5</span><span style="color: black;">&#41;</span></pre></div></div>

<p>&#8230; to make my server wait half a second before returning, but since Tornado is using asynchronous networking and hence runs in a single thread, this would block all other requests made to my server. Not good&#8230;</p>
<p>I need to do this asynchronously. Here is an example on how this can be done with Tornado without blocking.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
</pre></td><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">time</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">import</span> tornado.<span style="color: black;">web</span>
<span style="color: #ff7700;font-weight:bold;">import</span> tornado.<span style="color: black;">ioloop</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> RequestHandler<span style="color: black;">&#40;</span>tornado.<span style="color: black;">web</span>.<span style="color: black;">RequestHandler</span><span style="color: black;">&#41;</span>:
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> _finish_request<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #008000;">self</span>.<span style="color: black;">finish</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    @tornado.<span style="color: black;">web</span>.<span style="color: black;">asynchronous</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> get<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        ioloop = tornado.<span style="color: black;">ioloop</span>.<span style="color: black;">IOLoop</span>.<span style="color: black;">instance</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        ioloop.<span style="color: black;">add_timeout</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">time</span>.<span style="color: #dc143c;">time</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> + <span style="color: #ff4500;">0.5</span>, <span style="color: #008000;">self</span>._finish_request<span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">add_header</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Content-Type&quot;</span>, <span style="color: #483d8b;">&quot;text/plain&quot;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Hello, world&quot;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>So, this is an example of an asynchronous Tornado request handler that will wait for half a second before returning and will not block other requests while doing that. Here we are using decorator <code>tornado.web.asynchronous</code> on line 11 to tell Tornado that this request should not be returned immediately and we need to call <code>tornado.web.RequestHandler.finish()</code> on our own. The timeout is implemented by calling <code>tornado.ioloop.IOLoop.add_timeout()</code> method which is given a callback method that will finish the request.</p>
<p>Now, the problem with this is that, if I need other request handlers to do the same thing, I would need to copy paste this peace of code all over the place. And I don&#8217;t like that. We can do this bit more elegantly by using <a href="http://en.wikipedia.org/wiki/Python_syntax_and_semantics#Decorators">Python decorators</a>. By writing a decorator we can avoid duplicating the same code to every request handler. This is how the same example will look using a decorator.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
</pre></td><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> tornado.<span style="color: black;">web</span>
<span style="color: #ff7700;font-weight:bold;">import</span> tornado.<span style="color: black;">decorators</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> RequestHandler<span style="color: black;">&#40;</span>tornado.<span style="color: black;">web</span>.<span style="color: black;">RequestHandler</span><span style="color: black;">&#41;</span>:
&nbsp;
    @tornado.<span style="color: black;">decorators</span>.<span style="color: black;">wait_for</span><span style="color: black;">&#40;</span>milliseconds=<span style="color: #ff4500;">500</span><span style="color: black;">&#41;</span>                                               
    <span style="color: #ff7700;font-weight:bold;">def</span> get<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:                                                            
        <span style="color: #008000;">self</span>.<span style="color: black;">set_header</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Content-Type&quot;</span>, <span style="color: #483d8b;">&quot;text/plain&quot;</span><span style="color: black;">&#41;</span>                         
        <span style="color: #008000;">self</span>.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Hello, world&quot;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>Looks nice and clean. Doesn&#8217;t it? Well, the complex part has been moved now to the decorator <code>tornado.decorators.wait_for</code>. Let&#8217;s look now how we can implement that.</p>
<p><code>tornado/decorators.py</code></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
</pre></td><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">time</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">from</span> functools <span style="color: #ff7700;font-weight:bold;">import</span> partial
&nbsp;
<span style="color: #ff7700;font-weight:bold;">from</span> tornado.<span style="color: black;">web</span> <span style="color: #ff7700;font-weight:bold;">import</span> asynchronous
<span style="color: #ff7700;font-weight:bold;">from</span> tornado.<span style="color: black;">ioloop</span> <span style="color: #ff7700;font-weight:bold;">import</span> IOLoop
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> wait_for<span style="color: black;">&#40;</span>milliseconds=<span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">def</span> _finish_request<span style="color: black;">&#40;</span>request, start_time<span style="color: black;">&#41;</span>:
        timeout = <span style="color: black;">&#40;</span><span style="color: #dc143c;">time</span>.<span style="color: #dc143c;">time</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> - start_time<span style="color: black;">&#41;</span> <span style="color: #66cc66;">*</span> <span style="color: #ff4500;">1000.0</span>
	request.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;<span style="color: #000099; font-weight: bold;">\n</span><span style="color: #000099; font-weight: bold;">\n</span>Server waited for %.3f ms&quot;</span> <span style="color: #66cc66;">%</span> timeout<span style="color: black;">&#41;</span>
        request.<span style="color: black;">finish</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> _decorator<span style="color: black;">&#40;</span>func<span style="color: black;">&#41;</span>:
	func = asynchronous<span style="color: black;">&#40;</span>func<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">def</span> _wrapper<span style="color: black;">&#40;</span><span style="color: #66cc66;">*</span>args, <span style="color: #66cc66;">**</span>kwargs<span style="color: black;">&#41;</span>:
            ioloop = IOLoop.<span style="color: black;">instance</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
            callback = partial<span style="color: black;">&#40;</span>_finish_request, args<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>, <span style="color: #dc143c;">time</span>.<span style="color: #dc143c;">time</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
            ioloop.<span style="color: black;">add_timeout</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">time</span>.<span style="color: #dc143c;">time</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> + milliseconds / <span style="color: #ff4500;">1000.0</span>, callback<span style="color: black;">&#41;</span>
            func<span style="color: black;">&#40;</span><span style="color: #66cc66;">*</span>args, <span style="color: #66cc66;">**</span>kwargs<span style="color: black;">&#41;</span>
	<span style="color: #ff7700;font-weight:bold;">return</span> _wrapper
    <span style="color: #ff7700;font-weight:bold;">return</span> _decorator</pre></td></tr></table></div>

<p>Here I have implemented the decorator <code>wait_for</code> that takes the number of milliseconds to wait as a parameter.  Let&#8217;s start from line 13 where the actual decorator is implemented. Decorator&#8217;s parameter is always the function that is being decorated. You can think of this&#8230;</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">@my_decorator
<span style="color: #ff7700;font-weight:bold;">def</span> my_function<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    // do something</pre></div></div>

<p>&#8230;being same as this&#8230;</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> my_function<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    // do something
my_function = my_decorator<span style="color: black;">&#40;</span>my_function<span style="color: black;">&#41;</span></pre></div></div>

<p>Now, on line 14 decorate the function with Tornado&#8217;s <code>tornado.web.asynchronous</code> decorator. Just like we did in the first example. So that our request does not return before we call <code>tornado.web.RequestHandler.finish()</code>. Then on line 15 we write a wrapper method that adds the timeout and callback to <code>tornado.ioloop.IOLoop</code> and after that calls the original function that we are decorating. The trickiest part here probably is that we need to give our callback function some parameters and Tornado&#8217;s <code>add_timeout</code> method only takes the callback function as the parameter. For that we use Python&#8217;s <code>functools.partial</code> to generate the callback and give some parameters to it on line 17.</p>
<p>To conclude the blog post here is a complete example of a script that you can test this with. You need to create the <code>tornado/decorators.py</code> using the code above for this to work.</p>
<p><code>http_server.py</code></p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">time</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">import</span> tornado.<span style="color: black;">httpserver</span>
<span style="color: #ff7700;font-weight:bold;">import</span> tornado.<span style="color: black;">ioloop</span>
<span style="color: #ff7700;font-weight:bold;">import</span> tornado.<span style="color: black;">web</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">from</span> tornado.<span style="color: black;">decorators</span> <span style="color: #ff7700;font-weight:bold;">import</span> wait_for
&nbsp;
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> MainHandler<span style="color: black;">&#40;</span>tornado.<span style="color: black;">web</span>.<span style="color: black;">RequestHandler</span><span style="color: black;">&#41;</span>:
&nbsp;
    @wait_for<span style="color: black;">&#40;</span>milliseconds=<span style="color: #ff4500;">500</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> get<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #008000;">self</span>.<span style="color: black;">set_header</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Content-Type&quot;</span>, <span style="color: #483d8b;">&quot;text/plain&quot;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Hello, world&quot;</span><span style="color: black;">&#41;</span>
&nbsp;
application = tornado.<span style="color: black;">web</span>.<span style="color: black;">Application</span><span style="color: black;">&#40;</span><span style="color: black;">&#91;</span><span style="color: black;">&#40;</span>r<span style="color: #483d8b;">&quot;/&quot;</span>, MainHandler<span style="color: black;">&#41;</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">&quot;__main__&quot;</span>:
    http_server = tornado.<span style="color: black;">httpserver</span>.<span style="color: black;">HTTPServer</span><span style="color: black;">&#40;</span>application<span style="color: black;">&#41;</span>
    http_server.<span style="color: black;">listen</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">8080</span><span style="color: black;">&#41;</span>
    tornado.<span style="color: black;">ioloop</span>.<span style="color: black;">IOLoop</span>.<span style="color: black;">instance</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">start</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>If everything goes right your server should return something like this&#8230;</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">Hello, world
&nbsp;
Server waited for 500.371 ms</pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://blog.teemu.im/2010/10/03/exercise-in-python-decorators/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using zc.buildout in a Twisted project</title>
		<link>http://blog.teemu.im/2009/02/08/using-zcbuildout-in-a-twisted-project/</link>
		<comments>http://blog.teemu.im/2009/02/08/using-zcbuildout-in-a-twisted-project/#comments</comments>
		<pubDate>Sun, 08 Feb 2009 07:48:25 +0000</pubDate>
		<dc:creator>Teemu Harju</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[twisted]]></category>
		<category><![CDATA[zc.buildout]]></category>

		<guid isPermaLink="false">http://blog.teemu.im/?p=248</guid>
		<description><![CDATA[I&#8217;ve been learning how to use zc.buildout in my Python projects. It seems to be used mostly by the Zope and the Plone communities, but I feel that it might be a useful tool to be used in any Python project. I do lots of work with Twisted and I wanted to try zc.buildout with [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been learning how to use <a href="http://pypi.python.org/pypi/zc.buildout">zc.buildout</a> in my Python projects. It seems to be used mostly by the <a href="http://www.zope.org/">Zope</a> and the <a href="http://plone.org/">Plone</a> communities, but I feel that it might be a useful tool to be used in any Python project. I do lots of work with <a href="http://twistedmatrix.com/trac/">Twisted</a> and I wanted to try zc.buildout with a Twisted project. It wasn&#8217;t trivial and I wasn&#8217;t able to find any good examples, so I thought I might as well document my experiences here.</p>
<p>Let&#8217;s start this exercise by setting a new virtual Python environment using <a href="http://pypi.python.org/pypi/virtualenv">virtualenv</a>. It gives you a nice constrained Python environment that does not mess up your system. Easiest way to get virtualenv on your system is by using <a href="http://pypi.python.org/pypi/setuptools">setuptools</a>. When you have setuptools installed you can get virtualenv by typing:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ easy_install virtualenv</pre></div></div>

<p>Now that you have virtualenv installed it&#8217;s time to create the virtual environment. In this example I will create the environment in a directory called <code>twistedenv</code>. You can place it anywhere you want in your system.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">mkdir</span> twistedenv
$ virtualenv <span style="color: #660033;">--no-site-packages</span> twistedenv<span style="color: #000000; font-weight: bold;">/</span>
New python executable <span style="color: #000000; font-weight: bold;">in</span> twistedenv<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>python
Please <span style="color: #c20cb9; font-weight: bold;">make</span> sure you remove any previous custom paths from your <span style="color: #000000; font-weight: bold;">/</span>Users<span style="color: #000000; font-weight: bold;">/</span>teemu<span style="color: #000000; font-weight: bold;">/</span>.pydistutils.cfg file.
Installing setuptools............done.</pre></div></div>

<p>Now that the virtual environment is setup you can activate it by typing:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #7a0874; font-weight: bold;">cd</span> twistedenv
$ <span style="color: #7a0874; font-weight: bold;">source</span> bin<span style="color: #000000; font-weight: bold;">/</span>activate</pre></div></div>

<p>This will activate the new Python interpreter that was installed in <code>twistedenv/bin/python</code>.</p>
<p>Ok, now we can get to the actual topic, that is how to use zc.buildout with a Twisted project. What you will need is a bootstrap script that will install zc.buildout inside your environment and a buildout configuration file. Let&#8217;s start with the configuration file, since we need that before running the bootstrap script. In zc.buildout the configuration file is called <code>buildout.cfg</code>. It will tell the buildout system, what packages are needed and setup your development system in a blink of an eye. I&#8217;ll start with an example that will install Twisted and some dependencies and a sample Twisted application that is under development. Here&#8217;s the <code>buildout.cfg</code> that will do this.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
</pre></td><td class="code"><pre class="ini" style="font-family:monospace;"><span style="color: #000066; font-weight:bold;"><span style="">&#91;</span>buildout<span style="">&#93;</span></span>
<span style="color: #000099;">parts</span> <span style="color: #000066; font-weight:bold;">=</span>
    depends
    twisted
    twisteds
<span style="color: #000099;">develop</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> ./src</span>
&nbsp;
<span style="color: #000066; font-weight:bold;"><span style="">&#91;</span>versions<span style="">&#93;</span></span>
<span style="color: #000099;">Twisted</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> 8.2.0</span>
<span style="color: #000099;">pyOpenSSL</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> 0.8</span>
<span style="color: #000099;">pyserial</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> 2.4</span>
<span style="color: #000099;">pycrypto</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> 2.0.1</span>
&nbsp;
<span style="color: #000066; font-weight:bold;"><span style="">&#91;</span>depends<span style="">&#93;</span></span>
<span style="color: #000099;">recipe</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> minitage.recipe:egg</span>
<span style="color: #000099;">eggs</span> <span style="color: #000066; font-weight:bold;">=</span>
    pyOpenSSL
    pyserial
    pycrypto
&nbsp;
<span style="color: #000066; font-weight:bold;"><span style="">&#91;</span>twisted<span style="">&#93;</span></span>
<span style="color: #000099;">recipe</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> minitage.recipe:egg</span>
<span style="color: #000099;">eggs</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> Twisted</span>
&nbsp;
<span style="color: #000066; font-weight:bold;"><span style="">&#91;</span>twisteds<span style="">&#93;</span></span>
<span style="color: #000099;">recipe</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> minitage.recipe:scripts</span>
<span style="color: #000099;">interpreter</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> twistedpy</span>
<span style="color: #000099;">extra-paths</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> $<span style="">&#123;</span>buildout:directory<span style="">&#125;</span>/src</span>
<span style="color: #000099;">eggs</span> <span style="color: #000066; font-weight:bold;">=</span>
  $<span style="">&#123;</span>twisted:eggs<span style="">&#125;</span>
  $<span style="">&#123;</span>depends:eggs<span style="">&#125;</span></pre></td></tr></table></div>

<p>I&#8217;ll briefly explain what it does. Section <code>buildout</code> is the first thing to put in the config file. It lists what parts of the configuration file are used and the location of the code that is being developed. The section called <code>depends</code> installs the dependencies for Twisted using recipe <code>minitage.recipe</code>. Section <code>twisted</code> naturally installs Twisted, but it does not install the scripts that are installed to the <code>bin</code> directory. That is what the section <code>twisteds</code> is for. By the way, you are free to choose the names of the sections or parts except for the <code>buildout</code> section. In the <code>twisteds</code> section we also define the variable <code>interpreter</code> to create us a new Python interpreter that will be used when running these scripts. For this interpreter we define which eggs are included in the interpreter path and using <code>extra-paths</code> variable we can include our development code there also. It is useful that we can keep our own code separate from 3rd party code while developing it. Section <code>versions</code> can be used to specify which versions of 3rd party libraries we want to use. If you don&#8217;t specify a version, a newest version available is used.</p>
<p>Now that we have the <code>buildout.cfg</code> file ready, we can bootsrap the buildout. Download the bootstrap script from <a href="http://svn.zope.org/*checkout*/zc.buildout/trunk/bootstrap/bootstrap.py">this URL</a> and put it in the <code>twistedenv</code> directory. Before running the bootstrap script you can make sure that you are using the Python interpreter from the virtual environment to run it instead of the syste Python. Do that by typing:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">which</span> python
<span style="color: #000000; font-weight: bold;">/</span>Users<span style="color: #000000; font-weight: bold;">/</span>teemu<span style="color: #000000; font-weight: bold;">/</span>Programming<span style="color: #000000; font-weight: bold;">/</span>twistedenv<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>python</pre></div></div>

<p>As you can see, for me it shows that I&#8217;m using the Python interpreter from inside the <code>twistedenv</code> where we created the virtual environment. That is good. Naturally, for you the complete path is something else. Then we can run the bootstrap script by typing:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ python bootstrap.py
Creating directory <span style="color: #ff0000;">'/Users/teemu/Programming/twistedenv/parts'</span>.
Creating directory <span style="color: #ff0000;">'/Users/teemu/Programming/twistedenv/eggs'</span>.
Creating directory <span style="color: #ff0000;">'/Users/teemu/Programming/twistedenv/develop-eggs'</span>.
Generated script <span style="color: #ff0000;">'/Users/teemu/Programming/twistedenv/bin/buildout'</span>.</pre></div></div>

<p>As you can see from the output the script created couple of directories and generated a script called <code>buildout</code> to the <code>bin</code> directory. Now our buildout environment is almost ready. The only thing is missing is that our <code>./src</code> directory does not contain any code. You will see an error if you now try to run <code>bin/buildout</code>.</p>
<p>Let&#8217;s create a quick sample Twisted application to demonstrate a more complete buildout environment. This is what we need. Create the required directories for our code:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">mkdir</span> <span style="color: #660033;">-p</span> src<span style="color: #000000; font-weight: bold;">/</span>sample
<span style="color: #c20cb9; font-weight: bold;">mkdir</span> <span style="color: #660033;">-p</span> src<span style="color: #000000; font-weight: bold;">/</span>twisted<span style="color: #000000; font-weight: bold;">/</span>plugins
<span style="color: #c20cb9; font-weight: bold;">touch</span> src<span style="color: #000000; font-weight: bold;">/</span>sample<span style="color: #000000; font-weight: bold;">/</span>__init__.py</pre></div></div>

<p>Then we need the following files:</p>
<p><code>src/sample/tap.py</code>:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
</pre></td><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">from</span> twisted.<span style="color: black;">application</span> <span style="color: #ff7700;font-weight:bold;">import</span> internet
<span style="color: #ff7700;font-weight:bold;">from</span> twisted.<span style="color: black;">web</span> <span style="color: #ff7700;font-weight:bold;">import</span> server
<span style="color: #ff7700;font-weight:bold;">from</span> twisted.<span style="color: black;">web</span>.<span style="color: #dc143c;">resource</span> <span style="color: #ff7700;font-weight:bold;">import</span> Resource
<span style="color: #ff7700;font-weight:bold;">from</span> twisted.<span style="color: black;">python</span> <span style="color: #ff7700;font-weight:bold;">import</span> usage
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> SimpleResource<span style="color: black;">&#40;</span>Resource<span style="color: black;">&#41;</span>:
    isLeaf = <span style="color: #008000;">True</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> render_GET<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, request<span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #483d8b;">&quot;&lt;h1&gt;It Works!&lt;/h1&gt;&quot;</span>
&nbsp;
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> Options<span style="color: black;">&#40;</span>usage.<span style="color: black;">Options</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">pass</span>
&nbsp;
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> makeService<span style="color: black;">&#40;</span>config<span style="color: black;">&#41;</span>:
    <span style="color: #dc143c;">site</span> = server.<span style="color: black;">Site</span><span style="color: black;">&#40;</span>SimpleResource<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> internet.<span style="color: black;">TCPServer</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">8080</span>, <span style="color: #dc143c;">site</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p><code>src/twisted/plugins/sample.py</code>:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">from</span> twisted.<span style="color: black;">application</span>.<span style="color: black;">service</span> <span style="color: #ff7700;font-weight:bold;">import</span> ServiceMaker
&nbsp;
Sample = ServiceMaker<span style="color: black;">&#40;</span>
    <span style="color: #483d8b;">&quot;Sample&quot;</span>,
    <span style="color: #483d8b;">&quot;sample.tap&quot;</span>,
    <span style="color: #483d8b;">&quot;Twisted sample application&quot;</span>,
    <span style="color: #483d8b;">&quot;sample&quot;</span>
<span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>And last, but not least, <code>src/setup.py</code>:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
</pre></td><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">from</span> setuptools <span style="color: #ff7700;font-weight:bold;">import</span> setup
&nbsp;
setup<span style="color: black;">&#40;</span>name=<span style="color: #483d8b;">'sample'</span>,
      version=<span style="color: #483d8b;">'0.0.1'</span>,
      description=<span style="color: #483d8b;">'Sample Twisted application'</span>,
      author=<span style="color: #483d8b;">'Teemu Harju'</span>,
      author_email=<span style="color: #483d8b;">'teemu.harju@gmail.com'</span>,
      url=<span style="color: #483d8b;">'http://blog.teemu.im'</span>,
      packages=<span style="color: black;">&#91;</span><span style="color: #483d8b;">'sample'</span><span style="color: black;">&#93;</span>,
      package_data=<span style="color: black;">&#123;</span><span style="color: #483d8b;">'twisted.plugins'</span>: <span style="color: black;">&#91;</span><span style="color: #483d8b;">'twisted/plugins/sample.py'</span><span style="color: black;">&#93;</span><span style="color: black;">&#125;</span>,
      zip_safe=<span style="color: #008000;">False</span>
<span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>These files will create a Twisted application called <code>sample</code> that runs a webserver on port <code>8080</code> that responds &#8220;It works!&#8221; when the root URL is accessed.</p>
<p>Now, run:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ bin<span style="color: #000000; font-weight: bold;">/</span>buildout
...</pre></div></div>

<p>I&#8217;ve not put the output to the example since there is so much of it. But after the buildout is ready and if everything worked fine you can test that your environment is ready by running the <code>bin/twistd</code> script like this:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ bin<span style="color: #000000; font-weight: bold;">/</span>twistd <span style="color: #660033;">--help</span></pre></div></div>

<p>The output should contain our <code>sample</code> application and you can run it by typing:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ bin<span style="color: #000000; font-weight: bold;">/</span>twistd <span style="color: #660033;">-n</span> sample</pre></div></div>

<p>Now you can start developing your Twisted application and test it in your safe and restricted environment using virtualenv and buildout. By the way, if you want to get out of your virtual Python environment you can do that simply by typing:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ deactivate</pre></div></div>

<p>It would be probably good to include some kind of a test runner in the buildout script to make sure that your buildout is not broken. How that can be done is probably a blog post topic of it&#8217;s own. That&#8217;s all for now. Have fun with buildout and Twisted. Feel free to ask in the comments if this didn&#8217;t work for you for some reason.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.teemu.im/2009/02/08/using-zcbuildout-in-a-twisted-project/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Python For Series 60 v.1.9 Released For Testing</title>
		<link>http://blog.teemu.im/2008/12/28/python-for-series-60-v19-released-for-testing/</link>
		<comments>http://blog.teemu.im/2008/12/28/python-for-series-60-v19-released-for-testing/#comments</comments>
		<pubDate>Sun, 28 Dec 2008 06:41:45 +0000</pubDate>
		<dc:creator>Teemu Harju</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Series 60]]></category>
		<category><![CDATA[s60]]></category>

		<guid isPermaLink="false">http://blog.teemu.im/?p=233</guid>
		<description><![CDATA[Python for Nokia&#8217;s Series 60 platform has been around for four years now and to be honest, not much has happened on that front during the past year. However, suddenly on 24th of December Nokia releases a version 1.9.0 of the Python for Series 60 that is a major rewrite of the whole thing and [...]]]></description>
			<content:encoded><![CDATA[<p>Python for Nokia&#8217;s Series 60 platform has been around for four years now and to be honest, not much has happened on that front during the past year. However, suddenly on 24th of December <a href="http://discussion.forum.nokia.com/forum/showthread.php?t=154215">Nokia releases a version 1.9.0 of the Python for Series 60</a> that is a major rewrite of the whole thing and comes now with Python 2.5 version of the core language. As usual, the odd-number version branch means that the release is for testing purposes only and the even-numbered 2.0 version branch should be released once it becomes more stable. <a href="http://croozeus.com/blog">Blog at Croozeus.com</a> has done pretty nice <a href="http://croozeus.com/blogs/?p=153">wrap up of the new release</a> and here are my thoughts.</p>
<blockquote><p>First of all I should mention that as I write this blog entry I&#8217;ve not yet had time to test the new Python for Series 60 release. So I apologize beforehand for all false comments I&#8217;m about to make. </p></blockquote>
<p>It seems that they are giving a lot more focus on the ease of development in this new release. Which is a really good thing I must say. What pleases me the most is that they are planning on improving the Python runtime deployment so that the end-user or the guy that is installing Python applications should not have to worry too much about having or not having the Python runtime installed on his phone. Definitely a good thing. The new release includes a packaging tool that is not part of the S60 SDK and is basically <a href="http://code.google.com/p/ensymble/">ensymble</a> with added GUI. Ensymble is an excellent tool and it is very nice to see it included in the official PyS60 release.</p>
<p>Like mentioned already, the new release includes the version 2.5 of the Python interpreter and most of it&#8217;s standard libraries. Ok, the word &#8220;most&#8221; does not sound good here. I&#8217;ll focus first on the good things. First, <strong>the new release has Expat XML parser in it</strong>. Definitely a good thing since XML is something that pretty much every application out there uses and so far people have had to make ugly regexp XML parsers or use 3rd party package of expat to be able to parse XML in their PyS60 applications. However, I would say that including <a href="http://docs.python.org/library/json.html">JSON parser</a> as the official Python 2.6 release did lately, would probably be a good idea too.</p>
<p>Also, inclusion of <a href="http://www.python.org/doc/2.5.4/lib/module-asyncore.html">asyncore</a> and <strong>more compliant socket module</strong> sounds nice. I can&#8217;t wait to try <a href="http://twistedmatrix.com/trac/">Twisted</a> on PyS60 and see how it works. One could do some crazy things with that on a mobile phone.</p>
<p>Then to the things that are not included from the standard Python 2.5 libraries. Now, I don&#8217;t have too much information on this since, like said before, I haven&#8217;t tried the new release yet. However, to my disappointment I noticed that <a href="http://www.python.org/doc/2.5.4/lib/module-sqlite3.html">sqlite3</a> is <a href="http://discussion.forum.nokia.com/forum/showpost.php?p=521671&#038;postcount=2">not included</a>. SQLite should probably be a platform component in S60 because it is kind of becoming a de facto standard in mobile platforms since both iPhone and Android platforms use it. I don&#8217;t know what is the equivalent in S60 or does such exist but having some kind of storage other than just plain text file for PyS60 applications would be extremely nice thing to have.</p>
<p>Ok, I have to try out the new PyS60 release soon. I&#8217;m hoping that I will be pleasantly surprised. I&#8217;ll definitely write more about it later.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.teemu.im/2008/12/28/python-for-series-60-v19-released-for-testing/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Python for Series 60 Goes Final</title>
		<link>http://blog.teemu.im/2007/07/10/python-for-series-60-goes-final/</link>
		<comments>http://blog.teemu.im/2007/07/10/python-for-series-60-goes-final/#comments</comments>
		<pubDate>Tue, 10 Jul 2007 18:23:06 +0000</pubDate>
		<dc:creator>Teemu Harju</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Series 60]]></category>

		<guid isPermaLink="false">http://www.teemuharju.net/2007/07/10/python-for-series-60-goes-final/</guid>
		<description><![CDATA[Finally it happened. It was announced today in the Forum Nokia Python section that a 1.4.0 final version of Python for Series 60 has been released. This is something that I&#8217;ve been waiting this for a long time since I&#8217;ve been kind of pissed of with the Symbian signing policy. And guess what&#8230; this final [...]]]></description>
			<content:encoded><![CDATA[<p>Finally it happened. It was announced today in the <a href="http://discussion.forum.nokia.com/forum/showthread.php?t=111485">Forum Nokia Python section</a> that a 1.4.0 final version of Python for Series 60 has been released. This is something that I&#8217;ve been waiting this for a long time since I&#8217;ve been kind of pissed of with the Symbian signing policy. And guess what&#8230; this final version of PyS60 has been officially signed by Nokia with all developer certificate capabilities so no more signing is required for Python application in order to access e.g., the GSM location or GPS APIs. How cool is this? Finally, it is humanly possible to develop applications for S60 mobiles. You can expect to see more PyS60 related stuff in this blog once the summer holidays are over. Until then, have a good summer&#8230;. I know I will. <img src='http://blog.teemu.im/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.teemu.im/2007/07/10/python-for-series-60-goes-final/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Fupper</title>
		<link>http://blog.teemu.im/2006/09/13/fupper/</link>
		<comments>http://blog.teemu.im/2006/09/13/fupper/#comments</comments>
		<pubDate>Wed, 13 Sep 2006 12:10:00 +0000</pubDate>
		<dc:creator>Teemu Harju</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Series 60]]></category>

		<guid isPermaLink="false">http://www.teemuharju.net/2006/09/13/fupper/</guid>
		<description><![CDATA[I&#8217;m announcing a new software for Series 60 mobile phones called Fupper. It&#8217;s a Flickr upload tool written in Pyhon. Look here for more information.]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m announcing a new software for Series 60 mobile phones called Fupper. It&#8217;s a Flickr upload tool written in Pyhon. Look <a href="http://fupper.teemuharju.net">here</a> for more information.</p>
<p><img id="image162" src="http://blog.teemu.im/wp-content/uploads/2006/09/main_menu.png" alt="Fupper main menu" height="207" width="175" /> <img id="image164" src="http://blog.teemu.im/wp-content/uploads/2006/09/photo_upload.png" alt="Fupper upload" height="207" width="175" /></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.teemu.im/2006/09/13/fupper/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Python Imaging Library for Maemo 2.0</title>
		<link>http://blog.teemu.im/2006/08/10/python-imaging-library-for-maemo-20/</link>
		<comments>http://blog.teemu.im/2006/08/10/python-imaging-library-for-maemo-20/#comments</comments>
		<pubDate>Thu, 10 Aug 2006 15:21:25 +0000</pubDate>
		<dc:creator>Teemu Harju</dc:creator>
				<category><![CDATA[Nokia Tablets]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://www.teemuharju.net/2006/08/10/python-imaging-library-for-maemo-20/</guid>
		<description><![CDATA[As I got things going now, I decided to port (or more like package) the Python Imaging Library for the Maemo 2.0 platform. I decided to take the 1.1.6 beta release, since the 1.1.5 had some annoying bugs that made e.g., the pildriver.py script unusable. I hope that the 1.1.6 is more stable. You can [...]]]></description>
			<content:encoded><![CDATA[<p>As I got things going now, I decided to port (or more like package) the <a href="http://www.pythonware.com/products/pil/">Python Imaging Library</a> for the <a href="http://www.maemo.org">Maemo 2.0</a> platform. I decided to take the 1.1.6 beta release, since the 1.1.5 had some annoying bugs that made e.g., the pildriver.py script unusable. I hope that the 1.1.6 is more stable. You can get the deb packages for both armel and i386 from <a href="http://www.saunalahti.fi/~tsharju/pymaemo">here</a>.</p>
<p>Besides being a usefull Python library, you can use the included scripts to modify images on your 770. For example you can use the pildriver.py script to resize an image (larger.jpg) to size 320&#215;240 and save it to a separate file (smaller.jpg) by typing the following line in terminal window&#8230;</p>
<pre>pildriver.py save smaller.jpg resize 320 240 open larger.jpg</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.teemu.im/2006/08/10/python-imaging-library-for-maemo-20/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>First experiments with the new Pymaemo</title>
		<link>http://blog.teemu.im/2006/08/10/first-experiments-with-the-new-pymaemo/</link>
		<comments>http://blog.teemu.im/2006/08/10/first-experiments-with-the-new-pymaemo/#comments</comments>
		<pubDate>Thu, 10 Aug 2006 09:14:59 +0000</pubDate>
		<dc:creator>Teemu Harju</dc:creator>
				<category><![CDATA[Nokia Tablets]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://www.teemuharju.net/2006/08/10/first-experiments-with-the-new-pymaemo/</guid>
		<description><![CDATA[Since summer holidays are now over (for me at least), it is time to start getting familiar with the new Pymaemo version for Maemo 2.0 platform. I decided to start with a no-brainer by porting the pysqlite library, since I thought it might be useful in my future projects. I&#8217;ll put the link to the [...]]]></description>
			<content:encoded><![CDATA[<p>Since summer holidays are now over (for me at least), it is time to start getting familiar with the new <a href="http://pymaemo.sf.net">Pymaemo</a> version for <a href="http://www.maemo.org">Maemo 2.0 platform</a>. I decided to start with a no-brainer by porting the <a href="http://www.pysqlite.org">pysqlite</a> library, since I thought it might be useful in my future projects. I&#8217;ll put the link to the deb-packages to the <a href="http://maemo.org/maemowiki/ApplicationCatalog2006?action=show#head-791d286281c364506920899c1eceb08e888296e1">MaemoWiki Application Catalog</a>.</p>
<p>I&#8217;m also continuing to work with the <a href="http://www.teemuharju.net/2006/05/23/bittorrent-for-maemo-continued/">BitTorrent</a> and <a href="http://www.teemuharju.net/2006/05/23/maemoflickr/">Flickr Uploader</a> clients that I wrote about earlier. I&#8217;m also very eager in testing the new D-Bus and GStreamer stuff that should also be possible in the new Pymaemo version. Maybe, I even get <a href="http://www.teemuharju.net/pymaemo-tutorials/">my tutorial section</a> back up againg and updated to Maemo 2.0 stuff. But still <a href="http://maemo.org/platform/docs/pymaemo/python_maemo_howto.html">the best Python tutorial so far</a> can be found from the Maemo Howto pages.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.teemu.im/2006/08/10/first-experiments-with-the-new-pymaemo/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Python and Maemo 2.0</title>
		<link>http://blog.teemu.im/2006/06/10/python-and-maemo-20/</link>
		<comments>http://blog.teemu.im/2006/06/10/python-and-maemo-20/#comments</comments>
		<pubDate>Sat, 10 Jun 2006 05:53:42 +0000</pubDate>
		<dc:creator>Teemu Harju</dc:creator>
				<category><![CDATA[Nokia Tablets]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://www.teemuharju.net/2006/06/10/python-and-maemo-20/</guid>
		<description><![CDATA[As we all probably know by now the Beta version of Maemo 2.0 and OS2006 has been released. Too bad that I forgot my Nokia 770 at work and I cannot test the new software yet. Of all the weekends, why It had to be now. Anyway, I&#8217;ve been browsing through the Maemo.org site and [...]]]></description>
			<content:encoded><![CDATA[<p>As we all probably know by now the <a href="http://maemo.org/downloads/releases.html#maemo20beta">Beta version of Maemo 2.0 and OS2006</a> has been released. Too bad that I forgot my Nokia 770 at work and I cannot test the new software yet. <img src='http://blog.teemu.im/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' />  Of all the weekends, why It had to be now.</p>
<p>Anyway, I&#8217;ve been browsing through the Maemo.org site and I noticed that there was very nice <a href="http://maemo.org/platform/docs/pymaemo/python_maemo_howto.html">Python tutorial</a> there that includes lots of useful information. It seems that now it is really possible to develop fully working applications for Maemo platform using Python, since LibOSSO and D-BUS services are included. The tutorial has also very good instructions on how to make application installer packages from your Python applications.</p>
<p>The tutorial mentions that the Nokia 770 software images won&#8217;t include the Python runtime by default, but it has to be installed separately. This is quite understandable considering the amount of memory that is available on Nokia 770 for installable software. Also according to the tutorial the Pymaemo runtime package should be downloadable via maemo.org, but I haven&#8217;t found it yet. Anyway, the future looks promising.</p>
<p>Please also note that my <a href="http://www.teemuharju.net/pymaemo-tutorials/">previous tutorials</a> do not apply anymore on Maemo 2.0 since hildon.App and hildon.AppView have changed to hildon.Program and hildon.Window.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.teemu.im/2006/06/10/python-and-maemo-20/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Collection of my Pymaemo tutorials</title>
		<link>http://blog.teemu.im/2006/06/02/collection-of-my-pymaemo-tutorials/</link>
		<comments>http://blog.teemu.im/2006/06/02/collection-of-my-pymaemo-tutorials/#comments</comments>
		<pubDate>Fri, 02 Jun 2006 05:50:55 +0000</pubDate>
		<dc:creator>Teemu Harju</dc:creator>
				<category><![CDATA[Nokia Tablets]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://www.teemuharju.net/2006/06/02/collection-of-my-pymaemo-tutorials/</guid>
		<description><![CDATA[I though that I set up a collection of the pymaemo tutorials I&#8217;ve written so that they would be more easily accessible. From now on you can find them at pymaemo.teemuharju.net. Of course, I still put them on my blog also. I haven&#8217;t written much new tutorials lately, but I think that during the weekend [...]]]></description>
			<content:encoded><![CDATA[<p>I though that I set up a collection of the <a href="http://pymaemo.sf.net">pymaemo</a> tutorials I&#8217;ve written so that they would be more easily accessible. From now on you can find them at <a href="http://pymaemo.teemuharju.net">pymaemo.teemuharju.net</a>. Of course, I still put them on my blog also. I haven&#8217;t written much new tutorials lately, but I think that during the weekend I could write about things like how to create a Hildonized toolbar etc.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.teemu.im/2006/06/02/collection-of-my-pymaemo-tutorials/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

