Downloading a file served by a tornado web server
Question: This is how I have my tornado web server currently defined:

    
    
    application = tornado.web.Application([
        tornado.web.url(r"/server", MainHandler),
        tornado.web.url(r"/(.*)", tornado.web.StaticFileHandler, { "path": scriptpath,  "default_filename": "index.html" }),
    ])
    

index.html is the start page of a web based gui. It will communicate with the
backend server through http:///server and the requests by the gui to the
server are handled by the MainHandler function.

The directory structure looks like:

    
    
    root_directory/
        server.py
        fileiwanttodownload.tar.gz
        index.html
    

I would like to be able to type into the browser:

http:///data/fileiwanttodownload.tar.gz

and have the file delivered to me as a regular file download.

What I have tried to do is:

    
    
    application = tornado.web.Application([
        tornado.web.url(r"/server", MainHandler),
        tornado.web.url(r"/data", tornado.web.StaticFileHandler, { "path": scriptpath } ),
        tornado.web.url(r"/(.*)", tornado.web.StaticFileHandler, { "path": scriptpath,  "default_filename": "index.html" }),
    ])
    

But this is not working for reasons that are probably obvious to those who
know the answer.

The only clue I have is the following error message:

    
    
    Uncaught exception GET /data (192.168.4.168)
    HTTPServerRequest(protocol='http', host='192.168.4.195:8888', method='GET', uri='/data', version='HTTP/1.1', remote_ip='192.168.4.168', headers={'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_2) AppleWebKit/601.3.9 (KHTML, like Gecko) Version/9.0.2 Safari/601.3.9', 'Host': '192.168.4.195:8888', 'Accept-Encoding': 'gzip, deflate', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'Connection': 'keep-alive', 'Accept-Language': 'en-us'})
    Traceback (most recent call last):
      File "/usr/local/lib/python3.4/dist-packages/tornado/web.py", line 1445, in _execute
        result = yield result
      File "/usr/local/lib/python3.4/dist-packages/tornado/gen.py", line 1008, in run
        value = future.result()
      File "/usr/local/lib/python3.4/dist-packages/tornado/concurrent.py", line 232, in result
        raise_exc_info(self._exc_info)
      File "<string>", line 3, in raise_exc_info
      File "/usr/local/lib/python3.4/dist-packages/tornado/gen.py", line 267, in wrapper
        result = func(*args, **kwargs)
    TypeError: get() missing 1 required positional argument: 'path'
    


Answer: `scriptpath` you haven't shown, is probably wrong. In `path` you should
provide root dir to the files, in URI matcher capture only the file or so.
Simple example:

    
    
    import tornado.ioloop
    import tornado.web
    import os
    
    class MainHandler(tornado.web.RequestHandler):
        def get(self):
            self.write("Hello, world")
    
    def make_app():
        script_path = os.path.dirname(__file__)
        return tornado.web.Application([
            (r"/", MainHandler),
            (r"/data/(.*)", tornado.web.StaticFileHandler, {"path": script_path}),
            #         ^ we capture only this part
        ])
    
    if __name__ == "__main__":
        app = make_app()
        app.listen(8888)
        tornado.ioloop.IOLoop.current().start()
    

As you can run it works, but it is recommended to store static/data files in
separate directory, because it is possible to download everything from the app
root dir, including python one.

So put your downloadable file e.g. in data subdirectory and then

    
    
    script_path = os.path.join(os.path.dirname(__file__), 'data')
    

More info about
[StaticFileHandler](http://www.tornadoweb.org/en/stable/web.html?highlight=staticfilehandler#tornado.web.StaticFileHandler).

**edit**

The error you are getting is because in your code `/data` route has
StaticFileHandler, but nothing is captured `()` from requested path.

