Execution environment
While everything discussed here works fine, we recommend instead building your application using components, as described in Chapter 12.
web2py model and controller files are not Python modules in that they cannot be imported using the Python import
statement. The reason for this is that models and controllers are designed to be executed in a prepared environment that has been pre-populated with web2py global objects (request, response, session, cache and T) and helper functions. This is necessary because Python is a statically (lexically) scoped language, whereas the web2py environment is created dynamically.
web2py provides the exec_environment
function to allow you to access models and controllers directly. exec_environment
creates a web2py execution environment, loads the file into it and then returns a Storage object containing the environment. The Storage object also serves as a namespace mechanism. Any Python file designed to be executed in the execution environment can be loaded using exec_environment
. Uses for exec_environment
include:
- Accessing data (models) from other applications.
- Accessing global objects from other models or controllers.
- Executing controller functions from other controllers.
- Loading site-wide helper libraries.
This example reads rows from the user
table in the cas
application:
from gluon.shell import exec_environment
cas = exec_environment('applications/cas/models/db.py')
rows = cas.db().select(cas.db.user.ALL)
Another example: suppose you have a controller “other.py” that contains:
def some_action():
return dict(remote_addr=request.env.remote_addr)
Here is how you can call this action from another controller (or from the web2py shell):
|
|
In line 2, request=request
is optional. It has the effect of passing the current request to the environment of “other”. Without this argument, the environment would contain a new and empty (apart from request.folder
) request object. It is also possible to pass a response and a session object to exec_environment
. Be careful when passing request, response and session objects —- modification by the called action or coding dependencies in the called action could lead to unexpected side effects.
The function call in line 3 does not execute the view; it simply returns the dictionary unless response.render
is called explicitly by “some_action”.
One final caution: don’t use exec_environment
inappropriately. If you want the results of actions in another application, you probably should implement an XML-RPC API (implementing an XML-RPC API with web2py is almost trivial). Don’t use exec_environment
as a redirection mechanism; use the redirect
helper.