https://a.storyblok.com/f/270183/1368x665/282a97b9c0/26jul-pydantic_using_vonage_verify-blog_r1.jpg

Em busca da validação: validação de dados em Python com Pydantic e Vonage Verify

Publicado em July 30, 2026

Tempo de leitura: 17 minutos

Esta postagem no blog apresenta uma introdução ao Pydantic, a popular biblioteca de validação de dados para Python. Ela inclui uma demonstração do valor que o Pydantic oferece ao utilizar a Verify API do Vonage. 

Introdução

O que é o “duck-typing” em Python?

Para entender por que o Pydantic é uma biblioteca tão útil, é importante primeiro entender como funciona a tipagem no Python. Na programação, “tipagem” refere-se aos sistemas de classificação e categorização de dados. A forma como os dados são tipados determina como podem ser manipulados – por exemplo, não é possível somar a palavra “dois” com o número 2.

O Python deve grande parte de seu sucesso e popularidade à sua flexibilidade em relação à tipagem. Ao contrário da maioria das linguagens compiladas, que exigem que você declare explicitamente os tipos, o Python implementa algo chamado duck-typing. O duck-typing é um sistema de tipos dinâmico que parte do princípio de que, se um objeto “anda como um pato e grasna como um pato, então deve ser um pato”.

Mais especificamente, de acordo com a documentação do Python, o duck-typing é:

“Um estilo de programação que não leva em conta o tipo de um objeto para determinar se ele possui a interface correta; em vez disso, o método ou atributo é simplesmente chamado ou utilizado… Ao dar ênfase às interfaces em vez de tipos específicos, um código bem projetado aumenta sua flexibilidade, permitindo a substituição polimórfica. O duck-typing evita testes que utilizam type() ou isinstance().”

Na prática, um exemplo disso é a função len função do Python. len() retorna “o comprimento (o número de itens) de um objeto”. No código abaixo, observe como len() ela produz uma saída corretamente, independentemente do tipo de objeto com o qual é chamada:

>>> example_1 = "Hello? World!"
>>> type(example_1)
<class 'str'>

>>> example_2 = [1, 3, 5, 8]
>>> type(example_2)
<class 'list'>

>>> example_3 = {"hello" : "world", "foo": "bar"}
>>> type(example_3)
<class 'dict'>

>>> len(example_1)
13                                 # 13 letters in "Hello? World!"

>>> len(example_2)
4                                  # 4 items in the list

>>> len(example_3)
2                                  # 2 key-value pairs in the dictionary

Em um exemplo de tipagem dinâmica que provavelmente representa melhor o que você pode encontrar no Python na prática, o código abaixo define três classes diferentes de raças de cães, sendo que cada uma delas pode bark():

class Pug:
    def bark(self):
        print("The pug goes arf arf!")

class LabradorRetriever:
    def bark(self):
        print("The labrador retriever goes arf arf!")

class Wolfhound:
    def bark(self):
        print("The wolfhound goes arf arf!")

Você pode instanciar um exemplar de cada raça de cão e chamar bark() a interface em cada um deles sem erros, pois todos possuem a mesma interface. Graças ao duck-typing, o código a seguir é executado com sucesso:

>>> pets = [Pug(), LabradorRetriever(), Wolfhound()]

>>> for pet in pets:
...     pet.bark()

The pug goes arf arf!
The labrador retriever goes arf arf!
The wolfhound goes arf arf!

pet pode ser da classe Pug, LabradorRetriever, ou Wolfhound e o Python ainda assim chamará a bark função sem erros.

 Isso pode ser prático e, em muitos contextos, é exatamente o que você deseja. Para scripts, ciência de dados e trabalhos exploratórios, a tipagem dinâmica do Python é um recurso, não um defeito. A tipagem por semelhança permite que você itere rapidamente sem a sobrecarga de declarações de tipo rígidas. Isso é um dos principais motivos pelos quais o Python se tornou a linguagem dominante para fluxos de trabalho de IA e ciência de dados.

