SlideShare uma empresa Scribd logo
Desenvolvimento Ágil de Aplicações Web com Python
                                                                       por Cláudio Torcato


terça-feira, 22 de novembro de 2011
terça-feira, 22 de novembro de 2011
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
Inspirações
                  Ruby 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
Características
              Sem 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
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
Arquitetura: MVC




terça-feira, 22 de novembro de 2011
Arquitetura




terça-feira, 22 de novembro de 2011
Controller



terça-feira, 22 de novembro de 2011
Estrutura




terça-feira, 22 de novembro de 2011
Default.py




terça-feira, 22 de novembro de 2011
Roteamento de URL
                       http://localhost:8080/minicurso/default/index.html

                       padrão

                             init

                             default

                             index

                             html



terça-feira, 22 de novembro de 2011
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
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
Session
                                          def contador():
                                            if session.cont: session.cont = session.cont+1
                                            else: session.cont = 1
                                            return dict( contador = session.cont )

              session.variavel = "Oinc"

              session.forget()

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




terça-feira, 22 de novembro de 2011
Response

              response.body

              response.cookies

              response.flash

              response.headers

              response.render(view, vars)

              response.view


terça-feira, 22 de novembro de 2011
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
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
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
View



terça-feira, 22 de novembro de 2011
Estrutura




terça-feira, 22 de novembro de 2011
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
Exemplos
                                      {{
                                      if request.args(0):
                                          response.write('existe')
                                      else:
                                          response.write('não existe')
                                      pass
                                      }}




terça-feira, 22 de novembro de 2011
Geração da View
                         <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)


