Metadata-Version: 2.4
Name: br-address-normalize
Version: 0.1.0
Summary: Biblioteca de normalização de endereços brasileiros
Author: Inspire / F1 Qualidade
License: MIT
Project-URL: Homepage, https://github.com/inspire-f1/br-address-normalize
Project-URL: Bug Tracker, https://github.com/inspire-f1/br-address-normalize/issues
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Natural Language :: Portuguese (Brazilian)
Classifier: Topic :: Text Processing :: Linguistic
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: pydantic>=2.0.0
Requires-Dist: httpx>=0.24.0
Requires-Dist: redis>=5.0.0
Requires-Dist: symspellpy>=6.7.0
Dynamic: license-file

# Pipeline de Normalização de Endereços

Sistema de normalização de endereços brasileiros com expansão de abreviações, correção ortográfica e tratamento de encoding corrompido.

## Arquitetura Geral

```
+-----------------------------------------------------------------------------------+
|                               NormalizerFacade                                    |
|                                                                                   |
|  +----------+  +----------+  +-------------+  +-------------+  +--------------+  |
|  |Uppercase |->| Encoding |->|Abbreviation |->|Preprocessing|->|   Spelling   |  |
|  |  Step    |  |   Step   |  |    Step     |  |    Step     |  |     Step     |  |
|  +----------+  +----------+  +-------------+  +-------------+  +--------------+  |
|                                                                                   |
+-----------------------------------------------------------------------------------+
```

## Fluxo de Processamento

O pipeline processa endereços em 5 etapas sequenciais. A ordem é crítica:
encoding é corrigido logo após o uppercase para que abreviações operem
sobre texto íntegro, e abreviações são expandidas antes da limpeza para
que a remoção de prefixo duplicado funcione corretamente.

### 1. UppercaseStep

Converte todos os campos de texto para UPPERCASE. Executado primeiro para
garantir que tokens sejam identificados corretamente nas etapas seguintes.

**Campos processados:** `logradouro`, `numero`, `complemento`, `bairro`, `municipio`, `uf`

**Arquivo:** `src/pipeline/steps/uppercase.py`

### 2. EncodingStep (Correção de Encoding)

Corrige nomes corrompidos por conversão ISO-8859-1 → ASCII. Executado antes
das abreviações para que o texto esteja íntegro na hora da expansão.

**Exemplos de correção:**
- `ANT NIO` → `ANTÔNIO`
- `JOO` → `JOÃO`
- `CORA OES` → `CORAÇÕES`
- `GET LIO` → `GETÚLIO`

**Campos processados:** `logradouro`, `complemento`, `bairro`

**Arquivo:** `src/modules/encoding.py`

### 3. AbbreviationStep (Expansão de Abreviações)

Expande abreviações usando o provider configurado (local, API ou orchestrator).
Executado antes da limpeza para que tipos expandidos sejam reconhecidos
na remoção de prefixo duplicado (ex: `R RUA SILVA` → `RUA RUA SILVA` → `RUA SILVA`).

**Campos processados:** `logradouro`, `complemento`, `bairro`

**Arquitetura L1/L2:**
- **L1 (Determinística):** Regras hardcoded com confiança 100%
- **L2 (Probabilística):** Fallback opcional via API externa

**Arquivo principal:** `src/modules/abbreviation/orchestrator.py`

### 4. PreprocessingStep (Limpeza)

Normaliza e limpa dados brutos.

**Operações (em ordem):**
1. Remoção de placeholders (`LOGRADOURO`, `ENDERECO`, `INDEFINIDO`)
2. Remoção de prefixos duplicados (`RUA RUA` → `RUA`)
3. Remoção de códigos numéricos no início
4. Separação de número colado no logradouro
5. Normalização de CEP (com detecção de inválidos)
6. Normalização de UF (2 caracteres)

**Campos processados:** todos

**Arquivo:** `src/modules/preprocessing.py`

#### Normalização de CEP

O CEP passa por 3 etapas:

**1. Limpeza:** Remove absolutamente tudo que não for dígito.

**2. Padding/Ajuste:**
| Tamanho | Ação | Motivo |
|---------|------|--------|
| 8 dígitos | Mantém | CEP íntegro |
| 7 dígitos | Adiciona `0` à esquerda | Perda de formatação Excel |
| 9 dígitos começando com `0` | Remove primeiro `0` | Exportação errônea (080010-000) |
| Outros | Mantém + flag `cep_invalido=True` | CEP incorreto |

**3. Filtro de Lixo:**
CEPs que passam na contagem mas são falsos:
- Sequências repetidas: `00000000`, `11111111`, ..., `99999999`
- Sequências óbvias: `12345678`, `87654321`

Quando detectado, o campo `cep_invalido` é setado como `True` no resultado.

### 5. SpellingStep (Correção Ortográfica)

Corrige erros ortográficos em nomes próprios.

**Campos processados:** `logradouro`, `bairro`, `municipio`

**Arquivo:** `src/modules/spelling/`

---

## Sistema de Abreviações (Detalhado)

### Camada L1 — Gates de Decisão

