E
Web app para armazenamento e vizualização de dados do projeto EMM (Estações Meteorológicas Modulares). – README.md

README.md

emm-webapp

Aplicação web dedicada ao armazenamento de dados meteorológicos do projeto Estações Meteorológicas Modulares (EMM).

Atualmente publicada em:

API

A webapp oferece uma RESTful API para envio e acesso aos dados armazenados. Funciona assim: envia-se uma requisição HTTP contendo um objeto JSON (header content-type: application/json) para a URL; a webapp responde com outro objeto JSON.

Note: Objetos JSON são análogos (em geral) aos dicionários de Python.

  • No advento de erros, o seguinte JSON será retornado:
    • {"Error": message}

/get/boardhash (POST)

Permite ao usuário obter a hash de autenticação da sua própria estação. Esta hash (string de 128 caracteres) deve ser utilizada para autenticar o envio de dados pela API.

  • ENTRADA:

    {
      "board_id": int,
      "user_password": str
    }
    
  • SAÍDA:

    {
      "board_hash": str
    }
    

/post/rawsensordata (POST)

Permite ao usuário enviar dados para sua estação.

Naturalmente, a tarefa pode ser automatizada por um data logger, tal como emm-logger.

  • ENTRADA:

    {
      "board_hash": str,               # hash de autenticação de usuário
      "data":                          # dados a serem guardados
       [
            {
                "datetime":            # chave primária da tabela
                {
                    "value": str,      # ex: 2016-08-10-17-20-00
                    "format": str,     # ex: %Y-%m-%d-%H-%M-%S
                    "source": str      # ex: "RTC", "WEB", "SYS"
                },
                "sensors":             # N sensores lidos
                {
                    "name1": number, "name2": number, ..., "nameN": number
                }
            }
       ]
    }
    
  • SAÍDA:

    {
      "success": "{N} new points were saved on the board."
    }
    

/get/csv/rawsensordata/

Permite a qualquer pessoa obter os dados da estação identificada por <int:board_id>.

  • Retorna um arquivo .csv contendo TODOS os dados da estação, no formato: DATETIME,sensor1,sensor2,...,sensorN

Esta é uma requisição GET simples (não requer JSON) e pode ser feita em um web browser quaquer.

Utilizando a API RESTful

Há duas opções básicas para interagir com a API:

  • Curl

    $ curl -i -H 'content-type: application/json' -X POST 
           -d  '{"board_id": 3,"user_password": "1234"}' 
           http://dados.cta.if.ufrgs.br/emm/api/get/boardhash
    
    HTTP/1.1 200 OK
    Server: nginx/1.6.2
    Date: Thu, 25 Jun 2011 21:45:12 GMT
    Content-Type: application/json
    Content-Length: 88
    Connection: keep-alive
    Set-Cookie: session=eyJfaWQiOiJhMjUwZjVhMDViMjdkMGNkOTUzN2Q4YTViYWQzODFiMiJ9.CqDqWA.5TmPTa9zus8ZVo0avVnwz-O4-Dc; Domain=.dados.cta.if.ufrgs.br; HttpOnly; Path=/
    
    {
      "board_hash": "pbkdf2:sha1:1000$rT98ercf$bf77e6ca081826cbf9fc0fab23cb93bf17fe598b"
    }
    
  • Python + excelente biblioteca requests (instale via pip3).

    >>> import requests
    >>> url = 'http://dados.cta.if.ufrgs.br/emm/api/get/boardhash'
    >>> d = {'board_id': 3, 'user_password': '1234'}
    >>> r = requests.post(url, json=d)
    >>>> r
    <Response [200]>          # 200 significa "sucesso"
    >>> r.json()
    {'board_hash': 'pbkdf2:sha1:1000$rT98ercf$bf77e6ca081826cbf9fc0fab23cb93bf17fe598b'}
    

Instalação e manutenção

Seguem abaixo instruções para instalação e manutenção da webapp em seu próprio servidor.

O projeto inclui um arquivo Makefile contendo diversos comandos simples para manutenção no diretório raiz. É preciso estar neste diretório para executar:

~/emm-webapp $ make <command>

Execute simplesmente make ou make help para obter uma lista de todos os comandos disponíveis e uma breve descrição.

