GeoProcess Consumer-Dash-Sample
Introdução
O módulo Consumer-Dash-Sample é na verdade um módulo implementando de um super consumidor para dashboards de demostração e exemplificação das principais funcionalidades disponíveis na plataforma GeoProcess. A idéia desse módulo é ser utilizado como um sistema de consulta para implementação de consumidores para construção de dashboards para propósitos específicos em qualquer projeto.
Quando desejamos desenvolver um dashboard devemos pensar em algumas questões como: Quantos gráficos são necessários? Quais as dependências desses gráficos? Quais as entradas desses gráficos? Quais as bases de dados utilizadas na construção desses gráficos? Quais tipos de gráficos melhor se ajusta ao meu objetivo? A partir dessas informações podemos começar a implementação do consumidor de dashboard. Os exemplos mostrados a seguir exemplificam diversas possibilidades para a construção de dashboards e para demonstração das capacidades da plataforma GeoProcess.
Um Dashboard é um conjunto de gráficos e de entradas, em que cada gráfico pode ter múltiplas entradas. Os Dashboards são recursos úteis para realizar análises exploratórias nos dados. Pode-se construir dashboards com quantos gráficos e entradas se desejar. Os Dashboards dentro da plataforma GeoProcess não tem nenhuma relação com os consumidores (Perguntas).
Objetivo Deste Dashboard
O objetivo dessa aplicação exemplo é mostrar a robustez da plataforma na construção de dashboards interativos. Nesse sentido, o objetivo e exibir gráficos de barras, gráficos de pizza e tabelas contendo informações sobre tamanho da população e o IDH para diferentes estados e regiões do Brasil. A resposta visual esperada nesse dashboard é mostrado a seguir.

Para cada um dos gráficos, parâmetros de entradas podem ser selecionados. Através dessas seleções a saída mostrada é alterada. Alguns dos parâmetros deste exemplo são: estado alvo, ano alvo e região alvo.
A seguir será descrita uma visão geral do módulo Consumer-Dash-Sample.
Visão Geral
A estrutura com as pastas e arquivos principais do projeto Consumer-Dash-Sample está destacada a seguir.

Na raiz do projeto, estão os principais componentes do CONSUMER-DASH-SAMPLE, incluindo:
-
main.py: Módulo principal em Python e ponto de entrada da aplicação consumidora.
-
consumer_dash/: Pasta em que fica localizado o módulo consumidor, nesse exemplo o módulo
service.pyna pastabasic. -
conf_samples/ Pasta em que temos o arquivo de configuração
env.confque deverá ser copiado para a raiz do projeto. -
graph_output/: Armazena os arquivos de resposta com os gráficos que serão utilizados na construção do dashboard.
-
logs/: Armazena os logs gerados pelo consumidor, facilitando o acompanhamento de sua execução.
-
tests/: Pasta dedicada aos testes de software.
-
dashboards/: Pasta que contém arquivos de configuração importante em formato JSON. Esses arquivos definem uma série de configurações sobre o consumidor de dashboard.
A seguir será detalhado alguns dos principais arquivos, módulos e diretórios destacados acima do consumidor dash sample.
Módulo Service
No módulo service.py na pasta consumer_dash/basic/ temos o código do consumidor responsável pelo dashboard a ser mostrado. Neste módulo, temos a declaração de uma classe chamada Service que herda de DashWorker (definida na biblioteca PGST-LIB). Essa classe contém um consumidor de dashboards com o objetivo e exibir gráficos de barras, gráficos de pizza e tabelas contendo informações sobre tamanho da população e o IDH para diferentes estados e regiões do Brasil.
A seguirm, apresentamos uma visão geral dos métodos da classe Service.
class Service(DashWorker):
...
@dashProcess(componentId="graph_s1")
def process1(self, input)
...
@dashProcess(componentId="graph_s2")
def process2(self, input)
...
...
@dashProcess(componentId="graph_d2_s1")
def process21(self, input)
...
@dashProcess(componentId="graph_d2_s1")
def process21(self, input)
...
...
A seguir vemos a implementação do método process1. Este método é responsável pelo processamento do primeiro gráfico (acessado através do componentId que é igual a graph_s1) do dashboard.
Informação
Repare que, por ser uma aplicação de exemplo, os dados estão injetados diretamente no código. Em uma aplicação real, esses dados são carregados de algum banco de dados.
O arquivo CSV lido possui dados separados nas categorias: ano, estado, região, população e IDH:
ano,estado,região,população,IDH
1991,AC,Norte,406835,0.402
1991,AL,Nordeste,2655073,0.37
...
1991,TO,Norte,982132,0.369
2001,AC,Norte,557526,0.517
2001,AL,Nordeste,3025646,0.471
...
2001,TO,Norte,1181548,0.525
2011,AC,Norte,758000,0.663
2011,AL,Nordeste,3189000,0.631
...
2011,TO,Norte,1393000,0.699
2022,AC,Norte,910000,0.710
2022,AL,Nordeste,3435000,0.684
...
2022,TO,Norte,1669000,0.731
Nessa implementação temos a modelagem de um dos gráficos do dashboard. Esse método (process1) possui um decorador @dashProcess com o parâmetro componentId (linha 1). Este método recebe apenas um parâmetro com nome input que é uma lista contendo as informações de entrada do método (linha 2). A primeira ação do método é imprimir na tela uma informação indicando esse gráfico já começou a ser processado (linha 3). As linhas 4 a 7 definem o valor do padrão da variável estado, quando não setado, ou então, pegam o valor definido na interface gráfica. Na linha 9 é lido um arquivo CSV com os dados para exibição do gráfico e armazenado em uma variável do tipo dataframe (pandas). Na linha 10 até 51, é definido um dificionário com a resposta. O dicionário possui as partes principais de data e layout. Esse código é autoexplicativo assim não será explicado com detalhes, os valores permitidos para parâmetros do gráfico são os valores definidos na biblioteca Plotly. Na linha 52, a resposta é retornada.
Após executar a aplicação consumidora (python3 main.py CONTRACT_TEST 001), um arquivo HTML é gerado na pasta graph_outpout para ser posteriormente exibido no dashboard do GeoProcess. A imagem a seguir mostra a resposta no frontend do sistema.