O motor determinístico processa tokens através de 8 gates em ordem:

| Gate | Nome | Descrição | Ação |
|------|------|-----------|------|
| 1 | TOKENS_TO_REMOVE_FIELD | `ND`, `NINF` | Nulifica campo inteiro |
| 1.5 | SIGLA_SISTEMA | `NI`, `END` | Expande + flag para consumidor |
| 2 | DO_NOT_EXPAND | Siglas de órgãos | Preserva sem tocar |
| 3 | BCO | Ambiguidade BECO/BANCO | Resolução posicional |
| 4 | PENDING_SAMPLE | Tokens em análise | Preserva + flag |
| 5 | POSITIONAL_AMBIGUOUS | `CD`, `CM`, `PA`, `LG`, `GL`, `BX` | Resolução contextual |
| 6 | Dicionários por Categoria | Ver tabela abaixo | Expansão por campo |
| 7 | Dicionário Geral | Injetado/configurado | Fallback |
| 8 | SIGLA+dígito | Padrão `ABC123` | Flag código interno |

**Arquivo:** `src/modules/abbreviation/deterministic.py`

### Dicionários por Categoria

| Dicionário | Campos Aplicáveis | Posições |
|------------|-------------------|----------|
| TIPO_LOGRADOURO | logradouro, bairro | 0-1 (logradouro), qualquer (bairro) |
| TITULO_PROPRIO | logradouro, bairro | qualquer |
| MUNICIPIO_SAFE | municipio | qualquer |
| COMPLEMENTO | complemento | qualquer |

**Arquivo de regras:** `src/modules/abbreviation/entity_rules.py`

### Resolução de Ambiguidades

**BCO (Beco vs Banco):**
- Posição 0 em logradouro → `BECO`
- Outras posições → `BANCO`

**PA (Passagem vs Projeto de Assentamento):**
- Em logradouro → `PASSAGEM`
- Em complemento com `zona_rural=True` → `PROJETO DE ASSENTAMENTO`

---

## Arquivos de Dados

Todos os dicionários de abreviações ficam centralizados em `src/data/` para fácil manutenção:

| Arquivo | Descrição |
|---------|-----------|
| `abbreviations.json` | Dicionário geral (LocalProvider, ApiProvider) |
| `complement_expansions.json` | Expansões específicas de complemento |
| `null_markers.json` | Marcadores de campo vazio/nulo |
| `brasilia_prefixes.json` | Prefixos de Brasília para expansão contextual |
| `whitelist.json` | Nomes que não devem ser alterados pelo corretor |

---

## Abreviações Implementadas

### Tipos de Logradouro

| Sigla | Expansão |
|-------|----------|
| R | Rua |
| AV | Avenida |
| TV, TRA | Travessa |
| RD, ROD | Rodovia |
| AL | Alameda |
| RM, RAM | Ramal |
| ET, ESTR | Estrada |
| PCA | Praça |
| BEC, BCO | Beco |
| PSG | Passagem |
| VIL, VLA | Vila |
| CGO, CRG | Córrego |
| FZ | Fazenda |
| IG | Igarapé |
| JRD | Jardim |
| CHAC | Chácara |
| DIST | Distrito |
| LG | Largo |
| PQ, PARQ, PQE | Parque |
| COND | Condomínio |
| CONJ | Conjunto |
| BALN | Balneário |
| UNIV | Universidade |
| ST | Setor |
| QD | Quadra |
| VC | Vicinal |
| LIN, LI | Linha |

### Títulos e Tratamentos

| Sigla | Expansão |
|-------|----------|
| PRES | Presidente |
| GEN | General |
| MAL | Marechal |
| CAP | Capitão |
| CEL | Coronel |
| DR | Doutor |
| PE | Padre |
| PROF, PRF | Professor |
| VER | Vereador |
| SEN | Senador |
| DEP | Deputado |
| GOV | Governador |
| PREF | Prefeito |
| DES | Desembargador |
| DQ | Duque |
| MARQ | Marquês |
| CDE | Conde |
| CDR, CDOR | Comendador |
| DNA | Dona |
| FCO | Francisco |
| JOS | José |
| JORN | Jornalista |
| MNS | Monsenhor |
| NS | Nossa Senhora |
| NSA | Nossa Senhora Aparecida |
| NSRA | Nossa Senhora |
| JK | Juscelino Kubitschek |
| JR | Júnior |
| FREI | Frei |
| STA | Santa |
| STO | Santo |

### Complemento

| Sigla | Expansão |
|-------|----------|
| APTO, APT | Apartamento |
| BL, BLC | Bloco |
| QD, QDA | Quadra |
| LT | Lote |
| SL | Sala |
| LJ | Loja |
| AND | Andar |
| COND | Condomínio |
| CONJ | Conjunto |
| EDIF | Edifício |
| FD, FUND | Fundos |
| FR | Frente |
| KIT | Kitnet |
| MOD | Módulo |
| NR | Número |
| PV | Pavimento |
| PROX, PX | Próximo |
| SOB | Sobrado |
| SS | Subsolo |
| ST | Setor |
| BX | Box |
| KM | Quilômetro |