No entanto, a situação muda significativamente no código de back-end de produção. Uma aplicação Flask ou Django sem tipos declarados pode causar dificuldades na manutenção e na depuração. Com o duck-typing do Python, as incompatibilidades de tipos se manifestam como erros de tempo de execução enigmáticos, em vez de falhas claras e precoces. O problema se torna ainda mais grave quando as aplicações dependem de tipos específicos de dados para funcionar conforme o esperado, como ao trabalhar com APIs, processar arquivos de configuração ou lidar com entradas do usuário. 

Por exemplo, se você definiu a seguinte classe:

class Sphynx:
    def meow(self):
        print("The sphynx goes meow meow!")

E, em seguida, atualizei o código de exemplo para incluir uma instância de Sphynx na lista de pets pela qual se deve iterar, você encontrará um erro:

>>> pets = [Pug(), LabradorRetriever(), Sphynx()]

>>> for pet in pets:
...     pet.bark()
...     

The pug goes arf arf!
The labrador retriever goes arf arf!
Traceback (most recent call last):
  File "<python-input-74>", line 2, in <module>
    pet.bark()
    ^^^^^^^^
AttributeError: 'Sphynx' object has no attribute 'bark'

Como ilustra este exemplo, em determinados contextos, a flexibilidade do duck-typing torna-se um risco. Por exemplo, um tipo incorreto passado a uma chamada de API pode não gerar erro até que a solicitação já esteja em andamento, o que pode resultar em um custo financeiro por uma chamada cobrável que estava fadada a falhar desde o início.

Uma maneira de resolver alguns dos problemas que surgem com a tipagem dinâmica é por meio das dicas de tipo.

O que são anotações de tipo?

Uma sugestão de tipo é uma anotação de código que “especifica o tipo esperado para uma variável, um atributo de classe, um parâmetro de função ou um valor de retorno”. Portanto, uma anotação de tipo refere-se à forma como as dicas de tipo são utilizadas sintaticamente no Python.

O código a seguir é um exemplo básico do uso de anotação de tipo:

def greeting(name: str) -> str:
    return 'Hello ' + name

Neste exemplo, a sugestão de tipo é str e a anotação de tipo é a name: str e -> str . A anotação de tipo nos informa que o tipo esperado do parâmetro name é uma string e que o tipo de retorno esperado da função greeting é uma string.

Adicionando anotações de tipo à classe de exemplo Pug poderia ficar assim:

class Pug:
    def init(self, name: str) -> None:
        self.name: str = name

    def bark(self) -> None:
        print(f"The pug {self.name} goes arf arf!")

E se atualizarmos nosso pets código de iteração para incluir anotações de tipo, ele poderia ficar assim:

def make_dogs_bark(pets: List[Pug | LabradorRetriever | Wolfhound ]) -> None:
    for pet in pets:
        pet.bark() 

make_dogs_bark([Pug(), LabradorRetriever(), Sphynx()])

Como o nome sugere, trata-se apenas de sugestões. Elas ajudam a tornar o código mais legível e fácil de manter, mas não são impostas pelo interpretador do Python. Poderíamos usar uma ferramenta adicional como o mypy para verificar os tipos e receber um erro como este:

error: List item 2 has incompatible type "Sphynx"; expected "Pug | LabradorRetriever | Wolfhound"  [list-item]

Isso teria que ser feito como uma etapa adicional – nada impede que esse código seja executado e gere um erro em tempo de execução.

Em busca de validação

Para evitar erros durante a execução — como uma chamada de API com dados incorretos —, você poderia validar os dados em sua solicitação antes de enviá-la. No código de exemplo, poderíamos definir algum tipo de validação para garantir que cada item da lista pets possa bark():

