Загрузить файлы в Google App Engine

Я планирую создать веб-приложение, которое позволит пользователям переходить на более раннюю версию своих файлов проектов Visual Studio. Однако похоже, что Google App Engine принимает загрузку файлов и хранение плоских файлов на сервере Google через db.TextProperty и db.BlobProperty.

Я буду рад, что кто-нибудь может предоставить образец кода (как на стороне клиента, так и на стороне сервера) о том, как это можно сделать.

@ user858915 Ссылка битая :(

Marco 07.10.2013 04:34
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
79
1
82 544
11
Перейти к ответу Данный вопрос помечен как решенный

Ответы 11

Вы не можете хранить файлы, так как нет традиционной файловой системы. Вы можете хранить их только в их собственном хранилище данных (в поле, определенном как BlobProperty)

В предыдущей ссылке есть пример:

class MyModel(db.Model):
  blob = db.BlobProperty()

obj = MyModel()
obj.blob = db.Blob( file_contents )

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

Вы можете хранить файлы как атрибуты TextProperty или BlobProperty.

Для записей в хранилище данных существует ограничение в 1 МБ, что может быть проблемой, а может и не быть.

Как сохранить файлы размером более 1мб. Я использую github.com/ckopanos/django-google-cloud-storage

Geo Jacob 14.01.2016 21:48

Об этом есть ветка в группах Google:

Загрузка файлов

С большим количеством полезного кода это обсуждение очень помогло мне в загрузке файлов.

Фактически, ответ на этот вопрос содержится в документации App Engine. См. Пример на Загрузка пользовательских изображений.

HTML-код внутри <form> </form>:

<input type = "file" name = "img"/>

Код Python:

class Guestbook(webapp.RequestHandler):
  def post(self):
    greeting = Greeting()
    if users.get_current_user():
      greeting.author = users.get_current_user()
    greeting.content = self.request.get("content")
    avatar = self.request.get("img")
    greeting.avatar = db.Blob(avatar)
    greeting.put()
    self.redirect('/')

Не нравится этот подход, потому что вы теряете информацию о типе пантомимы.

santiagobasulto 16.01.2012 18:27

@santiagobasulto: Почему бы тебе самому не проверить это?

vietean 20.01.2012 15:28

Я не хочу это проверять. Когда вам нужно отобразить изображение, вы должны предоставить информацию о типе MIME (будь то изображение JPG, GIF и т. д.), Поэтому вы должны предоставить HTTP-заголовок типа контента. Если вы загрузите изображение с помощью предоставленного вами решения, то в будущем вы не будете знать тип содержимого изображения, следовательно, вы не можете установить заголовок, следовательно, старые странные браузеры будут иметь проблемы с отображением изображения ( из-за отсутствия типа контента)

santiagobasulto 25.01.2012 19:24

Если вы не проверяете тип MIME, которому доверяете клиент, оставляя вас уязвимым для атак типа «черная шляпа» или неверно настроенных типов MIME в клиенте. Если вы собираетесь это сделать, вы можете просто доверять самому расширению файла.

Nacho Coloma 04.12.2012 19:58

Если проблема не исчезла, убедитесь, что вы используете enctype в теге формы.

Нет:

<form encoding = "multipart/form-data" action = "/upload">

Да:

<form enctype = "multipart/form-data" action = "/upload">

Я получал ошибку кодирования, прежде чем реализовал ваш ответ

Jader Dias 03.01.2010 23:44

Когда я делал это, меня действительно раздражала проблема отсутствия «размера» для типа ввода файла. Я тестировал Safari, который, по-видимому, имеет очень короткую длину файла по умолчанию (?), И все, что я получал в GAE для содержимого файла, это имя файла. Просто слово предупреждения, которое может спасти кого-то от небольшой головной боли.

John Carter 30.11.2010 03:44

Лично я считаю, что учебник, описывающий здесь, полезен при использовании среды выполнения Java с GAE. По какой-то причине, когда я пытался загрузить файл с помощью

<form action = "/testservelet" method = "get" enctype = "multipart/form-data">
    <div>
        Myfile:<input type = "file" name = "file" size = "50"/>
    </div>

    <div>
        <input type = "submit" value = "Upload file">
    </div>
</form>

Я обнаружил, что мой класс HttpServlet по какой-то причине не принимает форму с атрибутом enctype. Однако удаление работает, это означает, что я не могу загружать файлы.

Это может быть потому, что вы используете метод get, попробуйте вместо этого настроить его на публикацию. Я не уверен, что это сработает, но попробовать стоит.

slashnick 09.09.2009 23:55

Google выпустила сервис для хранения больших файлов. Взгляните на документация по API blobstore. Если размер ваших файлов> 1 МБ, вам следует его использовать.

Как сохранять файлы> 1мб. Я использую github.com/ckopanos/django-google-cloud-storage

Geo Jacob 14.01.2016 22:07

Пробую сегодня, работает он следующим образом:

моя версия sdk - 1.3.x

html-страница:

<form enctype = "multipart/form-data" action = "/upload" method = "post" > 
<input type = "file" name = "myfile" /> 
<input type = "submit" /> 
</form> 

Код сервера:

file_contents = self.request.POST.get('myfile').file.read() 

Я заметил странное поведение при загрузке файлов в App Engine. Когда вы отправляете следующую форму:

<form method = "post" action = "/upload" enctype = "multipart/form-data">
    <input type = "file" name = "img" />
    ...
</form>

Затем вы извлекаете img из запроса следующим образом:

img_contents = self.request.get('img')

Переменная img_contents - это str() в Google Chrome, но в Firefox - это Unicode. И как вы сейчас, конструктор db.Blob() принимает строку и выдаст ошибку, если вы передадите строку в Юникоде.

Кто-нибудь знает, как это можно исправить?

Кроме того, что мне кажется совершенно странным, так это то, что когда я копирую и вставляю приложение «Гостевая книга» (с аватарами), оно работает отлично. Я делаю все точно так же в своем коде, но это просто не сработает. Я очень близок к тому, чтобы выдернуть волосы.

: D В форме говорилось: multipart / form-data вместо multipart / form-data. Chrome достаточно умен, чтобы исправить опечатку, а Firefox - нет.

Honza Pokorny 23.08.2010 16:30
Ответ принят как подходящий

Вот полный рабочий файл. Я взял оригинал с сайта Google и изменил его, чтобы сделать его немного более реальным.

Обратите внимание на несколько вещей:

  1. Этот код использует BlobStore API
  2. Назначение этой строки в Класс ServeHandler предназначен для "исправления" ключ, чтобы он избавился от любого имени искажение, которое могло произойти в браузер (в Хром)

    blob_key = str(urllib.unquote(blob_key))
    
  3. Предложение "save_as" в конце этого очень важно. Он будет следить за тем, чтобы имя файла не искажалось при отправке в ваш браузер. Избавьтесь от него и понаблюдайте за тем, что происходит.

    self.send_blob(blobstore.BlobInfo.get(blob_key), save_as=True)
    

Удачи!

import os
import urllib

from google.appengine.ext import blobstore
from google.appengine.ext import webapp
from google.appengine.ext.webapp import blobstore_handlers
from google.appengine.ext.webapp import template
from google.appengine.ext.webapp.util import run_wsgi_app

class MainHandler(webapp.RequestHandler):
    def get(self):
        upload_url = blobstore.create_upload_url('/upload')
        self.response.out.write('<html><body>')
        self.response.out.write('<form action = "%s" method = "POST" enctype = "multipart/form-data">' % upload_url)
        self.response.out.write("""Upload File: <input type = "file" name = "file"><br> <input type = "submit" name = "submit" value = "Submit"> </form></body></html>""")

        for b in blobstore.BlobInfo.all():
            self.response.out.write('<li><a href = "/serve/%s' % str(b.key()) + '">' + str(b.filename) + '</a>')

class UploadHandler(blobstore_handlers.BlobstoreUploadHandler):
    def post(self):
        upload_files = self.get_uploads('file')
        blob_info = upload_files[0]
        self.redirect('/')

class ServeHandler(blobstore_handlers.BlobstoreDownloadHandler):
    def get(self, blob_key):
        blob_key = str(urllib.unquote(blob_key))
        if not blobstore.get(blob_key):
            self.error(404)
        else:
            self.send_blob(blobstore.BlobInfo.get(blob_key), save_as=True)

def main():
    application = webapp.WSGIApplication(
          [('/', MainHandler),
           ('/upload', UploadHandler),
           ('/serve/([^/]+)?', ServeHandler),
          ], debug=True)
    run_wsgi_app(application)

if __name__ == '__main__':
  main()

Удивительно, что это работает для всех, кроме меня ... self.__uploads в blobstore_handler - это None, когда я пробую это.

Tim 08.08.2015 13:47

Есть способ использовать плоская файловая система (по крайней мере, с точки зрения использования)

Есть этот Проект виртуальной файловой системы Google App Engine. который реализован с помощью API хранилища данных и кэша памяти для имитации обычной файловой системы. Используя эту библиотеку, вы можете использовать в своем проекте аналогичный доступ к файловой системе (чтение и запись).

Другие вопросы по теме