O Anonbr tem como objetivo transformar dados sensíveis de formato padrão brasileiro para que documentos (atualmente apenas CSV) possam ser compartilhados de forma segura, sem exposição de dados pessoais, conforme a LGPD.
Contribua sem compromisso, talvez isso se transforme em algo grande, talvez não, o que importa é praticar e estudar. O projeto foi criado para estimular programadores de todos os níveis a praticarem Python, testes, versionamento e boas praticas de engenharia de dados, aplicados a um problema real: anonimizacao de dados pessoais no contexto brasileiro.
Contribuições de qualquer nível são bem-vindas, desde correção de typos até novos detectores.
- Faça um fork do repositório e clone localmente:
git clone https://github.com/seu-usuario/anonbr.git
cd anonbr- Instale as dependências com uv:
uv sync --group dev Isso instala o projeto e as ferramentas de desenvolvimento (pytest, pytest-cov).
- Verifique que os testes passam antes de comecar:
uv run pytest tests/ -vou, sem pyproject:
# Crie e ative seu ambiente virtual
python3 -m venv venv
source venv/bin/activate
# Instale as dependências do projeto
pip install -r requirements.txt
pip install -e .
# Execute o teste
pytest tests/ -vSe todos passarem, o ambiente está pronto.
Antes de contribuir, entenda como o projeto está organizado:
anonbr/
├── __init__.py # API pública do pacote (imports e __all__)
├── anonymizer.py # Orquestrador que processa DataFrames
├── pattern_loader.py # Carregador central dos padrões regex do YAML
└── detectors/
├── cpf.py # Detecção e mascaramento de CPF
├── cnpj.py # Detecção e mascaramento de CNPJ
├── email.py # Detecção e mascaramento de email
├── pdf.py # Detecção e mascaramento em PDF
└── telefone.py # Detecção e mascaramento de telefone
config/
└── patterns.yaml # Fonte única de todos os padrões regex
tests/
├── test_cpf.py
├── test_cnpj.py
├── test_email.py
├── test_pdf.py
├── test_pattern_loader.py
└── test_telefone.py
main.py # Script de execuçãoCada detector segue o mesmo padrão: uma classe com métodos detect e mask, e funções auxiliares (helpers) fora da classe para uso rápido. A detecção é baseada em padrões visuais via regex, sem validação matemática. Isso é intencional: para anonimização, qualquer dado que pareça um CPF, email ou telefone deve ser mascarado.
Os padrões regex não ficam no código dos detectores. Todos são definidos no config/patterns.yaml e carregados via pattern_loader. Isso centraliza as expressões regulares num único lugar e evita duplicação entre os detectores de CSV e PDF.
O mascaramento tem três níveis: high (mascara tudo), default (equilíbrio) e low (revela mais). Novos detectores devem seguir esse mesmo padrão.
O projeto precisa de ajuda em diversas frentes. Algumas ideias: implementar novos detectores (RG, CEP, CNH, PIS, etc), suporte a processamento em batch com múltiplos arquivos, etc.
Tip
Não se limite a essa lista. Se identificar algo que pode melhorar, abra uma issue ou mande um PR.
Aqui está o caminho mais direto para quem quer adicionar um padrão de dado novo ou uma variação de padrão existente.
Se o dado já tem um detector (CPF, CNPJ, email, telefone) e você quer adicionar uma nova forma de escrita que ainda não é reconhecida, o fluxo é simples:
1. Abra o config/patterns.yaml e localize a chave do detector.
Cada chave tem uma lista patterns. Cada item da lista tem:
- name: nome_do_padrao # identificador único, usado pelo código
regex: 'sua_expressao' # expressão regular como string YAML simples
description: descrição # texto legível explicando o padrão2. Adicione seu padrão ao final da lista, respeitando a ordem de prioridade.
Os padrões são carregados na ordem em que aparecem no YAML. Padrões mais específicos devem vir antes dos mais genéricos para que a deduplicação por posição funcione corretamente.
3. Verifique se o detector existente consegue usar o novo padrão sem alteração.
Para detectores que carregam os padrões como lista ordenada (como telefone.py), o novo padrão é capturado automaticamente. Para detectores que acessam por nome (como cpf.py), pode ser necessário adicionar uma linha no __init__ do detector para carregar o novo nome.
4. Escreva testes para o novo padrão no arquivo de testes correspondente em tests/.
Se o dado ainda não tem nenhum suporte (RG, CEP, CNH, etc.), o processo tem mais etapas mas segue sempre o mesmo padrão:
1. Defina os padrões no config/patterns.yaml com uma nova chave no nível raiz:
rg:
description: "Registro Geral"
priority: 4
patterns:
- name: formatted
regex: 'seu_regex_aqui'
description: "RG formatado com ponto e traço"
- name: unformatted
regex: 'outro_regex'
description: "RG apenas com dígitos"2. Crie o arquivo do detector em anonbr/detectors/nome_dado.py seguindo a estrutura dos detectores existentes:
from anonbr.pattern_loader import get_compiled_by_name
class NomeDadoDetector:
def __init__(self):
compiled = get_compiled_by_name('chave_no_yaml')
self.formatted_regex = compiled['formatted']
self.unformatted_regex = compiled['unformatted']
def detect(self, text: str) -> list:
...
def mask(self, value: str, level: str = 'default') -> str:
...
# Funções auxiliares
def detect_nome_dado(text: str) -> list:
return NomeDadoDetector().detect(text)
def mask_nome_dado(value: str, level: str = 'default') -> str:
return NomeDadoDetector().mask(value, level)3. Exporte o detector em anonbr/__init__.py para que fique disponível na API pública do pacote.
4. Integre ao anonymizer.py se quiser que o novo detector seja chamado automaticamente no fluxo principal de CSV.
5. Integre ao pdf.py se quiser suporte em PDF também. Nesse caso, adicione o padrão ao dict self.patterns e implemente o método _nome_dado_mask_pattern.
6. Escreva os testes em tests/test_nome_dado.py. Cubra pelo menos: detecção do formato principal, detecção de variações, mascaramento nos três níveis e casos que não devem ser detectados (falsos positivos).
Note
Antes de criar um detector novo, confira se o dado que você quer detectar tem um padrão visual suficientemente distinto para não gerar falsos positivos em excesso. A validação aqui é sempre visual, não matemática.
- Escreva testes para qualquer código novo
- Não quebre testes existentes
- Mantenha o código legível e com comentários onde necessário
- Textos de outputs em PT-BR, devido ao foco atual em dados com padrão brasileiro