POTHIEDU Não Decore a Resposta. Entenda o Caminho

O Que O Vigilante Faz

O Que O Vigilante Faz

Guia prático de validação com Vigilante

Vigilante é uma biblioteca de validação de dados para Python, bastante usada em projetos Django e APIs FastAPI no Brasil. O básico é simples: você define um esquema, passa os dados brutos (geralmente um JSON ou dict) e ela devolve um resultado validado ou uma lista de erros detalhados. O que o vigilante faz, resumidamente, é transformar campos que podem ser qualquer coisa em tipos estritos com regras configuráveis. A instalação é padrão pip: pip install vigilante

Depois disso, você importa e define um esquema. Aqui vai um exemplo mínimo que eu uso no dia a dia: from vigilante import Schema, Required, String, Integer class UserSchema(Schema):

nome = Required(String()) idade = Integer(min=0, max=120) email = Required(String())

O que é um Vigilante? Entenda a profissão, O que faz e Como ser
O que é um Vigilante? Entenda a profissão, O que faz e Como ser

Para validar, chama schema.load(data). Se algo estiver errado, o método levanta uma exceção com um dicionário de erros organizado por campo. Esse é o fluxo principal que a maioria dos desenvolvedores segue.

O que o vigilante faz na prática

O grande diferencial dele em relação a outras bibliotecas de validação similares é a forma como lida com conversões implícitas de tipos. Você pode passar um string "25" para um campo Integer e ele converte automaticamente, desde que a string seja um número válido. Isso economiza uma linha de código que seria necessária se você tivesse que fazer a conversão manualmente antes de chamar o validador. Outro ponto: o modo de validação em lote. Diferente de bibliotecas que param no primeiro erro encontrado, o Vigilante percorre todos os campos e gera um mapa completo de problemas. Em uma API que recebe payload com 20 campos, isso evita que o cliente tenha que corrigir um erro por vez em requisições separadas. Cuidado com campos obrigatórios e opcionais misturados. Se um campo Required() não vier no payload, o erro retornado é "campo requerido ausente". Mas se o campo existir com valor null, o comportamento muda — algumas versões tratam null como ausente, outras como valor presente nulo. Sempre verifique isso na documentação da versão que você está usando.

Um caso real que eu encontrei

Tinha um endpoint de cadastro de usuário que recebia datas em formato YYYY-MM-DD como string. Funcionava bem até um usuário enviar "01/01/2024" com barras em vez de traços. O campo String() aceitava sem reclamar, mas na hora de gravar no banco, a consulta falhava porque a query esperava o formato correto. Não era um erro de validação — era um erro silencioso que só aparecia na camada seguinte. A solução foi adicionar um filtro de formatação personalizada. Eu criei uma subclass simples de String que normaliza barras para traços antes de validar: class DateString(String):

Vigilante - O que é, O que faz, Onde trabalha e Como se Tornar ...
Vigilante - O que é, O que faz, Onde trabalha e Como se Tornar ...

def deserialize(self, value, context=None): if isinstance(value, str) and "/" in value: value = value.replace("/", "-")

return super().deserialize(value, context) Esse padrão de subclass fica limpo e mantém a responsabilidade de transformação perto da definição do esquema, sem espalhar lógica de sanitização pelo código da view.

Pegadinhas comuns

Valores vazios em campos String não disparam erro de required, apenas de length. Ou seja, uma string vazia passa na obrigatoriedade mas falha se você configurar min_length=1. Muita gente acha que vazio é o mesmo que ausente, mas não é. Outro ponto: a ordem dos esquemas importa. Se você usa composição com subclasses e herança, o esquema pai é verificado primeiro. Um campo definido no pai e sobrescrito no filho pode ter seu behavior alterado de forma inesperada se os validadores forem incompatíveis. Performance também vale atenção. Em payloads muito grandes com muitos campos aninhados, o tempo de validação cresce linearmente. Para requisições que vêm com centenas de campos, considere validar apenas o que é necessário usando o modo parcial ou filtrando o input antes de passar para o schema.

O que faz um vigilante? suas funções e responsabilidades
O que faz um vigilante? suas funções e responsabilidades

Alternativas quando o Vigilante não é a melhor opção

Se seu projeto já usa Pydantic, a curva de aprendizado é pequena e Pydantic tem suporte nativo para integração com FastAPI, serialização automática e geração de schemas OpenAPI. O Vigilante é mais leve e tem uma API mais direta para quem está começando, mas perde em recursos avançados como validação customizada via decorators e integrações com frameworks modernos. Outra alternativa é o Cerberus, mais antigo, com suporte a validação simples e extensível, porém sem a elegância das conversões automáticas que o Vigilante oferece. Para projetos Django puros, existe ainda o Django REST Framework serializers, que já vem embutido no ecossistema.

Download e recursos

O código-fonte e a documentação estão no PyPI. Você encontra o pacote em pypi.org/project/vigilante/. A documentação oficial tem exemplos de uso com nested schemas, validação personalizada e integração com Flask, que cobre a maioria dos casos de uso comuns. Se tiver dúvidas específicas sobre algum schema ou comportamento de validação, o repositório no GitHub tem issues abertas onde usuários relatam problemas similares e mantenedores respondem com workarounds. Vale dar uma olhada antes de abrir uma nova issue.