So I've been hammering away at this thing for the past 3-4 days. I'm surprised to say that it's actually in a working state now. Maybe functional enough to be classified as a 'toy' web framework? Well, I suppose I need to finish more components first, since having only text fields for form input could get quite frustrating.
But the basics are all there... component rendering, event triggers, parameter binding (both by value and by reference), automatic persistence of session data.
Time to polish it, add more components, refine the interfaces. But I wonder... do I ever really want to publish it? Make it widely available? Document and support it?
Related to a recent entry I've made, I started thinking about a Python port (at least in concept) of Tapestry. Rather than go for the template/spec/class approach of Tapestry 4, I opted to go for the wholly annotation-based approach of Tapestry 5 (still in development) thus eliminating the need for a spec file.
Annotating methods/functions in Python is pretty simple, just use decorators. Annotating member variables, on the other hand, seemed non-trivial. But then I remembered ORMs like SQLObject and SQLAlchemy and that gave me an idea. However, it would require metaclass magic...
So when I woke up this morning, I grabbed my laptop and started hacking away at a proof-of-concept (while still in bed!) Many hours later (and I did get out of bed, eventually), I had most of the metaclass infrastructure for flannel done. Yes, flannel. (I'm entertaining ideas for a better name though.)
So now I can easily mark variables as a persistent, transient, or parameter type. And the variables will be magically transformed into a Python property with my own setters and getters. Also, I can mark methods with certain "lifecycle decorators" which defines when during the rendering cycle they should be called. Basically something like:
Transient variables don't really need to be annotated... but doing so allows them to be reset to an initial value at the start of a processing cycle. Speaking of which, if you aren't familiar with Tapestry, the abbreviated request/response cycle I'm aiming for looks something like:
Figure out which page/component the request was targetting via PATH_INFO.
Get an instance of the page from the pool.
Restore persistent variables from storage (typically the session), reset transient variables to their initial values, bind parameter variables and ensure all required parameter variables are bound.
Render the page! (Which recursively renders components within.)
Save persistent variables to storage.
Return page to pool.
Actions or pages with forms would require slightly different handling, which I haven't thought about yet. Form handling, I think, is the strength of these event-driven frameworks... so I'm aiming to get it right. Basically you "bind" input components (like text fields, checkboxes, etc.) to properties or even property paths and give it an "event handler" to call when the form is submitted. When your event handler is called, you can expect the properties to reflect the user input.
Anyhow, a significant (and unfortunate, I think) part of this project will involve coming up with yet another templating engine. However, it should be a fairly simple tag-based system, since most of the functionality will actually be implemented by components.
It will be interesting. Though I don't expect to take this project very seriously. But maybe if/when I actually get it to where I want it to be, I'll change my mind.
I added FCGIApp and SCGIApp to the (new) flup.client package. I wrote FCGIApp a few months ago for Ian Bicking's WPHP. While attempting to debug a problem with flup's fcgi server on Dreamhost (vs. my old fcgi.py module), I thought of an interesting solution.
Since the problem seemed to stem from the app's long startup time, and since Dreamhost only allows dynamic (i.e. web server-launched) FastCGI apps, why not have the web server-started app be as simple as possible and have it forward requests to a static, manually-launched app server?
Anyway, it's a trade off and I really don't know how significant it is. But I was never really a fan of web server-launched FastCGI apps. Unless you configure mod_fastcgi explicitly, it has a tendency to launch an application multiple times. And if your application isn't multi-process safe and aware, it can lead to problems.
Consider these two modules experimental for now. I'm not really sure where I want them to live. But they're there for the time being to play around with.
Nothing about Python per-se, but applications/frameworks written in Python that I wish I could find. (And that weren't related to Zope/Plone!)
A Python portal framework. Perhaps even a standardized Python portlet specification, to facilitate this.
Similarly, a Python CMS, along the lines of Drupal and Joomla! Is there one?
A web framework similar to Tapestry (and therefore, similar to WebObjects). But perhaps more Pythonic, whatever that means within that context.
I'm contemplating starting one of those projects myself. But I've been so out of touch with the Python community. Supporting flup has been almost nightmarish lately. (I guess I'm just too nice... it is OSS afterall.)
Poor flup. Reviled and yet seemingly a necessary evil because it was one of the first. (But thankfully, no longer the only choice as more FastCGI servers are released.)
Whatever. Winter break is coming up. I should have time to work on something.
I briefly toyed with Trac some time ago. Though I had to patch it to use WSGI, I found it pretty easy to use and maintain. My efforts eventually stalled, however, probably due to the way my public repository was derived from my real repository (i.e. lots of empty changesets).
Anyway, yesterday I updated to Trac 0.10.2 and was pleasantly surprised to find that it supported WSGI and flup's ajp and scgi servers out-of-the-box. The empty changeset issue is still there (which is my problem to fix). I just might have to split my repository up in the future.