terça-feira, 22 de novembro de 2011
{{=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
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
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 Layout
                         layout.html

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


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


terça-feira, 22 de novembro de 2011
Exemplo

                   controllers/visao.py
                                          def lista():
                                             return dict(numeros = range(30))



                                          <ul>
                views/visao/lista.html
                                          {{ for numero in numeros: }}
                                              <li> {{=numero }} </li>
                                          {{ pass }}
                                          </ul>



terça-feira, 22 de novembro de 2011
Model



terça-feira, 22 de novembro de 2011
Estrutura




terça-feira, 22 de novembro de 2011
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
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
String de Conexão
                 SQLite               sqlite://storage.db
                 MySQL                mysql://username:password@localhost/
                 PostgreSQL           postgres://username:pass@localhost/test
                                      test
                 MSSQL                mssql://username:pass@localhost/test
                 Firebird             firebird://username:pass@localhost/test
                 Oracle               oracle://username/pass@test
                 DB2                  db2://username:pass@test
                 Ingres               ingres://username:pass@localhost/test
                 Informix             informix://username:pass@test
                 Google App
                            gae
                 Engine


terça-feira, 22 de novembro de 2011
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
Tipos de Campos




terça-feira, 22 de novembro de 2011
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
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
Query


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

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




terça-feira, 22 de novembro de 2011
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
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
Exemplo de Rows e Row

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

                    view              <h2>Lista de Solteiros</h2>
                                      <ul>
                                        {{ for solteiro in linhas: }} solteiro['nome']
                                        <li> {{=solteiro.nome }} solteiro('pessoas.nome')
                                        {{ pass }}
                                      </ul>

terça-feira, 22 de novembro de 2011
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
Select: argumentos opcionais


              orderby

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

              distinct




terça-feira, 22 de novembro de 2011
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
Campos Computados
                               from 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
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
Update

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

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

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




terça-feira, 22 de novembro de 2011
Joins
                       Inner Join


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


                       Left Outer Join


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


              Métodos de login:

                    tabela auth_user

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




terça-feira, 22 de novembro de 2011
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
Forms

              FORM

              SQLFORM

              SQLFORM.factory

              CRUD




terça-feira, 22 de novembro de 2011
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
FORM
                       Validaçã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
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
SQLFORM.factory




terça-feira, 22 de novembro de 2011
CRUD
                                      from gluon.tools import Crud
                                      crud = Crud(db)
              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




terça-feira, 22 de novembro de 2011
Métodos CRUD
              crud.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
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
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
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
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
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
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
Service Decorator




terça-feira, 22 de novembro de 2011
Do que não falamos
              URL Rewrite                  Central Authentication
                                           Service
              Roteamento de Erros
                                           jQuery e Ajax
              Tarefas em background
                                           Deploy em Servidores de
              Pyjamas
                                           Produção
              Blocks in Views
                                           Escalabidade
              Caching
                                           Google App Engine
              Exportação e Importação de
                                           Componentes e Plugins
              Dados

terça-feira, 22 de novembro de 2011
Referências

              Web2py: http://www.web2py.com

              web2py-users-brazil: https://groups.google.com/group/
              web2py-users-brazil?hl=pt-BR

              The Official Web2py Book: http://www.web2py.com/book

              http://www.infoworld.com/d/application-development/
              pillars-python-six-python-web-frameworks-compared-169442



terça-feira, 22 de novembro de 2011

Mais conteúdo relacionado

ODP
Trabalhando com as views do Web2Py
PDF
Java recursos avançados - socket connection
PDF
Java orientação a objetos (interfaces)
PDF
Java orientação a objetos (variaveis de instancia e metodos)
PDF
Design Patterns na Programação de Jogo
PDF
Java orientação a objetos (associacao, composicao, agregacao)
ODP
Dependency injection
PPTX
Clean Code e Object Calisthenics - Aplicados no PHP
Trabalhando com as views do Web2Py
Java recursos avançados - socket connection
Java orientação a objetos (interfaces)
Java orientação a objetos (variaveis de instancia e metodos)
Design Patterns na Programação de Jogo
Java orientação a objetos (associacao, composicao, agregacao)
Dependency injection
Clean Code e Object Calisthenics - Aplicados no PHP

Mais procurados (20)

PDF
Combatendo code smells em aplicações Java
PDF
Java script aula 05 - funções
PDF
Vraptor
PDF
As novidades do PHP5 (2005)
PDF
Java introdução ao eclipse
PDF
Java script - funções
PDF
Java script aula 02 - operadores
PPTX
Programação Orientada por Objectos - Aula 6
PPTX
PPT
[CLPE] Design patterns com c#
PDF
FLTK Summer Course - Part II - Second Impact
PDF
Java - Introdução a banco de dados
PDF
Plataforma de compiladores .NET, Visual Studio 2015, C# 6 e futuro C# 7
PDF
Java script aula 08 - formulários
PDF
Java 06
PDF
Programação orientada a objetos em delphi
PDF
Reduzindo o boilerplate code com Lombok
PDF
Java introdução ao java
PPTX
Javascript
Combatendo code smells em aplicações Java
Java script aula 05 - funções
Vraptor
As novidades do PHP5 (2005)
Java introdução ao eclipse
Java script - funções
Java script aula 02 - operadores
Programação Orientada por Objectos - Aula 6
[CLPE] Design patterns com c#
FLTK Summer Course - Part II - Second Impact
Java - Introdução a banco de dados
Plataforma de compiladores .NET, Visual Studio 2015, C# 6 e futuro C# 7
Java script aula 08 - formulários
Java 06
Programação orientada a objetos em delphi
Reduzindo o boilerplate code com Lombok
Java introdução ao java
Javascript
Anúncio

Destaque (9)

PDF
Como o Plone domina os serviços Web dos Correios.com.br utilizando Diazo
PDF
Plone e eGov: Presente e Futuro
PDF
Oficina Mergulhando no Plone 4
PDF
Plone - Poderoso e flexível
PDF
Otimizando Portais Plone: Dicas de Desempenho
PDF
Plone total#2 - Gerenciamento de conteúdos
PDF
Canivete suíço do Python
PDF
Canivete python
ODP
Desenvolvendo aplicações web com python e web2py
Como o Plone domina os serviços Web dos Correios.com.br utilizando Diazo
Plone e eGov: Presente e Futuro
Oficina Mergulhando no Plone 4
Plone - Poderoso e flexível
Otimizando Portais Plone: Dicas de Desempenho
Plone total#2 - Gerenciamento de conteúdos
Canivete suíço do Python
Canivete python
Desenvolvendo aplicações web com python e web2py
Anúncio

Semelhante a Web2py: Desenvolvimento Ágil de Aplicações Web com Python (20)

PDF
Jython no JavaOne Latin America 2011
ZIP
Python e Django na Globo.com
PDF
REST com Python
PDF
Desenvolvimento web ágil com python e web2py
PDF
Globo.com - Porque amamos open-source?
PDF
Cp2011 python agil-ramiroluz
PDF
Introdução à Programação em Python
PDF
Python - Programando em alto nível
PDF
Django Tem Ritmo
PDF
Desbravando a web com python - Matheus Lima
ODP
Introdução a Desenvolvimento Web
PDF
Introdução a linguagem Python
PDF
Lua & C++
PPT
W2py pyconpe
PDF
PHP - O que, porquê e como
PDF
Hackeando o Facebook com Python
PDF
O poder do Python/Django
PDF
Automatizando tarefas com Python
PDF
Porque Python? Semana Acadêmica UTFPR 2011
PDF
Por que Python? IFC Concórdia 2011
Jython no JavaOne Latin America 2011
Python e Django na Globo.com
REST com Python
Desenvolvimento web ágil com python e web2py
Globo.com - Porque amamos open-source?
Cp2011 python agil-ramiroluz
Introdução à Programação em Python
Python - Programando em alto nível
Django Tem Ritmo
Desbravando a web com python - Matheus Lima
Introdução a Desenvolvimento Web
Introdução a linguagem Python
Lua & C++
W2py pyconpe
PHP - O que, porquê e como
Hackeando o Facebook com Python
O poder do Python/Django
Automatizando tarefas com Python
Porque Python? Semana Acadêmica UTFPR 2011
Por que Python? IFC Concórdia 2011

Último (19)

PDF
COBITxITIL-Entenda as diferença em uso governança TI
PDF
Fullfilment AI - Forum ecommerce 2025 // Distrito e Total Express
PDF
Gestão de transportes básica no SAP S/4HANA, S4611 Col20
PPTX
Aula16ManipulaçãoDadosssssssssssssssssssssssssssss
PDF
Otimizador de planejamento e execução no SAP Transportation Management, TM120...
PPTX
BANCO DE DADOS - AULAS INICIAIS-sgbd.pptx
PDF
20250805_ServiceNow e a Arquitetura Orientada a Serviços (SOA) A Base para Ap...
PPTX
Informática Aplicada Informática Aplicada Plano de Ensino - estudo de caso NR...
PDF
Custos e faturamento no SAP S/4HANA Transportation Management, S4TM3 Col26
PDF
Custos e liquidação no SAP Transportation Management, TM130 Col18
PPTX
Programação - Linguagem C - Variáveis, Palavras Reservadas, tipos de dados, c...
PDF
Aula04-Academia Heri- Tecnologia Geral 2025
PPTX
Aula 18 - Manipulacao De Arquivos python
PPTX
Gestao-de-Bugs-em-Software-Introducao.pptxxxxxxxx
PDF
Mergulho profundo técnico para gestão de transportes no SAP S/4HANA, S4TM6 Col14
PDF
Processos na gestão de transportes, TM100 Col18
PPTX
Como-se-implementa-um-softwareeeeeeeeeeeeeeeeeeeeeeeee.pptx
PDF
Fundamentos de gerenciamento de ordens e planejamento no SAP TransportationMa...
PDF
Apple Pippin Uma breve introdução. - David Glotz
COBITxITIL-Entenda as diferença em uso governança TI
Fullfilment AI - Forum ecommerce 2025 // Distrito e Total Express
Gestão de transportes básica no SAP S/4HANA, S4611 Col20
Aula16ManipulaçãoDadosssssssssssssssssssssssssssss
Otimizador de planejamento e execução no SAP Transportation Management, TM120...
BANCO DE DADOS - AULAS INICIAIS-sgbd.pptx
20250805_ServiceNow e a Arquitetura Orientada a Serviços (SOA) A Base para Ap...
Informática Aplicada Informática Aplicada Plano de Ensino - estudo de caso NR...
Custos e faturamento no SAP S/4HANA Transportation Management, S4TM3 Col26
Custos e liquidação no SAP Transportation Management, TM130 Col18
Programação - Linguagem C - Variáveis, Palavras Reservadas, tipos de dados, c...
Aula04-Academia Heri- Tecnologia Geral 2025
Aula 18 - Manipulacao De Arquivos python
Gestao-de-Bugs-em-Software-Introducao.pptxxxxxxxx
Mergulho profundo técnico para gestão de transportes no SAP S/4HANA, S4TM6 Col14
Processos na gestão de transportes, TM100 Col18
Como-se-implementa-um-softwareeeeeeeeeeeeeeeeeeeeeeeee.pptx
Fundamentos de gerenciamento de ordens e planejamento no SAP TransportationMa...
Apple Pippin Uma breve introdução. - David Glotz

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

  • 1. Desenvolvimento Ágil de Aplicações Web com Python por Cláudio Torcato terça-feira, 22 de novembro de 2011
  • 2. terça-feira, 22 de novembro de 2011
  • 3. 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
  • 4. Inspirações Ruby 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
  • 5. Características Sem 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
  • 6. 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
  • 7. Arquitetura: MVC terça-feira, 22 de novembro de 2011
  • 10. Estrutura terça-feira, 22 de novembro de 2011
  • 11. Default.py terça-feira, 22 de novembro de 2011
  • 12. Roteamento de URL http://localhost:8080/minicurso/default/index.html padrão init default index html terça-feira, 22 de novembro de 2011
  • 13. 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
  • 14. 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
  • 15. Session def contador(): if session.cont: session.cont = session.cont+1 else: session.cont = 1 return dict( contador = session.cont ) session.variavel = "Oinc" session.forget() session.connect(request, response, db, masterapp=None) terça-feira, 22 de novembro de 2011
  • 16. Response response.body response.cookies response.flash response.headers response.render(view, vars) response.view terça-feira, 22 de novembro de 2011
  • 17. 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
  • 18. 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
  • 19. 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
  • 20. View terça-feira, 22 de novembro de 2011
  • 21. Estrutura terça-feira, 22 de novembro de 2011
  • 22. 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
  • 23. Exemplos {{ if request.args(0): response.write('existe') else: response.write('não existe') pass }} terça-feira, 22 de novembro de 2011
  • 24. Geração da View <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) terça-feira, 22 de novembro de 2011
  • 25. {{=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
  • 26. 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
  • 27. 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
  • 28. Page Layout layout.html <html><head><title>Page Title</title></head> <body> {{include}} </body> </html> {{extend 'layout.html'}} index.html <h1>Hello World</h1> {{include 'page.html'}} terça-feira, 22 de novembro de 2011
  • 29. Exemplo controllers/visao.py def lista(): return dict(numeros = range(30)) <ul> views/visao/lista.html {{ for numero in numeros: }} <li> {{=numero }} </li> {{ pass }} </ul> terça-feira, 22 de novembro de 2011
  • 30. Model terça-feira, 22 de novembro de 2011
  • 31. Estrutura terça-feira, 22 de novembro de 2011
  • 32. 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
  • 33. 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
  • 34. String de Conexão SQLite sqlite://storage.db MySQL mysql://username:password@localhost/ PostgreSQL postgres://username:pass@localhost/test test MSSQL mssql://username:pass@localhost/test Firebird firebird://username:pass@localhost/test Oracle oracle://username/pass@test DB2 db2://username:pass@test Ingres ingres://username:pass@localhost/test Informix informix://username:pass@test Google App gae Engine terça-feira, 22 de novembro de 2011
  • 35. 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
  • 36. Tipos de Campos terça-feira, 22 de novembro de 2011
  • 37. 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
  • 38. 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
  • 39. Query Objeto que representa a cláusula “where” do SQL. query = (db.pessoas.nome == 'Alex') terça-feira, 22 de novembro de 2011
  • 40. 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
  • 41. 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
  • 42. Exemplo de Rows e Row controller def solteiros(): query = (db.pessoas.casado == False) linhas = db(query).select() return dict( linhas = linhas) view <h2>Lista de Solteiros</h2> <ul> {{ for solteiro in linhas: }} solteiro['nome'] <li> {{=solteiro.nome }} solteiro('pessoas.nome') {{ pass }} </ul> terça-feira, 22 de novembro de 2011
  • 43. 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
  • 44. Select: argumentos opcionais orderby groupby rows = db(db.pessoas) .select(orderby=db.pessoas.nome) limitby distinct terça-feira, 22 de novembro de 2011
  • 45. 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
  • 46. Campos Computados from 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
  • 47. 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
  • 48. Update db.pessoas[ 2 ] db(db.pessoas.id == 2).select().first() obj = db.pessoas(2) obj.update_record(nome='Edna') db(db.pessoas.data_nascimento.year() > 1990). update(db.pessoas.cidade_natal = 'Teresina') terça-feira, 22 de novembro de 2011
  • 49. Joins Inner Join db(db.pessoas.id == db.caes.dono).select() Left Outer Join 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
  • 50. 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
  • 51. 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
  • 52. Authentication Métodos de login: tabela auth_user Google, PAM, LDAP, Facebook, LinkedIn, OpenID, OAuth, etc. terça-feira, 22 de novembro de 2011
  • 53. 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
  • 54. Forms FORM SQLFORM SQLFORM.factory CRUD terça-feira, 22 de novembro de 2011
  • 55. 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
  • 56. FORM Validaçã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
  • 57. 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
  • 59. CRUD from gluon.tools import Crud crud = Crud(db) 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 terça-feira, 22 de novembro de 2011
  • 60. Métodos CRUD crud.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
  • 61. 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
  • 62. 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
  • 63. 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
  • 64. 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
  • 65. 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
  • 66. 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
  • 67. Service Decorator terça-feira, 22 de novembro de 2011
  • 68. Do que não falamos URL Rewrite Central Authentication Service Roteamento de Erros jQuery e Ajax Tarefas em background Deploy em Servidores de Pyjamas Produção Blocks in Views Escalabidade Caching Google App Engine Exportação e Importação de Componentes e Plugins Dados terça-feira, 22 de novembro de 2011
  • 69. Referências Web2py: http://www.web2py.com web2py-users-brazil: https://groups.google.com/group/ web2py-users-brazil?hl=pt-BR The Official Web2py Book: http://www.web2py.com/book http://www.infoworld.com/d/application-development/ pillars-python-six-python-web-frameworks-compared-169442 terça-feira, 22 de novembro de 2011