Сохранение файла изображения в файловой системе на Google App Engine с помощью Python Flask - PullRequest
0 голосов
/ 28 октября 2019

У меня есть приложение Flask, где пользователь может загрузить изображение, и изображение сохраняется в статической папке в файловой системе. В настоящее время я использую Google App Engine для хостинга и обнаружил, что невозможно сохранить в статическую папку в стандартной среде. Вот код

def save_picture(form_picture,name):
    picture_fn = name + '.jpg'
    picture_path = os.path.join(app.instance_path, 'static/image/'+ picture_fn)
    output_size = (1000,1000)
    i = Image.open(form_picture)
    i.thumbnail(output_size)
    i.save(picture_path)
    return picture_path

@app.route('/image/add', methods=['GET', 'POST'])
def addimage():
    form = Form()
    if form.validate_on_submit():
        name = 'randomname'
        try:
            picture_file = save_picture(form.image.data,name)
            return redirect(url_for('addimage'))
        except:
            flash("unsuccess")
            return redirect(url_for('addimage'))

Мой вопрос: если я перейду со стандартной среды на гибкую, можно ли будет сохранить ее в статическую папку? Если нет, то какие другие варианты хостинга я должен рассмотреть? Есть ли у вас какие-либо предложения?

Заранее спасибо.

Следуя вашим советам, я перехожу на использование облачного хранилища. мне интересно, что я должен использовать от upload_from_file (), upload_from_filename () или upload_from_string (). исходный_файл берет данные из form.photo.data из flask-wtform. я еще не успешно экономлю на облачном хранилище. это мой код:

def upload_blob(bucket_name, source_file, destination_blob_name):
storage_client = storage.Client()
bucket = storage_client.get_bucket(bucket_name)

blob = bucket.blob(destination_blob_name)

blob.upload_from_filename(source_file)

return destination_blob_name

@app.route('/image/add', methods=['GET', 'POST'])
def addimage():
form = Form()
if form.validate_on_submit():
    name = 'randomname'
    try:
        filename = 'foldername/'+ name + '.jpg'
        picture_file = upload_blob('mybucketname', form.photo.data, filename)
        return redirect(url_for('addimage'))
    except:
        flash("unsuccess")
        return redirect(url_for('addimage'))

Ответы [ 3 ]

2 голосов
/ 28 октября 2019

Проблема с сохранением его в какой-либо папке заключается в том, что он будет жить в этом одном экземпляре, а другие экземпляры не смогут получить к нему доступ. Кроме того, экземпляры в GAE приходят и уходят, поэтому в конечном итоге вы потеряете изображение.

Для этого вам следует использовать Google Cloud Storage:

from google.cloud import storage
client = storage.Client()
bucket = client.get_bucket('bucket-id-here')
blob = bucket.get_blob('remote/path/to/file.txt')
blob.upload_from_string('New contents!')

https://googleapis.dev/python/storage/latest/index.html

0 голосов
/ 29 октября 2019

Переход от стандартной среды Google App Engine к гибкой среде Google App Engine позволит вам выполнять запись на диск, а также выбрать тип компьютера Compute Engine с большим объемом памяти для вашего конкретного приложения [ 1 ],Если вы заинтересованы в том, чтобы следовать по этому пути, найдите всю соответствующую документацию по миграции приложения Python здесь .

Тем не менее, как это было объяснено пользователем @Alex в его предоставленном ответе при создании экземпляров(количество экземпляров уменьшено) или удалено (количество экземпляров уменьшено) в зависимости от нагрузки, в вашем конкретном случае лучшим вариантом будет использование Cloud Storage. Найдите пример загрузки объектов в облачное хранилище с Python здесь .

0 голосов
/ 28 октября 2019

С помощью Flask и Appengine, Python3.7, я сохраняю файлы в корзину следующим образом, потому что хочу зациклить его для многих файлов:

for key, upload in request.files.items():
    file_storage = upload
    content_type = None
    identity = str(uuid.uuid4()) # or uuid.uuid4().hex
    try:
        upload_blob("f00b4r42.appspot.com", request.files[key], identity, content_type=upload.content_type)

Вспомогательная функция:

from google.cloud import storage

def upload_blob(bucket_name, source_file_name, destination_blob_name, content_type="application/octet-stream"):
    """Uploads a file to the bucket."""
    storage_client = storage.Client()
    bucket = storage_client.get_bucket(bucket_name)
    blob = bucket.blob(destination_blob_name)
    blob.upload_from_file(source_file_name, content_type=content_type)
    blob.make_public()

    print('File {} uploaded to {}.'.format(
        source_file_name,
        destination_blob_name))
...