Tornado and Django — serving static content

I recently inherited a project for CLIx, a Django app running off of a Tornado WSGI server. Everything seemed to run fine, until we started getting reports that video and audio files were not playing correctly. It turns out that the original app was using Django to serve static files — not quite recommended for production use. This worked fine for small files like .html and .vtt, but larger files would not stream (.mp4, .mp3). You could not seek videos, and pausing / waiting / playing again would cause the video to re-play from the beginning.

In the Chrome dev tools, we could see that only part of the files were loading, but nothing else. So I decided to make Tornado serve the static content … not a lot of documentation about doing this. Luckily the Tornado-Django example application gives us a hint:

wsgi_app = tornado.wsgi.WSGIContainer(django.core.handlers.wsgi.WSGIHandler())
tornado_app = tornado.web.Application([
('/hello-tornado', HelloHandler),
('.*', tornado.web.FallbackHandler, dict(fallback=wsgi_app)),
server = tornado.httpserver.HTTPServer(tornado_app)


And a bunch of StackOverflow questions show how to configure Tornado URLs with the static URL handler:

handlers = [
  (r'/favicon.ico', tornado.web.StaticFileHandler, {'path': favicon_path}),
  (r'/static/(.*)', tornado.web.StaticFileHandler, {'path': static_path}), 
  (r'/', WebHandler)

Combining these two, you can make a Tornado WSGI server handle static files for a Django app!

sgi_app = tornado.wsgi.WSGIContainer(DJANGO_WSGI_APP)
tornado_app = tornado.web.Application([
  (r'/static/(.*)', tornado.web.StaticFileHandler, {'path': STATIC_URL}), 
  (r'/media/(.*)', tornado.web.StaticFileHandler, {'path': MEDIA_URL}), 
  (r'.*', tornado.web.FallbackHandler, dict(fallback=wsgi_app)),
server = tornado.httpserver.HTTPServer(tornado_app)