For our March meeting, the Utah python user group had multiple people present a solution to the PyWebOff challenge.
This is not an attempt at an authoritative web frameworks review. The backgrounds of the presenters are too different -- in particular, only the Rails and Spyce presenters had prior prior experience with the frameworks they used.
That said -- and obviously I'm all sorts of biased as both presenter and maintainer of Spyce -- I think Spyce came off looking pretty well. Partly because it was designed to automate repetitive tasks with relatively little "magic," and partly because Spyce doesn't try to put you in a straitjacket: you can write strict MVC code if you want, but if mixing some code into your view makes more sense than the alternatives, you can do that too.
"I," "me," etc. in the remainder of this post refers to the presenter speaking of himself. In presentation order, here are my notes:
TurboGears
Presenter: Byron Clark (Prior web experience: some playing with Rails)
- sum of parts (kid, cherrypy, etc)
- 0.89 reviewed
- tg-admin shell
- decorators describe template in use on methods
- can load template in browser; easier for designers?
- designers may have trouble with the py.content stuff
- server crashes on python syntax error in controller
- turbogears.flash -- validation errors, or debugging
- cherrypy behavior changed: in cherrypy you usually return the page you want to render. in TG, you return a dict of stuff to expose to your template. (But if you return a string instead of dict, it just gets "printed." This is also useful for debugging.)
- "kid wasn't completely worthless. (laughter) It could have been a lot worse. (more laughter) It gave me less trouble than everything else."
- lots of validator methods, but nothing to turn list of strings into list of ints (say, for a bunch of checkboxes)
- things that were hard:
- getting validators to work
- "would it kill the sqlobject developers to add a delete method?"
Zope 3
Presenter: Shane Hathaway (Prior web experience: extensive Zope 2)
- Zope 3: learn from maintainability problems of Zope 2
- target: python programmers
- Zope 2 target: web designers
- getting started: interface for content object
- "here's the implementation of the book interface. it's not finished."
- many many lines of xml config file. "I wrote it by hand."
- forms generated from xml -- no manual html needed
- student
- "this is where I got stuck"
- Zope 3 book talks about annotating objects; started to use that, "but zope 3.2 eliminated the code that made that work."
- hours and hours
- "I got really, really annoyed at the violation of DRY here"
- Q: is zope3 configure-through-web, or is it xml now? A: I really don't know; I've been discussing that with (inaudible). Seems to let you do both, but I can't tell which they're emphasizing. Fredrik Lundh's crisis of faith link. "That's kind of where I am, too." Believe Zope3 will turn out better for larger projects.
Ruby on Rails
Presenter: Lee Never-got-his-last-name (Prior web experience: several months? of professional Rails)
PyWebOff source: http://utahpython.org/data/pyweboff-rails.tgz
- breakpoint method throws test webserver into console mode
- authentication -- missed this while taking a phone call
- ajax basics: server sends back a script fragment that gets eval'd to replace elements on page
- Q: I've heard Rails is inefficient. Can you comment? A: I've found it to be rather efficient -- my code is about 100 loc. I think my time is more valuable than server processing time. We serve 50 req/s on some pages on dual cpu, 1GB ram servers.
- Q: FastCGI? A: Yes, with lighttpd
- Q: How much does the ORM force you to stick to it? A: You pretty much need to stick to ActiveRecord, but you can drop down to SQL if you really need to. I like AR a lot.
Django
Presenter: Roberto Mello (Prior web experience: co-founder of OpenACS framework)
- "spent way too much time trying to do things that I thought should have been a lot simpler"
- url mapping w/ regexp; first argument is namespace-ish thing
- admin was pretty cool
- "Way too much magic! Way too much! At least for my taste."
- When stuff fails, like my user registration, I have no idea what's going on
- Talking w/ people on #django I guess it just takes a different frame of mind -- "what's a join?"
- I'm an old school database guy, so I wanted to create a join on all my tables that would give me what I wanted, but I couldn't figure out a way to do that!
- No way to specify method arguments from template, some people suggested looping over ALL rows in DB, basically performing a WHERE clause with if statements
- others suggested making custom tag
- found how to get cursor, but had to dig through source to figure out how to use it
- finally settled on performing ORM lookups in controller, passing to template
- also have to pass dict of stuff to template
- ORM ugly and hard to get used to. Some syntax:
- books.get_list(id__exact='5')
- books.get_list(loans__loan_id__startswith='tom')
- books.get_list(tables=['loans'], where=['foo=bar'])
- very intimidating example of 20+ lines
- I've only had a day of experience with django now, but it takes a very different frame of mine -- a very inefficient one -- to use it. But the admin's pretty cool.
- @login_required decorator
- Conclusion: can't get past the ORM. Way too much magic. Maybe "magic removal" branch will help. It seems to have just accumulated the magic, more and more.
Spyce
Presenter: Jonathan Ellis
Slides: http://utahpython.org/data/pyweboff-spyce.pdf
PyWebOff source: http://utahpython.org/data/pyweboff-spyce.tar.gz
- Spyce 1.x: mostly JSP influence
- Spyce 2.x: some ASP.NET influence. Goals:
- less repetitive tasks for form processing
- provide reusable components w/o the complexity that comes from trying to pretending HTTP is stateful (which is ASP.NET's big mistake)
- other modern facilities such as parent/child composition (sort of like what others call template inheritance)
- Challenge solution
- model-less data access via sqlalchemy introspection ("simpledb" module, hopefully soon to make it into sqlalchemy.ext subversion)
- "data binding" (ASP.NET term) in select box; no need to manually specify option tags
- bobo (early zope)-inspired :list:int naming convention (see checkboxes)
- (these are Spyce 2.1 features, currently in svn trunk)
- auth tag (from contrib/; not easily customizable yet)
- Q: What is the difference between [[! and [[\ ? A: [[! compiles the code fragement into the class that spyce generates; the other just inserts it as part of the "run" method body in that same class. [[! is primarily used for in-lined handlers, since non-class-level methods aren't in scope yet when handlers are processed.
- Q: Is it really compiled? A: Yes; you can invoke spyceCompile.py from the command line to see what kind of code it generates.
- Q: Do you have to do that manually? A: No, spyce compiles .spy files as-needed, and (by default) checks for changes with each request. You can turn this off for speed in a production environment, in which case you just restart spyce if you change things.
Comments
For SQLObject you can .delete(id) or .destroySelf() to delete an object.
db.loans.insert(user_name=user_name, book_id=book_id)
loan = db.loans.selectfirst_by(book_id=book.id)
user = db.users.selectone_by(name=loan.user_name)
db.delete(loan)
I haven't decided yet how hard to push this but I'm leaning towards putting it in the core (as opposed to the frigid wastes of contrib/).
I don't plan to write any demos using the full-blown traditional ORM from SqlAlchemy though. Naturally people are welcome to do so, and I'd encourage those who want a real ORM to pick SqlAlchemy, but I'm not sure that's a good fit for Spyce's "target market" at this point.
(You're welcome to email jonathan at utahpython dot org if you'd rather not post your identity.)