def make_dogs_bark_safely(dogs):
    """Manual validation in the function"""
    for dog in dogs:
        if not hasattr(dog, 'bark') or not callable(getattr(dog, 'bark')):
            raise TypeError(f"Invalid dog type: {type(dog).__name__}")
        dog.bark()

# Now this fails immediately with a clear message:
pets = [Pug(), Sphynx()]

make_dogs_bark_safely(pets)
# TypeError: Invalid dog type: Sphynx

Além de se tornar rapidamente tedioso e complicado, esse padrão prejudica algumas das vantagens da tipagem dinâmica inerente ao Python, ao mesmo tempo em que deixa de aproveitar alguns dos benefícios da anotação de tipos.

Felizmente, o Pydantic oferece validação de dados, mantendo a facilidade e a rapidez da linguagem por meio de uma sintaxe já integrada.

O que é o Pydantic?

Pydantic é uma biblioteca de validação de dados para Python que oferece os seguintes benefícios:

Vamos examinar mais de perto como esses recursos se combinam na prática para proporcionar uma validação de dados confiável e eficiente, em harmonia com a sintaxe e a estrutura do Python.

Principais recursos de validação do Pydantic

É importante entender que, no Pydantic, “validação” se refere ao “o processo de instanciar um modelo (ou outro tipo) que esteja em conformidade com os tipos e restrições especificados”. Em outras palavras, a validação do Pydantic se aplica ao resultado da instanciação de um modelo, e não aos dados de entrada. Assim, o Pydantic gera uma ValidationError quando os dados não podem ser analisados com sucesso para formar uma instância de um modelo.

ModeloBase

BaseModel está no cerne do Pydantic. Você herda dele para definir modelos de dados com campos anotados por tipo. Um dos principais métodos para definir esquemas no Pydantic é por meio de modelos. Ao instanciar um BaseModel o Pydantic valida automaticamente os dados em relação ao esquema definido.

Usando o Pydantic, a Pug classe agora fica assim:

class Pug(BaseModel):
    name: str
    age: int
    color: str = "fawn"

    def bark(self):
        print(f"The pug {self.name} goes arf arf!")

Se você fosse instanciar Pug, o Pydantic garantiria que o objeto resultante tivesse um name do tipo string, um age do tipo inteiro e um color do tipo string com fawn como valor padrão.

Sugestões de tipo e campos obrigatórios

As anotações de tipo controlam a validação do esquema e a serialização. Os campos declarados apenas com uma anotação de tipo são obrigatórios; os campos com valores padrão são opcionais.

Por Pug exemplo, o name campo está anotado com str , o que significa que qualquer sequência de caracteres é válida, mas uma sequência de caracteres deve ser fornecida; o mesmo se aplica ao age campo. O color campo, no entanto, fornece um valor padrão de fawn e, portanto, não é obrigatório ao instanciar um Pug.

Coerção de tipos

O Pydantic pode ser usado tanto no modo estrito quanto no modo flexível (padrão). No modo flexível, a biblioteca converterá automaticamente os dados para o tipo definido no esquema.

Então, por exemplo, se fornecêssemos "5" como uma string para o age de um Pug, o Pydantic a converteria em um inteiro.

Configuração de campo

A Field função permite adicionar metadados e restrições aos campos do esquema.

Alguns parâmetros comumente utilizados são:

  • Restrições como maior que gt) e maior ou igual a ge), e min_length e max_length

  •  Aliases para mapear nomes de campos de entrada e saída usando alias, validation_alias, e serialization_alias)

  • Modo estrito para impedir a coerção de tipos em determinados campos strict=True)

Para aplicar restrições ao name campo para Pug, você usaria o seguinte código:

class Pug(BaseModel):
    name: str = Field(..., min_length=1, description="The pug's name")
    age: int
    color: str = "fawn"

    def bark(self):
        print(f"The pug {self.name} goes arf arf!")

Serialização

