Table of Contents

webpy web framework

Getting started

  $ mkdir webpy; cd webpy
  $ wget http://webpy.org/web.py
  $ wget http://webpy.org/markdown.py

`markdown` is used by harry's wiki. It's not the required modules for webpy. The next step is to execute wiki.py

  $ vi wiki.py
  $ chmod u+x wiki.py
  $ export PYTHONPATH=/home/kamal/webpy
  $ ./wiki.py

the wiki code:-

#!/usr/bin/env python
 
import web
from markdown import Markdown
import os, time, re, cgi
 
# For debugging use only
web.internalerror = web.debugerror
 
urls = (
    '/', 'WikiPages',
    '/page/([a-zA-Z_]+)', 'WikiPage',
    '/editor/([a-zA-Z_]+)', 'WikiEditor'
)
 
wikidir = os.path.realpath('/home/kamal/webdev/public')
 
class WikiPages:
 
        def GET(self):
                web.header("Content-Type","text/html; charset=utf-8")
                t = re.compile('^[a-zA-Z_]+$')
                wikipages = os.listdir(wikidir)
                print "<html><head><title>wiki pages</title></head><body>"
                print "<h1>Wiki Pages:</h1><ul>"
                for wikipage in wikipages:
                        if os.path.isfile(os.path.join(wikidir, wikipage)) and t.match(wikipage):
                                print "<li><a href=\"%(path)s/page/%(page)s\">%(page)s</a></li>" \
                                        % {'path':web.rstrips(web.ctx.home, '/wiki.py')+web.ctx.path[1:],'page':wikipage}
                print "</ul></body></html>"
 
class WikiPage:
 
        def GET(self, name):
                page = os.path.join(wikidir,name)
                web.header("Content-Type","text/html; charset=utf-8")
                if os.path.exists(page):
                        print "<html><head><title>%s</title></head><body>" % name
                        print "<h1>%s</h1>" % name
                        print "<p>"
                        print "[<a href=\"%s\">Pages</a>] " \
                                        % (web.ctx.home+"/")
                        print "[<a href=\"%s\">Edit</a>] " \
                                        % (web.ctx.home+'/editor/'+name)
                        print "</p>"
                        print Markdown(open(page).read())
                        print "</body></html>"
                else:
                        web.ctx.status = '404 Not Found'
                        print "<html><head><title>Does not exist: %s</title></head><body>" % name
                        print "<p>Page %s does not yet exist - " % name
                        print "<a href=\"%s\">Create</a>" % (web.ctx.home+'/editor/'+name)
 
        def POST(self,name):
                page = os.path.join(wikidir,name)
                if os.path.exists(page):
                        newpage = page+'.'+time.strftime("%Y%m%d%H%M%S", time.gmtime())
                        os.rename(page,newpage)
                f = open(page, "w")
                f.write(web.input(page='').page)
                f.close()
                web.redirect(web.ctx.home+'/page/'+name)
 
class WikiEditor:
 
        def GET(self,name):
                web.header("Content-Type","text/html; charset=utf-8")
                print "<html><head><title>Editing %s</title></head><body>" % name;
                print "<h1>Editing: %s</h1>" % name
                print "<form method=\"POST\" accept-charset=\"utf-8\" action=\"%s\">" \
                        % (web.ctx.home+'/page/'+name)
                print "<textarea name=\"page\" cols=\"100\" rows=\"20\">"
 
                page = os.path.join(wikidir,name)
                if os.path.exists(page):
                        print cgi.escape(open(page).read())
                print "</textarea><br><input type=\"submit\" value=\"Update\"></form>"
                print "<p><a href=\"http://daringfireball.net/projects/markdown/syntax\">Markdown Syntax</a></p>"
 
                print "</body></html>"
 
if __name__ == "__main__": web.run(urls)

webpy will start it's built in web server listening on port 8080. That's it ! and harry's wiki simply work. Ok, forget the wiki, let see some simple code of webpy apps.

#!/usr/bin/env python
 
import web
 
# For debugging use only
web.internalerror = web.debugerror
 
urls = (
    '/', 'Hello',
)
 
class Hello:
    def GET(self):
        web.header("Content-Type","text/html; charset=utf-8")
        print "<html<head><title>hello</title></head>"
        print "<body><b>hello world</b>"</body></html>"
 
 
if __name__ == "__main__": web.run(urls)

FastCGI/Lighttpd

create some public dir for docroot. This is also a place where we will place our code. The directory layout look's like:-

  $ ls .
  webpy public flup
  $ ls webpy
  web.py markdown.py
  $ ls public
  wiki.py

We need flup in order to use webpy as FastCGI binary through lighttpd. This is lighttpd.conf file:-

server.modules = ( "mod_rewrite",
                   "mod_access",
                   "mod_fastcgi",
            "mod_accesslog")
server.port                =  8800
server.document-root = "/home/kamal/webdev/public/"
 
$HTTP["host"] == "wiki.laptop.int" {
  server.document-root = "/home/kamal/webdev/public/"
  server.errorlog = "/home/kamal/lighttpd/lighttpd-error.log"
  accesslog.filename = "/home/kamal/lighttpd/access_log"
 
  fastcgi.debug  = 1
  fastcgi.server = ( "/wiki.py" =>
   (( "socket" => "/tmp/webpy.socket",
      "bin-path" => "/home/kamal/webdev/public/wiki.py",
      "max-procs" => 1
   ))
 )
 
 url.rewrite-once = (
    "^/favicon.ico$" => "/static/favicon.ico",
    "^/static/(.*)$" => "/static/$1",
    "^/(.*)$" => "/wiki.py/$1",
 )
 
 }
 
## change uid to <uid> (default: don't care)
server.username            = "kamal"
 
## change uid to <uid> (default: don't care)
server.groupname           = "users"

Make sure webpy and flup were in your PYTHONPATH. Now you can start lighttpd with lighttpd -f lighttpd.conf.