webpy Example
A short write up on how to bootstrap a webpy app and at the same time show how to make a system call with popen. I based this short app on the skeleton example here: http://webpy.org/skeleton/0.3
Just a note on where my test live for my own reference later.
$ pwd /DATA/src/hvInfo $ ls call1.py call.pyc config.pyc hvInfo.pyc my test with spaces_ and more... templates view.pyc web.py-0.37 call.py config.py hvInfo.py index.html simpleHTTP.py view.py web web.py-0.37.tar
Main python app:
hvInfo.py
import web import view, config from view import render urls = ( '/', 'index' ) class index: def GET(self): return render.base(view.listing()) if __name__ == "__main__": app = web.application(urls, globals()) app.run()
Define some functions here:
call.py
import config #from subprocess import Popen, PIPE import subprocess def listing_experiment1(): cmd = "ls -l ~/" p = Popen(cmd , shell=True, stdout=PIPE, stderr=PIPE) #out, err = p.communicate() #print "Return code: ", p.returncode #return out.rstrip(), err.rstrip() outputlines = filter(lambda x:len(x)>0,(line.strip() for line in p.stdout)) return outputlines #return out.replace('\n','<br>') ##return config.DB.select('items', **k) def dir_listing(): ## http://stackoverflow.com/questions/8880461/python-subprocess-output-to-list-or-file ls_lines = subprocess.check_output(['ls', '-l']).splitlines() ## I want to pass output as separate fields but space as a delimiter won't do the trick since filenames can have spaces... ls_arr= [] for item in ls_lines: if not "total" in item: f = item.split() #fname = item.join(str(v) for v in item.index if v > 7) fname = "" for idx,val in enumerate(f): if idx > 7: fname = fname + str(val) + " " fname = fname[:-1] ls_fields = [f[0],f[1],f[2],f[3],f[4],f[5]+"-"+f[6]+"-"+f[7],fname] ls_arr.append(ls_fields) return ls_arr
Lets maintain a config file. Especially when DB access becomes necessary.
config.py
import web #DB = web.database(dbn='postgres', db='appname', user='username', pw='') cache = False
Following MVC type framework. It makes sense to keep presentation separate.
view.py
import web import call import config t_globals = dict( datestr=web.datestr, ) render = web.template.render('templates/', cache=config.cache, globals=t_globals) render._keywords['globals']['render'] = render def listing(): l = call.dir_listing() return render.listing(l)
Templates as follow:
$ cat templates/base.html
$def with (page, title=None) <html><head> <title>hvInfo\ $if title: : $title\ </title> </head><body> <h1><a href="/">hvInfo</a></h1> $:page </body></html>
$ cat templates/listing.html
$def with (items) <table> $for item in items: <tr><td>$item[0]<td>$item[1]<td>$item[2]<td>$item[3]<td>$item[4]<td>$item[5]<td><b>$item[6]</b> </table>
$ cat templates/item.html
$def with (item) $item
Run web server as follow:
$ python hvInfo.py http://0.0.0.0:8080/
Test in browser at this link: http://localhost:8080/