Package: berry
Berry is a minimal DSL for building a WSGI application.Basically, you map some routes to functions.  Berry takes this mapping andgenerates a WSGI app, which you can serve however you like.Example-------Here is an example using the wsgiref server, included in Python's stdliband ideal for development use.import berryfrom wsgiref.simple_server import make_server@berry.get('^$')def index(req):return "Welcome to the home page."@berry.get('^hello/(.+)/?$')def hello(req, name):return "Hello, %s!" % name# generate a WSGI appwsgi_app = berry.app# start a WSGI servermake_server('127.0.0.1', 8000, wsgi_app).serve_forever()How to use it-------------Decorate a function with berry.get(route) or berry.post(route) to serveGET/POST requests that match a route.  Routes must be regular expressions.Your function will be passed a Request object as the first argument.Example:@berry.get('^$')@berry.get('^home$')def home(req):return 'This is the home page.'As above, you can map multiple routes to the same function.Request objects---------------Useful attributes of Request objects are:- env: the WSGI environ variable.- params: parameters passed through both GET and POST.- path: the path requested, minus the initial '/' and the query string- query: the query string, if any- fullpath: the full path requested, including the initial '/' and thequery string- method: the method (GET or POST)Example:@berry.post('^login$')def login(req):username = req.params.get('username')password = req.params.get('password')# ...Note: if you have a field like 'a[b]' with value 'c', Berry will parse itinto a dictionary.  For example:<input name="person[name]" value="James" /><input name="person[age]" value="20" />will result in req.params being:{'person': {'name': 'James', 'age': '20'}}.Also,<input name="person[friends][]" value="James" /><input name="person[friends][]" value="John" />will result in req.params being:{'person': {'friends': ['James', 'John']}}.Handling errors---------------Using the berry.error(code) decorator, you can make custom error pages.Example:@berry.error(404)def notfound(req):return "%s was not found." % req.fullpathBerry has Redirect, Forbidden, NotFound, and AppError classes, whichare exceptions that inherit berry.HTTPError.  Just raise one of them:if not user.is_logged_in():raise berry.Forbidden()To add an exception for a new HTTP status code you can do something like:class Unauthorized(berry.HTTPError):status = (401, 'Unauthorized')content = "<h1>401 Unauthorized</h1>"Application errors------------------If you set berry.debug = True, tracebacks will be outputted when thereis an exception in your code.  Otherwise they will only be written tostderr.Redirecting-----------To redirect, raise the berry.Redirect exception:raise berry.Redirect(url)Headers-------To add HTTP headers, use the berry.header decorator:@berry.header('Content-Type', 'text/plain')def download_as_txt(req, id):# ...By default the Content-Type is set to 'text/html'.How to install--------------If you have setuptools just do:easy_install berryOtherwise, you can get the latest release from:http://pypi.python.org/pypi/berryOr get the latest development snapshot with git:git clone git://github.com/adeel/berry.gitThen:python setup.py installIf you try Berry, please write me at adeel2@umbc.edu and let me know whatyou think.Latest changes--------------- Not logging requests anymore (this should be done by a middleware).- Berry simply generates a WSGI app for you to serve yourself, instead ofserving it for you.- The convenience function redirect() was removed.