web2py without exec

75 views
Skip to first unread message

Jonathan Lundell

unread,
Feb 11, 2011, 3:48:48 PM2/11/11
to web2py-developers
The other day Massimo mentioned web2py without exec, in the context of exocet. Setting exocet aside, I was trying to think about what would be necessary to do something like that, and I'm not at all sure that I've got a complete list of the problems that need to be solved. So let me construct a straw man solution, and find out what's wrong with it.

1. My goal is to replace exec with import.

2. Each application a package, imported by gluon (conceptually by the wsgi application) to service a request.

3. Application code imports its own modules with absolute_import (this requires Python 2.5, which ought to be fine for this purpose). That is, a controller imports models, etc. This eliminates the need for local_import().

4. request-scope variables (request, response, session, etc) are held in gluon.globals.rq, thus:

from gluon.globals import rq
...
request = rq.request # or just use rq.request

(we've also called this gluon.globals.current; I'm using rq because it's shorter)

5. Application code imports html helpers, validators, etc, from gluon.html or gluon.validators directly.

6. Running models. A model file would have a single callable function that would be called on each request, if present. Immutable application globals could go in the module namespace. Request-scope "globals" would go in thread-local storage.

So stuff like mail settings could be global to the module, and initialized at import time. Per-request stuff would run in the called function, so maybe like:

from gluon.globals import rq

def run_model():
rq.db = DAL(whatever)

or perhaps

def run_model():
app = rq.app # all the app-specific thread-local info goes in rq.app = Storage()
app.db = DAL(whatever)

7. As a package, each application automatically runs in its own namespace(s), but that namespace is common to all requests.

8. Possible reloading solution: each request takes a reader lock on its application. To force a reload, set a per-app flag. When a request sees that flag, it takes the writer lock instead of the reader lock. Once it has the writer lock, if the flag is still set, it clears the flag, reloads the application package, releases the writer lock, takes the reader lock, and runs the request. (If the flag isn't still set, it skips the reload.)

9. Views. Views would be 'compiled' by parsing their templates and using the result to populate a compiled-views folder (package). A compiled view is the parsed template wrapped in a callable function, with a standard set of imports--a .py file.

Views would access request-scope globals, including stuff defined in model files, in the same way that controllers do, via thread-local storage: rq.request, rq.app.db.

Assuming that this works (a dangerous assumption) ... what are the implications for an application author?

1. No injected globals means explicit imports of validators, html helpers, request-scope objects. This can be viewed as a plus.

2. Syntax for request-scope objects changes from (eg) 'request' to 'rq.request'.

3. Apps would have to distinguish app-wide globals from request-scope globals. The rq.something syntax makes this explicit.

Again, this isn't a proposal per se. At this point I'm just curious about what an import-based version of web2py might look like. Is it possible? What are the advantages and disadvantages?

It's not unlikely that I've overlooked some gaping hole in the logic; if so, somebody break it to me gently.

Massimo Di Pierro

unread,
Feb 11, 2011, 3:54:53 PM2/11/11
to web2py-d...@googlegroups.com

The main point you cannot put any code any more outside controller
functions, not even in models, not even as parameters of
Field(objects). For example

db.define_table(Field(...,default=request.now))

would have to be

db.define_table(Field(...,default=lambda:global.request.now))

where global is a new thread local object.

There should be a lot of changes inside web2py because the DAL thread
pooling would break. I do not think this can be done without a
complete rewrite of main.py and, give that, I would just use bottle.py

> --
> mail from:GoogleGroups "web2py-developers" mailing list
> make speech: web2py-d...@googlegroups.com
> unsubscribe: web2py-develop...@googlegroups.com
> details : http://groups.google.com/group/web2py-developers
> the project: http://code.google.com/p/web2py/
> official : http://www.web2py.com/

Bruno Rocha

unread,
Feb 11, 2011, 3:59:03 PM2/11/11
to web2py-d...@googlegroups.com
There should be a lot of changes inside web2py because the DAL thread pooling would break. I do not think this can be done without a complete rewrite of main.py and, give that, I would just use bottle.py

What about some kind of merge? bottle2py ? a different project. 

Massimo Di Pierro

unread,
Feb 11, 2011, 4:09:14 PM2/11/11
to web2py-d...@googlegroups.com
I am all for a successor of web2py but, given that it will break backward compatibility, I would change a lot of things.

Here is what I am thinking....

- The controller should be a REST engine.

- All views for each app (in html) should automatically be packaged into one single html that talks to the rest services via ajax. The app should not transmit html at every requet, only data in JSON. All required html should be sent at once when the app is loaded. 

- would preserve the web based editors admin interface.

- I am not sure I would use Python any more for serverside. I think node.js or erlang are a better choice today.

- If it has to be in Python, I would use Tornado or Gevent to make sure it handles well asynchronous IO and would build on that. The only parts that I really like of web2py are the new DAL and the template system, and admin so I would salvage them.

Massimo


On Feb 11, 2011, at 2:59 PM, Bruno Rocha wrote:

There should be a lot of changes inside web2py because the DAL thread pooling would break. I do not think this can be done without a complete rewrite of main.py and, give that, I would just use bottle.py

What about some kind of merge? bottle2py ? a different project. 

Michele Comitini

unread,
Feb 11, 2011, 4:45:28 PM2/11/11
to web2py-d...@googlegroups.com
2011/2/11 Massimo Di Pierro <massimo....@gmail.com>:

> - If it has to be in Python, I would use Tornado or Gevent to make sure it
> handles well asynchronous IO and would build on that. The only parts that I
> really like of web2py are the new DAL and the template system, and admin so
> I would salvage them.

I'd like not to drop python, C-python without threads, IMHO is a good
performer. Avoiding threads if not on PyPy python would be a good
start. PyPy python can be a good choice to have for having restricted
python interpreters on the fly thus making framework more secure.
Anyway that would be
a long term project

http://pypi.python.org/pypi/Spawning/0.9.5

Massimo Di Pierro

unread,
Feb 11, 2011, 4:52:24 PM2/11/11
to web2py-d...@googlegroups.com
have you seen the reia language on erlang?

Bruno Rocha

unread,
Feb 11, 2011, 5:16:55 PM2/11/11
to web2py-d...@googlegroups.com
I also do not want to drop Python, and I do not think web2py has problems that deserve to be discontinued or replaced.

I'm quite grateful for the great framework which has been and for all that has facilitated in my life, and I'm more than a year living only for projects related to web2py. (web2py really pays all my bills)

Okay I'm not a Python purist, and my applications have not scaled as much, so maybe I have not much to add regarding the imports issue.

What I can say is that this period of one year working only with web2py,I've made some websites, several business applications already in production and web2py has been more than enough.

And I'm really quite passionate about this framework and each day I discover more'm more that I made the right choice when we changed our technology from Pylons to web2py and not decided to go with django.

For me, except for better organizing the implementation of the models, I think there is no thing in usability issues that need to be changed.

However, upon entering the performance and purism themes, we know that web2py has a certain stigma fueled by a bad reputation in the python community.

Some customers have questioned whether I could not use another framework to develop their projects because of the bad press that web2py has in the corporate environment.

Although I know that web2py works much better and more performatic than any .net application,but we really need to clean this false image of the memory eater and impure decisions.

For me web2py has 99.99% of goodies, including the community. we just need to improve the 1% remaining. Even if it is to break compatibility in a side project called 'web2py new generation' or anything like that.

but it is very important always maintaining compatibility, passion and evolution of the current web2py, and continuing with the use of exec() if needed - which for me is a feature, not a bug.

Massimo Di Pierro

unread,
Feb 11, 2011, 5:37:26 PM2/11/11
to web2py-d...@googlegroups.com
For sure I am biased but when I think about the future, it is not the exec that I want to move away. Actually it is the lack of exec in other languages like erlang that has prevented from moving on.

The problems I found with web2py (and with every other python web framework) is the MVC design. It assumes you ask for a page, the server gives you that page.
We no longer program that way. A page is comprised of multiple parts. Each of those parts should have its own MVC. We tried to add this to web2py with components but this design is not really built into the framework because the framework tried to be js agnostic. Moreover there is no need to process templates server side, it can should done client-side. The http connection should stay open and reused to mininize latency.

Forms were originally built around html forms and that does not allow ajax pre-validation. crud() can handle json submission but that was piggy backed and it should be done better and more efficiently.

The more I think about web2py feature the less I want its successor to resemble the other frameworks out there. I want it to be more radically different. 

Massimo


Jonathan Lundell

unread,
Feb 11, 2011, 6:19:18 PM2/11/11
to web2py-d...@googlegroups.com
On Feb 11, 2011, at 2:37 PM, Massimo Di Pierro wrote:
> For sure I am biased but when I think about the future, it is not the exec that I want to move away. Actually it is the lack of exec in other languages like erlang that has prevented from moving on.
>
> The problems I found with web2py (and with every other python web framework) is the MVC design. It assumes you ask for a page, the server gives you that page.
> We no longer program that way. A page is comprised of multiple parts. Each of those parts should have its own MVC. We tried to add this to web2py with components but this design is not really built into the framework because the framework tried to be js agnostic. Moreover there is no need to process templates server side, it can should done client-side. The http connection should stay open and reused to mininize latency.
>
> Forms were originally built around html forms and that does not allow ajax pre-validation. crud() can handle json submission but that was piggy backed and it should be done better and more efficiently.
>
> The more I think about web2py feature the less I want its successor to resemble the other frameworks out there. I want it to be more radically different.
>

The growth of JavaScript as a practical platform and its strength on the client side certainly makes it an interesting candidate for a new framework. And the fact that one can leverage all those client-side CPU cycles doesn't hurt, either.

A DAL seems like a handy part of such an architecture. I wonder if JSON could serve as the abstract representation of a request. (I'm thinking DAL here, not ORM.)

Jonathan Lundell

unread,
Feb 11, 2011, 6:43:10 PM2/11/11
to web2py-d...@googlegroups.com
On Feb 11, 2011, at 12:54 PM, Massimo Di Pierro wrote:
>
> The main point you cannot put any code any more outside controller functions, not even in models, not even as parameters of Field(objects). For example
>
> db.define_table(Field(...,default=request.now))
>
> would have to be
>
> db.define_table(Field(...,default=lambda:global.request.now))
>
> where global is a new thread local object.
>
> There should be a lot of changes inside web2py because the DAL thread pooling would break. I do not think this can be done without a complete rewrite of main.py and, give that, I would just use bottle.py

I was thinking that a model would (could) contain a wrapper function (let's call it 'run') that would be called per-request. So if db.py is now:

db = DAL(...)
...Field(...request.now)

it would become:

def run(rq):
rq.db = DAL(...)
...Field(...rq.now)

Would that break DAL thread pooling? I don't really understand it well enough to have an opinion.

A side note: rq (what we were calling 'current') can just as well have stuff like rq.now and rq.env at its root level. In particular, 'request' isn't all that useful as its own object, in the way that session is. OTOH, we wouldn't actually change it, because gluon wants to support both app styles.

And yes, this would be incompatible at the app level, though the conversion would be straightforward.

>> 3. Apps would have to distinguish app-wide globals from request-scope globals. The rq.something syntax makes this explicit.

Jonathan Lundell

unread,
Feb 11, 2011, 6:44:27 PM2/11/11
to web2py-d...@googlegroups.com
On Feb 11, 2011, at 1:09 PM, Massimo Di Pierro wrote:
I am all for a successor of web2py but, given that it will break backward compatibility, I would change a lot of things.

Here is what I am thinking....

- The controller should be a REST engine.

- All views for each app (in html) should automatically be packaged into one single html that talks to the rest services via ajax. The app should not transmit html at every requet, only data in JSON. All required html should be sent at once when the app is loaded. 

- would preserve the web based editors admin interface.

- I am not sure I would use Python any more for serverside. I think node.js or erlang are a better choice today.

I like node.js's no-thread approach. 

Michele Comitini

unread,
Feb 11, 2011, 7:11:24 PM2/11/11
to web2py-d...@googlegroups.com
Did you see how wicket builds a page? http://wicketstuff.org/wicket14/compref/

Everything is a component You can nest components inside container components.
you add component to outer component till you reach a Page component.
Every component can have Behaviors to handle events or to contribute
to Page headers.
Note that unlike web2py components need to instantiated before being
added. You manipulate class definition not
objects. i.e. a Button is a class in Wicket, BUTTON in web2py is an
object. So if I want to have a custom button i do

Button myButton = new Button() { // extend as anonymous class
...
...
}

container.add(myButton);

or to reuse

public class MyButton extends Button {
..
..
}


Better yet is this http://www.webtoolkit.eu/widgets you can make full
featured ajax apps with integrated http server (boost w forking) in
less than
200kb


2011/2/11 Massimo Di Pierro <massimo....@gmail.com>:

Michele Comitini

unread,
Feb 11, 2011, 7:13:22 PM2/11/11
to web2py-d...@googlegroups.com
Forgot to say that python can be used to do much better than those
(except C++ small footprint).

2011/2/12 Michele Comitini <michele....@gmail.com>:

Massimo Di Pierro

unread,
Feb 11, 2011, 9:04:15 PM2/11/11
to web2py-d...@googlegroups.com
this would be ok.
Reply all
Reply to author
Forward
0 new messages