2010-11-21 21 views
79

¿Existe alguna solución inteligente para almacenar archivos estáticos en el directorio raíz de la aplicación de Flask. Se espera que robots.txt y sitemap.xml que se encuentran en /, así que mi idea era crear rutas para ellos:Archivos estáticos en Flask - robot.txt, sitemap.xml (mod_wsgi)

@app.route('/sitemap.xml', methods=['GET']) 
def sitemap(): 
    response = make_response(open('sitemap.xml').read()) 
    response.headers["Content-type"] = "text/plain" 
    return response 

Tiene que haber algo más conveniente :)

Respuesta

60

la mejor manera es establecer static_url_path a URL raíz

from flask import Flask 

app = Flask(__name__, static_folder='static', static_url_path='') 
+2

este fue el que funcionó para archivos estáticos, Gracias. +1 –

+0

Vale la pena mencionar que static_folder no tiene que estar en la carpeta del proyecto. p.ej. static_folder = '/ app/ui' está bien. – ashic

15

sirven archivos estáticos no tiene nada para hacer con la aplicación que está destinada a entregar contenido dinámico. La forma correcta de servir archivos estáticos depende del servidor que está utilizando. Después de todo, cuando inicies y ejecutes tu aplicación, deberás vincularla a un servidor web. Solo puedo hablar sobre apache httpd, por lo que la forma de servir archivos estáticos se define en el host virtual que está vinculando a su aplicación a través de mod-wsgi. Aquí está la guía que le mostrará cómo servir mapas de sitio, robots.txt o cualquier contenido estático: http://code.google.com/p/modwsgi/wiki/QuickConfigurationGuide#Mounting_At_Root_Of_Site

+0

Esa es la respuesta que he estado buscando.¡Gracias! – biesiad

+1

Una aplicación está destinada a entregar contenido, algo dinámico y algo de estática. –

65

@vonPetrushev es correcta, en la producción querrá servir archivos estáticos a través de nginx o Apache, sino para el desarrollo Es agradable tener tu entorno de desarrollo simple teniendo tu aplicación de python sirviendo también el contenido estático para que no tengas que preocuparte por cambiar configuraciones y proyectos múltiples. Para hacer eso, querrá usar el SharedDataMiddleware.

from flask import Flask 
app = Flask(__name__) 
''' 
Your app setup and code 
''' 
if app.config['DEBUG']: 
    from werkzeug import SharedDataMiddleware 
    import os 
    app.wsgi_app = SharedDataMiddleware(app.wsgi_app, { 
     '/': os.path.join(os.path.dirname(__file__), 'static') 
    }) 

Este ejemplo asume sus archivos estáticos están en la carpeta de "estática", ajuste a lo que se adecue a su entorno.

+0

¡GRACIAS! Esto es lo que necesitaba! Estoy buscando hacer esto para mi producción heroku. Vea las respuestas en el siguiente hilo: http://flask.pocoo.org/mailinglist/archive/2012/2/22/flask-on-heroku-%2B-gunicorn-static-files/#20ff50d1dac06bf228b38d62ab11c6a9 – David

+0

Esto es muy, muy buen consejo! –

+2

Atención: hay una manera más fácil de manejar esto ahora. Mira mi respuesta –

3

De la documentación aquí: http://flask.pocoo.org/docs/quickstart/#static-files

aplicaciones web dinámicas necesitan archivos estáticos también. Por lo general, donde están los archivos CSS y JavaScript . Lo ideal es que su servidor web esté configurado para servirlos, , pero durante el desarrollo el Frasco también puede hacer . Simplemente cree una carpeta llamada estática en su paquete o la siguiente en su módulo y será disponible en/static en la aplicación .

Para generar direcciones URL a esa parte de la URL , utilice el URL especial 'estática' nombre:

url_for ('estático', archivo = 'style.css')

El archivo tiene que ser almacenado en el sistema de archivos como static/style.css.

5

esto podría haber sido añadido desde que se hizo esta pregunta, pero yo estaba mirando a través de "helpers.py" del frasco y me encontré con flask.send_from_directory:

send_from_directory(directory, filename, **options) 
''' 
    send_from_directory(directory, filename, **options) 
    Send a file from a given directory with send_file. This 
    is a secure way to quickly expose static files from an upload folder 
    or something similar. 
''' 

... que hace referencia a flask.send_file :

send_file(filename_or_fp, mimetype=None, as_attachment=False, attachment_filename=None, add_etags=True, cache_timeout=43200, conditional=False) 

