2012-12-27 22 views
21

Ho letto in silenzio alcuni posti in cui i file statici devono essere lasciati al server, ad esempio in un paio delle risposte su questo SO question. Ma io uso OpenShift PaaS e non riesco a capire come modificare il file .htaccess lì.Con Flask, come posso fornire robots.txt e sitemap.xml come file statici?

Mi sono imbattuto in questo piece of code che serve la mappa del sito da un modello. L'ho fatto sulla mia app sia per la mappa del sito, e il file robots.txt, in questo modo -

@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") 

C'è di male in questo, o è il mio approccio va bene?

risposta

61

Mettere robots.txt e sitemap.xml nella directory della tua applicazione static e definire questo punto di vista:

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

grazie, praticamente quello che stavo cercando. – elssar

+0

Grazie - lo farà per le app Flask su Heroku. Sembra quasi impossibile ottenere il router di Heroku (basato su Nginx) per servire direttamente il contenuto statico, a meno che non si trovi nella directory 'static' o' public' di un progetto. Preferiremmo, ovviamente, servire 'robots.txt' e' sitemap.xml' direttamente con Nginx, in ambienti che mi permettessero di farlo. – Jaza

+0

Correzione al commento precedente: sembra che Heroku non usi affatto Nginx, in realtà passa tutte le richieste (comprese le richieste alla 'static' o alla' public' dir) direttamente a un processo dell'app (ad esempio direttamente a Gunicorn per un tipico App Python), passando solo tramite un proxy/bilanciamento del carico personalizzato chiamato Vegur - vedi: http://superuser.com/questions/837925/what-is-vegur-appearing-in-http-headers – Jaza

7

Flask ha il supporto integrato per servire file statici.

Creare una directory /static e inserire i file lì. Poi, quando si crea un'istanza di Flask, specificare il parametro static_url_path:

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

Il valore predefinito è quello di servire i file statici dal percorso /static/, ma si desidera che servito da / in modo che siano dove previsto.

Vedere Flask API Docs per ulteriori informazioni.

Oltre al sovraccarico e al codice non necessario, il problema con l'approccio è se/quando uno dei file che si desidera pubblicare contiene qualcosa che assomiglia a un tag modello a render_template - si può causare un errore di rendering. Se dovessi leggere il file in memoria (una volta, non all'interno del metodo), allora usa quella stringa come corpo della risposta senza chiamare render_template, eviterai almeno quel problema.

+0

Vuoi dire qualcosa di simile - ' robot = open (cwd + '/ static/robots.txt', 'r'). read() 'e quindi' return robots' nella funzione 'robots_txt'? – elssar

+0

@elssar - Non penso che dovresti reinventare il caching dei file - controlla http://packages.python.org/Flask-Cache/ –

+0

@elssar Sì, questo è quello che intendo, ma non sto suggerendo che tu lo faccia realmente quella. Stavo solo sottolineando che se si intendeva leggere e produrre file statici, 'render_template' non stava facendo proprio questo. – agf

2

Il modo migliore è quello di impostare static_url_path per sradicare url

from flask import Flask 

app = Flask(__name__, static_folder='static', static_url_path='') 
Problemi correlati