Juno: A Lightweight and Simple Web Framework for Python
brianreily.com
brianreily.com
Luckily this is Python so it's possible to monkeypatch the implementation.
IMO, web.py qualifies to be called "really lightweight"
take for instance the hello world code:
import web
urls = (
'/(.*)', 'hello'
)
app = web.application(urls, globals())
class hello:
def GET(self, name):
if not name:
name = 'world'
return 'Hello, ' + name + '!'
if __name__ == "__main__":
app.run()
This has two advantages over the Juno code..1. more `REST`y (GET/POST)
2. `app` object is a wsgi callable..
More importantly, web.py does not need have any external library dependencies unless you choose to use mysql/postgresql when you have to install the db interface libraries. I had problem running the hello world Juno code because I did not have pysqlite2 installed.. huh? why do I need pysqlite2 to return a string?
While some may object saying that web.py has a case of NIH, the code of web.py itself does not reflect any such attitude. The whole library is just a directory of aptly named modules. You can plop it anywhere in the python path and start coding ..
Umm... can somebody compare Juno to Pylons please - I'm kind of confused here
http://www.recessframework.org/page/routing-in-recess-screen...
I have a lot of negative things to say about a lot of different languages, but I think what Kris has done with annotations in PHP is pretty cool, even if it is ultimately a hack.
PS. Juno looks nice though I'm not a huge fan of frameworks that return rendered html from controllers. But I do like it's Sinatra-esque simplicity.
I'm not so sure there is a "semantic contract" for comment blocks since they're made available via reflection. Comments are metadata after all.
And this is more akin to annotations/attributes ala python, java, C#. C++ doesn't have any feature that is approximate by virtue that annotations are aspects of reflection and C++ doesn't have reflection.
1) it's more DRY because for external files to say something about a construct in code there is repeated information, i.e. <route><to><class>Foo</class><method>bar</method></to><from><method>GET</method><url>some/url/here</url></to></route>,
2) because you're using the PHP language to specify metadata about a PHP construct refactoring is easier, i.e. change the name of a function and you don't have to go update your routing somewhere else,
3) having the metadata inline with code turns out to be mentally lightweight once you get over the initial shock of seeing metadata in a comment.
It's little known that doccomments are a PHP language construct that can be reflected over just as Python's doc strings can be introspected with __doc__.
http://us3.php.net/manual/en/language.oop5.reflection.php#la...
Thus !Route GET, a/good/$programmer is just as much a language construct in a PHP program as @route('a/good/:programmer') is in a Python program. The key difference is Python defines at the language level how that particular bit of script is expanded as a decorator. Recess does its expansion of annotations at the framework level.
Python is a much better and more thoughtfully designed programming language than PHP, for sure. PHP has loop holes, doccomments is one of them. PHP does not do anything, by default, with a doccomment, but it does give an opportunity to introduce meta-data on classes, methods, and properties and easily reflect over that meta-data and then it's up to the programmer to define a 'DSL'.
In this sense PHP offers something powerful and dangerous. Recess choose a simple data format, such that parsing can be expressed in a regexp that is then processed by essentially 'Constructing a class of type [FirstWord] and call init method with array of [Following words as a PHP array] - finally make these annotations available through reflection'. Not too much different than annotations in Java/C#. Simple enough that the danger is mostly negated and the utility makes the 'hack' justifiable.
For a better-written justification of why this design decision was made for Recess: http://www.recessframework.org/page/on-hiding-our-dick-tracy...
(Aside: This is why I'm a huge fan of Scala - extending a language with the language is awesome.)
The equivalent in Python would be:
def my_controller(request): """route: /thing/:var/""" pass
or similar.
dict holding list holding tuple holding dict :) no biggy to throw a wrapper over it though. Is it possible to place all the routes in one place you think with this? I am worried with a larger project I will forget which module contains what url... Unless there is some convention for url path->module name (if there isnt I would suggest establishing one). A suggestion I would have is standardize on some templating so if people end up using this there wont be a person using a different available one. (http://wiki.python.org/moin/Templating) I noticed http://karrigell.sourceforge.net/en/pythoninsidehtml.htm was not on that page though... albeit its more like php.