Tornado如何在任意位置提供单个静态文件?

Ran*_*ook 9 python tornado static-files

我正在使用Tornado开发一个简单的Web应用程序.它提供一些动态文件和一些静态文件.动态的不是问题,但我在提供静态文件时遇到问题.我想要做的是在访问/foo.json URL时提供文件/path/to/foo.json.

请注意,/ path/to/foo.json位于文档根目录之外.在Apache中我只想设置一个Alias.有了龙卷风,我有:

app = tornado.web.Application([
    (r'/dynamic\.html', MyService, dict(param = 12345)),
    (r'/(foo\.json)', tornado.web.StaticFileHandler, {'path': '/path/to/foo.json'})
    ])
Run Code Online (Sandbox Code Playgroud)

我添加了正则表达式组运算符()以满足Tornado,否则会抛出异常.但现在,当我访问/foo.json时,我得到一个404:File Not Found.

测试显示Tornado正在尝试使用作为根目录提供的路径来附加foo.json,这意味着如果它位于/path/to/foo.json/foo.json,则可以找到我的文件.关闭,但不完全.

我想我可以简单地将我的路径简化为"/ path/to",这将触发/foo.json URL上的/path/to/foo.json的获取,但这迫使我在URL中使用相同的名称就像在文件系统上一样.我怎样才能做一个简单,随意的文件映射URL?

我已经做了一些研究,阅读tornado.web.Applicationtornado.web.StaticFilehandler的文档,以及其他 一些SO 问题.没有什么是我的用例.

Mar*_*ark 12

StaticFileHandler需要两个参数,因此如果您希望将单个url(/foo.json)映射到文件路径,则可以使用:

app = tornado.web.Application([
(r'/foo.json()', tornado.web.StaticFileHandler, {'path': '/path/to/foo.json'})
])
Run Code Online (Sandbox Code Playgroud)

正则表达式将匹配/foo.json并发送空捕获组(),这将导致文件路径按原样使用.当捕获组不为空时,/path/to/foo.json将被视为目录/path/to/foo.json/,并且处理程序将尝试将捕获组中的任何内容与该目录中的文件名进行匹配.


Ben*_*ell 6

StaticFileHandler获取来自正则表达式捕获组的文件名和来自其路径参数的目录名.如果您/path/to/用作路径,它将起作用:

(r'/(foo\.json)', tornado.web.StaticFileHandler, {'path': '/path/to/'})
Run Code Online (Sandbox Code Playgroud)

StaticFileHandler适用于URL和文件名匹配的情况; 如果您不能安排在磁盘上以相同的名称提供此文件,那么您必须使用自定义处理程序.


A. *_*vis 5

这样的事情应该有效:

import os
import tornado.ioloop
import tornado.web


class MyFileHandler(tornado.web.StaticFileHandler):
    def initialize(self, path):
        self.dirname, self.filename = os.path.split(path)
        super(MyFileHandler, self).initialize(self.dirname)

    def get(self, path=None, include_body=True):
        # Ignore 'path'.
        super(MyFileHandler, self).get(self.filename, include_body)

app = tornado.web.Application([
    (r'/foo\.json', MyFileHandler, {'path': '/path/to/foo.json'})
])

app.listen(8888)
tornado.ioloop.IOLoop.current().start()
Run Code Online (Sandbox Code Playgroud)

URL模式和文件名不需要相关,你可以这样做,它也可以工作:

app = tornado.web.Application([
    (r'/jesse\.txt', MyFileHandler, {'path': '/path/to/foo.json'})
])
Run Code Online (Sandbox Code Playgroud)