As instâncias do modelo Pydantic podem ser convertidas em dicionários sem a necessidade de escrever nenhum código adicional de serialização, utilizando model_dump(). Isso facilita a serialização para JSON ou outros formatos para uso em outras partes do projeto. Por exemplo, model_dump_json() serializa um modelo diretamente para JSON.

A seguir, um exemplo de como criar uma instância de Pug e, em seguida, serializá-la usando uma das funções integradas do Pydantic:

matty_pug = Pug(name="Matty", age=14)

result = matty_pug.model_dump()

print(result)

O que geraria o seguinte resultado:

{'name': 'Matty', 'age': 14, 'color': fawn}

Qual é um caso de uso prático do Pydantic?

Desde sua criação, o Pydantic rapidamente se tornou uma das bibliotecas de validação de dados mais utilizadas para Python. Aproximadamente 8.000 pacotes no PyPI utilizam o Pydantic, incluindo (entre os mais conhecidos) o FastAPI, o huggingface, o Django Ninja, o SQLModel, o LangChain e o Vonage.

Em novembro de 2024, a Vonage lançou uma versão totalmente reescrita do SDK da Vonage para Python. Nem sempre é fácil recomeçar do zero, mas a reescrita foi uma oportunidade para fazer algumas melhorias estruturais essenciais e aprimorar a interação do usuário com o SDK.

Entre algumas das mudanças incluídas nessa iniciativa estava a incorporação do Pydantic ao SDK, com o objetivo de facilitar a chamada das APIs da Vonage e a análise das respostas.

Confira o Video abaixo para ouvir o depoimento de um de nossos desenvolvedores que trabalha no SDK do Python e ver o que ele tem a dizer sobre o uso do Pydantic.

Como o SDK do Python da Vonage utiliza os modelos do Pydantic

O uso de modelos Pydantic para formar solicitações garante a tipagem correta e facilita o envio dos objetos adequados às APIs da Vonage. Com a versão 4 do SDK, as respostas da API agora são deserializadas em modelos Pydantic totalmente documentados, o que proporciona mais consistência do que o retorno de dicionários, como na versão anterior. Além disso, ainda é possível converter modelos Pydantic em dicionários ou strings JSON com model.model_dump e model.model_dump_json respectivamente.

Nesta demonstração, vamos dar uma olhada na Verify API do Vonage e em como ela é modelada usando o Pydantic no SDK.

O que é a Verify API?

A Verify API é o produto de autenticação de dois fatores (2FA) de última geração da Vonage. Com a Verify API, você pode autenticar seus usuários e prevenir fraudes por meio de uma API simples e fácil de usar, que elimina a complexidade da 2FA em escala global.

Ela amplia os métodos tradicionais de autenticação ao oferecer suporte a uma gama mais ampla de canais, incluindo canais over-the-top (OTT), como o WhatsApp, além de SMS, voz e e-mail. A API oferece suporte tanto a tokens JSON da Web (JWT) quanto autenticação básica. A autenticação básica é mais fácil de começar a usar, mas não oferece suporte a recursos avançados, como ACLs. Você pode usar a autenticação JWT ou a básica, mas não ambas ao mesmo tempo. Saiba mais sobre autenticação na documentação.

Em linhas gerais, a Verify API segue este fluxo de trabalho:

  1. Um usuário final inicia uma solicitação de autenticação de dois fatores (2FA) em um aplicativo

  2. No back-end, essa solicitação de autenticação de duas etapas (2FA) aciona uma solicitação à Verify API

  3. A Verify API envia uma senha de uso único (OTP) ao usuário final por meio do canal configurado (SMS, chamada de voz, WhatsApp ou e-mail)

  4. O usuário final fornece a OTP ao aplicativo

  5. Isso inicia uma solicitação de Verify para comparar a OTP fornecida pelo usuário final com a OTP gerada pela API

  6. O resultado dessa verificação determina, então, o que acontece a seguir (o usuário final é autenticado, etc.)

A diagram of the Verify V2 Request with Summary Callbacks.A diagram of the Verify V2 Request with Summary Callbacks.Uma solicitação típica de verificação inicial inclui a seguinte carga útil:

{

   "locale": "es-es",
   "channel_timeout": 180,
   "client_ref": "myPersonalRef",
   "code_length": 4,
   "code": "e4dR1Qz",
   "brand": "ACME",
   "template_id": "4ed3027d-8762-44a0-aa3f-c393717413a4",
   "workflow": [
      {
         "channel": "sms",
         "to": "44770090000"
      },
      {
         "channel": "voice",
         "to": "44770090000"
      }
   ]
}

Isso é explicado com mais detalhes a seguir:

Chave

Descrição

Obrigatório ou opcional

configuração regional

A configuração regional a ser usada para a mensagem de verificação

Opcional; o valor padrão é en-us

tempo_de_espera_do_canal

O tempo, em segundos, que deve ser aguardado entre as tentativas de envio do código de verificação

Opcional; o valor padrão é 180 segundos

client_ref

Um identificador único para a solicitação de verificação

Opcional

comprimento_do_código

O comprimento do código de verificação a ser gerado

Opcional; o valor padrão é 4

código

Um código alfanumérico personalizado opcional a ser utilizado, caso você não queira que a Vonage gere o código

Opcional

marca

O nome da empresa ou do serviço que está enviando a solicitação de verificação – ele aparecerá no corpo da mensagem SMS ou TTS

Obrigatório, comprimento máximo de 16 caracteres

template_id

Um ID de modelo personalizado a ser usado – funciona apenas quando channel for sms ou rcs

Opcional

fluxo de trabalho

A lista de canais a serem utilizados no fluxo de trabalho de verificação, utilizados na ordem em que estão listados

Obrigatório, com no máximo 3 itens

Para saber mais sobre a API e como ela funciona, consulte a documentação do Vonage Verify.

Uma solicitação bem-sucedida retorna um 202 OK para indicar que a solicitação de verificação foi iniciada. A resposta também incluirá um request_id que é necessário para concluir o processo de verificação:

{"request_id": "c11236f4-00bf-4b89-84ba-88b25df97315",}

Ao mesmo tempo, a Vonage envia uma senha de uso único (OTP) ao usuário final por meio do fluxo de trabalho configurado, tentando cada canal na ordem em que estão definidos.

Assim que o usuário final receber e fornecer a OTP ao aplicativo, será enviada outra solicitação ao endpoint Verify com o request_id como parâmetro de caminho https://api.nexmo.com/v2/verify/:request_id) e a OTP no corpo da solicitação para a code chave.

Se o código fornecido corresponder ao código gerado e enviado pela Vonage, uma 200 OK resposta é retornada juntamente com um "status": "complete" .

Demonstração: Como a Verify API utiliza o Pydantic?

O SDK do Vonage para Python facilita a implementação das APIs do Vonage em um aplicativo Python. A integração do Pydantic ao SDK torna o uso das APIs ainda mais fácil. Com o Pydantic, em vez de descobrir um erro após fazer uma chamada à API e incorrer em cobranças, os modelos de solicitação são validados antes a execução, sem a necessidade de código adicional para isso.

A demonstração desta postagem no blog é um aplicativo minimalista de autenticação de duas etapas (2FA) que utiliza o framework FastAPI. O usuário final acessa uma página da web onde insere seu endereço de e-mail. Utilizando a Verify API, o aplicativo gera então um código OTP, que é enviado para o endereço de e-mail fornecido pelo usuário final. O usuário final fornece esse código à aplicação e, se a verificação da Verify for bem-sucedida, ele é recompensado com um GIF animado. 

Se quiser, você pode ir direto para código e usar o README para colocá-lo em funcionamento.

O código a seguir é onde a solicitação de Verify é criada:

   verify_request = VerifyRequest(
        brand=settings.verify_brand_name,
        workflow=[
            EmailChannel(to=email),
        ],
        channel_timeout=60,
        code_length=5,
    )

