tannermkerr
tannermkerr

Reputation: 17

How can I call a web2py url from an outside module?

I'm trying to get the html generated by web2py from a different module, so I can turn it into a pdf file:

html = response.render('path/myview.html', context_dict)

I've included this at the top of my file:

sys.path.append('/home/www-data/web2py')
from gluon import *

However, I'm still getting: NameError: global name 'response' is not defined

Maybe there's an easier way to do this I haven't thought of?

Upvotes: 0

Views: 498

Answers (2)

tannermkerr
tannermkerr

Reputation: 17

I was able to get it to work by adding my python script into the web2py "modules" folder. After doing this I had to modify my import statements that referenced the other files in the "modules" directory:

from applications.myapp.modules.mymodule import mystuff from gluon import *

html = current.response.render('myview.html', context_dict)

Then to run it from the command line I used:

python /home/www-data/web2py/web2py.py -S myapp -R 'path/to/myscript.py' As described by Anthony

I plan to call this module from a cron job once it's completed. I assume the web2py cron will use the web2py environment, which won't require the same execution script I've used to test.

Upvotes: 0

Anthony
Anthony

Reputation: 25536

You can execute web2py templates using the gluon.template.render function, but if the template was designed to be executed within a web2py application, it may include references to some web2py environment objects (e.g., HTML helper objects, the T translation object, the request and response objects, etc.), which would not be available when calling the render function outside of a web2py HTTP request.

If proper execution of the template requires a web2py environment, you can build one using the gluon.shell.env function:

    import os
    import gluon.shell

    context_dict = {...} # The context to be passed to the template.

    app = 'myapp'
    app_path = os.path.join(os.path.dirname(os.path.abspath(gluon.shell.__file__)),
                            '..', '..', 'applications', app)
    w2p_env = gluon.shell.env(app, dir=app_path, import_models=True)
    context_dict.update(**w2p_env) # Update context with web2py environment objects.
    response = w2p_env['response']
    html = response.render(os.path.join(app_path, 'views', 'mycontroller', 'myview.html'),
                           context=context_dict)

gluon.shell.env returns a dictionary containing all the web2py execution environment objects. If import_models=True, as in the code above, it will also execute the application's models (and therefore, any objects defined in the models will also be included in the returned dictionary).

By updating context_dict with the full web2py execution environment, we ensure that any web2py objects referenced in the template (and any templates it extends or includes) will be available.

The w2p_env environment also includes a response object, so we can use the response.render method to render the template. Alternatively, as noted above, we could have used the gluon.template.render function.

An alternative approach is to simply run your Python script in the environment of your web2py application:

python web2py.py -S myapp -M -R '/path/to/myscript.py'

With this approach, myscript.py can make reference to any web2py environment objects that would be available from within the application code (no need to import anything or explicitly build a web2py environment).

Also, note that you can exclude the -M if you don't need the application's models to be run.

Upvotes: 1

Related Questions