<?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>Wil Tan &#187; python</title>
	<atom:link href="http://dready.org/blog/category/python/feed/" rel="self" type="application/rss+xml" />
	<link>http://dready.org/blog</link>
	<description>musings on internationalized identifiers: domain names, OpenID, TLDs</description>
	<lastBuildDate>Thu, 15 Dec 2011 03:42:26 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Tornado with VirtualEnv and Pip Quickstart</title>
		<link>http://dready.org/blog/2009/10/09/tornado-with-virtualenv-and-pip-quickstart/</link>
		<comments>http://dready.org/blog/2009/10/09/tornado-with-virtualenv-and-pip-quickstart/#comments</comments>
		<pubDate>Fri, 09 Oct 2009 08:50:37 +0000</pubDate>
		<dc:creator>wil</dc:creator>
				<category><![CDATA[python]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[webeng]]></category>
		<category><![CDATA[tornado]]></category>

		<guid isPermaLink="false">http://dready.org/blog/?p=243</guid>
		<description><![CDATA[Friendfeed&#8217;s open source Tornado web server is great, and is incredibly easy to get up-and-running. Just install tornado, write your app and run it. At some point, however, you&#8217;d want more structure in your project and manage dependencies to ease deployment. This is where virtualenv and pip shines. For a few more steps, you can [...]
No related posts.

Related posts brought to you by <a href='http://yarpp.org'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<p>Friendfeed&#8217;s open source <a href="http://www.tornadoweb.org/">Tornado web server</a> is great, and is incredibly easy to get up-and-running. Just install tornado, write your app and run it.</p>
<p>At some point, however, you&#8217;d want more structure in your project and manage dependencies to ease deployment. This is where <a href="http://pypi.python.org/pypi/virtualenv">virtualenv</a> and <a href="http://pypi.python.org/pypi/pip">pip</a> shines. For a few more steps, you can bootstrap your project and have the warm fuzzy feeling that you can easily deploy the stuff when the code is ready.</p>
<h3>Installing <code>virtualenv</code> and <code>pip</code></h3>
<p>If you haven&#8217;t set up virtualenv, do so (as root):</p>
<pre class="code">
# easy_install virtualenv
</pre>
<p>Decide where you&#8217;d put your project directory. I&#8217;ll use <code>/path/to/myapp</code> for now. The next step is to create a virtualenv where all your Python packages are stored. I like to use the convention of a directory called <code>root</code> where all dependencies are installed. I&#8217;d generally also use it as the prefix for any <acronym title="./configure &amp;&amp; make &amp;&amp; make install">cmmi</acronym> packages that I&#8217;d like to contain within the project.</p>
<pre class="code">
$ cd /path/to/myapp
$ virtualenv --no-site-packages root
</pre>
<p>Activate the environment that we just created:</p>
<pre class="code">
$ . root/bin/activate
(root)[wil@wasabi /path/to/myapp]$
</pre>
<p>From now on, all packages installed with <code>easy_install</code> will be placed in this virtualenv.</p>
<p>Next, we will install <code>pip</code> into this virtualenv:</p>
<pre class="code">
(root)[wil@wasabi /path/to/myapp]$ easy_install pip
</pre>
<p>Once <code>pip</code> is installed, as long as you&#8217;ve got your virtualenv activated, anything installed with <code>pip</code> will also go into the right place (without your having to remember to use the <code>-E</code> command line argument.)</p>
<h3>Installing Tornado</h3>
<p>Tornado (as of the current version) needs two mandatory dependencies, i.e. <a href="http://pycurl.sourceforge.net/">pycURL</a> and <a href="http://pypi.python.org/pypi/simplejson/">simplejson</a>. Make sure you have the right libcURL version installed on your system (using <code>apt-get</code> or other mechanism) and pick the compatible pyCURL version.</p>
<pre class="code">
(root)[wil@wasabi /path/to/myapp]$ pip install pycurl==7.16.4
(root)[wil@wasabi /path/to/myapp]$ pip install simplejson
</pre>
<p>Now we&#8217;ll install tornado proper. I chose to go with the bleeding edge and ask <code>pip</code> to install from the git trunk.</p>
<pre class="code">
(root)[wil@wasabi /path/to/myapp]$ pip install -e \
  git+git://github.com/facebook/tornado.git#egg=tornado
</pre>
<p>Should you not want that, you can tell <code>pip</code> to install from the tarball URL instead (at least until tornado gets added to PyPI.)</p>
<pre class="code">
(root)[wil@wasabi /path/to/myapp]$ pip install \

http://www.tornadoweb.org/static/tornado-0.2.tar.gz
</pre>
<p>Tornado is installed!</p>
<p>Every now and then, it&#8217;s a good idea to save your pip dependencies by running</p>
<pre class="code">
(root)[wil@wasabi /path/to/myapp]$ pip freeze > pip-req.txt
</pre>
<h3>Start your project</h3>
<p>What I like about this is that the project directory has all the dependencies contained within a single directory (<code>root</code>). This is really just my convention; I&#8217;d create a <code>src</code> directory where my application code lives.</p>
<pre class="code">
(root)[wil@wasabi /path/to/myapp]$ mkdir src
(root)[wil@wasabi /path/to/myapp]$ cd src
(root)[wil@wasabi /path/to/myapp/src]$
</pre>
<p>Let&#8217;s test drive Tornado:</p>
<pre class="code">
(root)[wil@wasabi /path/to/myapp/src]$ cp ../root/src/tornado/demos/helloworld/helloworld.py .
(root)[wil@wasabi /path/to/myapp/src]$ python helloworld.py
</pre>
<p>From browser, visit your host at port <code>8888</code> to verify.</p>
<p>That&#8217;s it!</p>
<p>No related posts.</p>
<p>Related posts brought to you by <a href='http://yarpp.org'>Yet Another Related Posts Plugin</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://dready.org/blog/2009/10/09/tornado-with-virtualenv-and-pip-quickstart/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>web.py with mod_python on Apache</title>
		<link>http://dready.org/blog/2009/01/29/webpy-with-mod_python-on-apache/</link>
		<comments>http://dready.org/blog/2009/01/29/webpy-with-mod_python-on-apache/#comments</comments>
		<pubDate>Thu, 29 Jan 2009 09:54:41 +0000</pubDate>
		<dc:creator>wil</dc:creator>
				<category><![CDATA[python]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[modpython]]></category>
		<category><![CDATA[webpy]]></category>

		<guid isPermaLink="false">http://dready.org/blog/?p=205</guid>
		<description><![CDATA[Normally, I&#8217;m a Django-head, but today I wanted a quick way to write a small web app and have heard good things about web.py so I decided to give it a try. I also wanted minimum fuss to get something up-and-running quickly, and decided to have it served by my existing Apache installation with mod_python. [...]
No related posts.

Related posts brought to you by <a href='http://yarpp.org'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<p>Normally, I&#8217;m a <a href="http://www.djangoproject.com/">Django</a>-head, but today I wanted a quick way to write a small web app and have heard good things about <a href="http://webpy.org/cookbok/xmlfiles">web.py</a> so I decided to give it a try. I also wanted minimum fuss to get something up-and-running quickly, and decided to have it served by my existing Apache installation with <a href="http://www.modpython.org/">mod_python</a>.</p>
<p>In the process of setting it up, I ran into a few bumps, and would like to share them:</p>
<ul>
<li>My setup is: Python 2.5.2, web.py 0.31, Apache 2.2.8 with mod_python 3.3.1</li>
<li>The section on configuring mod_python on the <a href="http://webpy.org/install">web.py installation page</a> doesn&#8217;t work for this version. In particular, it tells you to do this:
<pre>
main = web.wsgifunc(web.webpyfunc(urls, globals()))
</pre>
<p>which seems to be the API in web.py 0.2. Using it on 0.3 will land you a nice <code>AttributeError: 'module' object has no attribute 'wsgifunc'</code>. Instead, do this:</p>
<pre>
app = web.application(urls, globals(), autoreload=False)
main = app.wsgifunc()
</pre>
<p>It&#8217;s also worth noting that the version of modpython_gateway.py I&#8217;m using is <a href="http://www.aminus.net/browser/modpython_gateway.py?rev=106&#038;format=raw">revision 106</a>. With this version, there is no need to place it in the <code>wsgiref</code> package directory since it no longer depend on <code>wsgiref</code>.</p>
</li>
<li>My Apache config is:
<pre>
  Alias /path /vhosts/dready.org/apps/myapp/
  &lt;Directory /vhosts/dready.org/apps/myapp/&gt;
    Allow from all

    &lt;IfModule python_module&gt;
      SetHandler python-program
      PythonHandler modpython_gateway::handler
      PythonOption wsgi.application codep::main
      PythonOption SCRIPT_NAME /path
    &lt;/IfModule&gt;
  &lt;/Directory&gt;
</pre>
</li>
<li>Notice that I specified the <code>autoreload</code> argument, because the other problem I ran into was that web.py complained the following:
<pre>
Traceback (most recent call last):
  File "/usr/local/lib/python2.5/site-packages/web.py-0.31-py2.5.egg/web/application.py", line 209, in process
    return p(lambda: process(processors))
  File "/usr/local/lib/python2.5/site-packages/web.py-0.31-py2.5.egg/web/application.py", line 536, in processor
    h()
  File "/usr/local/lib/python2.5/site-packages/web.py-0.31-py2.5.egg/web/application.py", line 73, in reload_mapping
    mod = __import__(module_name)
ImportError: No module named _mp_4ba3724007eff4c08a72054c4da2c222
</pre>
<p>I&#8217;m not sure the reason for this, but definitely has something to do with web.py&#8212;s auto-reload feature, and the fact that it is running under <code>mod_python</code> so the module name seems to be mangled.
        </li>
<li>The other thing is that if you ever run into the problem of getting a file save dialog when requesting the root URL of your app, with the content type of <code>httpd/unix-directory</code>, but not other URLs, this could be due to either Apache or <code>mod_python</code> passing the hint on the request, so if you don&#8217;t respond with a <code>Content-Type</code> header (using <code>web.header('Content-Type', 'text/html')</code>, that hint gets copied over to the response.</li>
</ul>
<p>No related posts.</p>
<p>Related posts brought to you by <a href='http://yarpp.org'>Yet Another Related Posts Plugin</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://dready.org/blog/2009/01/29/webpy-with-mod_python-on-apache/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Python 3.0: Text vs. Data Instead Of Unicode vs. 8-bit</title>
		<link>http://dready.org/blog/2008/12/15/python-30-text-vs-data-instead-of-unicode-vs-8-bit/</link>
		<comments>http://dready.org/blog/2008/12/15/python-30-text-vs-data-instead-of-unicode-vs-8-bit/#comments</comments>
		<pubDate>Sun, 14 Dec 2008 17:26:58 +0000</pubDate>
		<dc:creator>wil</dc:creator>
				<category><![CDATA[i18n]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[unicode]]></category>
		<category><![CDATA[django]]></category>

		<guid isPermaLink="false">http://dready.org/blog/?p=188</guid>
		<description><![CDATA[Python 3.0 (Py3K) is out. I&#8217;m with Sam Ruby &#8212; this seemingly simple change of paradigm from &#8220;Unicode vs. 8-bit&#8221; to &#8220;Text vs. Data&#8221; is a breath of fresh air. What&#8217;s inconsistent in this new version though is that the new bytes type still contains many of the methods with text semantics that should only [...]
Related posts:<ol>
<li><a href='http://dready.org/blog/2011/10/24/find-for-else-statements-in-python-code/' rel='bookmark' title='Find For-Else Statements in Python Code'>Find For-Else Statements in Python Code</a> <small>I came across Ned Batchelder&#8217;s post on the for/else construct, which explains its purpose in a different way from the...</small></li>
</ol>

Related posts brought to you by <a href='http://yarpp.org'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.python.org/download/releases/3.0/">Python 3.0</a> (Py3K) is out. I&#8217;m with <a href="http://intertwingly.net/blog/2008/12/04/Python-3-0-Released">Sam Ruby</a> &#8212; this seemingly simple change of paradigm<a href="http://docs.python.org/dev/3.0/whatsnew/3.0.html#text-vs-data-instead-of-unicode-vs-8-bit"> from &#8220;Unicode vs. 8-bit&#8221; to &#8220;Text vs. Data&#8221;</a> is a breath of fresh air.</p>
<p>What&#8217;s inconsistent in this new version though is that the new <code>bytes</code> type still contains many of the methods with text semantics that should only make sense as <code>string</code> methods: e.g. <code>capitalize()</code> and <code>islower()</code>. I suspect these are provided as convenience methods, which is fine. But one would imagine that these byte methods will work by decoding the bytes using the default encoding of your locale, then performing the operations on the resulting string. As it turns out from my trials, it seems to assume that your bytes are encoded in Latin1:</p>
<p><code><br />
&gt;&gt;&gt; greek_beta = "Β" # This is the uppercase greek letter "beta", not regular B.<br />
&gt;&gt;&gt; greek_beta.isupper()<br />
True<br />
&gt;&gt;&gt; greek_beta.islower()<br />
False<br />
&gt;&gt;&gt; greek_beta.lower()<br />
'β'<br />
&gt;&gt;&gt; greek_beta_bytes = greek_beta.encode('iso8859-7')<br />
&gt;&gt;&gt; greek_beta_bytes<br />
b'\xc2'<br />
&gt;&gt;&gt; greek_beta_bytes.isupper()<br />
False<br />
&gt;&gt;&gt; greek_beta_bytes.islower()<br />
False<br />
&gt;&gt;&gt; greek_beta_bytes.lower()<br />
b'\xc2'<br />
&gt;&gt;&gt; greek_beta_bytes.upper()<br />
b'\xc2'<br />
</code></p>
<p>This is definitely a gotcha that may lead to hard to find bugs. So, it is best to avoid using those methods on <code>bytes</code> objects.</p>
<p>Otherwise, this change is definitely more &#8220;correct&#8221; in that Py3K forces you to know the type of your variables earlier or at the interfaces (to the outside world) so errors like these are less likely to sneak up from your back. For example, you can no longer use the <code>+</code> (sequence concatenation operator) to mix text and data. Whereas in Python 2.x, you can do:</p>
<p><code><br />
&gt;&gt;&gt; name = 'Wil'<br />
&gt;&gt;&gt; greet = lambda n: u'Hello ' + n<br />
&gt;&gt;&gt; greet(name)<br />
u'Hello Wil'<br />
&gt;&gt;&gt; name = u'François'.encode('utf-8')<br />
&gt;&gt;&gt; name<br />
'Fran\xc3\xa7ois'<br />
&gt;&gt;&gt; greet(name)<br />
Traceback (most recent call last):<br />
  File "&lt;stdin&gt;", line 1, in &lt;module&gt;<br />
  File "&lt;stdin&gt;", line 1, in &lt;lambda&gt;<br />
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 4: ordinal not in range(128)<br />
</code></p>
<p><small>What went wrong was that you&#8217;re relying on Python&#8217;s automatic Unicode conversion, which uses the standard ASCII codec (which is a good thing) to promote your <code>str</code> to <code>unicode</code>.</small></p>
<p>In Python 3.x, you will be greeted by the <code><a href="http://docs.python.org/dev/3.0/library/exceptions.html#exceptions.TypeError">TypeError</a>: Can't convert 'bytes' object to str implicitly</code> message if you tried to pass a <code>bytes</code> object to the function. This will happen on any bytes object, so the error is easier to catch.</p>
<p>In this new version, the <a href="http://docs.python.org/dev/3.0/library/unicodedata.html"><code>unicodedata</code></a> module is upgraded to Unicode version 5.1.0.</p>
<p>Now, I&#8217;m not ready to run production code on Py3K yet but it would be nice if Django (my favourite Python-based web framework) can run on it. It looks like <a href="http://loewis.de/martin/">Martin von Löwis</a> has started the <a href="http://wiki.python.org/moin/PortingDjangoTo3k" title="Porting Django to Python 3.0 (Py3K)">porting</a>.</p>
<p>Related posts:<ol>
<li><a href='http://dready.org/blog/2011/10/24/find-for-else-statements-in-python-code/' rel='bookmark' title='Find For-Else Statements in Python Code'>Find For-Else Statements in Python Code</a> <small>I came across Ned Batchelder&#8217;s post on the for/else construct, which explains its purpose in a different way from the...</small></li>
</ol></p>
<p>Related posts brought to you by <a href='http://yarpp.org'>Yet Another Related Posts Plugin</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://dready.org/blog/2008/12/15/python-30-text-vs-data-instead-of-unicode-vs-8-bit/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

