HTTP
Se comunicando através da internet
19 de Setembro de 2014
Slide 2
Slide 2 text
Enviando e recebendo informações
Como que o caminhão do João vai enviar as
informações até ele?
?
Slide 3
Slide 3 text
No content
Slide 4
Slide 4 text
HTT-Quê?
Em 1989 Tim Bernes-Lee cientista da computação britânico,
trabalhando no CERN, fez uma proposta de software para
aumentar a eficácia das comunicações no laboratório e, que
poderia ser extendida ao mundo.
Slide 5
Slide 5 text
World Wide Web
HTT-Quê?
Clientes Servidores
http://www.ntu.edu.sg/home/ehchua/programming/webprogramming/HTTP_Basics.html
Slide 6
Slide 6 text
HTT-Quê?
Requisição
Resposta
www
Slide 7
Slide 7 text
HTT-Quem?
O seu navegador é responsável em transformar o
endereço que digitou, em uma requisição HTTP.
Slide 8
Slide 8 text
Uniform Resource Locator (URL)
http://www.google.com:80/search?q=breaking%20bad
● Protocolo
● Endereço
● Porta (opcional)
● Caminho para o arquivo / pasta
Parâmentro Query-string
Slide 9
Slide 9 text
No content
Slide 10
Slide 10 text
Formatação da URL
Caracteres ASCII:
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
a b c d e f g h i j k l m n o p q r s t u v w x y z
0 1 2 3 4 5 6 7 8 9 - _ . ~
Caracteres com significado especial:
! * ' ( ) ; : @ & = + $ , / ? % # [ ]
http://en.wikipedia.org/wiki/Percent-encoding
Requisição HTTP
É apenas um texto com um formato padrão:
● Uma ação / verbo
● Caminho do arquivo ou pasta solicitado
● O endereço do servidor
● Informações de cabeçalho
● Dados da requisição (ex: um formulário)
Slide 13
Slide 13 text
Requisição HTTP
GET /search/index.html HTTP/1.1
Host: www.google.com
Accept: image/gif, image/jpeg, */*
Accept-Language: en-us
Content-Type: application/x-www-form-urlenconde
Content-Length: 207
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0)
q=breaking%20bad
Requisição
Headers /
Cabeçalho
Linha em branco
Corpo (opicional)
Slide 14
Slide 14 text
Verbos HTTP
A mesma URL pode realizar ações diferentes:
● http://host.com/artigos
■ GET
■ POST
■ PUT
■ DELETE
Slide 15
Slide 15 text
Ações através dos verbos
● GET
● POST
● PUT
● DELETE
CRUD
Create - Read - Update - Delete
Outros verbos: HEAD, TRACE, OPTIONS, CONNECT
Slide 16
Slide 16 text
Resposta HTTP
● Código do status da requisição
● Tipo do conteúdo (imagem, html, vídeo)
● Cabeçalhos
● Conteúdo
Status da resposta
Headers /
Cabeçalho
Linha em branco
Corpo da resposta
Slide 18
Slide 18 text
No content
Slide 19
Slide 19 text
Status da resposta HTTP
● 1xx: Informação
● 2xx: Sucesso
● 3xx: Redirecionar
● 4xx: Erro no cliente
● 5xx: Erro no servidor
Slide 20
Slide 20 text
Status importantes
Código Descrição
200 OK
201 Criado
204 Modificado / Atualizado / Deletado
301 Movido a outro endereço
401 Não autorizado
403 Não permitido
404 Não encontrado
500 Erro interno do servidor
http://en.wikipedia.org/wiki/List_of_HTTP_status_codes
Slide 21
Slide 21 text
Tipos de conteúdo
● HTML text/html
● Imagem image/gif, image/jpeg
● Vídeo video/mp4
● JSON application/json
Slide 22
Slide 22 text
JSON
Padrão de formatação de texto para transmitir
informações entre duas
aplicações/computadores de forma eficiente.
Todas as linguagens de programação já tem
suporte ao formato, que se tornou *padrão.
Slide 23
Slide 23 text
JSON
Imagine uma tabela de banco de dados:
Carro Hora Temperatura Coordenadas
EFG-9809 2014/08/03 15:01:32 3ºC 51° 28' 38"
ABC-5432 2014/06/30 12:34:56 4ºC 23° 42' 23"
GTD-1357 2014/07/25 54:32:10 3ºC 56° 43' 83"
FRA-7532 2014/08/01 01:23:45 2ºC 12° 28' 78"
ZOO-6853 2014/07/31 32:54:21 5ºC 90° 23' 38"
Um serviço web capaz de criar, ler, atualizar e
deletar as informações dos caminhões.
Construindo uma API
API
HTTP HTTP
Slide 28
Slide 28 text
Construindo uma API
Uma API é um software que define um padrão de
comunicação criando uma interface comum onde
qualquer dispositivo pode cosumir suas
informações.
Slide 29
Slide 29 text
Servidores HTTP
São programas de computador especializados em
receber e requisições no formato HTTP, realizar
alguma ação e fornecer uma resposta a eles.
Slide 30
Slide 30 text
Quem usa Python?
Slide 31
Slide 31 text
Frameworks são bibliotecas de código que visam
adicionar uma funcionalidade genérica, de uma forma
consitente, para simplificar a construção de uma
ferramentas mais específicas, de maneira rapida e
fácil.
Frameworks HTTP
No seu computador crie um diretório vazio e o
arquivo servidor.py.
imt-webapp/
| models.py
| servidor.py
Estrutura
Slide 34
Slide 34 text
Gerando uma resposta
import webapp2
class HelloWorld(webapp2.RequestHandler):
def get(self):
self.response.write('Ola Mundo!')
# Nao utilizar acentos!
servidor.py
Slide 35
Slide 35 text
Rotas
As rotas é um processo de pegar uma URL e
decidir qual aplicação vai ser executada. Eles tem
o papel de mapear o endereço com a função.
GET /endereco
class Hello(Request):
def get(self):
# Executa ação!
Lendo as informações enviadas
# GET /url?id=1234&log=true
class UrlHandler(webapp2.RequestHandler):
def get(self):
self.request.params.get('id') # => 1234
self.request.params.get('log') # => 'true'
self.request.params.get('foo') # => None
self.request.params.get('foo', 'bar') # => 'bar'
Slide 43
Slide 43 text
Método Dispatch
Função que é executada toda vez que uma requisição é
iniciada, é boa para iniciar a conexão com o banco de dados
por exemplo.
import sqlite3
class UrlHandler(webapp2.RequestHandler):
def dispatch(self):
self.dbconn = sqlite3.connect('db.sqlite3')
Estrutura de Dados
devices
id PRIMARY KEY
nome TEXT
obs TEXT
medidas
id PRIMARY KEY
device_id FOREIGN KEY
recebido_em DATETIME
temperatura INT
humidade INT
lat INT
lng INT
Slide 46
Slide 46 text
Modelos do Banco de dados
Caso vocês não possuam o arquivo de modelos
models.py, que pega as informações do banco
de dados e as retorna tratadas, baixe o kit:
http://bit.ly/imt-backend
Slide 47
Slide 47 text
Modelo de dados
import models
# Dispositivos
models.Devices.get_all() # Retorna todos os dispositivos
models.Devices.get_by_id(XXX) # Retorna o dispositivo com ID
models.Devices.get_by(id=XXX, foo='a') # Retorna o dispositivo com o parametro
models.Devices.count() # Retorna a quantidade de dispositivos
# Medidas
models.Medidas.get_all() # SELECT * FROM medidas
models.Medidas.get_by_id(XXX) # ... WHERE id=XXX
models.Medidas.get_by(abc=XXX, foo='a') # ... WHERE abc=XXX AND foo='a'
models.Medidas.count()
Slide 48
Slide 48 text
Modelo de dados
# Cria um novo device mas não salva no banco de dados
d = models.Devices(nome='ABC', obs=123)
print d["nome"] # => ABC
print d["obs"] # => 123
d.save() # Executa o INSERT no banco de dados
print d["id"] # => X (o ID do item após ser inserido no banco)
d.delete()
Slide 49
Slide 49 text
Modelo de dados
# Retorna o dispositivo com o ID = 123
d = models.Devices.get_by_id(123)
print d["nome"] # Exibe o nome salvo no banco
d["nome"] = "Foo Bar" # Altera o nome
d.save() # Realiza o UPDATE
Slide 50
Slide 50 text
Criando a base de dados e adicionando alguns
dados fictícios:
Estrutura de dados
$ python migrate.py
___ ___ __ ____ _ ____ ___ __ _____ ___ ___
| |_) | | \ / /`_ | |_ | |\ | | |_ | |_) / /\ | | / / \ | |_)
|_|_) |_|_/ \_\_/ |_|__ |_| \| |_|__ |_| \ /_/--\ |_| \_\_/ |_| \
________________________________________________________________________
Slide 51
Slide 51 text
Planejando URLs
/api/devices
/api/devices/ID
– Dispositivos
– Medidas do dispositivo
Slide 52
Slide 52 text
Devices
Verbo URL Parâmetros
GET /api/devices
POST /api/devices
PUT /api/devices {'id': N}
DELETE /api/devices {'id': N}
POST /api/devices
def post(self):
'Cria um novo device, parametros: nome, obs'
device = models.Device(
nome=self.request.params.get('nome'),
obs=self.request.params.get('obs')
)
device.save()
self.response.content_type = 201 # Criado com sucesso
api.py
Slide 59
Slide 59 text
PUT /api/devices
def put(self):
'Atualiza um device, parametros: id, nome, obs'
device = models.Device.get_by_id(
self.request.params.get('id')
)
if not device:
self.abort(404)
device['nome'] = self.request.params.get('nome') # device.nome = ...
device['obs'] = self.request.params.get('obs') # device.obs = ...
device.save()
self.response.content_type = 204 # Atualizado com sucesso
api.py
Slide 60
Slide 60 text
DELETE /api/devices
def delete(self):
'Deleta um device, parametros: id'
device = models.Device.get_by_id(
self.request.params.get('id')
)
if not device:
self.abort(404)
device.delete()
self.response.content_type = 204 # Deletado com sucesso
api.py
Slide 61
Slide 61 text
Medidas do Device
Verbo URL Parâmetros
GET /api/devices/(.+) {'device_id': N}
POST /api/devices/(.+) {'device_id': N}
Slide 62
Slide 62 text
Rota
GET /api/devices/(.+) def get(self, device_id=None):
Controlador de Medidas
# ...
class MedidasDeviceHandler(webapp2.RequestHandler):
def get(self, device_id=None):
pass
def post(self, device_id=None):
pass
api.py
Slide 65
Slide 65 text
GET /api/device/N
def get(self, device_id):
'Retorna um device com todas as medidas coletadas'
device = models.Devices.get_by_id(device_id)
if not device:
self.abort(404)
device['medidas'] = device.medidas()
self.response.content_type = 'application/json'
self.response.write(json.dumps(device))
api.py
POST /api/device/N
def post(self, device_id):
'Cria uma nova medida para um device'
device = models.Devices.get_by_id(device_id)
if not device: self.abort(404)
medida = models.Medidas(
device_id=device_id,
temperatura=self.request.params.get('temperatura'),
humidade=self.request.params.get('humidade'),
lat=self.request.params.get('lat'),
lng=self.request.params.get('lng')
)
medida.save()
self.response.status = 204
Slide 68
Slide 68 text
Alerta de temperatura
Caso a temperatura ultrapasse 5ºC devemos
enviar um email de alerta para que seja tomada as
providencias.
Em qual momento recolhemos a temperatura?
Slide 69
Slide 69 text
import smtplib
from email.mime.test import MIMEText
# ...
def post(self, device_id):
# ...
if not medida.temperatura >= 5:
msg = MIMEText('''
Atencao!
O dispositivo #{device_id} esta com a temperatura de {temperatura}C.
'''.format(**medida))
msg['Subject'] = 'Temperatura alta!'
s = smtplib.SMTP('smtp.gmail.com:587')
s.starttls()
s.login('username', '*****')
s.sendmail('', '', msg.as_string())
s.quit()
https://docs.python.org/2/library/email-examples.html