emilysoueu / minicurso_ercemapi

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Os cinco passos para transformar qualquer site de dados públicos em uma API de dados abertos

  • Sérgio Souza Costa
  • Mateus Vitor Duarte Sousa
  • Micael Lopes da Silva

Acessem aqui o Capítulo do Livro - Rascunho


Roteiro

  1. Introdução
  2. Passo 1: Identificação e modelagem dos dados
  3. Passo 2: Extração dos dados
  4. Passo 3: Desenvolvimento da API
  5. Passo 4: Documentação
  6. Passo 5: Implantação
  7. Passo extra: Experimentando a API
  8. Considerações finais

Introdução

  • A Constituição de 1988 foi reforçado através Lei de Acesso à Informação (http://www.planalto.gov.br/ccivil_03/_ato2011-2014/2011/lei/l12527.htm) demanda das instituições disponibilizar os seus dados públicos.

  • Dados públicos são todos aqueles sem nenhuma restrição.

  • Dados abertos, por sa vez precisam seguir os seguintes princípios:

    • ser completos,
    • primários,
    • atuais,
    • acessíveis,
    • compreensíveis por máquina,
    • não proprietários e
    • livres de licença
  • Atualmente espera-se que tudo que não for sigiloso esteja disponível na internet no formato de dados abertos, ou seja, não basta disponibilizar quando solicitado⁠


Introdução

  • O objetivo desse minicurso é apresentar uma solução para expor os dados públicos como dados abertos utilizando para isso a extração de dados e disponibilizá-los através de uma API implantada na plataforma Heroku.

Algo similar ao que estamos fazendo com os dados dad UFMA, onde estamos criando a seguinte API de dados abertos:

Adicionalmente, um servidor de dados conectados:


Introdução (principais requisitos)


Introdução (principais tecnologias)

As principais tecnologias usadas são:

principais tecnologias usadas


Passo 1: Identificação e modelagem dos dados

  • Identificar sites com dados de interesse da sociedade e que ainda não possuem APIs
  • Muitos sites de instituições públicas ainda não migraram para dados abertos.
  • Um exemplo é o site da transparência do governo do Estado do Maranhão http://www.transparencia.ma.gov.br.
    • Ele foi lançado em 2015 e apresenta diversas melhorias em relação ao anterior, mas ainda não disponibiliza dados abertos através de uma API.
    • O acesso a todos os dados requer a interação entre um usuário e um navegador web.
    • Mesmo para baixar os dados, é necessário a interação com um usuário.

Passo 1: Identificação e modelagem dos dados

Por exemplo, ao acessar o seguinte endereço

Tem se a seguinte tabela que descreve as despesas de cada função administrativa em 2019.

  • Nesse site, já temos os dados bem estruturados, o que é preciso estraí-los e criar o acesso através de uma API.

  • O processo de identificação dos dados poderá ser feito e refeito, a medida que exploramos o site de interesse.

Vamos para o PASSO 2 ?


Passo 2: Extração dos dados

  • Existem hoje diversas bibliotecas nas mais distintas linguagens capazes de executar o "web scrapping".

  • Nesse minicurso, usaremos o Python e a biblioteca beautifulsoup4.

  • Vamos configurar o ambiente ?


Passo 2: Extração dos dados (instalando o pipenv)

  • Antes de mais nada, iremos usar o pipenv, então vamos lopo instalar.

  • Abra um terminal e instale o pipenv com o seguinte comando

      $ pip install pipenv
    

Passo 2: Extração dos dados (criando o projeto e instalando as depedências)

  • Para criar o projeto, crie uma pasta chamada transparencia-ma, e nela execute o seguinte comando:

      $ pipenv --three
    
  • Instalando as depedências básicas:

    $ pipenv install requests beautifulsoup4 lxml
    

Passo 2: Extração dos dados (testando a configuração inicial)

  • Antes de prosseguir, vamos ver se está tudo ok com as instalações.

  • Crie um arquivo chamado scrapper.py com o seguinte código:

import requests
from bs4 import BeautifulSoup as BS

url = "http://www.transparencia.ma.gov.br/app/despesas/por-funcao/2019#lista"
page_response = requests.get(url)
page = BS(page_response.text, 'lxml')
table = page.find ('table')
print (table)
  • No terminal, inicialize o ambiente pipenv e então execute o arquivo scrapper.py

      $ pipenv shell
      $ python scrapper.py 
    
  • Ao executar o comando acima, será impresso um codigo HTML da tabela selecionada.

<tr>
<td>19</td>
<td class="secondLeft">
<a href="http://www.transparencia.ma.gov.br/app/despesas/por-funcao/2019/funcao/19?">
            CIENCIA E TECNOLOGIA
            </a>
</td>
<td>22.570.913,72</td>
<td>17.746.719,47</td>
<td>13.433.197,71</td>
</tr>

CHECKPOINT Conseguiu executar o comando acima ? Imprimiu o HTML ? Ok, podemos seguir:


Passo 2: Extração dos dados (função de extração de despesas)

  • Substitua o codigo do arquivo scapper.py pelo código a seguir, já com a função despesas_total:
import requests
from bs4 import BeautifulSoup as BS

def despesas_total ():
    url = "http://www.transparencia.ma.gov.br/app/despesas/por-funcao/2019#lista"
    response = requests.get(url)
    page = BS(response.text, 'lxml')
    table = page.find ('table')
    rows = table.find_all('tr')
    despesas = []
    for row in rows[1:]: 
        cols =row.find_all("td")
        despesa = {}
        despesa["nome"] = cols[1].find("a").get_text().strip()
        despesa["url_detalhe"] = cols[1].find("a").get('href')
        despesa["empenhado"] = cols[2].get_text().strip()
        despesa["liquidado"] = cols[3].get_text().strip()
        despesa["pago"] = cols[4].get_text().strip()
        despesas.append(despesa)

    return despesas

# remover o codigo abaixo
print (despesas_total())

Passo 2: Extração dos dados (testando a função de extração de despesas)

Execute o codigo novamente, agora para testar a função de estração de despesas:

 $ python scrapper.py 
[{'nome': 'ADMINISTRACAO', 'url_detalhe': 'http://www.transparencia.ma.gov.br/app/despesas/por-funcao/2019/funcao/04?', 'empenhado': '530.070.090,32', 'liquidado': '452.420.550,87', 'pago': '351.633.728,08'}, {'nome': 'AGRICULTURA', 'url_detalhe': 'http://www.transparencia.ma.gov.br/app/despesas/por-funcao/2019/funcao/20?', 'empenhado': '69.816.420,71', 'liquidado': '58.739.278,15', 'pago': '45.119.980,63'}, ...]

Apos este teste, remova a seguinte linha:

print (despesas_total())

CHECKPOINTNesse ponto, é importante que tenha executa o comando acima, e já tenha obtido como resultado os dados no formato JSON.


Passo 3: Desenvolvimento da API (instalando ...)

  • Depois de criado a função despesas_total, podemos partir para o desenvolvimento da API.

  • Primeiro instale o framework flask, que será usado para criar a API:

      $ pipenv install flask-restplus
    

Passo 3: Desenvolvimento da API (versão 0.001)

  • Para ter uma API bem simples, crie um arquivo app.py com o seguinte código:
from flask import Flask
from flask_restplus import Resource, Api, fields
from scrapper import despesas_total

app = Flask(__name__)
api = Api(app)

@api.route('/despesas')
class Despesas(Resource):
    def get(self):
        return despesas_total()

if __name__ == '__main__':
    app.run(debug=True)
  • Pronto, já pode iniciar a API:
$ python app.py
 * Serving Flask app "app" (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: on
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 230-864-203
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

Passo 3: Desenvolvimento da API (testando a versão 0.001)

  • Podemos testar diretamente no navegador, basta entrar com o seguinte endereço http://127.0.0.1:5000/, já será retornado os dados como na figura:


Passo 3: Desenvolvimento da API (versão 0.002, incluindo o ano)

  • A funcao despesa_total está sempre retornando os dados para o ano de 2019. Podemos mudar isso, alterando ela como no código abaixo:
def despesas_total (ano):
    url_base = "http://www.transparencia.ma.gov.br/app"
    url = url_base + "/despesas/por-funcao/"+ano
    response = requests.get(url)
    page = BS(response.text, 'lxml')
    table = page.find ('table')
    rows = table.find_all('tr')
    despesas = []
    for row in rows[1:]: # testando apenas com 3 linhas
        cols =row.find_all("td")
        despesa = {}
        despesa["nome"] = cols[1].find("a").get_text().strip()
        despesa["url_detalhe"] = cols[1].find("a").get('href')
        despesa["empenhado"] = cols[2].get_text().strip()
        despesa["liquidado"] = cols[3].get_text().strip()
        despesa["pago"] = cols[4].get_text().strip()
        despesas.append(despesa)

    return despesas
  • Precisa atualizar a rota lá na API, para incluir o ano:
app = Flask(__name__)
api = Api(app)

@api.route('/despesas/<string:ano>')
class Despesas(Resource):
    def get(self, ano):
        return despesas_total(ano)

if __name__ == '__main__':
    app.run(debug=True)

Passo 3: Desenvolvimento da API (testando a versão 0.002)


Passo 3: Desenvolvimento da API (versão 0.002, despesas por função)

  • O site da transparência do Governo do Maranhão permite visualizar os detalhes das despesas de uma dada função ou órgão administrativo.
  • Por exemplo, o código da função administrativa "educação" é 12. Então, a http://www.transparencia.ma.gov.br/app/despesas/por-funcao/2018/funcao/12 detalha como a despesa com a educação foi distribuída para cada orgão.


Passo 3: Desenvolvimento da API (versão 0.003, adaptando a extração para considerar a função administrativa)

  • Vamos adaptar o código do arquivo scrapper.py incluindo uma função que irá extrair o total das despesas e outra detalhada por função administrativa:
import requests
from bs4 import BeautifulSoup as BS
def despesas_total (ano):
    url_base = "http://www.transparencia.ma.gov.br/app"
    url = url_base + "/despesas/por-funcao/"+ano
    return extrai_despesas (url)
    
def despesas_por_funcao (cod, ano):
    url_base = "http://www.transparencia.ma.gov.br/app"
    url = url_base + "/despesas/por-funcao/"+ano+"/funcao/"+cod
    return extrai_despesas (url)

def extrai_despesas (url):
    response = requests.get(url)
    page = BS(response.text, 'lxml')
    table = page.find ('table')
    rows = table.find_all('tr')
    despesas = []
    for row in rows[1:]:
        cols =row.find_all("td")
        despesa = {}
        despesa["codigo"]  = cols[0].get_text().strip()
        despesa["nome"] = cols[1].find("a").get_text().strip()
        despesa["url_detalhe"] = cols[1].find("a").get('href')
        despesa["empenhado"] = cols[2].get_text().strip()
        despesa["liquidado"] = cols[3].get_text().strip()
        despesa["pago"] = cols[4].get_text().strip()
        despesas.append(despesa)
    return despesas
   

Passo 3: Desenvolvimento da API (versão 0.003, adicionando a nova rota)

  • Para atualizar a API e a rota, primeiro importe a nova função:
from scrapper import despesas_total , despesas_por_funcao
  • Agora adiciona a seguinte rota:
@api.route('/despesas/<string:cod_funcao>/<string:ano>')
class DespesasPorFuncao(Resource):
    def get(self, cod_funcao, ano):
        return despesas_por_funcao(cod_funcao, ano)

Passo 3: Desenvolvimento da API (testando a nova rota)

  • Caso o servidor não esteja em execução, inicie-o
  • Teste a nova rota em um navegador

ou diretamente pelo console:

curl -X GET "http://localhost:5000/despesas/12/2018" -H "accept:application/json"

Passo 4: Documentação

  • Uma parte importante em qualquer API é uma boa documentação. Então, no quarto passo será utilizado a biblioteca Swagger

  • A biblioteca flask-restplus vem com o suporte para o Swagger e já cria uma documentação básica ao acessar o endereço raiz da API, como na figura abaixo:

documentacao_inicial


Passo 4: Documentação (adicionando novas informações)

  • Adicionando a versão, o nome e a descrição como informações principais da API.

  • Criando o namespaces despesas para agrupar as rotas. Com a evolução da API, poderia ser criado um namespace receitas.

from flask import Flask
from flask_restplus import Resource, Api, fields
from scrapper import despesas_total, despesas_por_funcao

app = Flask(__name__)
api = Api(app = app, 
		  version = "1.0", 
		  title = "Transparência Maranhão", 
          description = "Uma API não oficial com os dados sobre as receitas e despesas do Governo do Maranhão")
          
ns = api.namespace('despesas', description='Dados de despesas')

@ns.route('/<string:ano>')
class Despesas(Resource):
    def get(self, ano):
        return despesas_total(ano)
@ns.route('/<string:cod_funcao>/<string:ano>')
class DespesasPorFuncao(Resource):
    def get(self, cod_funcao, ano):
        return despesas_por_funcao(cod_funcao, ano)

if __name__ == '__main__':
    app.run(debug=True)

Passo 4: Documentação (documentação com as novas informações)

Com as informações adicionadas previamente, já teriamos o seguinte resultado

documentacao_1


Passo 4: Documentação (atualizando a documentação para as rotas e métodos)

Atualizando a documentação as rotas e métodos, através do decorator api.doc.

@ns.route('/<string:ano>')
class Despesas(Resource):
    @api.doc(responses={ 200: 'OK', 400: 'Despesas não encontradas' },  params={ 'ano': 'Ano de referência para as despesas' })
    def get(self, ano):
        return despesas.despesas_total(ano)
        
@ns.route('/<string:cod_funcao>/<string:ano>')
class DespesasPorFuncao(Resource):
    @api.doc(responses={ 200: 'OK', 400: 'Despesas não encontradas' },
     params={ 'ano': 'Ano de referência para as despesas',
    'cod_funcao' : 'Código da função (educação, saúde ...) de referência para as despesas'})
    def get(self, cod_funcao, ano):
        return despesas.despesas_por_funcao(cod_funcao, ano)

Tendo como resultado:


Passo 4: Documentação (atualizando os tipos de dados)

  • Os metadados, são importantes para descrever os dados, incluindo tipos de dados e exemplos de valores.

  • Antes de definir os metadados, vamos converter os valores liquidados, pagos e empenhados para números, pois atualmente eles estão como strings.

  • Como eles estão no formato brasileiro para os números, vamos usar uma biblioteca especifica para a conversão:

      $ pipenv install babel
    
  • Agora será necessário importar a função parse_decimal.

    from babel.numbers import parse_decimal

Atualizar a função extrai_despesas

  def extrai_despesas (url):
   response = requests.get(url)
   page = BS(response.text, 'lxml')
   table = page.find ('table')
   rows = table.find_all('tr')
   despesas = []
   for row in rows[1:]:
       cols =row.find_all("td")
       despesa = {}
       despesa["codigo"]  = cols[0].get_text().strip()
       despesa["nome"] = cols[1].find("a").get_text().strip()
       despesa["url_detalhe"] = cols[1].find("a").get('href')
       despesa["empenhado"] =   parse_decimal (cols[2].get_text().strip(), locale='pt_BR')
       despesa["liquidado"] =  parse_decimal (cols[3].get_text().strip(), locale='pt_BR')
       despesa["pago"] =  parse_decimal (cols[4].get_text().strip(), locale='pt_BR')
       despesas.append(despesa)

   return despesas

Passo 4: Documentação (atualizando os tipos de dados)

  • Com a atualização dos tipos de dados, podemos criar de fato os metadados.
model = api.model('Dados sobre uma função ou orgão', {
    'codigo': fields.String(description='Código da função ou orgão', example="04"),
    'nome': fields.String(description='Nome da função ou orgão', example="ADMINISTRACAO"),
    'url_detalhe': fields.String(description='Endereço para mais detalhes', example="http://www.transparencia.ma.gov.br/app/despesas/por-funcao/2016/funcao/04?"),
    'empenhado': fields.Float(description='Valor empenhado', example=821854500.93),
    'liquidado': fields.Float(description='Valor liquidado', example=794738131.95),
    'pago': fields.Float(description='Valor pago', example=775701742.7),
})
  • Para associar o metadado aos dados retornados, será usado o decorator @api.marshal_with em ambas rotas:
@ns.route('/<string:ano>')
class Despesas(Resource):

    @api.marshal_with(model, mask='*')
    @api.doc(responses={ 200: 'OK', 400: 'Despesas não encontradas' }, 
			 params={ 'ano': 'Ano de referência para as despesas' })
    def get(self, ano):
        return despesas_total(ano)


@ns.route('/<string:cod_funcao>/<string:ano>')
class DespesasPorFuncao(Resource):

    @api.marshal_with(model, mask='*')
    @api.doc(responses={ 200: 'OK', 400: 'Despesas não encontradas' }, 
    params={ 'ano': 'Ano de referência para as despesas',
    'cod_funcao' : 'Código da função (educação, saúde ...) de referência para as despesas'})
    def get(self, cod_funcao, ano):
        return despesas_por_funcao(cod_funcao, ano)

Passo 4: Documentação (visualizando os metadados)

  • Agora podemos visualizar os metadados na documentação, já sabemos os tipos de dados e exemplos de valores:


Passo 5: Implantação (pré-requisitos)

  • O quinto e último passo tem como objetivo implantar a API desenvolvida.

  • Será usado o Heroku, caso ainda não tenha uma conta, crie logo :)

  • Para a implantação será usado também o gerenciador de configuração Git e o repositório Github http://github.com/. Vais precisar ter uma conta também.


Passo 5: Implantação (preparando o projeto)

  • Instale o servidor WSGI (Web Server Gateway Interface) gunicorn.

      $ pipenv install gunicorn
    
  • Crie um arquivo denominado Procfile (https://devcenter.heroku.com/articles/procfile) que é utilizado pelo Heroku para a inicialização do serviço.

  • Ele indica o WSGI e o nome do aplicativo:

      web: gunicorn app:app
    

Passo 5: Implantação (preparando o repositorio no github usando git)

  • Logue na sua conta no Github e crie um repositório chamado transparencia-ma:

  • Caso tenha o git instalado, execute os seguintes comandos a partir da pasta do teu projeto.

  • Lembrem de substituir https://github.com/profsergiocosta/transparencia-ma.git pelo repositorio que criou

git init
git add *
git commit -m "first commit"
git remote add origin https://github.com/profsergiocosta/transparencia-ma.git
git push -u origin master

Fica a dica

Nesse exemplo está sendo um repositótio HTTP, então será necessário entrar com o nome do usuário e senha para enviar os dados para o repositório, ou seja, executar o comando push. Uma dica é trabalhar com repositório SSH ao invés de HTTP, caso esteja usando esses procedimento em um computador pessoal.


Passo 5: Implantação (preparando o repositorio no github fazendo upload dos arquivos)

  • Caso nao tenha o git instalado em seu computador, uma alternativa é fazer o upload dos arquivos diretamente no repositorio:


Passo 5: Implantação (fazendo o deploy no Heroku)

  • O deploy é feito em 4 passos:

    • O passo 1 cria uma aplicação Heroku com o nome transparencia-ma (ou outro nome ainda disponível)
    • Passo 2 conecta-se a aplicação ao repositório Github.
    • Passo 3 executa a implantação (deploy) manual.
    • Passo 4, verifiquem as mensagens para saber se o aplicativo foi implantado com sucesso.


Passo extra: Experimentando a API (análise de dados)

  • O portal da transparência do Maranhão já disponibiliza diversos dados tabelados. Porém, um usuário pode precisar de um dado que não esteja disponível diretamente.

  • Por exemplo, o usuário poderia querer um gráfico que mostrasse a evolução temporal dos gastos por uma dada função administrativa.

  • Sem uma API, seria necessário entrar em diversas páginas e manualmente anotar os gastos, ou salva-los e manipulá-los através de outro software.

  • Contudo, com a API desenvolvida aqui é possível gerar este gráfico escrevendo um pouco de código em linguagens como Python, R ou JavaScript.


Passo extra: Experimentando a API (análise de dados)

  • Entrem com o seguinte codigo:
import json, requests
import matplotlib.pyplot as plt

url = "escreva aqui a url do seu aplicativo no heroku"
valores =[]
anos = []
codigo_funcao = "19" # 19 é o código para ciência e tecnologia
for ano in range (2015, 2020):
  r = requests.get(url+str(ano))
  anos.append (ano)
  dados = r.json()
  for dado in dados:
    if dado['codigo'] == codigo_funcao:
      valores.append(dado['empenhado'])
      break
plt.bar (anos,valores)
plt.show()
  • O resultado será:

gráfico


Passo extra: Experimentando a API (aplicação JavaScript)

  • Além de ser usado para análise, os dados abertos podem ser acessados por aplicativos web e móveis. Nesse caso, uma possibilidade seria desenvolver aplicativos híbridos usando a linguagem JavaScript, através de como o Angular, React e Electron.

  • Como o objetivo é fazer um teste simples, foi escrito um código usando a biblioteca a velha e boa JQuery.

  • Como é só uma experimentação, a idéia é executar uma requisição e imprimir no console o resultado.

  • Então crie um arquivo HTML com o seguinte codigo

<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script>
$(document).ready(() =>  
    $("button").click( () =>  $.ajax({
        url: "url para a sua api", 
        success: (result) => console.log (result) })
))
</script>
</head>
<body>
<button>Executa a consulta ao REST</button>
</body>
</html>

Passo extra: Experimentando a API (aplicação JavaScript)

  • Antes de abrir o HTML no seu navegador, modifique a URL para referenciar o serviço que foi criado no Heroku. Porém, esse simples teste irá falhar e apresentar seguinte mensagem no navegador:

  • Lembrem de ativar o web console e clicar no botão.

  • A mensagem de Erro será:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://transparencia-ma.herokuapp.com/despesas/10/2018. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing).
  • Isso ocorre porque, por padrão, o JavaScript não permite que aplicações de domínios distintos compartilhem recursos. Porém é possível habilitar o que é conhecido como CORS (que em português seria Compartilhamento de Recursos de Origem Cruzada).
  • Então, para tudo funcionar corretamente, será necessário retornar ao ambiente de desenvolvimento da API.

Passo extra: Experimentando a API (aplicação JavaScript, habilitando o Cross)

  • Instale a extensão para dar esse suporte ao CROSS, que é feito pela biblioteca flask_cors:

      pipenv install flask_cors
    
  • Depois no arquivo app.py, adicione um novo import:

from flask_cors import CORS
  • E então, será executado a função CORS ao aplicativo:
CORS(app)
  • O código completo pode ser acessado em: \url{http://bit.ly/2PcfHXZ}.

  • Atualizado esse código, deve-se enviar as modificações para o repositório e, por fim, executar a implantação novamente no Heroku.


Passo extra: Experimentando a API (aplicação JavaScript)

  • Com o serviço implantado e atualizado, basta executar o código novamente para ser impresso os dados em JSON no console.

Lembrando, que esse é um exemplo extremamente simples, porém a sua execução mostra que a API está pronta para ser usada por aplicações em JavaScript.


Passo extra: Experimentando a API (evolução)

  • Observa-se que a tabela é muito similar a que foi extraída, com a diferença que cada credor possui um CPF ou CNPJ em vez de um código. Então o Código será muito similar:
def despesas_por_orgao (orgao, funcao, ano):
    url = "http://www.transparencia.ma.gov.br/app/despesas/por-funcao/"+ano+"/funcao/"+funcao+"/orgao/"+orgao+"?#lista"
    response = requests.get(url)
    page = BS(response.text, 'lxml')
    table = page.find ('table')
    rows = table.find_all('tr')
    despesas = []
    for row in rows[1:]:
        cols =row.find_all("td")
        despesa = {}
        despesa["nome"] = cols[0].find("a").get_text().strip()
        despesa["url_detalhe"] = cols[0].find("a").get('href')
        despesa["cpf/cnpj"] = cols[0].find("small").get_text().strip().replace ("CPF/CNPJ: ","")
        despesa["empenhado"] =  parse_decimal(cols[1].get_text().strip(), locale='pt_BR')
        despesa["liquidado"] =  parse_decimal(cols[2].get_text().strip(), locale='pt_BR')
        despesa["pago"] = parse_decimal (cols[3].get_text().strip(), locale='pt_BR')
        despesas.append(despesa)
    return despesas
  • Agora é criar uma nova rota que inclui o código do órgão administrativo. Tentem fazer essa rota, e fazer uma nova implantação

Considerações finais

O processo de transformação de dados públicos em dados abertos requer muita exploração do site de dados públicos. Por exemplo, aqui seria possível extrair ainda diversas outras informações como:

  • Ainda sobre despesas, é possível extrair informações detalhadas por credor.
  • Além dos dados de despesas, pode-se extrair os dados de receitas de modo muito similar.
  • Dados sobre servidores públicos, como salário e diárias.
  • Transferência de valores, por exemplo, repasse a municípios.

Além desses dados é possível evoluir bastante essa API, permitindo extrair cada vez mais informações relevantes.

About


Languages

Language:Python 100.0%