2016-03-06 31 views
8

Nell'app Flask servo le risorse statiche tramite l'app nel dev env, ma mi piacerebbe utilizzare un CDN in produzione. Ogni attività viene caricato in un modello chiamato base.hmtl, quindi credo che la soluzione più semplice è quella di passare una variabile alla funzione di rendering e utilizzarlo nel modello come:Serve file statici da un CDN invece che da un pallone in produzione

<script src="{{ STATIC_URL }}/js/main.js"></script> 

Normalmente sarebbe una stringa vuota nel dev env e l'url cdn in produzione. Mi piacerebbe evitare di passare questa variabile STATIC_URL ad ogni vista. Potrei farlo funzionare con

@bp.context_processor 
def set_static_path(): 
    return dict(STATIC_URL='https://foo.bar.com') 

Ma per me questo sembra un po 'hacky. C'è un modo migliore per risolvere questo problema?

risposta

12

Non è necessario modificare la modalità di collegamento ai file statici, è comunque possibile utilizzare url_for('static', filename='myfile.txt'). Sostituire la vista statica predefinita con una che reindirizza alla CDN se è configurata.

from urllib.parse import urljoin 
# or for python 2: from urlparse import urljoin 
from flask import redirect 

@app.endpoint('static') 
def static(filename): 
    static_url = app.config.get('STATIC_URL') 

    if static_url: 
     return redirect(urljoin(static_url, filename)) 

    return app.send_static_file(filename) 

Sia che siate su una macchina dev o di produzione, impostare il valore STATIC_URL config al CDN e le richieste di file statici saranno reindirizzati lì.


I reindirizzamenti sono relativamente economici e vengono ricordati dai browser. Se si arriva al punto in cui le prestazioni sono significativamente influenzate da esse, è possibile scrivere una funzione che si collega direttamente quando si utilizza la CDN.

@app.template_global() 
def static_url(filename): 
    static_url = app.config.get('STATIC_URL') 

    if static_url: 
     return urljoin(static_url, filename) 

    return url_for('static', filename=filename) 

Il decoratore template_global rende la funzione disponibile in tutti i modelli. Usalo invece di url_for quando hai bisogno di url per i file statici.

2

Questo pallone integration guide può valere la pena di essere letto. Fondamentalmente puoi installare il Flask-CDN extension e definire il tuo URL CDN all'interno del tuo file app.py in questo modo:

from flask import Flask 
from flask.ext.cdn import CDN 

app = Flask(__name__) 
app.config['CDN_DOMAIN'] = 'cdn.yourdomain.com' 
CDN(app)