¿Hay una mejor manera de manejar index.html con Tornado?

Quiero saber si hay una mejor manera de manejar mi archivo index.html con Tornado.

Utilizo StaticFileHandler para todas las solicitudes, y uso un MainHandler específico para manejar mi solicitud principal. Si solo uso StaticFileHandler obtuve un error 403: Prohibido

GET http://localhost:9000/ WARNING:root:403 GET / (127.0.0.1): is not a file 

aquí cómo me va ahora:

 import os import tornado.ioloop import tornado.web from tornado import web __author__ = 'gvincent' root = os.path.dirname(__file__) port = 9999 class MainHandler(tornado.web.RequestHandler): def get(self): try: with open(os.path.join(root, 'index.html')) as f: self.write(f.read()) except IOError as e: self.write("404: Not Found") application = tornado.web.Application([ (r"/", MainHandler), (r"/(.*)", web.StaticFileHandler, dict(path=root)), ]) if __name__ == '__main__': application.listen(port) tornado.ioloop.IOLoop.instance().start() 

Resulta que el StaticFileHandler de Tornado ya incluye la funcionalidad de nombre de archivo predeterminada .

La característica se agregó en Tornado versión 1.2.0: https://github.com/tornadoweb/tornado/commit/638a151d96d681d3bdd6ba5ce5dcf2bd1447959c

Para especificar un nombre de archivo predeterminado, debe configurar el parámetro “nombre de archivo predeterminado” como parte de la inicialización de WebStaticFileHandler.

Actualizando tu ejemplo:

 import os import tornado.ioloop import tornado.web root = os.path.dirname(__file__) port = 9999 application = tornado.web.Application([ (r"/(.*)", tornado.web.StaticFileHandler, {"path": root, "default_filename": "index.html"}) ]) if __name__ == '__main__': application.listen(port) tornado.ioloop.IOLoop.instance().start() 

Esto maneja las solicitudes de raíz:

  • / -> /index.html

solicitudes de sub-directorio:

  • /tests/ -> /tests/index.html

y parece que maneja correctamente las redirecciones para directorios, lo cual es bueno:

  • /tests -> /tests/index.html

Gracias a la respuesta anterior, aquí está la solución que prefiero:

 import Settings import tornado.web import tornado.httpserver class Application(tornado.web.Application): def __init__(self): handlers = [ (r"/", MainHandler) ] settings = { "template_path": Settings.TEMPLATE_PATH, "static_path": Settings.STATIC_PATH, } tornado.web.Application.__init__(self, handlers, **settings) class MainHandler(tornado.web.RequestHandler): def get(self): self.render("index.html") def main(): applicaton = Application() http_server = tornado.httpserver.HTTPServer(applicaton) http_server.listen(9999) tornado.ioloop.IOLoop.instance().start() if __name__ == "__main__": main() 

Y Settings.py

 import os dirname = os.path.dirname(__file__) STATIC_PATH = os.path.join(dirname, 'static') TEMPLATE_PATH = os.path.join(dirname, 'templates') 

Use este código en su lugar

 class IndexDotHTMLAwareStaticFileHandler(tornado.web.StaticFileHandler): def parse_url_path(self, url_path): if not url_path or url_path.endswith('/'): url_path += 'index.html' return super(IndexDotHTMLAwareStaticFileHandler, self).parse_url_path(url_path) 

ahora use esa clase en lugar de vanilla StaticFileHandler en su aplicación … ¡el trabajo está listo!

No es necesario agregar explícitamente un StaticFileHandler ; simplemente especifique la static_path y servirá esas páginas.

Tiene razón en que necesita un MainHandler, ya que por alguna razón Tornado no servirá el archivo index.html , incluso si agrega el nombre de archivo a la URL.

En ese caso, esta ligera modificación de su código debería funcionar para usted:

 import os import tornado.ioloop import tornado.web from tornado import web __author__ = 'gvincent' root = os.path.dirname(__file__) port = 9999 class MainHandler(tornado.web.RequestHandler): def get(self): self.render("index.html") application = tornado.web.Application([ (r"/", MainHandler), ], template_path=root, static_path=root) if __name__ == '__main__': application.listen(port) tornado.ioloop.IOLoop.instance().start()