Se entrarmos no VerifyRequest objeto, encontramos um modelo Pydantic:

class VerifyRequest(BaseModel):
    brand: str = Field(..., min_length=1, max_length=16)
    workflow: list[
        Union[
            SilentAuthChannel,
            SmsChannel,
            WhatsappChannel,
            VoiceChannel,
            EmailChannel,
        ]
    ]
    locale: Optional[Locale] = None
    channel_timeout: Optional[int] = Field(None, ge=15, le=900)
    client_ref: Optional[str] = Field(None, min_length=1, max_length=16)
    code_length: Optional[int] = Field(None, ge=4, le=10)
    code: Optional[str] = Field(None, pattern=r'^[a-zA-Z0-9]{4,10}$')

    @model_validator(mode='after')
    def check_silent_auth_first_if_present(self):
        if len(self.workflow) > 1:
            for i in range(1, len(self.workflow)):
                if isinstance(self.workflow[i], SilentAuthChannel):
                    raise VerifyError(
                        'If using Silent Authentication, it must be the first channel in the "workflow" list.'
                    )
        return self

O esquema converte a solicitação da API em tipos usando anotações em Python e a Field função para definir restrições. O workflow campo define um Union tipo derivado de outros tipos modelados, demonstrando como os tipos podem ser aninhados.

Por fim, o model_validator(mode='after') é um decorador do Pydantic que oferece configurações adicionais sobre como o VerifyRequest modelo deve ser validado. Nesse caso, o def check_silent_auth_first_if_present método é executado após o VerifyRequest modelo ter sido construído, para garantir que, se SilentAuthChannel estiver incluído no fluxo de trabalho, ele deve ser listado em primeiro lugar.

Verificação por e-mail

Após gerar e ativar um ambiente virtual e instalar as dependências necessárias, conforme indicado no arquivo README, você pode executar o aplicativo de demonstração da seguinte maneira:

fastapi dev

Isso iniciará um aplicativo web em http://127.0.0.1:8000:

A screenshot of the index page inviting the end-user to enter their email address to try out the Vonage Verify API.A screenshot of the index page inviting the end-user to enter their email address to try out the Vonage Verify API.Ao clicar em “Enviar código de verificação” ativa o fluxo de trabalho da Verify API. Você será redirecionado para uma página da web onde poderá inserir o código enviado para o endereço de e-mail que você forneceu:

A screenshot of the verification page inviting the end-user to enter the code they received in their email.A screenshot of the verification page inviting the end-user to enter the code they received in their email.Ao digitar o código correto aqui, você será redirecionado para uma página de confirmação.

Nos bastidores, o código utiliza os modelos Pydantic do SDK para garantir que a solicitação Verify seja formada e processada corretamente.

Verificação sem validação: testes sem o Pydantic

Agora, vamos dar uma olhada em como o Pydantic facilita o uso da Verify API.

No código a seguir, temos duas funções que realizam a mesma tarefa: fazer uma solicitação ao /verify ponto de extremidade. Uma das funções cria o corpo da solicitação manualmente e a outra usa o Pydantic.

Usando um corpo de solicitação criado manualmente:

def without_pydantic(request_payload):

    jwt_client = JwtClient(
        application_id=settings.vonage_application_id,
        private_key=settings.vonage_private_key_path,
    )

    jwt_token = jwt_client.generate_application_jwt()

    payload = {
        "brand": request_payload["brand"],
        "workflow": [
            {
                "channel": "email",
                "to": request_payload["to_email"],
            }
        ],
        "channel_timeout": request_payload["channel_timeout"],
        "code_length": request_payload["code_length"],
    }

    response = requests.post(
        "https://api.nexmo.com/v2/verify",
        headers={
            "Authorization": f"Bearer {jwt_token.decode()}",
            "Content-Type": "application/json",
        },
        json=payload,
    )

    return response

Usando o Pydantic:


