Thiago Avelino Desenvolvedor Python, Django e MongoDB



April archive

[TOPICOFF] Site fora do ar, DataCenter tirando meu sono

April 29, 2011

Peço 1001 desculpas por o Avelino.US ter ficado fora do ar durante os últimos 4 dias.

Depois de 8 mês o DataCenter onde estava meu site ele colocou algumas regrar para serviço contratado daquela data para frente e depois de 2 mês o DataCenter lançou a regra para os que já tinha servidor alugado, ou seja, todos os IP do servidor caiu.

Migramos de DataCenter e não vai mais ocorrer esse tipo de problema.

Upload da arquivo no Google App Engine (BlobProperty)

April 23, 2011

Essa semana que passou tive uma necessidade para um sistema de trabalhar com UPLOAD de arquivos, ate ai é simples, só que o sistema estava em Google App Engine, depois de apanhar um pouco resolvi fazer um post aqui no Blog para deixar documentado como não é complicado trabalhar com BlobProperty no BigTable.

Primeiro vamos criar um Modal onde vai ter dois campo o arquivo e o mimetype dele:

class DatastoreFile(db.Model):
    data = db.BlobProperty(required=True)
    mimetype = db.StringProperty(required=True)

Agora vamos criar a views onde ele vai processar o formulario e o POST do formulario:

class MainHandler(webapp.RequestHandler):
    def get(self):
        self.response.out.write(template.render("upload.html", {}))

    def post(self):
        file = self.request.POST['file']

        entity = DatastoreFile(data=file.value, mimetype=file.type)
        entity.put()

        file_url = "http://%s/%d/%s" % (self.request.host, entity.key().id(), file.name)
        self.response.out.write("Your uploaded file is now available at %s" % (file_url,))

Podemos notar que na definição get() temos apenas a renderização do "upload.html", o conteudo dele é bem simples, temos um input do tipo file e outro submit:

<html>
<head>
  <title>File Upload</title>
</head>
<body>
  <form method="post" action="/" enctype="multipart/form-data">
    <input type="file" name="file" />
    <input type="submit" value="Upload" />
  </form>
</body>
</html>

Falando da definição post() que esta na classe MainHandler ela que faz o trabalho de fazer o UPLOAD do arquivo para dentro do BlobProperty, é um processo bem simples, a variável "file" recebe o POST do input file, depois disso chamamos o modal que tem o nome de DatastoreFile passando dois parâmetros que é os dois campos criados, o data e mimetype, depois disso é só fazer o put() que seja salvo no banco de dados. Dentro do post() eu gero o link para download do arquivo na variável file_url, onde passo o HOST (url do sistema), id() (do arquivo que foi feito upload) e file name (Nome do campo que recebeu o arquivo).

Agora temos que fazer a classe para download do arquivo onde vamos mudar o Content-Type do response para o mime-type do arquivo que foi feito o upload, exemplo: fiz o upload de um arquivo no formato JPG o mime type dele é "image/jpeg", então tenho que fazer o responser renderizar em formatado "image/jpeg".

Na URL que montamos para download passamos a seguinte informação id e file name onde temos que criar uma definição get() que receba essas informações:

class DownloadHandler(webapp.RequestHandler):
    def get(self, id, filename):
        entity = DatastoreFile.get_by_id(int(id))
        self.response.headers['Content-Type'] = entity.mimetype
        self.response.out.write(entity.data)

Recebendo as duas variáveis podemos fazer um consulta no BigTable de forma simples onde busco o id, pego o retorno do banco de dados e coloco que o response.headers['Content-Type'] é o mime-type que esta salvo no banco e depois é só escrever o arquivo na tela.

Agora vamos criar as rotas da URL:

def main():
    application = webapp.WSGIApplication([
        ('/', MainHandler),
        ('/(\d+)/(.*)', DownloadHandler)
        ],debug=True)
    util.run_wsgi_app(application)

if __name__ == '__main__':
    main()

Quem ainda estiver com duvida pode dar uma olhar no repositorio: https://bitbucket.org/avelino/post_py_upload_de_arquivo_no_gae/src

Criando sistema com Multithreaded em Python

April 1, 2011

Multithreaded é quando temos mais de um programa executando ao mesmo tempo, totalmente diferente de executar duas vez o mesmo programa, com "threads" o sistema vai ser executado apenas uma vez e via thread vai processar mais de uma função ao mesmo tempo, isso é necessario para concorrência em sistema.

Algumas vantagens de trabalha com threads:

Uma thread tem um começo, meio e fim, assim podemos colocar um ponteiro de instrução para acompanhar onde esta sendo processado cada thread dentro de seu contexto.

Iniciando uma nova Thread:

#!/usr/bin/python
# -*- coding: UTF-8 -*-

import thread
import time

# Definição da função de thread
def print_time( name, delay):
    count = 0
    while count < 5:
        time.sleep(delay)
        count += 1
        print "%s: %s" % ( name, time.ctime(time.time()) )

# Criar dois tópicos
try:
    thread.start_new_thread( print_time, ("Thread-1", 2, ) )
    thread.start_new_thread( print_time, ("Thread-2", 4, ) )
except:
    print "Erro: não conseguiu iniciar a thread"

while 1:
    pass

Executando:

avelino:multithreading/ [11:01:01] $ python example.py
Thread-1: Thu Mar 31 11:03:20 2011
Thread-2: Thu Mar 31 11:03:22 2011
Thread-1: Thu Mar 31 11:03:22 2011
Thread-1: Thu Mar 31 11:03:24 2011
Thread-2: Thu Mar 31 11:03:26 2011
Thread-1: Thu Mar 31 11:03:26 2011
Thread-1: Thu Mar 31 11:03:28 2011
Thread-2: Thu Mar 31 11:03:30 2011
Thread-2: Thu Mar 31 11:03:34 2011
Thread-2: Thu Mar 31 11:03:38 2011

Se repararmos temos alguns processo concorrendo ao mesmo tempos, dessa forma já estamos trabalhando com Thread.

Modulos da biblioteca thread