Prévia do material em texto
{REST} API COM FLASK GUIA DE DESENVOLVIMENTO WEB L I V R O I I A N D R Á S H A R T M A N N P A T A K I R E Q U E S T S Este livro é o segundo material da série Desenvolvimento Web com Flask, da qual daremos continuidade aos estudos propostos anteriormente, fazendo uso da Biblioteca Requests para a Linguagem Python; Caso não tenha adquirido o Livro I, sugiro que o tenha, uma vez que é necessário possuir as configurações apresentadas previamente, para possibilitar o desenvolvimento das atividades seguintes. Aprendemos no último Livro, como baixar e instalar a linguagem Python em dois sistemas operacionais distintos (Windows e Linux), também criamos um ambiente virtual para trabalhar em nosso projeto Flask, que será desenvolvido ao longo da série. No Segundo Capítulo, entramos no escopo do funcionamento do protocolo HTTP, mais especificamente na base da arquitetura REST, onde em correlato, aprendemos sobre a diferença de um Web-Service tradicional e uma API. Agora, você deve estar pronto para embarcar no Universo das Requisições Http, e para isso, faremos uso da biblioteca Requests, indicada pela sua facilidade de uso; A mesma também oferece uma grande quantidade de recursos, e por isso, eu pessoalmente acredito que este livro se torne o mais importante da série. Sobre este Guia Foco do Material Introdução.................................................................4 Instalando Requests...............................................4 GET...............................................................................5 Passando Parâmetros na Requisição..................8 POST...........................................................................10 Submissão de Arquivos.......................................................................11 PUT................................................................................13 DELETE.........................................................................15 Conclusão....................................................................16 Autenticação-Básica..................................................16 INDEX Facilite suas consultas no livro acessando este indíce. Requests é uma biblioteca HTTP para o Python desenvolvida por Kenneth Reitz. O objetivo é facilitar a a programação das requisições, tornando-a mais simples e legivel para Humanos, por isso a construção do Slogan. A filosofia da extensão foi pensada sobre alguns conceitos do PEP20, conhecido também como o Código Zen do Python, que em sumo é uma coleção de 19 princípios orientadores para programar de forma "certa". Veja abaixo alguns exemplos: Bonito é melhor que feio Explicito é melhor que implícito Simples é melhor que complexo Complexo é melhor que complicado Legibilidade Conta. Capítulo I - Requests, Http para Humanos Sem querer entrar em muitos detalhes, acho válido que todo programador Python conhecesse melhor a cultura da própria Linguagem, por isso, sugiro posteriormente a leitura do PEP8. Prepare-se! pois dessa parte em diante, o livro será exclusivamente focado na prática, portanto esteja pronto para codar. Primeiramente devemos acessar a pasta my_first_api, que foi criada no primeiro material; Ative o ambiente virtual com o comando nativo do seu sistema. Instalando Requests O Console do Python vai nos permitir criar códigos imperativos, ou seja, vão executar automaticamente assim que digitados, afim de testarmos nossas primeiras requisições; Lembre-se que esse modo não é recomendado para desenvolvimento de scripts. Com o Requests instalado e o console aberto, faremos uma requisição do tipo GET para o servidor httpbin.org, o mesmo vai nos fornecer algumas rotas exclusiva para testes. Antes de começarmos, importe o módulo requests dessa forma: Certifique-se que seu Terminal/Prompt esteja parecido com isso: (venv) C:\Users\andras\Documents\my_first_api> Com tudo funcionando bem, instale a biblioteca Requests através desse argumento: (venv) C:\Users\andras\Documents\my_first_api> pip install requests Ao finalizar, ainda na janela do seu Terminal, digite o comando abaixo para entrarmos no console interativo do Python: (venv) C:\Users\andras\Documents\my_first_api> python >>import requests Primeiro GET No término do código, lembre-se de apertar o "Enter", assim o console irá verificar se a biblioteca foi instalada, caso sucesso, nenhuma mensagem deve aparecer. Na linha debaixo iniciaremos a requisição com esse argumento: >>requests.get('https://httpbin.org/get') Lembre-se de copiar corretamente a URL, uma vez que ela é crucial para que tudo de certo. Ao executar esse código, você deverá ver uma mensagem escrito: <Response [200]> Recordando ao Livro I, sabemos que o código de resposta 200 indica que a requisição foi feita com sucesso, pode comemorar! Porém apenas com o código que fizemos, fica complicado acessar ao corpo de resposta, uma vez que o resultado da requisição não esta guardada em uma variável, portanto devemos reescrever a nossa linha.Mas calma! não precisa digitar tudo denovo, você pode apertar a seta para cima do teclado para ativar o histórico. Tente deixar seu código assim: Não se desespere caso não tenha acontecido nada, é assim mesmo. >>r=requests.get('https://httpbin.org/get' ) Com a resposta alocada em uma variável, podemos passar alguns argumentos interessantes. Vamos primeiramente, visualizar o conteúdo através desse argumento: >>r.content Talvez você tenha ficado assustado com a quantidade de caracteres que apareceu no seu console, mas fique tranquilo, pois esse argumento serve justamente para entregar TUDO que tiver presente na resposta. Agora, transformaremos essa informação em um JSON, digite: >>r.json() Perceba que o conteúdo sofreu uma leve alteração, ficando bem idêntico ao exemplo apresentando no primeiro material. Lembre-se de memorizar bem o comando acima, pois através dele, é possível serializar muitas respostas em objetos JSON. Se quisessemos capturar apenas o texto do body, poderiamos fazer isso através desse comando: >>r.text O Exemplo acima funcionaria melhor, caso a requisição fosse para um site que devolvesse um corpo de resposta mais longo. Por fim, podemos ainda testar mais dois argumentos básicos, tente eles em sequência: >>r.url >>r.elapsed O Primeiro deverá retornar a URL que estamos nos conectando: https://httpbin.org/get ; O próximo mostrará em aproximação, o tempo que a requisição levou para ser completada, cujo formato é entregue em microssegundos. Existem outros recursos que poderíamos estar escrevendo, mas temos outros métodos ainda para testar. Tem momentos que se faz necessário passar parâmetros pela URL, pois estes vão atuar como filtros no banco de dados da aplicação. Como estudado no Livro I, as Query-Strings (assim chamados estes parâmetros) devem ser construidas no endereço de busca após um "?". O que torna essa tarefa um pouco chata, é justamente a digitação individual de cada letra,isto é, tomando o devido cuidado de não cometer nenhum erro. No entanto, através da biblioteca requests , podemos fazer isso de modo mais fácil, digite os seguintes códigos: Chamamos de Payload, todo o tipo de carga de dados enviados durante uma requisição HTTP; Normalmente, o mesmo é descartado após ser entregue a aplicação, uma vez que não tem mais utilidade posterior. Passagem de Parâmetros >>payload = {"chave_1":"valor_1"} >>r = requests.get('https://httpbin.org/get', params=payload) >>r.url Retornando ao código, perceba que na primeira linha, criamos um dicionário Python (não confunda com Json) que vai armazenar uma chave e um valor qualquer, apenas para concatenar na URL; Em seguida, reescrevemos nossa mesma requisição, só que dessa vez, passamos o payload como parâmetro(params); O resultado dessa experiência, deverá parecer com algo assim: >>'https://httpbin.org/get?chave_1=valor_1' Dessa forma, podemos acrescentar novos argumentos pela Url, podendo ser até outros tipos de dados, tais como listas ou vetores,veja um exemplo: No entanto, lembre-sede que todos os dados estejam contidos dentro de um dicionário Python. Como atividade extra, eu sugiro você testar as seguintes requisições: >>payload = {"key_1":["value_1", "value_2"]} >>r=requests.get('https://jsonplaceholder. typicode.com',params=payload) >>payload = {"id": [1,2,3]} Quando o valor das chaves for números, não é necessário o uso das aspas. No teste acima, tente verificar a resposta usando r.content, ou demais métodos já explicados. Uma requisição do tipo POST, leva o segundo método HTTP mais usado no mundo, pois ele é quem permite a submissão de dados para o servidor. Não existem limites quanto ao formato da informação, podendo ser um simples texto até uma imagem fullhd. Como já brincamos o suficiente com o GET, já estamos mais do que prontos para iniciar as primeiras requisições de Postagens. Preste atenção no código a seguir atentando-se as mudanças: Esse código possuí duas principais mudanças significativas. Primeiro que após a palavra requests, colocamos o argumento post, que serve para indicar o método passado; Em seguida, inicializamos um objeto chamado data, e assim como o params, vai carregar as informações que queremos que sejam armazenadas no servidor, que no caso é um nome. Lembre-se que é possível passar mais de um objeto pela URL. Verifique a resposta da sua requisição com o seguinte comando: Primeiro POST >>r=requests.post('https://httpbin.org/pos t', data= {"nome":"seu_nome"}) >>r.text Procure pelo nome que você escreveu, talvez você o encontre dessa forma: >>"form": {"nome": "seu_nome"} Quando inicializamos o objeto data dentro do argumento da requisição, significa que o formato dos dados serão entregues no tipo form-data, que é o mais usual em aplicações Web. No caso das APIs, o conteúdo é enviado em JSON, que como explicado anteriormente, possui um peso mais leve na transmissão. Altere o exemplo acima para código abaixo: Um recurso não muito explicado, mas que é muito importante dependendo do contexto da aplicação, é a submissão de arquivos estáticos para o servidor, tais como documentos de texto (txt, pdf, docx...) ou até mesmo imagens(png, jpeg,svg...). É possivel colocar as informações de submissão externamente a requisição, assim como fizemos nos exemplos anteriores, veja: >>payload = {"nome": "seu_nome","idade": "sua_idade"} >>r=requests.post('https://httpbin.org/pos t', data=payload) >>r=requests.post('https://httpbin.org/pos t',json=payload) Inspecione a resposta e perceba as modificações, recomendo que use o r.json() para isso. Submissão de Arquivos Parece ser um pouco complicado programar algo do tipo, mas graças a biblioteca requests, metade do sofrimento já foi descartado;Portanto, peço de antemão, que crie um arquivo txt dentro do diretório que estamos trabalhando(my_first_api), lembre-se de preenche-lo com alguma informação qualquer, e em sequência, nomeá-lo como: teste.txt Feito isso, escreva os seguintes argumentos: >>url = 'https://httpbin.org/post' >>arquivo = {'file':open('teste.txt','rb')} >>r = requests.post(url,files=arquivos) >>r.text *Para usuários do Windows, é necessário alterar a segunda linha do código para essa forma: >>arquivo= {'file':open('teste.txt.txt','rb')} Em uma breve explicação, criamos um arquivo txt qualquer, e o alocamos dentro de uma variável chamada arquivo, que é um dicionário em Python; Para que o teste.txt seja aberto, incluímos o método open() como valor da chave 'file', e usamos a sigla rb para indicar o nível da permissão (read-binary). Tudo isso foi possível, através do argumento files que foi passado como parâmetro durante a requisição. Você poderá ver o resultado do teste no seu console, tente encontrar o texto que você digitou. Tendo explorado alguns recursos do método POST, estamos aptos para se divertir com o próximo da lista. O PUT é o mais discreto dos métodos, pois serve para atualizar alguma informação existente no servidor, geralmente cadastrada pelo próprio usuário; Um exemplo comum do uso do PUT, é quando postamos uma mensagem com alguns erros ortográficos, onde infelizmente só os percebemos mais tarde; Para corrigi-los, iniciamos uma requisição através do PUT, devendo referenciar o objeto a ser atualizado. Quando se menciona a palavra "referenciar", é levado em conta que a postagem possua um identificador próprio, conhecido na programação como ID, pois através dele, o servidor pode encontrar a informação e aplicar as devidas atualizações. Recordando ao primeiro Capítulo deste material, mais precisamente na passagem de parâmetros através do GET, criamos uma Query-String que era passada como argumento na URL; Com o PUT, faremos algo de forma similar, no entanto estaremos passando dados como no POST. Primeiramente, vamos visualizar como se encontra a Postagem antes de qualquer modificação: >>r=requests.get('https://jsonplaceholder. typicode.com/posts/1') Primeiro PUT >>r.json Dentro do Payload que nós criamos, apontamos que a modificação só vai ocorrer para o valor da chave "title"; Caso você queira atualizar mais objetos, é só acrescenta-los ao corpo do payload. Sem a necessidade de criar uma Query-String para identificar a postagem, a arquitetura do servidor permite que simplesmente coloquemos o /posts/1 no final da url para buscar o Post escolhido. Caso você tenha reexecutado o GET,para a mesma URL, é bem provável que a atualização não esteja presente, isso acontece devido a segurança do servidor, que restringe a aplicação permanente dos métodos. >>r=requests.put('https://jsonplaceholder. typicode.com/posts/1', json=payload) >>payload = {"title": "Python é melhor"} >>r.json() O corpo de resposta deverá se assemelhar com algo assim: >>{'userId': 1, 'id': 1, 'title': 'sunt aut facere repellat provident occaecati excepturi optio reprehenderit', 'body': 'quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto'} Tente encontrar a chave "title", pois iremos modificar o valor da mesma, através desse argumento: Acalme-se! nossa viagem não esta chegando ao fim, deixei uma surpresinha para o final desse livro. Com os três principais métodos testados anteriormente(GET,POST & PUT), chegou a hora de executar a mais "perigosa" das requisições, o DELETE! Como o próprio nome sugere, esse método indica para o servidor, que alguma informação deverá ser removida, tal como um arquivo, uma imagem ou até mesmo algum registro no banco de dados. No entanto, não é necessário levar o método Delete ao pé da letra, uma vez que muitos Web- Service (Inclusive os meus), usam esse método em diversas operações que não necessariamente resultem, na exclusão de alguma coisa; Tal como realizar o Logout de algum usuário, retirar algum item do carrinho de compras...etc. Em analogia ao PUT, o delete geralmente deve referenciar o objeto que vai ser removido do servidor. Tente o código abaixo: Como resultado, nosso Console deverá mostrar um Json vazio, sem quaisquer dados; Isso indica que a nossa requisição apagou com sucesso a postagem. Lembre-se que cada servidor poderá dar um retorno personalizado a essa requisição, como este abaixo: >>r=requests.delete('https://jsonplacehold er.typicode.com/posts/1') >>r.json() Primeiro DELETE >>'https://httpbin.org/delete' Nesse livro, aprendemos a realizar os 4 principais métodos do Protocolo HTTP utilizando a extensão Requests. Primeiramente, ativamos nosso ambiente virtual configurado no Livro I dessa série, e em sequência, baixamos e instalamos a biblioteca, para em seguida, abrirmos o console interativo do Python. Com o Terminal aberto, fomos capazes de programar nossos próprios códigos e se conectar com dois servidores distintos (httpbin & jsonplaceholder) para realizar os testes;Dentre os métodos testados, averiguamos e entramos no escopo de cada resposta, utilizando os comandos: r.text, r.content, r,json(). Lembre-se que este Livro não substitui a documentação oficial do Requests, portanto caso deseje conhecer novosrecursos, fique a vontade para explorar o seguinte endereço: https://requests.readthedocs.io/en/master/ Como eu havia mencionado anteriormente, deixaria uma surpresa para o final desse livro, e agora como um bonús, vou ensinar você a como se conectar em um servidor que usa HTTP-BasicAuth para proteção das rotas; Geralmente esse recurso é usado quando a aplicação usa as credenciais do usuário para acessar um serviço especifico, tais como realizar pagamentos, cadastro de produtos...etc Conclusão Autenticação-Básica O HttpBasicAuth é só mais um dos diversos modos de autenticação disponiveis, dentre eles nós temos: -> Bearer Token ->Digest Auth -> API Key ->OAuth ... Os 4 acima listados são os mais comuns usados pela World-Wide-Web. Eu sugiro que você consulte algum material externo para estuda-los mais afundo. Agora, vamos realizar nosso teste, primeiro é necessário fazer uma nova importação, digite o código abaixo: Como a biblioteca requests vem ganhando constantes atualizações, muitas delas ainda não estão incluídas no pacote oficial, por isso é necessário fazer uma nova importação e especificar o recurso a ser usado. No código acima, estamos iniciando uma requisição do tipo GET, e chamando o parâmetro auth, que será responsavel por enviar as credenciais fornecidas ('user', 'pass'), e se estas forem aceitas pelo servidor, vão validar nosso acesso. O exemplo acima foi feito para não funcionar, uma vez que não temos credenciais de uma conta real para se conectar com o github. >>import requests >>from requests.auth import HTTPBasicAuth >>r=requests.get('https://api.github.com/u ser', auth=('user', 'pass')) >>r.status_code Você pode usar serviços externos para simular uma autenticação real e até a criação de Urls para passagem de métodos... Uma opção para fazer isso, seria criando seu próprio Web-server com Flask e dispachando suas próprias rotas. Levando em consideração que você já chegou até aqui, então estará pronto para o Livro III, que tratará exclusivamente do nosso querido microframework, portanto te espero lá! Até Mais! Em caso de dúvidas, mande um email para min: andras.h.pataki@gmail.com Aguardo seu contato! Te vejo no próximo livro!