Oficina Python e Google App Engine Rodrigo Amaral Google Developers Group Aracaju Fevereiro de 2014
Dec 18, 2014
Oficina Python e Google App Engine
Rodrigo Amaral
Google Developers Group AracajuFevereiro de 2014
Olá!
rodrigoamaral
rodrigoamaral.net
http://pug-se.github.io
Aplicações web são legais
■ Multiplataforma
■ Acessadas de qualquer lugar
■ Fácil distribuição
■ Atualização instantânea
■ Correção de bugs controlada
Mas as coisas podem ficar complicadas
■ Múltiplos acessos simultâneos
■ Administração de servidores
■ Precisa de alta disponibilidade
■ Custos de hospedagem
■ Programação precisa ser ágil
Platform as a Service (PaaS)
■ Delegar tarefas de administração
■ Permitir escalabilidade
■ Reduzir os custos iniciais
■ Prover serviços auxiliares
Google App Engine
Executar aplicações web na infraestrutura do Google
Google App EngineCaracterísticas da plataforma
Sandbox
■ Ambiente protegido
■ Facilita distribuição da demanda
■ Não escreve no sistema de arquivos
■ Somente HTTP(S) nas portas padrão
■ Não dispara subprocessos
■ Não enxerga outras aplicações
Armazenamento de dados
■ Datastore
● banco de dados não-relacional
● entidades, tipos, propriedades
● schemaless
■ Google Cloud SQL
● banco de dados relacional
■ Google Cloud Storage
Autenticação e autorização
■ Google Accounts
■ Users API
Serviços
■ URL Fetch
■ XMPP
■ Memcache
■ Manipulação de imagens
■ Fila de tarefas
PythonVisão geral da linguagem
Python
■ Tipagem dinâmica
■ Uso geral
■ Multiparadigma
■ Sintaxe clara e legível
■ Introspecção poderosa
■ Rica biblioteca padrão
Quem usa Python?
Python cabe no seu cérebro
class HelloWorld
{
public static void main(String[] args)
{
System.out.println("Hello, World!");
}
}
print "Hello, World!"
JAVA
PYTHON
Python cabe no seu cérebro (2)
vetor = [1, 2, 3, 4, 5, 6, 7]
quadrado_pares = [n ** 2 for n in vetor if n % 2 == 0]
print(quadrado_pares) # mostra [4, 16, 36]
QUADRADO DOS NÚMEROS PARES EM UM VETOR
Python cabe no seu cérebro (3)
import random
sorteio = 'Pedro Maria Paulo Joana Renato Sofia'.split()
print random.choice(sorteio)
SORTEIO SIMPLES
Módulos
⬝ Facilita a organização dos
programas
⬝ Todo arquivo .py é um módulo
⬝ Um módulo faz referência a outro
com o comando import
Importando módulos>>> import sys>>> print(sys.version)2.7.4 (default, Sep 26 2013, 03:20:56) [GCC 4.7.3]
>>> from math import pi>>> pi3.141592653589793
Listas [ ]>>> capitais = ["Aracaju", "Recife", "Natal"]>>> capitais['Aracaju', 'Recife', 'Natal']>>> len(capitais)3>>> capitais[1]'Recife'>>> capitais.append("Salvador")>>> capitais['Aracaju', 'Recife', 'Natal', 'Salvador']>>> capitais.insert(2, "Fortaleza")>>> capitais['Aracaju', 'Recife', 'Fortaleza', 'Natal', 'Salvador']
Listas (cont.)
>>> c = capitais.pop()>>> c'Salvador'>>> capitais['Aracaju', 'Recife', 'Fortaleza', 'Natal']>>> capitais[-1]'Natal'>>> capitais[1:3]['Recife', 'Fortaleza']>>> capitais[:2]['Aracaju', 'Recife']>>> capitais[2:]['Fortaleza', 'Natal']>>> capitais.sort()>>> capitais['Aracaju', 'Fortaleza', 'Natal', 'Recife']
Iterando
>>> for capital in capitais:... print(capital)... AracajuFortalezaNatalRecife
Dicionários { }⬝ Parecidos com listas
⬝ Conjunto de chaves e valores
⬝ Cada elemento é uma tupla de chave e
valor
⬝ Estrutura conhecida como mapping,
hash, array associativo etc.
Acessando valores
>>> agenda = {"Pedro": "2626-2626", "Maria": "2323-2323", "Paulo": "2121-2121"}>>> telefone = agenda["Maria"]>>> telefone'2323-2323'
Classes
⬝ Definidas com a palavra-chave class⬝ class Pessoa:
⬝ O primeiro argumento de todo método
é self⬝ def meu_metodo(self, x):
⬝ Atributos são referenciados com self⬝ self.atributo = 42
Chega de papo!Vamos construir juntos uma pequena
aplicação web com Python e App Engine
Download
http://developers.google.com/appengine/downloads
#Google_App_Engine_SDK_for_Python
Python App Engine SDK
■ Servidor de aplicação que simula o
ambiente App Engine● dev_appserver.py
■ Utilitário para upload● appcfg.py
■ Interface gráfica (Windows e Mac)
■ Python 2.7
Instalação
Linux: descompactar e configurar $PATH
Windows e Mac: executar instalador
app.yaml
Entre outras configurações, descreve
o que a aplicação deve fazer quando
uma URL é acessada
Web Server Gateway Interface (WSGI)
■ Especifica a comunicação entre
servidores web e aplicações
■ Se o framework é compatível,
funciona com o App Engine
■ Django, Flask, Pyramid, Bottle etc.
■ webapp2
main.py
Módulo principal da nossa aplicação
de exemplo.
É nele que vamos implementar as classes que
tratam nossas requisições.
Estrutura da aplicação
DatastoreTemplates
Cliente
app.yaml
Identificação
Versão
Resolução de URLs
Permissões
script.py
Aplicação WSGI
Módulos da aplicação
Frameworks e bibliotecas
APIs de serviços
requisição
resposta
webapp2
WSGIApplication
Responsável por rotear as requisições para as
classes que vão tratá-las, de acordo com a URL
Request Handlers
Classes que processam as requisições e constroem
as respostas
webapp2.RequestHandler
request
- get()
response
- headers
- write(<saida>)
redirect(<url>)
Integrando com Google Accounts
Users API
from google.appengine.api import users
users.get_current_user()
users.create_login_url(<url_retorno>)
users.create_logout_url(<url_retorno>)
Manipulando dados de forms
⬝ Implementar método post()
⬝ Obter dados do request
⬝ self.request.get(<nome>)
Armazenando dados
⬝ Datastore (NDB)
⬝ google.appengine.ext.ndb
⬝ Entidades
⬝ ndb.Model
⬝ Properties
⬝ ndb.StringProperty, ndb.IntegerProperty
etc...
Templates
⬝ Framework Jinja2
⬝ Arquivos .html
JINJA_ENVIRONMENT = jinja2.Environment( loader=jinja2.FileSystemLoader(os.path.dirname(__file__)), extensions=['jinja2.ext.autoescape'], autoescape=True)
Arquivos estáticos
⬝ Declarar no app.yamlhandlers- url: /css
static_dir: css
⬝ Handlers são resolvidos na ordem
⬝ URLs com .* devem ficar por último
Deploy da aplicação
⬝ Registrar aplicação no GAE
⬝ Ajustar configuração no app.yaml
⬝ Upload
⬝ appcfg.py update <pasta>
Obrigado!