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:

  1. from gluon.shell import exec_environment
  2. cas = exec_environment('applications/cas/models/db.py')
  3. rows = cas.db().select(cas.db.user.ALL)

Another example: suppose you have a controller “other.py” that contains:

  1. def some_action():
  2. return dict(remote_addr=request.env.remote_addr)

Here is how you can call this action from another controller (or from the web2py shell):

  1. 1
  2. 2
  3. 3
  1. from gluon.shell import exec_environment
  2. other = exec_environment(‘applications/app/controllers/other.py’, request=request)
  3. result = other.some_action()

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.