Web2py: Desenvolvimento Ágil de Aplicações Web com Python

69
Desenvolvimento Ágil de Aplicações Web com Python por Cláudio Torcato terça-feira, 22 de novembro de 2011

description

Slides para apresentação de minicurso na FATEPI.

Transcript of Web2py: Desenvolvimento Ágil de Aplicações Web com Python

Page 1: Web2py: Desenvolvimento Ágil de Aplicações Web com Python

Desenvolvimento Ágil de Aplicações Web com Pythonpor Cláudio Torcato

terça-feira, 22 de novembro de 2011

Page 2: Web2py: Desenvolvimento Ágil de Aplicações Web com Python

terça-feira, 22 de novembro de 2011

Page 3: Web2py: Desenvolvimento Ágil de Aplicações Web com Python

História

Lançada em 2007

Massimo di Pierro, professor da Universidade DePaul, Chicago

Objetivos principais:

Fácil uso, desenvolvimento rápido e segurança

Versão atual: 1.99.2 (26.09.11)

terça-feira, 22 de novembro de 2011

Page 4: Web2py: Desenvolvimento Ágil de Aplicações Web com Python

InspiraçõesRuby on Rails

Desenvolvimento rápido

MVC Design

Django

Geração de formulários a partir de tabelas do banco de dados

Coleção de validadores extensíveis

terça-feira, 22 de novembro de 2011

Page 5: Web2py: Desenvolvimento Ágil de Aplicações Web com Python

CaracterísticasSem necessidade de instalação e configuração

Interface Web para Manutenção, Deployment e Desenvolvimento

Sistema de Ticketing

Framework Full-Stack

Retrocompatibilidade garantida

Open Source

terça-feira, 22 de novembro de 2011

Page 6: Web2py: Desenvolvimento Ágil de Aplicações Web com Python

Administração Web Based

Gerenciar aplicações

Criar aplicações

Desenvolver aplicações

Testar e Debugar

Integração com Mercurial

terça-feira, 22 de novembro de 2011

Page 7: Web2py: Desenvolvimento Ágil de Aplicações Web com Python

Arquitetura: MVC

terça-feira, 22 de novembro de 2011

Page 8: Web2py: Desenvolvimento Ágil de Aplicações Web com Python

Arquitetura

terça-feira, 22 de novembro de 2011

Page 9: Web2py: Desenvolvimento Ágil de Aplicações Web com Python

Controller

terça-feira, 22 de novembro de 2011

Page 10: Web2py: Desenvolvimento Ágil de Aplicações Web com Python

Estrutura

terça-feira, 22 de novembro de 2011

Page 11: Web2py: Desenvolvimento Ágil de Aplicações Web com Python

Default.py

terça-feira, 22 de novembro de 2011

Page 13: Web2py: Desenvolvimento Ágil de Aplicações Web com Python

Request

http://localhost:8000/a/c/f.html/x/y/z?p=1&q=2

request.args = [ 'x', 'y', 'z' ]

request.vars = { 'p' : 1, 'q' : 2 }

request.application = 'a'

request.controller = 'c'

request.function = 'f'

terça-feira, 22 de novembro de 2011

Page 14: Web2py: Desenvolvimento Ágil de Aplicações Web com Python

Usando Request

def variaveis(): vars = request.vars args = request.args return dict(vars = vars, args = args)

def primeiro_argumento(): variavel = request.args(0) return dict(var=variavel)

terça-feira, 22 de novembro de 2011

Page 15: Web2py: Desenvolvimento Ágil de Aplicações Web com Python

Session

session.variavel = "Oinc"

session.forget()

session.connect(request, response, db, masterapp=None)

def contador(): if session.cont: session.cont = session.cont+1 else: session.cont = 1 return dict( contador = session.cont )

terça-feira, 22 de novembro de 2011

Page 16: Web2py: Desenvolvimento Ágil de Aplicações Web com Python

Response

response.body

response.cookies

response.flash

response.headers

response.render(view, vars)

response.view

terça-feira, 22 de novembro de 2011

Page 17: Web2py: Desenvolvimento Ágil de Aplicações Web com Python

URL

URL('f') -- /[application]/[controller]/f

Suporte a mapeamento de URL e mapeamento reverso

Redefine o mapeamento de URLs externas