... que parece mejor para un mayor control, aunque send_from_directory pasa directamente a través de las opciones ** a send_file.

0

Tengo el mismo dilema también.Hizo un poco de búsqueda y encontró mi respuesta (MHO):

fuerza también citar la documentación

aplicaciones web dinámicas necesitan archivos estáticos también. Por lo general, provienen de los archivos CSS y JavaScript. Idealmente, su servidor web está configurado para servirlo, pero durante el desarrollo, Flask también puede hacerlo. Simplemente cree una carpeta llamada static en su paquete o al lado de su módulo y estará disponible en/static en la aplicación.

mi humilde opinión: Cuando su aplicación es para la producción , sirviendo archivo estático debe ser (o es lo ideal) configurado en el servidor web (nginx, Apache); pero durante el desarrollo , Flask lo hizo disponible para servir archivos estáticos. Esto es para ayudarlo a desarrollarse rápidamente, no es necesario configurar servidores web ni nada más.

Espero que ayude.

13

Otra manera de enviar archivos estáticos es el uso de un cajón de sastre regla como la siguiente:

@app.route('/<path:path>') 
def catch_all(path): 
    if not app.debug: 
     flask.abort(404) 
    try: 
     f = open(path) 
    except IOError, e: 
     flask.abort(404) 
     return 
    return f.read() 

Lo utilizo para tratar de minimizar la puesta a punto en el desarrollo. Obtuve la idea de http://flask.pocoo.org/snippets/57/

Además, estoy desarrollando el uso de un matraz en mi máquina independiente pero implementando con Apache en el servidor de producción. Yo uso:

file_suffix_to_mimetype = { 
    '.css': 'text/css', 
    '.jpg': 'image/jpeg', 
    '.html': 'text/html', 
    '.ico': 'image/x-icon', 
    '.png': 'image/png', 
    '.js': 'application/javascript' 
} 
def static_file(path): 
    try: 
     f = open(path) 
    except IOError, e: 
     flask.abort(404) 
     return 
    root, ext = os.path.splitext(path) 
    if ext in file_suffix_to_mimetype: 
     return flask.Response(f.read(), mimetype=file_suffix_to_mimetype[ext]) 
    return f.read() 

[...] 

if __name__ == '__main__': 
    parser = optparse.OptionParser() 
    parser.add_option('-d', '--debug', dest='debug', default=False, 
         help='turn on Flask debugging', action='store_true') 

    options, args = parser.parse_args() 

    if options.debug: 
     app.debug = True 
     # set up flask to serve static content 
     app.add_url_rule('/<path:path>', 'static_file', static_file) 
    app.run() 
+1

Atención: hay una manera más fácil de manejar esto ahora. Mira mi respuesta –

+0

¡Excelente manera si necesita servir múltiples caminos! –

21

A pesar de que esta es una vieja pregunta contestada, yo estoy respondiendo esto porque este post viene bastante alto en los resultados de Google. Si bien no está cubierto en la documentación, si lee the API docs para el constructor de objetos de la Aplicación Flask está cubierto. Pasando el parámetro llamado static_folder así:

from flask import Flask 
app = Flask(__name__, 
      static_folder="/path/to/static", 
      template_folder="/path/to/templates") 

... puede definir en archivos estáticos se sirven de. Del mismo modo, puede definir un template_folder, el nombre de usted static_url_path.

+0

¡Excelente! Supongo que la ruta a los archivos estáticos todavía es/static/.... – chmike

+0

@chmike sí, su valor predeterminado es '/ static' pero puede cambiarlo anulando' static_url_path'. –

+0

Esto es correcto, pero otras respuestas son más flexibles. Esto está limitado por el hecho de que solo puede servir una ruta de directorio. –

53

La respuesta más limpia a esta pregunta es el answer a esta (idéntico) question:

from flask import Flask, request, send_from_directory 
app = Flask(__name__, static_folder='static')  

@app.route('/robots.txt') 
@app.route('/sitemap.xml') 
def static_from_root(): 
    return send_from_directory(app.static_folder, request.path[1:]) 

En resumen:

  • como David señaló, con la configuración correcta es ok to serve a few static files through prod
  • buscar /robots.txt no debería redirigir a /static/robots.txt. (. En Seans contesta que no es claro cómo eso se logra)
  • no es limpia para añadir archivos estáticos en la carpeta raíz aplicación
  • por último, la solución propuesta se ve mucho más limpio que el enfoque de middleware añadiendo:
Cuestiones relacionadas