def with_pydantic(request_payload):

    client = Vonage(
        Auth(
            application_id=settings.vonage_application_id,
            private_key=settings.vonage_private_key_path,
        )
    )

    verify_request = VerifyRequest(
        brand=request_payload["brand"],
        workflow=[EmailChannel(to=request_payload["to_email"])],
        channel_timeout=request_payload["channel_timeout"],
        code_length=request_payload["code_length"],
    )

    client.verify.start_verification(verify_request)

    last_response = client.http_client.last_response

    return last_response

Em seguida, o código usa unittest para testar as funções com test_data que violam os parâmetros da API:

   test_data = {
        "brand": 12345,
        "to_email": 678910,
        "channel_timeout": "sixty",
        "code_length": "five",
    }

Execute os testes com o seguinte comando:

python -m unittest -v

A execução dos testes deve resultar em dois resultados diferentes: um erro e uma falha.

O teste da função que utiliza o Pydantic deve retornar este erro:

pydantic_core._pydantic_core.ValidationError: 1 validation error for EmailChannel
to
  Input should be a valid string [type=string_type, input_value=678910, input_type=int]
    For further information visit https://errors.pydantic.dev/2.13/v/string_type

O que é importante observar aqui é que o teste não falhou – em vez disso, ele gerou um erro porque o Pydantic detectou um tipo de dados incorreto antes que a solicitação fosse feita. Além disso, a própria mensagem de erro fornece informações úteis para a depuração, em vez de uma mensagem genérica de erro de tipo. Não só sabemos que o tipo de dados fornecido não atendia aos requisitos do modelo, como também sabemos qual é o tipo esperado, bem como o tipo que foi passado:

Input should be a valid string [type=string_type, input_value=678910, input_type=int]

O teste para a função sem Pydantic retorna uma falha:

AssertionError: 422 != 202 : Test without Pydantic failed with: 422. Expected: 202

Isso significa que a solicitação foi feita e, como a API está definida, retornou um 422 por parâmetros inválidos. 

Nesse cenário de teste limitado, uma chamada de API incorreta é insignificante — em uma escala mais ampla, porém, isso pode ser um erro que custa caro. Usar o Pydantic para validar um modelo de solicitação antes de fazer a chamada de API ajuda a minimizar o desperdício de chamadas de API, permite um tratamento de erros mais suave e facilita o trabalho dos desenvolvedores.

Em resumo

O Pydantic oferece uma solução poderosa e de alto desempenho para validação de dados em Python, ajudando os desenvolvedores a superar as possíveis armadilhas do duck-typing. Ao definir esquemas, restrições e regras de validação com os modelos do Pydantic, você pode garantir a integridade dos dados e detectar erros antes mesmo que as solicitações de API sejam enviadas. Isso evita chamadas de API inválidas e dispendiosas e torna o tratamento de erros mais elegante.

Conforme demonstrado na integração do SDK do Python da Vonage com a Verify API, o Pydantic facilita o trabalho com modelos de solicitação complexos e aninhados, mantendo seu código legível e fácil de manter. Com a versão 4 do SDK, as respostas da API são deserializadas em modelos Pydantic totalmente documentados, proporcionando mais consistência, melhor suporte a ferramentas e uma experiência de desenvolvimento mais limpa em geral.

Leituras complementares e referências

Tem alguma dúvida ou quer compartilhar o que está criando?

Fique conectado e acompanhe as últimas notícias, dicas e eventos para desenvolvedores.

Compartilhar:

https://a.storyblok.com/f/270183/400x400/2c4345217d/liz-acosta.jpeg
Liz AcostaRepresentante de Desenvolvedores

Liz Acosta é Developer Advocate na Vonage. Embora sua trajetória profissional — de estudante de cinema a profissional de marketing, de engenheira a Developer Advocate — possa parecer pouco convencional, ela é bastante comum na área de Relações com Desenvolvedores! Liz adora pizza, plantas, pugs e Python.