### Siglas de Órgãos (Preservadas)

Estas siglas são preservadas sem expansão:

`ABC`, `CEEE`, `CTG`, `DAER`, `DNER`, `IBGE`, `PTB`, `SESI`, `SHIS`, `DF`, `KVA`

---

## Uso do Pipeline

```python
from address_normalizer.facade import NormalizerFacade
from address_normalizer.modules.abbreviation.local_provider import LocalAbbreviationProvider
from address_normalizer.modules.spelling.symspell_corrector import SymSpellCorrector

# Inicializar providers
abbreviation_provider = LocalAbbreviationProvider()
spelling_corrector = SymSpellCorrector()

# Criar facade
normalizer = NormalizerFacade(
    abbreviation_provider=abbreviation_provider,
    spelling_corrector=spelling_corrector,
)

# Normalizar endereço
endereco = {
    "logradouro": "R DR JOAO SILVA",
    "numero": "123",
    "complemento": "APTO 45",
    "bairro": "JRD AMERICA",
    "municipio": "SAO PAULO",
    "uf": "SP",
    "cep": "01234567",
}

result = await normalizer.normalize(endereco)
```

---

## Parâmetros de Configuração

### ExpanderConfig

| Parâmetro | Tipo | Default | Descrição |
|-----------|------|---------|-----------|
| use_default_dictionaries | bool | True | Carrega dicionários padrão |
| custom_general_dict | dict | {} | Dicionário adicional customizado |
| preserve_unknown_codes | bool | True | Preserva códigos internos (ABC123) |
| l2_caller | Callable | None | Função async para L2 probabilístico |
| min_l2_confidence | float | 0.85 | Confiança mínima para aceitar L2 |
| nullify_sistema_siglas | bool | False | Nulifica siglas de sistema (NI, END) |

---

## Estrutura de Diretórios

```
src/
├── core/
│   └── base.py                 # Interface PipelineStep
├── data/
│   ├── __init__.py             # Funções de carregamento de dados
│   ├── abbreviations.json      # Dicionário geral de abreviações
│   ├── complement_expansions.json  # Expansões de complemento
│   ├── null_markers.json       # Marcadores nulos
│   ├── brasilia_prefixes.json  # Prefixos de Brasília
│   └── whitelist.json          # Whitelist ortográfica
├── facade.py                   # Fachada pública do módulo
├── modules/
│   ├── abbreviation/
│   │   ├── base.py             # Interface AbbreviationProvider
│   │   ├── api_provider.py     # Provider via API externa
│   │   ├── local_provider.py   # Provider via JSON local
│   │   ├── orchestrator.py     # Orquestrador L1/L2
│   │   ├── orchestrator_adapter.py  # Adapter para interface Provider
│   │   ├── deterministic.py    # Camada L1 determinística
│   │   ├── entity_rules.py     # Regras por campo
│   │   ├── heuristics.py       # Heurísticas de confiança L2
│   │   ├── models.py           # Dataclasses do módulo
│   │   └── complement_expander.py  # Expansor específico de complemento
│   ├── encoding.py             # Correção de encoding corrompido
│   ├── preprocessing.py        # Limpeza e normalização
│   └── spelling/
│       ├── base.py             # Interface SpellingCorrector
│       └── symspell_corrector.py  # Implementação SymSpell
├── pipeline/
│   ├── orchestrator.py         # Pipeline principal
│   └── steps/
│       ├── uppercase.py        # Step de uppercase
│       ├── encoding.py         # Step de encoding
│       ├── abbreviation.py     # Step de abreviações
│       ├── preprocessing.py    # Step de limpeza
│       └── spelling.py         # Step de ortografia
└── schemas/
    └── endereco.py             # Schemas Pydantic/dataclass
```

---

## Notas de Implementação

1. **Ordem do Pipeline:** Uppercase → Encoding → Abreviações → Limpeza → Ortografia. Encoding vem antes de abreviações para que o texto esteja íntegro. Abreviações vêm antes da limpeza para que `R RUA` seja expandido para `RUA RUA` e depois deduplicado.

2. **Ordem dos Gates:** A ordem dos gates no `DeterministicLayer` é crítica. Gates anteriores têm prioridade sobre posteriores.

3. **Resolução Posicional:** Tokens como `BCO`, `PA`, `BX` têm significados diferentes dependendo do campo e posição.

4. **L2 Probabilístico:** Só é acionado para posição 0 do logradouro e requer `l2_caller` configurado.

5. **Encoding:** O módulo de encoding usa regex ordenadas por especificidade (mais longas primeiro).

6. **Whitelist:** Nomes na whitelist não são alterados pelo corretor ortográfico.

7. **Conflitos Conhecidos:**
   - `PRF`: No sistema = Professor. Na lista de referência = Polícia Rodoviária Federal. Mantido como Professor por ser mais comum em endereços.
   - `PA`: Tratado como PASSAGEM em logradouro, PROJETO DE ASSENTAMENTO em complemento rural.