URL('a', 'c', 'f', args=['x', 'y'], vars={ z : 't' })

terça-feira, 22 de novembro de 2011

Page 18: Web2py: Desenvolvimento Ágil de Aplicações Web com Python

HTTP and Redirect

raise HTTP(400, "mensagem de erro")

redirect('http://www.web2py.com')

redirect(URL('index', args=(1,2,3),vars=dict(a='b')))

terça-feira, 22 de novembro de 2011

Page 19: Web2py: Desenvolvimento Ágil de Aplicações Web com Python

i18n e l10n

Arquivos de linguagem

O objeto T é uma instância global do tradutor de linguagem

Constantes String deveriam ser marcadas por T

Exemplo: T("Hello World")

terça-feira, 22 de novembro de 2011

Page 20: Web2py: Desenvolvimento Ágil de Aplicações Web com Python

View

terça-feira, 22 de novembro de 2011

Page 21: Web2py: Desenvolvimento Ágil de Aplicações Web com Python

Estrutura

terça-feira, 22 de novembro de 2011

Page 22: Web2py: Desenvolvimento Ágil de Aplicações Web com Python

Template Language

Python embutido em HTML

Código python entre {{ }}

Sem restrições à linguagem

Blocos de código finalizados por pass

terça-feira, 22 de novembro de 2011

Page 23: Web2py: Desenvolvimento Ágil de Aplicações Web com Python

{{if request.args(0): response.write('existe')else: response.write('não existe')pass}}

Exemplos

terça-feira, 22 de novembro de 2011

Page 24: Web2py: Desenvolvimento Ágil de Aplicações Web com Python

<html><body>{{ for x in range(10):}} {{=x}}hello<br/>{{ pass }}</body></html>

response.write("<html><body>", escape=False)for x in range(10): response.write(x) response.write("hello<br/>", escape=False)response.write("</body></html>", escape=False)

Geração da View

terça-feira, 22 de novembro de 2011

Page 25: Web2py: Desenvolvimento Ágil de Aplicações Web com Python

{{=variavel}}

response.write(x, escape=True)

Escaped por padrão

Se o objeto tem o método .xml(), ele é chamado e o escaping é ignorado

Senão usa o método __str__ para serializar

terça-feira, 22 de novembro de 2011

Page 26: Web2py: Desenvolvimento Ágil de Aplicações Web com Python

HTML Helpers

Classes usadas para construir HTML programaticamente

Helpers: A, B, BEAUTIFY, BR, CENTER, CODE, DIV, EM, EMBED, FIELDSET, FORM, H1, H2, H3, H4, H5, H6, HEAD, HR, I, IFRAME, IMG, INPUT, LABEL, LEGEND, LI, LINK, OL, UL, MARKMIN, MENU, META, OBJETCT, ON, OPTION, P, PRE, etc.

terça-feira, 22 de novembro de 2011

Page 27: Web2py: Desenvolvimento Ágil de Aplicações Web com Python

Exemplo de uso do Helper

{{=DIV(B(I('hello','<world>'))), _class="myclass") }}

<div class="myclass"> <b><i>hello &lt;world&gt;</i></b></div>

terça-feira, 22 de novembro de 2011

Page 28: Web2py: Desenvolvimento Ágil de Aplicações Web com Python

Page Layout

{{extend 'layout.html'}}<h1>Hello World</h1>{{include 'page.html'}}

<html><head><title>Page Title</title></head><body> {{include}}</body></html>

layout.html

index.html

terça-feira, 22 de novembro de 2011

Page 29: Web2py: Desenvolvimento Ágil de Aplicações Web com Python

Exemplo

def lista(): return dict(numeros = range(30))

<ul>{{ for numero in numeros: }} <li> {{=numero }} </li>{{ pass }}</ul>

controllers/visao.py

views/visao/lista.html

terça-feira, 22 de novembro de 2011

Page 30: Web2py: Desenvolvimento Ágil de Aplicações Web com Python

Model

terça-feira, 22 de novembro de 2011

Page 31: Web2py: Desenvolvimento Ágil de Aplicações Web com Python

Estrutura

terça-feira, 22 de novembro de 2011

Page 32: Web2py: Desenvolvimento Ágil de Aplicações Web com Python

Responsabilidades do Model

