it-swarm-pt.tech

Carregar arquivos no Google App Engine

Estou planejando criar um aplicativo Web que permita aos usuários fazer o downgrade de seus arquivos de projeto do Visual Studio. No entanto, parece que o Google App Engine aceita upload de arquivos e armazenamento simples no servidor do Google por meio de db.TextProperty e db.BlobProperty.

Ficarei feliz em saber que alguém pode fornecer um exemplo de código (do lado do cliente e do servidor) sobre como isso pode ser feito.

77
Graviton

Aqui está um arquivo de trabalho completo. Peguei o original do site do Google e o modifiquei para torná-lo um pouco mais real.

Algumas coisas a serem observadas:

  1. Este código usa a API do BlobStore
  2. O objetivo desta linha na classe ServeHandler é "consertar" a chave para que ela se livre de qualquer nome que possa ter ocorrido no navegador (não observei nenhum no Chrome)

    blob_key = str(urllib.unquote(blob_key))
    
  3. A cláusula "save_as" no final disso é importante. Ele garantirá que o nome do arquivo não seja mutilado quando enviado ao seu navegador. Livre-se dele para observar o que acontece.

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

Boa sorte!

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 __== '__main__':
  main()
42
010110110101

De fato, essa pergunta é respondida na documentação do App Egnine. Veja um exemplo em pload de imagens do usuário .

Código HTML, dentro de <form> </form>:

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

Código Python:

classe Livro de Visitas (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 ('/')
49
sastanin

Há um tópico nos Grupos do Google sobre o assunto:

pload de arquivos

Com muito código útil, essa discussão me ajudou muito no upload de arquivos.

10
Gustavo Diaz Jaimes

Eu tento hoje, funciona da seguinte forma:

minha versão do sdk é 1.3.x

página html:

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

Código do servidor:

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

O Google lançou um serviço para armazenar arquivos grandes. Dê uma olhada em documentação da API do blobstore . Se seus arquivos tiverem> 1 MB, você deverá usá-lo.

6
jbochi

Se você ainda estiver com problemas, verifique se está usando enctype na tag do formulário

Não:

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

Sim:

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

Você não pode armazenar arquivos, pois não existe um sistema de arquivos tradicional. Você só pode armazená-los em seu próprio DataStore (em um campo definido como BlobProperty )

Há um exemplo no link anterior:

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

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

Pessoalmente, achei o tutorial descrito aqui útil ao usar o tempo de execução Java com o GAE. Por alguma razão, quando tentei fazer upload de um arquivo usando

<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>

Eu descobri que minha classe HttpServlet, por algum motivo, não aceitaria o formulário com o atributo 'enctype'. Removê-lo funciona, no entanto, isso significa que não consigo carregar nenhum arquivo.

1
Vijay Sharma

Existe uma maneira de usar sistema de arquivos simples (pelo menos na perspectiva de uso)

Existe este projeto do sistema de arquivos virtual do Google App Engine . que é implementado com a ajuda das APIs do armazenamento de dados e do memcache para emular um sistema de arquivos comum. Usando esta biblioteca, você pode usar no projeto um acesso semelhante ao sistema de arquivos (leitura e gravação) .

0
vivek_jonam

Não há armazenamento de arquivo simples no Google App Engine. Tudo tem que ir para o Datastore que é um pouco como um banco de dados relacional, mas não completamente.

Você pode armazenar os arquivos como atributos TextProperty ou BlobProperty .

Há um limite de 1 MB nas entradas do DataStore que pode ou não ser um problema.

0
Dave Webb

Eu observei algum comportamento estranho ao fazer upload de arquivos no App Engine. Quando você envia o seguinte formulário:

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

E então você extrai o img da solicitação como esta:

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

A variável img_contents É uma str() no Google Chrome, mas é unicode no Firefox. E como você agora, o construtor db.Blob() pega uma string e gera um erro se você passar uma string unicode.

Alguém sabe como isso pode ser corrigido?

Além disso, o que acho absolutamente estranho é que, quando copio e colo o aplicativo Livro de Visitas (com avatares), ele funciona perfeitamente. Faço tudo exatamente da mesma maneira no meu código, mas simplesmente não funciona. Estou muito perto de arrancar meus cabelos.

0
Honza Pokorny