Aplicação web em Python e Bottle – parte 3

bottle-3_abertura

Na primeira parte o Bottle foi instalado e configurado, na segunda foi incluída alteração modificar do estado do led — conectado na porta GPIO — do Edison diretamente pelo protocolo HTTP e, nesta última parte, será adicionada tanto a leitura do estado do led (algo importante) como também a interface web com o usuário (algo mais importante ainda) e que completa a aplicação.

Mas antes um pequeno problema a ser resolvido…

De volta ao Python 2.x

A instalação do Yocto Poky, que é a distribuição Linux que é instalada no Edison¹, tem apenas a versão 2.7 do Python instalada por padrão. A versão 3.x até pode ser instalada via opkg mas ela não parece estar completa, então…

…o jeito é adaptar o programa para a versão 2.7 da linguagem — o que felizmente significou mudar a referência de “3” para “2” no começo dos dois programas e incluir um arquivo”__init__.py” vazio dentro do diretório do módulo que criei.

Esta “surpresa” aconteceu pois dividi o desenvolvimento da parte web, que foi local, da parte específica da GPIO, que foi diretamente no Edison via SSH.

(¹) É possível trocá-la, por exemplo, pela Ubilinux que é baseada em Debian. Aliás, em algum momento eu disse que o Edison tem um processador Atom, ou seja, a “boa e velha” arquitetura de 32-bit da Intel? 🙂

(re)Definindo a API

Inicialmente deixei o programa funcionando as URL “…/led/0” e “…/led/1” para respectivamente apagar e acender o led mas que tal fazer algo mais próximo daquilo que a RESTful (ou apenas REST) API especifica?

No caso da RESTe aí simplificando o máximo possível para que caiba em um parágrafo — é a implementação de um CRUD é feita a partir de uma abstração que utiliza os comandos do próprio protocolo HTTP. Assim o comando POST é usado para criar um novo objeto, o GET para recuperar um ou mais objetos, o PUT para atualizar um objeto já existente e o DELETE para removê-lo.

Considerando que POST e DELETE não se aplicam neste exemplo² implementarei apenas os métodos GET e PUT para, respectivamente, recuperar e alterar o status do(s) led(s) do Edison e que correspondem a dois casos distintos:

    • /led/«led» — Retorna o status do led indicado em «led».
    • /led/«led»/«valor» — Altera o status do led indicado em «led» para «valor».

Ué? Podem parecer iguais mas o primeiro usa o método GET enquanto que o último utiliza o PUT — o protocolo HTTP saberá diferenciá-los.

No código em Python fica assim:

@get('/led/')
def get_once(led):
    ...
@put('/led//')
def set_value(led,value):
    ...

Os parâmetros entre os “” indicam o valor que servirá de parâmetro de entrada nas funções que se seguem.

(²) Já que não tenho como inserir ou remover fisicamente  leds no sistema. 🙂

A parte em HTML

bottle-3_interface-web

Um pacote “padrão” contendo uma única página web que usa Boostrap CSS, jQuery e um pouco de Javascript para dar funcionalidade. Acabei fazendo especificamente pensando em dispositivos móveis, daí o jeitão curiosamente esticado da página. A novidade está na separação dos elementos do HTML em arquivos de template do Bottle — os arquivos de extensão “tpl” dentro do diretório “./template/” — para facilitar a manutenção.

Por exemplo, o arquivo “index.tpl” ficou assim:

%include('template/header.tpl', title='')
    ...
        %include('template/title.tpl')
    ... 
%include('template/footer.tpl',js='index.js')

Os “%include()” servem para adicionar um arquivo externo dentro dele e até permitem a passagem de parâmetros para eles também é possível embutir código em Python dentro deles mas acabei não utilizando pois ficou tudo com o Javascript.

O jQuery é usado para alterar os elementos da página, assim como para se comunicar (via AJAX) com o servidor web rodando no Edison. Por fim o método setInterval() do JavaScript me permite definir uma função para executar a cada intervalo de tempo e que utilizo para monitorar o estado do led — aqui está tudo dentro do arquivo “./static/index.js”.

Instalação e uso

Todo o código foi colocado em um repositório no GitLab GitHub*. Daí

# git clone https://github.com/plainspooky/led_blink.git
...
# cd led_blink
# pip install -r requirements.txt
...
# ./server.py

Basta acessar «IP do Edison»:8080 no navegador web para controlar o led. 🙂

(*) Pois é, mudança de última hora.

Testando 1,2,3

Para facilitar resolvi gravar um vídeo para demonstrar o programa em execução, creio que tenha ficado autoexplicativo.

Considerações finais

Antes de terminar… Por que não fiz uma aplicação padrão com formulários, inserção em banco de dados etc?

  1. Sendo o Bottle um framework simples ele não implementa vários recursos como objetos de acesso a bases de dados, renderização de formulários etc, daí tudo precisaria ser criado³ e tornaria um exemplo de aplicação nele algo comprido, além de chato, e
  2. Para fazer um programa como o criado no exemplo em Rails eu usaria o Django que foi feito para isto!

Fora que brincar com a GPIO do Edison foi bem mais divertido. Aliás este exemplo deve funcionar em um Raspberry Pi, bastando conectar um led na GPIO dele — no caso dos primeiros modelos, que não tem porta 13, será preciso alterar no arquivo “./api/v1.py” — e rodar o programa.

Ah sim, deixei pré-pronto o suporte a bem mais de um led ou qualquer outra coisa que possa pendurar através da GPIO.

(³) Ou importados de módulos já existentes que funcionam em conjunto com o Bottle.

Anúncios

2 comentários sobre “Aplicação web em Python e Bottle – parte 3

  1. Pingback: Testando RPi1/2/3 em um Power Bank | giovannireisnunes

  2. Pingback: REST em Python com Bottle – parte 1 | giovannireisnunes

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s