使用python 3在谷歌云上托管的flask网站中显示来自谷歌云存储的图像

时间:2020-12-22 16:43:41

标签: python html google-app-engine flask google-cloud-storage

我正在尝试制作一个接受文本输入、生成图像,然后在 html 中显示该图像的网站。

当我有本地测试实现时,通过将图像写入静态目录可以正常工作,但是当我推送到谷歌云时,我不允许写入目录。我想出了如何将图像保存到我的 google 云存储桶中,但现在我无法将图像恢复显示在 html 模板中。

我使用 Flask 和 python 3.7

这是我正在做的:

from flask import Flask, render_template, request, send_file
import time
#import cloudstorage
import io, os
from google.cloud import storage
import tempfile

import functions

app = Flask(__name__)
app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 0

@app.route("/")
def home():
    return render_template("home_css.html")
    
@app.route('/', methods=['POST'])
def my_form_post():
    text = request.form['text']
    URL = functions.main(text)
    print(URL)
    return render_template("return_img_css.html", picture_path = URL, screen_name = text)

其中函数部分包含一个块,该块可以成功保存图像以返回图像的网址:

def make_plot():
    ....
    # NEED to SAVE THE IMAGE TO GOOGLE CLOUD
    client = storage.Client(project='meytweets')
    bucket = client.bucket('meytweets.appspot.com')
    savename =  'static/'+ screen_name+ '_network.png'
    blob = bucket.blob(savename)
    # temporarily save image to buffer
    buf = io.BytesIO()
    plt.savefig(buf, format='png')
    
    # upload buffer contents to gcs
    blob.upload_from_string(
        buf.getvalue(),
        content_type='image/png')
    buf.close()
    return blob.public_url

该网址通常如下所示: https://storage.googleapis.com/meytweets.appspot.com/static/twitter_network.png

HTML 模板如下所示:

{% extends 'base.html' %}

{% block content %}
    <h1>{% block title %} Network for Twitter User: {{ screen_name }} {% endblock %}</h1>    
    <img src="{{ picture_path }}" >
{% endblock %}

这是 app.yaml:

runtime: python37

env_variables:
    CLOUD_STORAGE_BUCKET: meytweets.appspot.com

handlers:
- url: /static
  static_dir: public
- url: /.*
  script: auto
  

正如我上面写的,它确实将图像保存到我的谷歌云存储桶中,但随后我无法将其恢复以显示在 html 中: screenshot

我对其他不写入谷歌云的策略持开放态度,任何可以显示我在 matplotlib 中生成的图像的方法都适合我。

1 个答案:

答案 0 :(得分:1)

当您在无服务器环境中运行您的应用时,只有 /tmp 目录是可写的。您不能更改其他目录的内容,例如 /static。此外,/tmp 目录是内存文件系统,因此,当实例被杀死时,所有 /tmp 都会消失。

现在,您可以尝试在处理程序中设置 /tmp。我从未测试过,不确定结果及其一致性。

另一种解决方案是将图像保存到 Google Cloud Storage,最后使用 Google Cloud Storage 中的图像生成 HTML,publicly accessible of course