6

I'd love to be able to change the webpy static directory without the need to set up and run nginx locally. Right now, it seems webpy will only create a static directory if /static/ exists. In my case, I want to use /foo/bar/ as my static directory, but couldn't find any info related to configuring this (other than running apache or nginx locally).

This is for local use only, not production. Any ideas? Thanks

Shane Reustle
  • 8,633
  • 8
  • 40
  • 51

1 Answers1

5

If you need to have different directory for the same path then you may subclass web.httpserver.StaticMiddleware or write your own middleware like this (it tricks StaticApp by modifying PATH_INFO):

import web
import os
import urllib
import posixpath

urls = ("/.*", "hello")
app = web.application(urls, globals())

class hello:
    def GET(self):
        return 'Hello, world!'


class StaticMiddleware:
    """WSGI middleware for serving static files."""
    def __init__(self, app, prefix='/static/', root_path='/foo/bar/'):
        self.app = app
        self.prefix = prefix
        self.root_path = root_path

    def __call__(self, environ, start_response):
        path = environ.get('PATH_INFO', '')
        path = self.normpath(path)

        if path.startswith(self.prefix):
            environ["PATH_INFO"] = os.path.join(self.root_path, web.lstrips(path, self.prefix))
            return web.httpserver.StaticApp(environ, start_response)
        else:
            return self.app(environ, start_response)

    def normpath(self, path):
        path2 = posixpath.normpath(urllib.unquote(path))
        if path.endswith("/"):
            path2 += "/"
        return path2


if __name__ == "__main__":
    wsgifunc = app.wsgifunc()
    wsgifunc = StaticMiddleware(wsgifunc)
    wsgifunc = web.httpserver.LogMiddleware(wsgifunc)
    server = web.httpserver.WSGIServer(("0.0.0.0", 8080), wsgifunc)
    print "http://%s:%d/" % ("0.0.0.0", 8080)
    try:
        server.start()
    except KeyboardInterrupt:
        server.stop()

Or you can create symlink named "static" and point it to another directory.

Andrey Kuzmin
  • 4,479
  • 2
  • 23
  • 28
  • Thanks! I get: `AttributeError: 'module' object has no attribute 'StaticMiddleware'` – Shane Reustle Aug 05 '11 at 19:46
  • What is the output of `print web.__version__`? It works with Python 2.6.1 and web.py 0.36. – Andrey Kuzmin Aug 05 '11 at 19:51
  • Ah, I'm on 0.32. I upgraded to 0.36 and that works, but isn't 100% what I need. I need to map /static/ to /foo/static/. Thanks for the help! – Shane Reustle Aug 05 '11 at 20:33
  • At least, by changing this I'm now able to route /static/ to wherever I want, which should allow me to hack my own staticdir class, eh? – Shane Reustle Aug 05 '11 at 20:36
  • 1
    Check the sources of `httpserver.py`, static middleware is implemented in classes `StaticMiddleware` and `StaticApp(SimpleHTTPRequestHandler)`. You can create your own middleware that have directory setting. – Andrey Kuzmin Aug 05 '11 at 20:43
  • 1
    I updated my example with `StaticMiddleware` that has both settings, though it acts a bit tricky by changing `environ["PATH_INFO"]` from `/static/...` to `/foo/bar/...`. – Andrey Kuzmin Aug 05 '11 at 21:17