A seguir vemos a implementação do método process2. Este método representa o processamento do primeiro gráfico (acessado através do componentId que é igual a graph_s2) do dashboard.
Após executar a aplicação consumidora (python3 main.py CONTRACT_TEST 002), uma resposta visual é exibida no dashboard do sistema após processado do process2. A imagem a seguir mostra a resposta no frontend do sistema.

A seguir vemos a implementação do método process3. Este método representa o processamento do terceiro gráfico do dashboard.
Após executar a aplicação consumidora (python3 main.py CONTRACT_TEST 003), uma resposta visual é exibida no dashboard do sistema após processado do process3. A imagem a seguir mostra a resposta no frontend do sistema.

A seguir vemos a implementação do método process4. Este método representa o processamento do quarto gráfico do dashboard.
Após executar a aplicação consumidora (python3 main.py CONTRACT_TEST 004), uma resposta visual é exibida no dashboard do sistema após processado do process4. A imagem a seguir mostra a resposta no frontend do sistema.

A seguir vemos a implementação do método process5. Este método representa o processamento do quinto gráfico do dashboard.
Após executar a aplicação consumidora (python3 main.py CONTRACT_TEST 005), uma resposta visual é exibida no dashboard do sistema após processado do process5. A imagem a seguir mostra a resposta no frontend do sistema.

A seguir vemos a implementação do método process6. Este método representa o processamento do sexto gráfico do dashboard.
Após executar a aplicação consumidora (python3 main.py CONTRACT_TEST 006), uma resposta visual é exibida no dashboard do sistema após processado do process6. A imagem a seguir mostra a resposta no frontend do sistema.

A seguir vemos a implementação do método process7. Este método representa o processamento da primeira saída de dados do dashboard. Esse método não processa nenhum gráfico, apenas define os nomes dos campos exibidos no componente checklist que é mostrado no dashboard.
Após executar a aplicação consumidora (python3 main.py CONTRACT_TEST 007), nenhuma resposta visual é exibida no dashboard do sistema após processado do process7. Isso ocorre, pois esse método não faz nenhum processamento gráfico, ele faz apenas o processamento dos dados baseados na região selecionada pelo usuário e retorna uma lista de opções de estados para aquela região. Analise a imagem abaixo que será gerada apenas no dashboard final do sistema quando executado junto com o portal.

A seguir vemos a implementação do método process8. Este método representa o processamento da primeira tabela do dashboard.
Analise a imagem abaixo que será gerada apenas no dashboard final do sistema quando executado junto com o portal.

Essa tabela irá mostrar as informações na tela baseados nos estados selecionados. A seguir vemos a implementação do método process9. Este método representa o processamento do primeiro código markdown para ser exibido do dashboard.
Esse markdown irá mostrar informações no dashboard baseada na descrição feita em linguagem markdown. Analise a imagem abaixo que será gerada apenas no dashboard final do sistema quando executado junto com o portal.

