Search code examples
pythonweb.pylivereload

How can I get livereload to serve my js files?


Im using webpy together with livereload, works well, I can make changes to the app modules and the browser page reloads as expected. But livereload can't find my JS files, I get a 404 where as when I run the webpy app without livereload, the files are found and I don't get a 404

from livereload import Server

import web

from nestpas.views import *
from nestpas.urls import *
import sys

logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)

# web.config.debug = False
web.ctx.debug = False

app = web.application(urls, globals(), autoreload=False)
webapp = app.wsgifunc()

# Setup session storage
db = web.database(dbn='sqlite', db='dev.db')
store = web.session.DBStore(db, 'sessions')
session = web.session.Session(app, store,
    initializer={'login': 0}
)

if __name__ == '__main__':
    # app.run()
    server = Server(webapp)
    server.watch('static/', 'templates/', 'nestpas/')
    server.serve(port=8080, host='localhost')

the JS files are stored inside the static folder as described by webpy, but I see this error in my terminal

[W 170212 09:08:53 wsgi:355] 404 GET /static/js/require.js (::1) 26.46ms
WARNING:tornado.access:404 GET /static/js/require.js (::1) 26.46ms

If I change the app.py file to use app.run() instead of livereload the JS files are served as expected

127.0.0.1:55534 - - [12/Feb/2017 09:16:15] "HTTP/1.1 GET /static/js/require.js" - 200

Update

Adding URLs

urls = (
    '/', 'Index',
    '/blog/(.+)/', 'Blog',
    '/login/', 'Login',
    '/logout/', 'Logout',
    '/admin/', 'Admin',
    '/media/', 'Media',
    '/entry/(.+)?', 'Entry'
)

Solution

  • web.py has a shortcut: if the URL path starts with /static/, the file is directly loaded and returned to the requester. (You already know this.)

    However, the shortcut isn't loaded unless web.py running as a simple HTTPServer. When you load it through livereload, you're using tornado web server, so this feature isn't loaded.

    Fear not: you can add it in.

    web/httpserver.py defines this feature in StaticMiddleware, so you can add it to your application chain:

    if __name__ == '__main__':
        import web.httpserver
        static_plus_webapp = web.httpserver.StaticMiddelware(webapp)
        server = Server(static_plus_webapp)
        server.watch('static/', 'templates/')
        server.serve(port=8080, host='*')
    

    (I've not done extensive testing, but it appears to work fine.)