Acessar o Banco

Mapear Objetos e Tabelas

Gerar SQL dinamicamente

Validar campos das tabelas e formulários

terça-feira, 22 de novembro de 2011

Page 33: Web2py: Desenvolvimento Ágil de Aplicações Web com Python

Database Abstraction Layer - DAL

“An API that maps Python objects into database objects such as queries, tables, and records.”

Adapdadores para cada dialeto SQL

db = DAL("string de conexão")

terça-feira, 22 de novembro de 2011

Page 34: Web2py: Desenvolvimento Ágil de Aplicações Web com Python

String de Conexão

SQLite sqlite://storage.dbMySQL mysql://username:password@localhost/

testPostgreSQL postgres://username:pass@localhost/testMSSQL mssql://username:pass@localhost/testFirebird firebird://username:pass@localhost/testOracle oracle://username/pass@testDB2 db2://username:pass@testIngres ingres://username:pass@localhost/testInformix informix://username:pass@testGoogle App Engine gae

terça-feira, 22 de novembro de 2011

Page 35: Web2py: Desenvolvimento Ágil de Aplicações Web com Python

Table

db.define_table('pessoas', Field('nome'), Field('casado','boolean',default=False), Field('genero'), Field('data_nascimento','date',label='Data de Nascimento'))

db.pessoas.genero.requires = IS_IN_SET(['M','F','?'])

terça-feira, 22 de novembro de 2011

Page 36: Web2py: Desenvolvimento Ágil de Aplicações Web com Python

Tipos de Campos

terça-feira, 22 de novembro de 2011

Page 37: Web2py: Desenvolvimento Ágil de Aplicações Web com Python

Migrations

Alterações na definição de uma tabela no DAL refletirá no banco de dados

Tais mudanças são registradas em logs

db = DAL('sqlite://storage.db', migrate = False)

terça-feira, 22 de novembro de 2011

Page 38: Web2py: Desenvolvimento Ágil de Aplicações Web com Python

Métodos de Table

db.pessoas.insert(nome='Helena')

db.pessoas.truncate()

db.pessoas.bulk_insert({'nome':'Ana','sexo':'F'})

terça-feira, 22 de novembro de 2011

Page 39: Web2py: Desenvolvimento Ágil de Aplicações Web com Python

Query

Objeto que representa a cláusula “where” do SQL.

query = (db.pessoas.nome == 'Alex')

terça-feira, 22 de novembro de 2011

Page 40: Web2py: Desenvolvimento Ágil de Aplicações Web com Python

Set

Representa um conjunto de registros

Alguns métodos: count, select, update, delete

Exemplo: meu_set = db(query)

rows = meu_set.select()

meu_set.update(nome='Eloah')

meu_set.delete()

terça-feira, 22 de novembro de 2011

Page 41: Web2py: Desenvolvimento Ágil de Aplicações Web com Python

Rows

Resultado do comando select

class gluon.sql.Rows

Objeto iterável cujos elementos são objetos Row (gluon.sql.Row)

Objetos Row são parecidos com dicionários mas seus elementos podem ser acessados como atributos

terça-feira, 22 de novembro de 2011

Page 42: Web2py: Desenvolvimento Ágil de Aplicações Web com Python

Exemplo de Rows e Row

def solteiros(): query = (db.pessoas.casado == False) linhas = db(query).select() return dict( linhas = linhas)

<h2>Lista de Solteiros</h2><ul> {{ for solteiro in linhas: }} <li> {{=solteiro.nome }} {{ pass }}</ul>

controller

view

solteiro['nome']solteiro('pessoas.nome')

terça-feira, 22 de novembro de 2011

Page 43: Web2py: Desenvolvimento Ágil de Aplicações Web com Python

Selects Recursivos

db.define_table('caes', Field('nome'), Field('dono', db.pessoas))

caes = db(db.caes).select()

for cao in caes:print 'Nome do Dono:', cao.dono.nome

terça-feira, 22 de novembro de 2011

Page 44: Web2py: Desenvolvimento Ágil de Aplicações Web com Python

Select: argumentos opcionais

orderby

groupby

limitby

distinct

rows = db(db.pessoas).select(orderby=db.pessoas.nome)

terça-feira, 22 de novembro de 2011