A seguir vemos a implementação do método process10. Este método representa o processamento da segunda tabela do dashboard.
Essa tabela irá mostrar as informações na tela baseadas em uma série de filtros disponíveis. Analise a imagem abaixo que será gerada apenas no dashboard final do sistema quando executado junto com o portal.

Arquivo de Configuração env.conf
Existe um arquivo de configuração chamado env.conf na pasta conf_samples. Esse arquivo será copiado para um outro arquivo chamado env.conf na raiz do projeto no passo configurando a aplicação desse tutorial. O arquivo conf_samples/env.conf é um arquivo de exemplo que vem junto com o projeto e não deve ser alterado. O arquivo env.conf, que é uma cópia do anterior, pode ser alterado/customizado conforme a necessidade do desenvolvedor. A seguir é mostrado um exemplo desse arquivo seguido de uma breve explicação.
CONSUMER_CODE=sample
LOG_LEVEL=INFO
#LOCAL
TIME_WAIT_RESTART=10
MESSAGE_BROKER_HOST_DOCKER=host.docker.internal
MESSAGE_BROKER_PORT_DOCKER=5672
CACHE_HOST_DOCKER=host.docker.internal
CACHE_PORT_DOCKER=6379
#DOCKER
MESSAGE_BROKER_HOST=192.168.1.4
MESSAGE_BROKER_PORT=5672
MESSAGE_BROKER_USER=admin
MESSAGE_BROKER_PASSWORD=password
CACHE_HOST=192.168.1.4
CACHE_PORT=6379
#OPTIONAL
#METRICS_PORT=9091
#PORTAL_DIR=pgst-portal
#DB_NAME=postgres
#DB_USER=postgres
#DB_PASSWORD=root
#DB_HOST=localhost
#DB_PORT=5433
Os primeiros atributos são obrigatórios. O atributo CONSUMER_CODE informa o nome do código consumidor. O atributo LOG_LEVEL informa o nível de detalhes impressos no sistema de log. Os valores possíveis são: DEBUG, INFO, WARNING, ERROR e CRITICAL.
Os sete próximos atributos são opcionais. Os atributos DB_NAME, DB_USER, DB_PASSWORD, DB_HOST, DB_PORT são utilizados para estabelecer a conexão com o banco de dados do postgres, caso a aplicação integre com esse banco de dados.
Módulos para Testes
Na raiz do projeto existe uma pasta chamada tests que contém os testes de software implementados. Dentro dessa pasta terá um arquivo chamado test_001.py que define os testes para o primeiro dashboard. A seguir é mostrada uma parte do código do módulo test_001.py.
import logging
from consumer_dash.basic.service import Service
class Test001():
logger = logging.getLogger(__name__)
service = Service()
def test(self):
self.logger.info("Testando o método test do módulo test_001.py")
service = Service()
answer = service.test("graph_s1", ['SP'])
assert type(answer) == dict
Repare que o código desse teste é bastante genérico. Ele basicamente cria um consumidor do tipo Service. Quando esse teste for executado, o método com componentId igual a graph_s1 será chamado. Em nosso caso, é o método com nome process1 da classe Service que possui esse componentId. Então, ele irá pegar a saída gerada e verificar se a mesma é do tipo dicionário.
Atenção: É necessário criar um teste de software por gráfico a ser plotado nas telas do dashboard.
Diretório graph_output
Na raiz do projeto tem uma pasta chamada graph_output em que ficam armazenados os arquivos com os gráficos que serão utilizados no dashboard.
Ao mandar exibir, por exemplo, o arquivo graph_graph_s1.html uma tela semelhante a mostrada a seguir deverá ser exibida.

