2012-02-25 15 views
13

Estoy intentando volver a enrutar todo mi contenido/static para alojar en Amazon S3. Lo primero que pensé fue usar la configuración global ['ruta'] en todas mis plantillas de jinja, pero esto no funcionará para archivos css y js externos, además es un poco complicado. Encontré static_folder y static_url_path publicados en 0.7 y esto parece ser lo que quiero. Sin embargo, cuando voy al http://localhost:8000/static/img/abc.jpg, no encuentro los archivos en S3. ¿Estoy usando esta característica correctamente o hay alguna otra forma de hacerlo?Frasco static_folder alojado en S3

Gracias!

Respuesta

1

lo que está tratando de lograr es ser capaz de escribir

{{ url_for(app.static, file='img/abc.jpg', _external=True) }}

y tienen que resolver a una dirección URL en S3?

creo que static_folder y static_url_path están configurados de manera que si se llama

app = Application('app', static_folder='foo', static_url_path='bar')

luego ir a

lo anterior url_for emitiría

http://localhost:8000/bar/img/abc.jpg y sería buscar static/img/abc.jpg en el sistema de archivos

Creo que lo que quiere hacer es potencialmente escribir un filtro personalizado que se traduciría su camino hacia una url s3 por lo que se podía hacer una llamada algo así como

{{ 'img/abc.jpg'|s3_static_url }}

hay algo de documentación sobre eso aquí : flask custom filters

0

Lo que necesita es la URL de archivo público de Amazon S3 en lugar de http://localhost:8000/static/img/abc.jpg. Si solo se trata de unos pocos archivos, tal vez los codifique en su plantilla con la URL completa o si va a tener una versión local para probar y usar S3 en el sitio de producción (como hacemos nosotros), entonces puede probar el siguiente método.

Defina una nueva variable probablemente llamada STATIC_ROOT en la parte superior de su plantilla base (que heredan otras plantillas), y utilícela como el prefijo de la ruta del archivo.

Por ejemplo:

{% if app.debug %} 
    {% set STATIC_ROOT = url_for('static', filename='') %} 
{% else %} 
    {% set STATIC_ROOT = 'http://s3.amazonaws.com/bucketname/' } 
{% endif %} 

Esto le dará la ruta predeterminada cuando usted podría estar probando su aplicación a nivel local, y la url S3 público cuando en la producción (basado en indicador de depuración).

Su uso:

<script src="{{ STATIC_ROOT }}js/jquery.min.js">

+0

feo, no es necesario. Solo use un procesador de contexto para establecer la variable. –

6

deseo argumento del constructor de flask.Flaskstatic_url_path aceptaría un URI completo, sino que grita sobre el camino que necesitan una barra inicial cuando intenta eso. Si lo aceptó, puede usar url_for después de configurar static_url_path='http://my_s3_bucket.aws.amazon.com/' o menos.

Otra posible solución es usar un procesador de contexto. Creo que esta es la solución más limpia, pero no tengo mucha experiencia con el matraz. Seguro se ve limpio.Usando un procesador de contexto, saco la URL del entorno (estoy usando heroku así que es muy fácil de configurar). Entonces el procesador de contexto hace que la variable static_url esté disponible en mis plantillas.

En app.py:

# Environment has STATIC_URL='http://my_s3_bucket.aws.amazon.com/' 
@app.context_processor 
def inject_static_url(): 
    """ 
    Inject the variable 'static_url' into the templates. Grab it from 
    the environment variable STATIC_URL, or use the default. 

    Template variable will always have a trailing slash. 

    """ 
    static_url = os.environ.get('STATIC_URL', app.static_url_path) 
    if not static_url.endswith('/'): 
     static_url += '/' 
    return dict(
     static_url=static_url 
    ) 

En la plantilla:

<link rel="stylesheet" type="text/css" href="{{ static_url }}css/main.css" /> 

El resultado

<link rel="stylesheet" type="text/css" href="http://my_s3_bucket.aws.amazon.com/css/main.css" /> 
8

I recientemente devel Abrí una extensión de Flask para lidiar solo con esta situación. Se llama Flask-S3, y puede leer la documentación correspondiente here.

A modo de ejemplo, aquí es cómo se integraría en su aplicación Frasco:

from flask import Flask 
from flask_s3 import FlaskS3 

app = Flask(__name__) 
app.config['S3_BUCKET_NAME'] = 'mybucketname' 
s3 = FlaskS3(app) 

Puede utilizar la extensión para subir los elementos a su cubo elegido:

>>> from my_application import app 
>>> from flask_s3 import create_all 
>>> create_all(app) 

Flask- S3 es consciente de los planos, y cargará todos los activos asociados con cualquier planos registrados.

0

Sé que esta es una vieja pregunta, pero así es cómo soluciono este problema. Método

  • de importación Frasco url_for con un nombre diferente (por ejemplo, flask_url_for)
  • Crear su propio método personalizado url_for, que llama flask_url_for y luego utiliza sustitución de cadenas para agregar en su cubo S3 url.

Me gusta esta estrategia porque es simple e intuitiva de usar, y la interfaz es exactamente igual que el método original url_for.

from flask import url_for as flask_url_for 
from flask import current_app 

PRODUCTION_URL = 'https://s3.amazonaws.com/MY-BUCKET-NAME' 

def url_for(path, **kwargs): 
    url = flask_url_for(path, **kwargs) 
    if url.startswith("/static") and not current_app.debug: 
     url = url.replace("/static", "", 1) 
     return PRODUCTION_URL + url 
    return url 
Cuestiones relacionadas