Page 45: Web2py: Desenvolvimento Ágil de Aplicações Web com Python

Operadores Lógicos

rows = db((db.pessoas.nome == 'Alex') & (db.pessoas.idade > 18)).select()

rows = db((db.pessoas.nome == 'Alex') | (db.pessoas.idade > 18)). select()

rows = db(db.pessoas.nome != 'Alex').select()

terça-feira, 22 de novembro de 2011

Page 46: Web2py: Desenvolvimento Ágil de Aplicações Web com Python

Campos Computadosfrom datetime import date

def idade(tabela): niver = tabela.data_nascimento hoje = date.today() return niver.year - hoje.year

db.define_table('pessoas', Field('nome'), Field('data_nascimento','date'), Field('idade', compute = idade))

terça-feira, 22 de novembro de 2011

Page 47: Web2py: Desenvolvimento Ágil de Aplicações Web com Python

Campos Virtuais

Não alocados no BD

Computados a cada consulta no banco

class VirtualPessoa(object): def idade(self): return date.today().year - self.pessoas.data_nascimento.year

db.pessoas.virtualfields.append(VirtualPessoa())

terça-feira, 22 de novembro de 2011

Page 48: Web2py: Desenvolvimento Ágil de Aplicações Web com Python

Update

obj = db.pessoas(2)obj.update_record(nome='Edna')

db(db.pessoas.data_nascimento.year() > 1990). update(db.pessoas.cidade_natal = 'Teresina')

db.pessoas[ 2 ]db(db.pessoas.id == 2).select().first()

terça-feira, 22 de novembro de 2011

Page 49: Web2py: Desenvolvimento Ágil de Aplicações Web com Python

Joins

Inner Join

Left Outer Join

db(db.pessoas.id == db.caes.dono).select()

db().select(db.pessoas.ALL, db.caes.ALL, left=db.caes.on(db.pessoas.id==db.caes.dono))

terça-feira, 22 de novembro de 2011

Page 50: Web2py: Desenvolvimento Ágil de Aplicações Web com Python

Visualizando o SQL

print db.pessoas._insert(nome='Daniel')

print db(db.pessoas)._count()

print db(db.pessoas.idade < 19)._select()

print db(db.pessoas.idade == 20)._delete()

print db(db.pessoas.idade == 20)._update()

terça-feira, 22 de novembro de 2011

Page 51: Web2py: Desenvolvimento Ágil de Aplicações Web com Python

Auth

Role Based Access Control (RBAC)

Auth implementa RBAC

Tabelas:

auth_user, auth_group, auth_membership, auth_permission, auth_event

Decorators são usados para restringir acesso a funções por login, membership ou permissions

terça-feira, 22 de novembro de 2011

Page 52: Web2py: Desenvolvimento Ágil de Aplicações Web com Python

Authentication

Métodos de login:

tabela auth_user

Google, PAM, LDAP, Facebook, LinkedIn, OpenID, OAuth, etc.

terça-feira, 22 de novembro de 2011

Page 53: Web2py: Desenvolvimento Ágil de Aplicações Web com Python

Auth Decorators

@auth.requires_login()def function_um(): return "requer login"

@auth.requires_membership("agentes")def function_dois(): return "você é um agente"

@auth.requires_permission('read', db.documentos)def function_tres(): return "você pode ler documentos secretos"

terça-feira, 22 de novembro de 2011

Page 54: Web2py: Desenvolvimento Ágil de Aplicações Web com Python

Forms

FORM

SQLFORM

SQLFORM.factory

CRUD

terça-feira, 22 de novembro de 2011

Page 55: Web2py: Desenvolvimento Ágil de Aplicações Web com Python

FORM

def formulario(): form = FORM('Seu nome:', INPUT(_name='nome'), INPUT(_type='submit')) return dict(form=form)

{{=form}}

terça-feira, 22 de novembro de 2011

Page 56: Web2py: Desenvolvimento Ágil de Aplicações Web com Python

FORMValidação e processamento do Formulário

def formulario2(): form=FORM('Seu nome:', INPUT(_name='nome', requires=IS_NOT_EMPTY()), INPUT(_type='submit')) if form.process().accepted: response.flash = 'formulário aceito' elif form.errors: response.flash = 'formulário tem erros' else: response.flash = 'preencha o formulário' return dict(form=form)

