timmyt a écrit :
i'm interested in getting opinions on a small wsgi framework i
assembled from webob, sqlalchemy, genshi, and various code fragments i
found on the inter-tubes
here is the interesting glue - any comments / suggestions would be
much appreciated
<meta>
Well... My first comment would be about the usefulness of yet another
Python web framework, but let's not worry about this...
</meta>
------------------
the wsgi app
------------------
def application(environ, start_response):
path = environ.get('PATH_INFO', '').lstrip('/')
for regex, callback in urls:
match = re.search(regex, path)
I don't know where these "urls" come from. But anyway : if they live in
some sort of long-running process, you may want to precompile them.
if match:
environ['myapp.url_args'] = match.groups()
request = webob.Request(environ)
try:
return callback(request, start_response)
except Exception, ex:
How are redirect etc handled ?
start_response('500 Internal Server Error', [('Content-
Type', 'text/plain')])
return [traceback.format_exc()]
A configuration option controlling the display of the traceback would be
fine - I surely don't want the traceback being displayed to anyone when
the app goes into production.
Also, logging the error and traceback might be useful.
start_response('404 Not Found', [('Content-Type', 'text/plain')])
return ["Couldn't find the URL specified."]
And in both cases, having the ability to use "custom" 500 and 404 pages
might be nice too.
----------------------------------
the controller decorator
----------------------------------
def web_decorator(filename, method='html'):
>
def decorator(target):
May I suggest some renaming here ?
filename => path (or 'template_path' ?)
method => content_type
target => controller or function or callback or....
def wrapper(request, start_response):
#genshi TemplateLoader
template = loader.load(filename)
global config
Probably not thread-safe....
try:
return_dict = target(request, start_response)
return_string = template.generate(**return_dict).render
(method)
Renaming again:
return_dict => context
return_string => data or text or ???
config['database.Session'].commit()
except:
config['database.Session'].rollback()
raise
finally:
config['database.Session'].remove()
This doesn't leave much control on transactions... Sometimes you want to
handle it manually one way or another.
#TODO: alter 'Content-Type' per method being passed
start_response('200 OK', [('Content-Type', 'text/html')])
return [return_string]
Ok, so here again, I don't understand how redirects can work. Also, if
you do use start_response here, I don't get why you still pass it to the
callback function.
return wrapper
return decorator
slightly OT, but preserving infos on the decorated function might help
too (introspection, debugging etc).
My 2 cents...
--
http://mail.python.org/mailman/listinfo/python-list