Skip to main content

separador-rreo

PyPI Python CI Licença Status

Biblioteca e CLI em Python para separar anexos RREO publicados em diários oficiais da FEMURN (Federação dos Municípios do Rio Grande do Norte).

A partir de um PDF do diário com texto selecionável, o pacote:

  1. Localiza cabeçalhos PREFEITURA MUNICIPAL DE …
  2. Reconhece títulos de anexos RREO (padrões observados em publicações como Angicos, Bodó e Coronel João Pessoa)
  3. Recorta cada anexo em PDF individual por município
  4. Gera a planilha Controle_Publicacoes.xlsx para conferência manual
  5. Empacota tudo em um .zip

Instalação

pip install separador-rreo

Em desenvolvimento (clone local):

python -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"

Uso pela linha de comando

separador-rreo diario.pdf --municipios "Bodó" "Coronel João Pessoa" "Angicos"

Opções:

Opção Descrição
pdf Caminho do diário FEMURN (obrigatório se houver mais de um PDF na pasta)
--municipios Um ou mais nomes de municípios
--saida Pasta de saída (padrão: RREO_separados)
--version Mostra a versão

Sem argumentos, o comando pergunta interativamente pelo PDF e pelos municípios:

separador-rreo

Também é possível executar como módulo:

python -m separador_rreo diario.pdf --municipios "Bodó"

Saída gerada

RREO_separados/
├── BODO/
│   ├── RREO_01_BODO.pdf
│   ├── RREO_03_BODO.pdf
│   └── …
├── Controle_Publicacoes.xlsx
RREO_separados.zip

A coluna Situacao da planilha indica:

  • Encontrado — recorte delimitado pelo código identificador
  • Verificar limite final — código ausente; vale conferência manual
  • Nao localizado — anexo não encontrado para aquele município
  • variações com partes reunidas / multiplas publicacoes quando há fusão ou mais de uma publicação

Uso como biblioteca

Separação completa

from separador_rreo import separar_rreo

resultado = separar_rreo(
    "diario.pdf",
    municipios=["Bodó", "Angicos"],
    destino="saida_rreo",
)

print(resultado.quantidade_pdfs)
print(resultado.planilha)
print(resultado.arquivo_zip)

Análise e exportação separadas

from separador_rreo import SeparadorRreo

separador = SeparadorRreo()
analise, exportacao = separador.executar(
    "diario.pdf",
    municipios=["Bodó"],
    destino="saida_rreo",
)

for ocorrencia in analise.do_municipio("Bodó"):
    print(
        ocorrencia.anexo,
        ocorrencia.pagina_inicial,
        ocorrencia.pagina_final,
        ocorrencia.situacao.value,
    )

Tipos do domínio

Os anexos e as situações são representados por enums. Isso reduz erros de digitação e facilita comparações:

from separador_rreo import AnexoRreo, SituacaoOcorrencia

if ocorrencia.anexo is AnexoRreo.BALANCO_ORCAMENTARIO:
    print("Balanço orçamentário localizado")

if ocorrencia.situacao is SituacaoOcorrencia.VERIFICAR_LIMITE_FINAL:
    print("É necessário conferir manualmente o fim do recorte")

Ensinar um título novo ao reconhecedor

O pacote já conhece vários jeitos de um anexo RREO aparecer no diário (por exemplo ANEXO 01_RREO ou RREO - 4º BIM - BALANÇO ORÇAMENTÁRIO).

Se um município publicar com um texto de título diferente, o pacote pode não achar esse anexo. Nesse caso você pode passar uma função pequena que olha cada linha do PDF e devolve o número do anexo (ou None se a linha não for um título):

from separador_rreo import (
    AnalisadorRreo,
    AnexoRreo,
    ReconhecedorTituloRreo,
    SeparadorRreo,
)

def reconhecer_titulo_do_meu_municipio(linha: str) -> int | None:
    # Exemplo: se a linha for um título do Anexo 9, retorne 9
    if "DEMONSTRATIVO X DO ANEXO 9" in linha.upper():
        return AnexoRreo.RECEITAS_OPERACOES_CREDITO
    return None

reconhecedor = ReconhecedorTituloRreo(
    regras_adicionais=[reconhecer_titulo_do_meu_municipio]
)
separador = SeparadorRreo(
    analisador=AnalisadorRreo(reconhecedor=reconhecedor)
)
analise, exportacao = separador.executar(
    "diario.pdf", ["Meu Município"], "saida_rreo"
)

As regras adicionais são executadas junto com as regras já fornecidas pelo pacote. Assim você amplia o reconhecimento sem alterar o código interno.

Organização do código

  • analisador.py localiza municípios, títulos e limites dos anexos;
  • reconhecimento.py contém as regras de reconhecimento de títulos;
  • exportacao.py coordena a geração dos artefatos;
  • planilha.py, compactacao.py e agrupamento.py cuidam de tarefas específicas;
  • documento_pdf.py isola a dependência do PyMuPDF;
  • contratos.py, modelos.py e enumeracoes.py definem os contratos e o domínio.

Requisitos

  • Python 3.10+
  • Dependências: pymupdf, openpyxl
  • PDF com texto selecionável (OCR prévio se o diário for só imagem)

Testes

pytest
ruff check src tests

Há um diário de exemplo em tests/fixtures/publicado_117684.pdf usado no teste de integração.

Autores

Licença

MIT — veja LICENSE.

Metadata

Release files for separador-rreo 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for separador-rreo 0.3.0
File Size Uploaded
separador_rreo-0.3.0.tar.gz 13.4 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for separador-rreo 0.3.0
File Interpreter ABI Platform
separador_rreo-0.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 13.4 MB

Release files / separador_rreo-0.3.0.tar.gz

Download URL separador_rreo-0.3.0.tar.gz
Size 13.4 MB
Tags Source
SHA-256 checksum
How to use checksums
9ea7ff18f78d836b0fe3a5035b6a2ffa815f3040c362d8b56d20f344c7198e92
BLAKE2b-256 checksum
How to use checksums
57b2684e3d533ce3b71fe7c85f6c813d97ba4286ddde0e0df46b3021e624bad0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.15

Release files / separador_rreo-0.3.0-py3-none-any.whl

Download URL separador_rreo-0.3.0-py3-none-any.whl
Size 22.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
350f8cd1ba29a9d3525bfe4de4d8893ed80f5dcb386e93fa59ae049f289d21c7
BLAKE2b-256 checksum
How to use checksums
efd6688317ce1f9402b7f655efcfa64787862beb9f09d1d0aacef8c635c9d852
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.15

Release history Release notifications | RSS feed

This release

0.3.0 This release

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page