creating subprojects in bottle

I’m just starting Python web development, and have chosen Bottle as my framework of choice.

I’m trying to have a project structure that is modular, in that I can have a ‘core’ application that has modules built around it, where these modules can be enabled/disabled during setup (or on the fly, if possible…not sure how I would set that up tho).

My ‘main’ class is the following:

from bottle import Bottle, route, run
from bottle import error
from bottle import jinja2_view as view

from core import core

app = Bottle()
app.mount('/demo', core)

#@app.route('/')
@route('/hello/<name>')
@view('hello_template')
def greet(name='Stranger'):
    return dict(name=name)

@error(404)
def error404(error):
    return 'Nothing here, sorry'

run(app, host='localhost', port=5000)

My ‘subproject’ (i.e. module) is this:

from bottle import Bottle, route, run
from bottle import error
from bottle import jinja2_view as view

app = Bottle()

@app.route('/demo')
@view('demographic')
def greet(name='None', yob='None'):
    return dict(name=name, yob=yob)

@error(404)
def error404(error):
    return 'Nothing here, sorry'

When I go to http://localhost:5000/demo in my browser, it shows a 500 error. The output from the bottle server is:

localhost - - [24/Jun/2012 15:51:27] "GET / HTTP/1.1" 404 720
localhost - - [24/Jun/2012 15:51:27] "GET /favicon.ico HTTP/1.1" 404 742
localhost - - [24/Jun/2012 15:51:27] "GET /favicon.ico HTTP/1.1" 404 742
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/bottle-0.10.9-py2.7.egg/bottle.py", line 737, in _handle
    return route.call(**args)
  File "/usr/local/lib/python2.7/dist-packages/bottle-0.10.9-py2.7.egg/bottle.py", line 582, in mountpoint
    rs.body = itertools.chain(rs.body, app(request.environ, start_response))
TypeError: 'module' object is not callable

The folder structure is:

index.py
views (folder)
|-->hello_template.tpl
core (folder)
|-->core.py
|-->__init__.py
|-->views (folder)
|--|-->demographic.tpl

I have no idea what I’m doing (wrong) 馃檪

Anyone have any idea how this can/should be done?

Thanks!

Best answer

You are Passing the module “core” to the mount() function. Instead you have to pass the bottle app object to the mount() function, So the call would be like this.

app.mount("/demo",core.app)

Here are formal docs for the mount() function.

mount(prefix, app, **options)[source]

Mount an application (Bottle or plain WSGI) to a specific URL
prefix.
Example:

root_app.mount('/admin/', admin_app)

Parameters:
prefix 鈥?path prefix or mount-point. If it ends in a
slash, that slash is mandatory.
app 鈥?an instance of Bottle or a WSGI application