Esses gráficos em HTML são criados quando executamos os comandos de testes de contrato da seção Executando a Aplicação em Modo Teste.
Arquivo dashboards.json
Na raiz do projeto tem um arquivo chamado dashboards.json que contém arquivos de configurações importantes em formato JSON. Esses arquivos definem uma série de parâmetros sobre o consumidor de dashboards.
A seguir temos um exemplo de arquivo dashboards.json (apenas uma parte) com as configurações de como montar os dashboards.
Arquivo: dashboards.json
{
"id": "dash_3",
"version": 1.0,
"project_title": "Projeto 2",
"role_tag": "DASH03",
"title": "DashBoard - Exemplos - Informações do Brasil",
"description": "Este painel mostra diferentes informações sobre o Brasil.",
"consumer_id":"sample",
"components": [
{
"type": "div",
"components": [
{
"type": "markdown",
"id": "markdown_1"
}
]
},
{
"type": "div",
"style": {
"width": "49%",
"display": "inline-block",
"marginRight": "10px"
},
"components": [
{
"type": "dropdown",
"title": "Filtro - Selecione um Estado",
"id": "data_s1",
"properties": {
"options": [
{
"label": "AC",
"value": "AC"
},
...
{
"label": "TO",
"value": "TO"
}
],
"default": "MG"
}
},
{
"type": "graph",
"id": "graph_s1",
"help": "This parameter is not necessary, is just for documentation purposes. consumer_id is the queue name and graph_s1 is the function name. The Hardcoded mode only return from consumer_id queue."
}
]
},
{
"type": "div",
"style": {
"width": "49%",
"display": "inline-block"
},
"components": [
{
"type": "dropdown",
"title": "Filtro - Selecione um Estado",
"id": "data_s2",
"properties": {
"options": [
{
"label": "AC",
"value": "AC"
},
...
{
"label": "TO",
"value": "TO"
}
],
"default": "MG"
}
},
{
"type": "graph",
"id": "graph_s2"
}
]
},
{
"type": "div",
"style": {
"width": "49%",
"display": "inline-block",
"marginRight": "10px"
},
"components": [
{
"type": "dropdown",
"title": "Filtro - Selecione um Ano",
"id": "data_s3",
"properties": {
"options": [
{
"label": "1991",
"value": 1991
},
...
{
"label": "2022",
"value": 2022
}
],
"default": 2022
}
},
{
"type": "graph",
"id": "graph_s3"
}
]
},
{
"type": "div",
"style": {
"width": "49%",
"display": "inline-block"
},
"components": [
{
"type": "dropdown",
"title": "Filtro - Selecione um Ano",
"id": "data_s4",
"properties": {
"options": [
{
"label": "1991",
"value": 1991
},
...
{
"label": "2022",
"value": 2022
}
],
"default": 2022
}
},
{
"type": "graph",
"id": "graph_s4"
}
]
},
{
"type": "div",
"style": {
"width": "100%",
"display": "inline-block"
},
"components": [
{
"type": "dropdown",
"title": "Filtro - Selecione uma Região",
"id": "data_s5",
"properties": {
"options": [
{
"label": "Centro Oeste",
"value": "Centro Oeste"
},
...
{
"label": "Sul",
"value": "Sul"
}
],
"default": "Sudeste"
}
},
{
"type": "dropdown",
"title": "Filtro - Selecione um Ano",
"id": "data_s6",
"properties": {
"options": [
{
"label": "1991",
"value": 1991
},
...
{
"label": "2022",
"value": 2022
}
],
"default": 2022
}
}
]
},
{
"type": "div",
"style": {
"width": "49%",
"display": "inline-block",
"marginRight": "10px"
},
"components": [
{
"type": "graph",
"id": "graph_s5"
}
]
},
{
"type": "div",
"style": {
"width": "49%",
"display": "inline-block"
},
"components": [
{
"type": "graph",
"id": "graph_s6"
}
]
},
{
"type": "div",
"style": {
"width": "100%",
"display": "inline-block"
},
"components": [
{
"type": "dropdown",
"title": "Filtro - Selecione uma Região",
"id": "data_s7",
"properties": {
"options": [
{
"label": "Centro Oeste",
"value": "Centro Oeste"
},
...
{
"label": "Sul",
"value": "Sul"
}
],
"default": "Sul"
}
},
{
"type": "checklist",
"title": "Filtro - Selecione um Estado",
"id": "data_s11",
"properties": {
"options": [],
"default" :[],
"help": "This (options) should be empty in dynamic inputs, and the name of component should starts with ",
"style": {
"display": "inline-block",
"marginTop": "5px"
}
}
},
{
"type": "datatable",
"id": "datatable_1"
}
]
},
{
"type": "div",
"style": {
"width": "100%",
"display": "inline-block"
},
"components": [
{
"type": "dropdown",
"title": "Filtro - Selecione um Ano",
"id": "data_s8",
"properties": {
"options": [
{
"label": "1991",
"value": 1991
},
...
{
"label": "2022",
"value": 2022
}
],
"default": 2022
}
},
{
"type": "slider",
"title": "Filtro - Selecione um IDH",
"id": "data_s9",
"properties": {
"begin": 0.0,
"end": 1.0,
"step": 0.05,
"value": 0.5
}
},
{
"type": "checklist",
"title": "Filtro - Selecione uma Região",
"id": "data_s10",
"properties": {
"options": ["Centro Oeste", "Nordeste", "Norte", "Sudeste", "Sul"],
"default" : ["Sudeste", "Norte"],
"style": {
"marginTop": "5px"
}
}
},
{
"type": "datatable",
"id": "datatable_2"
}
]
}
],
"callbacks": [
{
"outputs": [
"markdown_1"
],
"inputs": [
"data_s1"
]
},
{
"outputs": [
"graph_s1"
],
"inputs": [
"data_s1"
],
"help": "This parameter is not necessary, is just for documentation purposes. It is not possible to have two callbacks with the same outputs."
},
{
"outputs": [
"graph_s2"
],
"inputs": [
"data_s2"
]
},
{
"outputs": [
"graph_s3"
],
"inputs": [
"data_s3"
]
},
{
"outputs": [
"graph_s4"
],
"inputs": [
"data_s4"
]
},
{
"outputs": [
"graph_s5",
"graph_s6"
],
"inputs": [
"data_s5",
"data_s6"
]
},
{
"outputs": [
"data_s11"
],
"inputs": [
"data_s7"
]
},
{
"outputs": [
"datatable_1"
],
"inputs": [
"data_s11"
]
},
{
"outputs": [
"datatable_2"
],
"inputs": [
"data_s8",
"data_s9",
"data_s10"
]
}
]
}
Nesse arquivo é importante destacar os seguintes atributos:
id: denota um identificador do dashboard.version: denota a versão do dashboard.project_title: denota o título do projeto ao qual o dashboard está vinculado.role_tag: é utilizado para dar permissões de acesso ao dashboard.title: é utilizado para exibir um título na interface do portal.description: é utilizado para especificar uma descrição para o dashboard exibida na interface do portal.components: é utilizado para especificar todos os elementos gráficos que apareceram no dashboard. Informando como será o layout de exibição os tipos de entrada e os tipos de saída.callbacks: é utilizado para relacionar as entradas e saídas dos gráficos.
Instalação
Para a execução do consumidor de dashboard sample, é necessário preparar o ambiente com as ferramentas adequadas. Abaixo, apresentamos um passo a passo sucinto para instalação e configuração.
Pré-Requisitos
Para que o Consumer-Dash-Sample funcione corretamente, é necessário atender aos seguintes pré-requisitos:
- Python
- Pip
- Git
- Postgres
- Postgis
- Docker Desktop
Além disso, alguns subprojetos do GeoProcess também são necessários. Para isso, clone os seguintes repositórios:
- pgst-portal
- pgst-lib
Após a instalação dos pré-requisitos, você poderá preparar o Consumer-Dash-Sample.
Preparando a Aplicação
Primeiramente, clone o projeto pgst-consumer-dash-sample com o seguinte comando:
Observação
Esse projeto deve ser clonado dentro de uma pasta geoprocess, conforme a organização do projeto.
Configurando a Aplicação
Em seguida, copie o arquivo de configuração do ambiente com o comando apropriado para o seu sistema operacional:
Depois, abra o arquivo env.conf e atualize-o conforme as configurações do seu ambiente de trabalho.
Para isolar as dependências do Python, crie um ambiente virtual venv com o comando a seguir:
Ative o ambiente virtual no seu computador utilizando o comando abaixo:
Agora, instale as dependências do projeto utilizando o comando abaixo:
Em seguida, instale as dependências do projeto pgst-lib dentro do projeto principal:
Executando a Aplicação em Modo Teste
Para executar a aplicação em modo teste unitário, utilize a linha de comando abaixo:
Para executar a aplicação em modo teste de contrato, utilize a linha de comando abaixo:
Após isso, a saída será gerada no diretório graph_output. Abra os exemplos html dessa pasta utilizando algum servidor web, como o Live Server http://127.0.0.1:5500/graph_output/graph_graph_s1.html.
Uma tela semelhante a mostrada a seguir deverá ser exibida.

Informação
Para encerrar a execução do consumidor, basta apertar o botão x ou pressionar Ctrl + C.
Executando a Aplicação junto com Portal
Para executar a aplicação, primeiro é necessário abrir o Docker Desktop e subir o Postgis, pgAdmin e o Redis.
Em um terminal, execute o Consumer-Dash-Sample.
cd pgst-consumer-dash-sample/
source venv/bin/activate
cd consumer_dash/
python3 manage.py dash_service
Em seguida, acesse a URL http://0.0.0.0:8000/. Vá em Projeto 2 e em Painéis vá em DashBoard - Exemplos - Informações do Brasil. Repare agora que os gráficos estão sendo exibidos.

Visualizando os Resultados
Para visualizar os resultados digite:
Acesse a URL http://0.0.0.0:8050/.
Github do Projeto
A seguir temos o link para o github do projeto.