Oficina Python e
Google App Engine

Rodrigo Amaral
Google Developers Group Aracaju
Fevereiro 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 Engine
Caracterí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
■ Mail
■ XMPP
■ Memcache
■ Manipulação de imagens
■ Fila de tarefas
Python
Visã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
JAVA
class HelloWorld
{
public static void main(String[] args)
{
System.out.println("Hello, World!");
}
}

PYTHON
print "Hello, World!"
Python cabe no seu cérebro (2)

QUADRADO DOS NÚMEROS PARES EM UM VETOR
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]
Python cabe no seu cérebro (3)

SORTEIO SIMPLES
import random
sorteio = 'Pedro Maria Paulo Joana Renato Sofia'.split()
print random.choice(sorteio)
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
>>> pi
3.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)
...
Aracaju
Fortaleza
Natal
Recife
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
app.yaml
Identificação

Módulos da
aplicação

Versão
requisição
Cliente

Resolução de URLs
Permissões

Frameworks
e bibliotecas

resposta
APIs de
serviços

script.py
Templates

Aplicação WSGI

Datastore
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.yaml
handlers
- 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!

Oficina Python e Google App Engine

  • 1.
    Oficina Python e GoogleApp Engine Rodrigo Amaral Google Developers Group Aracaju Fevereiro de 2014
  • 2.
  • 3.
  • 4.
    Aplicações web sãolegais ■ Multiplataforma ■ Acessadas de qualquer lugar ■ Fácil distribuição ■ Atualização instantânea ■ Correção de bugs controlada
  • 5.
    Mas as coisaspodem ficar complicadas ■ Múltiplos acessos simultâneos ■ Administração de servidores ■ Precisa de alta disponibilidade ■ Custos de hospedagem ■ Programação precisa ser ágil
  • 6.
    Platform as aService (PaaS) ■ Delegar tarefas de administração ■ Permitir escalabilidade ■ Reduzir os custos iniciais ■ Prover serviços auxiliares
  • 7.
    Google App Engine Executaraplicações web na infraestrutura do Google
  • 8.
  • 9.
    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
  • 10.
    Armazenamento de dados ■Datastore ● banco de dados não-relacional ● entidades, tipos, propriedades ● schemaless ■ Google Cloud SQL ● banco de dados relacional ■ Google Cloud Storage
  • 11.
    Autenticação e autorização ■Google Accounts ■ Users API
  • 12.
    Serviços ■ URL Fetch ■Mail ■ XMPP ■ Memcache ■ Manipulação de imagens ■ Fila de tarefas
  • 13.
  • 14.
    Python ■ Tipagem dinâmica ■Uso geral ■ Multiparadigma ■ Sintaxe clara e legível ■ Introspecção poderosa ■ Rica biblioteca padrão
  • 15.
  • 16.
    Python cabe noseu cérebro JAVA class HelloWorld { public static void main(String[] args) { System.out.println("Hello, World!"); } } PYTHON print "Hello, World!"
  • 17.
    Python cabe noseu cérebro (2) QUADRADO DOS NÚMEROS PARES EM UM VETOR 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]
  • 18.
    Python cabe noseu cérebro (3) SORTEIO SIMPLES import random sorteio = 'Pedro Maria Paulo Joana Renato Sofia'.split() print random.choice(sorteio)
  • 19.
    Módulos ⬝ Facilita aorganização dos programas ⬝ Todo arquivo .py é um módulo ⬝ Um módulo faz referência a outro com o comando import
  • 20.
    Importando módulos >>> importsys >>> print(sys.version) 2.7.4 (default, Sep 26 2013, 03:20:56) [GCC 4.7.3] >>> from math import pi >>> pi 3.141592653589793
  • 21.
    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']
  • 22.
    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']
  • 23.
    Iterando >>> for capitalin capitais: ... print(capital) ... Aracaju Fortaleza Natal Recife
  • 24.
    Dicionários { } ⬝ Parecidoscom listas ⬝ Conjunto de chaves e valores ⬝ Cada elemento é uma tupla de chave e valor ⬝ Estrutura conhecida como mapping, hash, array associativo etc.
  • 25.
    Acessando valores >>> agenda= {"Pedro": "2626-2626", "Maria": "2323-2323", "Paulo": "2121-2121"} >>> telefone = agenda["Maria"] >>> telefone '2323-2323'
  • 26.
    Classes ⬝ Definidas coma 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
  • 27.
    Chega de papo! Vamosconstruir juntos uma pequena aplicação web com Python e App Engine
  • 28.
  • 29.
    Python App EngineSDK ■ 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
  • 30.
    Instalação Linux: descompactar econfigurar $PATH Windows e Mac: executar instalador
  • 31.
    app.yaml Entre outras configurações,descreve o que a aplicação deve fazer quando uma URL é acessada
  • 32.
    Web Server GatewayInterface (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
  • 33.
    main.py Módulo principal danossa aplicação de exemplo. É nele que vamos implementar as classes que tratam nossas requisições.
  • 34.
    Estrutura da aplicação app.yaml Identificação Módulosda aplicação Versão requisição Cliente Resolução de URLs Permissões Frameworks e bibliotecas resposta APIs de serviços script.py Templates Aplicação WSGI Datastore
  • 35.
    webapp2 WSGIApplication Responsável por rotearas 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
  • 36.
  • 37.
    Integrando com GoogleAccounts Users API from google.appengine.api import users users.get_current_user() users.create_login_url(<url_retorno>) users.create_logout_url(<url_retorno>)
  • 38.
    Manipulando dados deforms ⬝ Implementar método post() ⬝ Obter dados do request ⬝ self.request.get(<nome>)
  • 39.
    Armazenando dados ⬝ Datastore(NDB) ⬝ google.appengine.ext.ndb ⬝ Entidades ⬝ ndb.Model ⬝ Properties ⬝ ndb.StringProperty, ndb.IntegerProperty etc...
  • 40.
    Templates ⬝ Framework Jinja2 ⬝Arquivos .html JINJA_ENVIRONMENT = jinja2.Environment( loader=jinja2.FileSystemLoader(os.path.dirname (__file__)), extensions=['jinja2.ext.autoescape'], autoescape=True )
  • 41.
    Arquivos estáticos ⬝ Declararno app.yaml handlers - url: /css static_dir: css ⬝ Handlers são resolvidos na ordem ⬝ URLs com .* devem ficar por último
  • 42.
    Deploy da aplicação ⬝Registrar aplicação no GAE ⬝ Ajustar configuração no app.yaml ⬝ Upload ⬝ appcfg.py update <pasta>
  • 43.