Slide 1

Slide 1 text

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

Slide 11

Slide 11 text

URLs http://localhost:8080 http://127.0.0.1:8080 https://facebook.com/zuck http://google.com/search?q=chrome mailto:[email protected] ftp://www.ftp.org/docs/test.txt

Slide 12

Slide 12 text

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

Slide 17

Slide 17 text

Resposta HTTP HTTP/1.1 200 Date: Sun, 18 Oct 2013 08:56:53 GMT Server: Apache/2.2.14 (Win32) Last-Modified: Sat, 20 Nov 2012 07:16:26 GMT Content-Length: 44 Content-type: text/html

Olá Mundo!

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"

Slide 24

Slide 24 text

JSON [ { "Carro": "EFG-9809", "Hora": "2014/08/03 15:01:32", "Temperatura": 3, "Coordenadas": {lat: 1.234, lng: -3.456} }, { ... }, { ... }, ... ]

Slide 25

Slide 25 text

Facebook App: Informação do banco de dados trafegando em JSON através do protocolo HTTP.

Slide 26

Slide 26 text

Recapitulando ● URL: http://localhost/caminho/do/arquivo ● Verbos: GET, POST, PUT, DELETE ● Status: 200, 404, 500 ● Tipos de conteúdo: HTML, JSON

Slide 27

Slide 27 text

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

Slide 32

Slide 32 text

Instalação $ pip install webob $ pip install paste $ pip install webapp2

Slide 33

Slide 33 text

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!

Slide 36

Slide 36 text

Rotas routes = [ ('/', HelloWorld), ] app = webapp2.WSGIApplication(routes, debug=True) servidor.py

Slide 37

Slide 37 text

Testando o servidor if __name__ == '__main__': from paste import httpserver httpserver.serve(app) servidor.py

Slide 38

Slide 38 text

import webapp2 class HelloWorld(webapp2.RequestHandler): def get(self): self.response.write('Ola Mundo!') routes = [ ('/', HelloWorld), ] app = webapp2.WSGIApplication(routes, debug=True) if __name__ == '__main__': from paste import httpserver httpserver.serve(app) servidor.py

Slide 39

Slide 39 text

Run baby run! $ python servidor.py serving on http://127.0.0.1:8080

Slide 40

Slide 40 text

Para parar aperte as teclas Ctrl + C e espere. A cada alteração dos arquivos do servidor você deve reinicia-lo. Stop!

Slide 41

Slide 41 text

class UrlHandler(webapp2.RequestHandler): def get(self): # Requisição self.request.method # GET self.request.url # http://localhost:8080/my-path?q=1 self.request.path # /my-path self.request.headers # [ … ] self.request.params # {'q': 1} # Resposta self.response.status = 200 # Padrão self.response.content_type = 'text/html' # Padrão self.response.redirect('http://www.google.com/') self.response.write('OK')

Slide 42

Slide 42 text

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')

Slide 44

Slide 44 text

Objetivos ● Gerenciar dispositivos ■ Listar ■ Criar ■ Atualizar ■ Deletar ● Gerencia medidas dos dispositivos ■ Listar ■ Criar

Slide 45

Slide 45 text

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}

Slide 53

Slide 53 text

Crie o arquivo api.py. imt-webapp/ | api.py | models.py | servidor.py Estrutura

Slide 54

Slide 54 text

Controlador de Devices import webapp2 import json import models class DevicesHandler(webapp2.RequestHandler): def get(self): pass def post(self): pass def put(self): pass def delete(self): pass api.py

Slide 55

Slide 55 text

from api import DevicesHandler # ... routes = [ # ..., ('/api/devices', DevicesHandler), ] Rota servidor.py

Slide 56

Slide 56 text

GET /api/devices def get(self): 'Retorna todos os devices registrados' devices = models.Devices.get_all() self.response.content_type = 'application/json' self.response.write( json.dumps(devices) # Converte para o formato JSON (devices.to_dict) ) api.py

Slide 57

Slide 57 text

Resposta [ { "id": 1, "nome": "DEF-1234", "obs": "DEF-1234", } ] [{"id": 1,"nome": "DEF-1234","obs": ""}] application/json

Slide 58

Slide 58 text

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):

Slide 63

Slide 63 text

Rota routes = [ # ..., ('/api/devices/(.+)', MedidasDeviceHandler), ] servidor.py

Slide 64

Slide 64 text

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

Slide 66

Slide 66 text

Resposta { "id": 1, "nome": "DEF-1234", "obs": "DEF-1234", "medidas": [ { "id": 3, "recebido_em": "2014-09-14 21:22:07", "temperatura": 2.19, "humidade": 0.2, "lat": -23.648241, "lng": -46.573678 }, ... ] } application/json

Slide 67

Slide 67 text

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

Slide 70

Slide 70 text

Parabéns hipster!

Slide 71

Slide 71 text

Próxima aula HTML & CSS