Showing posts with label mako. Show all posts
Showing posts with label mako. Show all posts

Thursday, May 15, 2008

python on web - getting started : building your first app

I would be focusing here on the following tasks.


  • install pylons.

  • create a helloworld app using pylons.

  • install genshi.

  • change template engine.

  • deploy on apache using mod_wsgi.



Install Pylons

Run the following:

$ easy_install Pylons==0.9.6.1
OR
$ easy_install -f http://pylonshq.com/download/ Pylons==0.9.6.1

More details at http://wiki.pylonshq.com/display/pylonsdocs/Installing+Pylons


Create helloworld app

$ paster create -t pylons helloworld

A directory helloworld with the following structure is created

jayant@jayantbox:~/myprogs/python/helloworld$ ls -lh
total 44K
drwxr-xr-x 4 jayant jayant 4.0K 2008-04-25 17:47 data
-rwxr-xr-x 1 jayant jayant 1.5K 2008-05-15 10:41 development.ini
drwxr-xr-x 2 jayant jayant 4.0K 2008-04-25 17:47 docs
drwxr-xr-x 2 jayant jayant 4.0K 2008-04-25 17:47 ez_setup
drwxr-xr-x 9 jayant jayant 4.0K 2008-05-14 19:52 helloworld
drwxr-xr-x 2 jayant jayant 4.0K 2008-04-25 17:47 helloworld.egg-info
-rwxr-xr-x 1 jayant jayant 79 2008-04-25 17:47 MANIFEST.in
-rwxr-xr-x 1 jayant jayant 463 2008-04-25 17:47 README.txt
-rwxr-xr-x 1 jayant jayant 1.2K 2008-04-25 17:47 setup.cfg
-rwxr-xr-x 1 jayant jayant 865 2008-04-25 17:47 setup.py
-rwxr-xr-x 1 jayant jayant 507 2008-04-25 17:47 test.ini

To run the app, from within the helloworld directory do

jayant@jayantbox:~/myprogs/python/helloworld$ paster serve --reload development.ini
Starting subprocess with file monitor
Starting server in PID 15555.
serving on 0.0.0.0:5000 view at http://127.0.0.1:5000

Create a test.html in the <path_to_helloworld>helloworld/helloworld/public directory

<html>
<body>
Hello World!!
</body>
</html>


And point your browser to http://127.0.0.1:5000/test.html to see the "Hello World!!" page.

Now lets create a controller and try printing info through a template.

jayant@jayantbox:~/myprogs/python/helloworld$ paster controller hello
Creating /home/jayant/myprogs/python/helloworld/helloworld/controllers/hello.py
Creating /home/jayant/myprogs/python/helloworld/helloworld/tests/functional/test_hello.py

Edit the <path_to_helloworld>/helloworld/helloworld/controllers/hello.py file and put in some python code

import logging

from helloworld.lib.base import *

log = logging.getLogger(__name__)

class HelloController(BaseController):

    def index(self):
        # Return a rendered template
        # return render('/some/template.mako')
        # or, Return a response
        return 'Hello World'
    def serverinfo(self):
        import cgi
        import pprint
        c.pretty_environ = cgi.escape(pprint.pformat(request.environ))
        c.name = 'Jayant Kumar'
        return render('serverinfo.mako')

Now create a template serverinfo.mako in <path_to_helloworld>/helloworld/helloworld/templates

<h2>
Server info for ${request.host}
</h2>

<p>
The URL you called: ${h.url_for()}
</p>

<p>Hi there ${c.name or c.full_name or "Joe Smith"}</p>

<p>
The name you set: ${c.name}
</p>

<p>The WSGI environ:<br>
<pre>${c.pretty_environ}</pre>
</p>

Edit the <path_to_helloworld>/helloworld/helloworld/config/routing.py file and check if the following code there in the "CUSTOM ROUTES" section

map.connect('', controller='hello', action='index')
map.connect(':controller/:action/:id')
map.connect('*url', controller='template', action='view')

This means that an empty URL is matched to the index action of the hello controller. Otherwise, the route mapper looks for URLs in the form controller/action/id, but if action or controller are not specified the request is routed to the view action of the templates controller (created by the Pylons template). This raises a 404 error by default

Now go to http://localhost:5000/hello/hello and http://localhost:5000/hello/serverinfo and check out the output.

Installing genshi and switching the template engine

$ easy_install Genshi

To enable genshi in your project edit the <path_to_helloworld>/helloworld/helloworld/config/environment.py file and change the template engine from mako to genshi

    config.init_app(global_conf, app_conf, package='helloworld',
        template_engine='genshi', paths=paths)


Now create a new template in <path_to_helloworld>/helloworld/helloworld/templates, say serverinfo.html and put in the following code

<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:py="http://genshi.edgewall.org/"
lang="en">
<h2>
Testing...
</h2>

<p>Hi there ${c.name}</p>

<p>
The name you set: ${c.name}
</p>

<p>The WSGI environ:<br/>
<div py:content="c.pretty_environ">Pretty Environ</div>
</p>
</html>

And change your <path_to_helloworld>/helloworld/helloworld/controllers/hello.py to render the new template

        return render('serverinfo')

