2012-12-27 2 views
21

J'ai lu sur le calme quelques endroits que les fichiers statiques servant de serveurs devraient être laissés au serveur, par exemple dans quelques-unes des réponses sur ce SO question. Mais j'utilise OpenShift PaaS, et je n'arrive pas à comprendre comment modifier le fichier .htaccess.Avec Flask, comment puis-je servir robots.txt et sitemap.xml en tant que fichiers statiques?

Je suis tombé sur ce piece of code qui sert le sitemap à partir d'un modèle. Je l'ai fait sur mon application tant pour le plan du site, et robots.txt, comme si -

@app.route("/sitemap.xml") 
def sitemap_xml(): 
    response= make_response(render_template("sitemap.xml")) 
    response.headers['Content-Type'] = 'application/xml' 
    return response 

@app.route("/robots.txt") 
def robots_txt(): 
    return render_template("robots.txt") 

Y at-il de mal à cela, ou est mon approche d'accord?

Répondre

61

Mettez robots.txt et sitemap.xml dans le répertoire static et définir ce point de vue de votre application:

from flask import Flask, request, send_from_directory 

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

merci, à peu près ce que je cherchais. – elssar

+0

Merci - cela fera pour les applications Flask sur Heroku. Il semble quasiment impossible de faire en sorte que le routeur de Heroku (basé sur Nginx) serve directement du contenu statique, sauf s'il se trouve dans le répertoire 'static' ou' public' d'un projet. Je préférerais, bien sûr, servir directement 'robots.txt' et' sitemap.xml' avec Nginx, dans des environnements qui me permettent de le faire. – Jaza

+0

Correction à mon commentaire ci-dessus: semble que Heroku n'utilise pas du tout Nginx, il passe réellement toutes les demandes (y compris les demandes au dossier static ou public) directement à un processus d'application (par exemple directement à Gunicorn pour un Application Python), uniquement via un proxy/load-balancer personnalisé appelé Vegur - voir: http://superuser.com/questions/837925/what-is-vegur-appearing-in-http-headers – Jaza

7

Flask est compatible avec la gestion des fichiers statiques.

Créez un répertoire /static et y mettez vos fichiers. Ensuite, lorsque vous instancier Flask, spécifiez le paramètre static_url_path:

app = Flask(__name__, static_url_path='/') 

La valeur par défaut est de servir les fichiers statiques à partir du chemin /static/, mais vous voulez qu'ils ont servi de / ils sont où prévu.

Voir le Flask API Docs pour plus d'informations. En plus de l'overhead et du code inutile, le problème avec votre approche est si/quand l'un des fichiers que vous voulez servir contient quelque chose qui ressemble à une balise template à render_template - vous pouvez provoquer une erreur de rendu. Si vous deviez lire le fichier en mémoire (une fois, pas à l'intérieur de la méthode) alors utilisez cette chaîne comme le corps de la réponse sans appeler render_template, vous éviterez au moins ce problème.

+0

Vous voulez dire quelque chose comme ça - ' robots = ouvert (cwd + '/ static/robots.txt', 'r'). read() 'et ensuite' return robots' dans la fonction 'robots_txt'? – elssar

+0

@elssar - Je ne pense pas que vous devriez réinventer la mise en cache de fichiers - consultez http://packages.python.org/Flask-Cache/ –

+0

@elssar Oui, c'est ce que je veux dire, mais je ne suggère pas que vous fassiez réellement cette. Je soulignais simplement que si vous aviez l'intention de lire et de sortir des fichiers statiques, 'render_template' ne le faisait pas. – agf

2

La meilleure façon est de mettre static_url_path à la racine url

from flask import Flask 

app = Flask(__name__, static_folder='static', static_url_path='') 
Questions connexes