Static files in a Bottle application cannot be found (404)
bottle, python
Solution
I don't quite understand your deployment. The `/Applications/MAMP/htdocs/` path, along with the lack of `app.run` in your code, suggest that you're running this under Apache. Is it a production deployment? For dev tasks you are supposed to use Bottle's built-in dev server, you know. Add a single `app.run()` towards the end of your `todo.py`, and you're done.
Now if you are using Apache, the most probably root cause is this line: `static_file(filename, root='./static')`. With mod_wsgi, you are not guaranteed that the working directory is equal to the directory where your `todo.py` is placed. In fact, it will almost never be.
You are using absolute paths for the database and the template, do so for the static files:
@route('/static/:filename#.*#', name='css')
def server_static(filename):
return static_file(filename, root=os.path.join(appPath, 'static'))
Next, I don't understand where your app is mounted. The URL `http://localhost:8888/todo/static/style.css` suggests that the mount point is `/todo`, but the route for the `todo_list` handler is again `/todo`. Is the full path supposed to be `http://localhost/todo/todo`? Does your app have a `/` handler?
I'd also suggest to avoid hard-coding paths and concat'ing the path fragments together. This would be cleaner:
from os.path import join, dirname
...
appPath = dirname(__file__)
@app.route('/todo')
def todo_list():
conn = sqlite3.connect(join(appPath, 'todo.db'))
...
Problem
I've reviewed all the questions here about this, reviewed the bottle tutorial, reviewed the bottle google group discussions, and AFAIK, I'm doing everything right. Somehow, though, I can't get my CSS file to load properly. I'm getting a 404 on the static file, that `http://localhost:8888/todo/static/style.css` is not found, which, according to the directory structure below, should not be the case. I'm using version 0.11 (unstable) of Bottle; is there anything I'm missing, or is this a bug in Bottle? My directory structure: ``` todo/ todo.py static/ style.css ``` My todo.py: ``` import sqlite3 from bottle import Bottle, route, run, debug, template, request, validate, static_file, error, SimpleTemplate # only needed when you run Bottle on mod_wsgi from bottle import default_app app = Bottle() default_app.push(app) appPath = '/Applications/MAMP/htdocs/todo/' @app.route('/todo') def todo_list(): conn = sqlite3.connect(appPath + 'todo.db') c = conn.cursor() c.execute("SELECT id, task FROM todo WHERE status LIKE '1';") result = c.fetchall() c.close() output = template(appPath + 'make_table', rows=result, get_url=app.get_url) return output @route('/static/:filename#.*#', name='css') def server_static(filename): return static_file(filename, root='./static') ``` My html: ``` %#template to generate a HTML table from a list of tuples (or list of lists, or tuple of tuples or ...) <head> <link href="{{ get_url('css', filename='style.css') }}" type="text/css" rel="stylesheet" /> </head> <p>The open items are as follows:</p> <table border="1"> %for row in rows: <tr style="margin:15px;"> %i = 0 %for col in row: %if i == 0: <td>{{col}}</td> %else: <td>{{col}}</td> %end %i = i + 1 %end <td><a href="/todo/edit/{{row[0]}}">Edit</a></td> </tr> %end </table> ```