Python 如何在应用程序引擎中从Google云存储动态加载Jinja2模板?
我在AppEngine上有一个应用程序,希望以一种方式部署我的Jinja2模板,使我能够动态更新它们,而无需重新部署整个应用程序 理想情况下,它们将存储在谷歌云存储中,这将允许我只需替换bucket中的模板文件,并让它们立即被实时应用程序使用。然而,Flask似乎要求模板是应用程序的本地模板Python 如何在应用程序引擎中从Google云存储动态加载Jinja2模板?,python,google-app-engine,flask,google-cloud-platform,jinja2,Python,Google App Engine,Flask,Google Cloud Platform,Jinja2,我在AppEngine上有一个应用程序,希望以一种方式部署我的Jinja2模板,使我能够动态更新它们,而无需重新部署整个应用程序 理想情况下,它们将存储在谷歌云存储中,这将允许我只需替换bucket中的模板文件,并让它们立即被实时应用程序使用。然而,Flask似乎要求模板是应用程序的本地模板 这是可能的吗?这可以通过直接从谷歌云存储为每个请求加载每个模板,并使用Flask中的函数来实现 例如,如果模板文件hello.html如下所示: <h1>Hello {{ name }}!<
这是可能的吗?这可以通过直接从谷歌云存储为每个请求加载每个模板,并使用Flask中的函数来实现 例如,如果模板文件
hello.html
如下所示:
<h1>Hello {{ name }}!</h1>
在您的main.py
中:
from flask import Flask, render_template_string
from google.cloud import storage
app = Flask(__name__)
# Initialize the bucket you created containing the templates
bucket = storage.Client().bucket('your-bucket')
@app.route('/')
def hello():
# Load the template string from Cloud Storage
template_string = bucket.blob('hello.html').download_as_string().decode('ascii')
# Now use render_template_string the same way you'd use render_template
return render_template_string(template_string, name='World')
请注意,由于此应用程序将为每个请求重新下载模板,因此对于高流量应用程序,它可能会导致大量额外的请求时间和成本
因此,最好以某种方式“缓存”模板字符串(例如,via),然后使用(可能是通过a)来确定文件在bucket中的更改时间,并更新缓存。这里有一个很好的Flask render_template()调用包装器,以实现以下两种目的:
- 1) 从URL加载静态文件,并传递参数
- 2) 或将文件名和参数传递给常规Flask render_模板方法
REMOTE_LOADING_ENABLED
您可以开发自己的Jinja模板加载器,从不同的源加载模板。但是你的“即时被实时应用程序使用”并不是那么容易,因为模板是缓存的。
from flask import Flask, render_template, render_template_string
def renderTemplateLocalOrRemote(file, **kwargs):
if REMOTE_LOADING_ENABLED is defined: # Load the template file remotely
r = requests.get('https://'+YOUR_BASE_URL+"/templates/"+file)
template_string = r.content.decode('utf-8')
return render_template_string(template_string, **kwargs)
else: # Load the template file from local, pass on to standard method
return render_template(file, **kwargs)
@app.route('/')
def hello():
return renderTemplateLocalOrRemote('hello.html', name='lalala', another_param='lilili')
@app.route('/another_route')
def hello2():
return renderTemplateLocalOrRemote('hello2.html', different_param='lilili')
REMOTE_LOADING_ENABLED