1. Preparando ambiente de execução

  • 1.1 Obtenha uma cópia do repositório atual:

    $ git clone https://git.cta.if.ufrgs.br/meteorolog/emm-webapp.git
    $ cd emm-webapp
    
  • 1.2 Instale os programas necessários (requer permissão de root):

    $ make deb-req
    

    Os seguintes programas serão instalados no sistema via apt-get (logo, apenas para distribuições Debian):

    • nginx: Servidor web, utilizado para reverse proxy;
    • supervisor: Gerenciador de processos em background;
    • python3: Interpretador da linguagem na qual a web app foi escrita;
    • python3-pip: Gerenciador de pacotes do Python;
    • virtualenv: Permite a criação de um ambiente virtual contendo uma instalação isolada de Python e das dependencias do projeto (ver arquivo requirements.pip);
  • 1.3 Crie o ambiente virtual de Python onde a web app será executada:

    $ make venv
    
  • 1.4 Exporte uma frase-chave para ser usada como token de segurança da web app:

    $  export EMMPASS=<DigiteUmaFraseSemEspaços>
    

    OBS: dê um espaço em branco depois do $ antes de digitar o comando export para que o texto não seja gravado no histórico do terminal!

2. Preparando o banco de dados

É possível trabalhar em modo desenvolvimento ou produção configurando a variável ambiente EMMCONFIG.

2.1 Desenvolvimento: SQLite, arquivo local

$ export EMMCONFIG=dev
$ make initdb

2.2 Produção: servidor MySQL

O Makefile proporciona vários comandos para execução de scripts MySQL (ver make help e production/manage_mysql.py para maiores detalhes).

Necessário apenas uma vez, o comando seguinte cria o usuário ctaemm e o banco emmdb no servidor:

$ make mysql-setup

OBS: Nesse o ponto o banco ainda está vazio (sem tabelas).

$ export EMMCONFIG=prod
$ make initdb

OBS: As tabelas serão recriadas e dados existentes serão perdidos!

3. Executando a web app

É possível executar a aplicação em modo desenvolvimento ou produção. Em ambos os casos, é um servidor WSGI rodando em uma porta específica que intermedia as requisições web (GET, POST, etc) com a aplicação Python.

A porta pode (e deve) ser configurada na variável ambiente EMMPORT. Padrão: 5000.

3.1 Desenvolvimento

  • Execução em primeiro plano;
  • Servidor WSGI: Werkzeug (padrão integrado ao Flask);
  • Flag DEBUG=True (brecha de segurança!);
  • Banco de dados local SQLite;

Execute fazendo:

$ make run

Publicado por padrão em: http://localhost:5000. Pressione CTRL+C para interromper a execução.

3.2 Produção

  • Execução em plano de fundo;
  • Servidor WSGI: Gunicorn (instalado via pip em make venv);
  • Flag DEBUG=False;
  • Servidor de banco de dados MySQL;

Requer variável ambiente EMMSERVER contendo o nome do servidor de rede da máquina.

A publicação é feita com:

$ make deploy

Assumindo EMMSERVER=localhost, o site estará publicado localmente em:

Em resumo, o comando acima faz:

  • Cria um servidor WSGI Gunicorn na porta EMMPORT;
  • Registra o processo Gunicorn na ferramenta Supervisor para iniciação automática junto ao sistema operacional;
  • Registra o site no servidor web Nginx na forma de um reverse proxy da porta 80 para a aplicação WSGI na porta EMMPORT.

A publicação pode ser desfeita com:

$ make undeploy

4. Manutenção

Independente do banco de dados utilizado, ele pode ser manipulado em alto nível graças ao mapeador objeto-relacional SQLAlchemy utilizado pela aplicação.

O comando:

$ make shell

inica uma sessão IPython onde as tabelas e registros podem ser acessados e alterados como objetos Python. A exemplo:

>>> tables                   # para ver as tabelas disponíveis
>>> boards                   # a exemplo, esta é a tabela boards
app.models.board.Board      
>>> boards.__fields__        # lista os campos da tabela
{'description', 'id', 'latitude', 'longitude', 'nickname', 'user_id'}
>>> boards.ls                # lista todas linhas/registros da tabela 
[<Board id=1 user='admin' nickname='Pezzi' sensor_count=4>,
 <Board id=2 user='admin' nickname='CAP' sensor_count=4>]
>>> b = boards.get(2)        # pega um registro via ID
>>> b.nickname = 'UFRGS'     # altera um campo
>>> commit()                 # confirma a operação no DB
>>> boards.ls
[<Board id=1 user='admin' nickname='Pezzi' sensor_count=4>,
 <Board id=2 user='admin' nickname='UFRGS' sensor_count=4>]