And check the output at http://localhost:5000/hello/hello and http://localhost:5000/hello/serverinfo

Deploy using mod_wsgi

For those who have not yet configured mod_wsgi, you can get mod_wsgi from http://code.google.com/p/modwsgi/.

Simply untar it and do a

./configure --with-apxs=/path/to/apache/bin/apxs
make
sudo make install


Bingo and you have the mod_wsgi.so file in your apache/modules directory

Change the httpd.conf and add the following

LoadModule wsgi_module modules/mod_wsgi.so

to load the wsgi module and then deploy the hello world application

WSGIDaemonProcess hello thread=25
WSGIScriptAlias /hello "/path/to/apache/anydirectory/hello.wsgi
<Location /hello>
        WSGIProcessGroup hello
        WSGIReloadMechanism Process
</Location>


This says that the application helloworld would run as a separate process with 25 threads. And since we have also enabled process reload mechanism available with mod_wsgi-2.0, all that is needed to restart/reload the application is to touch/change the wsgi script modification time.

Wait a minute, we did not create the hello.wsgi script. Create a directory in /path/to/apache or anywhere where apache has read access and where you want to keep your application startup scripts. So what i did was.

$ mkdir /path/to/apache/wsgi

And create a hello.wsgi inside it

cd /path/to/apache/wsgi
vim hello.wsgi


Add the following code here

import os, sys
sys.path.append('/path/to/python/application/helloworld')

from paste.deploy import loadapp

application = loadapp('config:/path/to/python/application/helloworld/development.ini')


And we are done. Please note that the /path/to/python/application should be readable and executable by apache. Or you can do (very unsafe - not recommended on production servers)

chmod -R a+rx /path

Now simply restart apache and point your browser to

http://localhost/hello/
and
http://localhost/hello/hello/serverinfo

To see the output.

Source:
http://wiki.pylonshq.com/display/pylonsdocs/Installing+Pylons
http://wiki.pylonshq.com/display/pylonsdocs/Getting+Started
http://wiki.pylonshq.com/display/pylonsdocs/Using+Other+Template+Languages
http://code.google.com/p/modwsgi/wiki/InstallationInstructions
http://code.google.com/p/modwsgi/wiki/IntegrationWithPylons

Python on web - getting started : selecting the tools

Why am i writing this? Well, because i felt that there are so many options, it is difficult to select an option for yourself. I was confused for quite some time in terms of what framework to use, what templating engine to use, which ORM layer to use and how to deploy the app on the web.

First of all, lets start of with the framework. The major frameworks are Django, TurboGears and pylons. Django is supposed to be the best framework from among the three. But Django is very tightly integrated to its template engine and ORM layer. And any sort of customization is not only difficult but also slows down the app. But it is good thing to start off python-on-web as a beginer. And its tight integration also accounts for its speed. It is the fastest framework among all of them. Take a look at some of the benchmarks on web here
http://www.rkblog.rk.edu.pl/w/p/simple-python-frameworks-benchmark/ And http://www.alrond.com/en/2007/feb/04/in-addition-to-the-test-of-mvc-frameworks/

Django is a good framework to use if you are building a small site with default settings. But when you need to have an enterprise level site with customizations, it is better to use something like Turbogears or Pylons. Turbogears is good and has "Turbogears Widgets" but it lacks proper documentation. TurboGears uses CherryPy whereas Pylons uses paste. I felt pylons to be much easier to use and easier to configure. Pylons has a very small base though it is not as fast as Django. There are lots of comparisons available on the net - just google for it. http://nxsy.org/unscientific-and-biased-comparison-of-django-pylons-and-turbogears gives a detailed comparison of different features of all the 3 frameworks.

After selecting Pylons as my framework, i have tons of options with respect to templating engine. I can use the default mako or kid or genshi or Cheetah (complete list available at http://projects.dowski.com/projects/buffet). I took a look on the performance benchmark and ease of use of all of them (from googlebaba ofcourse). And what i could figure out was that mako is the fastest template engine available. Genshi is a successor of kid and has a very clean xml-based integration. Which means that if i am using genshi, the html designer would not be able to see the code embedded within templates. So, i would prefer to use Mako or Genshi depending on the requirements. A list of different types of available template engines can be obtained from http://wiki.python.org/moin/Templating. Benchmarks are available here http://www.kuwata-lab.com/tenjin/pytenjin-users-guide.html#benchmark. Changing template engine for pylons is described here http://wiki.pylonshq.com/display/pylonsdocs/Using+Other+Template+Languages

I did not do any DB operations, so i did not go into selecting the ORM layer. Anyways, i always prefer to write my own queries instead of letting the ORM layer decide what query to fire. SQLAlchemy seems good though if you plan to use an ORM layer. SQLObject is also there, but it is old.

For deployment few options available are mod_wsgi, mod_python and the default paster. The paster server comes integrated with pylons and ofcourse cannot be used for production level deployment. mod_wsgi looked easy to use and is also supposed to be a small bit faster than mod_python. You can look at http://wiki.pylonshq.com/display/pylonscookbook/Production+deployment+using+mod_python for mod_python or http://code.google.com/p/modwsgi/wiki/IntegrationWithPylons or mod_wsgi integration.

Next we would look at building and deploying the "hello world" application