terça-feira, 22 de novembro de 2011

Page 57: Web2py: Desenvolvimento Ágil de Aplicações Web com Python

SQLFORM

def formulario(): form = SQLFORM(db.pessoas) if form.process().accepted: response.flash = 'form aceito.' elif form.errors: response.flash = 'form tem erro.' else: response.flash = 'preencha form.' return dict(form=form)

terça-feira, 22 de novembro de 2011

Page 58: Web2py: Desenvolvimento Ágil de Aplicações Web com Python

SQLFORM.factory

terça-feira, 22 de novembro de 2011

Page 59: Web2py: Desenvolvimento Ágil de Aplicações Web com Python

CRUD

API recente

Simplifica o uso do SQLFORM por incorporar diversas atividades numa única função

Precisa ser importada

Deve ser ligada a um banco de dados

from gluon.tools import Crudcrud = Crud(db)

terça-feira, 22 de novembro de 2011

Page 60: Web2py: Desenvolvimento Ágil de Aplicações Web com Python

Métodos CRUDcrud.tables()

crud.create(db.nome_tabela)

crud.read(db.nome_tabela, id)

crud.update(db.nome_tabela, id)

crud.delete(db.nome_tabela, id)

crud.select(db.nome_tabela, query)

crud.search(db.nome_tabela)

crud()

terça-feira, 22 de novembro de 2011

Page 61: Web2py: Desenvolvimento Ágil de Aplicações Web com Python

Funções com CRUD

def create_cao(): form = crud.create(db.caes) return dict(form = form)

def update_cao(): form = crud.update(db.caes, request.args(0)) return dict(form = form)

terça-feira, 22 de novembro de 2011

Page 62: Web2py: Desenvolvimento Ágil de Aplicações Web com Python

Validadores

Classes usadas para validar entrada de campos (incluindo forms gerados de tabelas)

Podem ser usadas em Fields e em Forms

Sempre atribuídos usando o atributo requires de um campo

terça-feira, 22 de novembro de 2011

Page 63: Web2py: Desenvolvimento Ágil de Aplicações Web com Python

Lista de Validadores

IS_ALPHANUMERIC, IS_DATE, IS_DATE_IN_RANGE, IS_DATETIME, IS_DATETIME_IN_RANGE, IS_DECIMAL_IN_RANGE, IS_EMAIL, IS_EXPR, IS_FLOAT_IN_RANGE, IS_IN_SET, IS_LENGTH, IS_LIST_OF, IS_LOWER, IS_URL, IS_STRONG, IS_EMPTY_OR, CLEANUP, CRYPT

terça-feira, 22 de novembro de 2011

Page 64: Web2py: Desenvolvimento Ágil de Aplicações Web com Python

Services

Sistema de software projetado para suportar a interação máquina-máquina numa rede

Suporte a XML, JSON, RSS, CSV, XMLRPC, JSONRPC, AMFRPC e SOAP

Modos de suporte:

Renderizar a saída de uma função

Remote Procedure Calls

terça-feira, 22 de novembro de 2011

Page 65: Web2py: Desenvolvimento Ágil de Aplicações Web com Python

Generic Views

default/contador.xml procura views/default/contador.xml

Não encontrando, procura views/default/generic.xml

Generics para JSON, PDF, RSS, XML

terça-feira, 22 de novembro de 2011

Page 66: Web2py: Desenvolvimento Ágil de Aplicações Web com Python

Remote Procedure Calls

Web2py prover mecanismo para tornar qualquer função um web service

O que precisamos:

instanciar o objeto service

expor um manipulador de serviços no controller

decorar a função que será exposta como um serviço

terça-feira, 22 de novembro de 2011

Page 67: Web2py: Desenvolvimento Ágil de Aplicações Web com Python

Service Decorator

terça-feira, 22 de novembro de 2011

Page 68: Web2py: Desenvolvimento Ágil de Aplicações Web com Python

Do que não falamosURL Rewrite

Roteamento de Erros

Tarefas em background

Pyjamas

Blocks in Views

Caching

Exportação e Importação de Dados

Central Authentication Service

jQuery e Ajax

Deploy em Servidores de Produção

Escalabidade

Google App Engine

Componentes e Plugins

terça-feira, 22 de novembro de 2011