O Python possui suporte para "dicas de tipo" ou "type hints" (também chamado de "anotações de tipo" ou "type annotations")
Esses "type hints" são uma sintaxe especial que permite declarar o tipo de uma variável.
Ao declarar tipos para suas variáveis, editores e ferramentas podem oferecer um melhor suporte.
Este é apenas um tutorial rápido / atualização sobre type hints do Python. Ele cobre apenas o mínimo necessário para usá-los com o FastAPI... que é realmente muito pouco.
O FastAPI é baseado nesses type hints, eles oferecem muitas vantagens e benefícios.
Mas mesmo que você nunca use o FastAPI, você se beneficiaria de aprender um pouco sobre eles.
Nota
Se você é um especialista em Python e já sabe tudo sobre type hints, pule para o próximo capítulo.
Existem algumas estruturas de dados que podem conter outros valores, como dict, list, set e tuple. E os valores internos também podem ter seu próprio tipo.
Estes tipos que possuem tipos internos são chamados de tipos "genéricos". E é possível declará-los mesmo com os seus tipos internos.
Para declarar esses tipos e os tipos internos, você pode usar o módulo Python padrão typing. Ele existe especificamente para suportar esses type hints.
A sintaxe utilizando typing é compatível com todas as versões, desde o Python 3.6 até as últimas, incluindo o Python 3.9, 3.10, etc.
Conforme o Python evolui, novas versões chegam com suporte melhorado para esses type annotations, e em muitos casos, você não precisará nem importar e utilizar o módulo typing para declarar os type annotations.
Se você pode escolher uma versão mais recente do Python para o seu projeto, você poderá aproveitar isso ao seu favor.
Em todos os documentos existem exemplos compatíveis com cada versão do Python (quando existem diferenças).
Por exemplo, "Python 3.6+" significa que é compatível com o Python 3.6 ou superior (incluindo o 3.7, 3.8, 3.9, 3.10, etc). E "Python 3.9+" significa que é compatível com o Python 3.9 ou mais recente (incluindo o 3.10, etc).
Se você pode utilizar a versão mais recente do Python, utilize os exemplos para as últimas versões. Eles terão as melhores e mais simples sintaxes, como por exemplo, "Python 3.10+".
Você pode declarar que uma variável pode ser de qualquer um dentre diversos tipos. Por exemplo, um int ou um str.
No Python 3.6 e superior (incluindo o Python 3.10), você pode utilizar o tipo Union de typing, e colocar dentro dos colchetes os possíveis tipos aceitáveis.
No Python 3.10 também existe uma nova sintaxe onde você pode colocar os possívels tipos separados por uma barra vertical (|).
O uso de Optional[str] em vez de apenas str permitirá que o editor o ajude a detectar erros, onde você pode estar assumindo que um valor é sempre um str, quando na verdade também pode ser None.
Optional[Something] é na verdade um atalho para Union[Something, None], eles são equivalentes.
Isso também significa que no Python 3.10, você pode utilizar Something | None:
Se você está utilizando uma versão do Python abaixo da 3.10, aqui vai uma dica do meu ponto de vista bem subjetivo:
🚨 Evite utilizar Optional[SomeType]
No lugar, ✨ use Union[SomeType, None] ✨.
Ambos são equivalentes, e no final das contas, eles são o mesmo. Mas eu recomendaria o Union ao invés de Optional porque a palavra Optional parece implicar que o valor é opcional, quando na verdade significa "isso pode ser None", mesmo que ele não seja opcional e ainda seja obrigatório.
Eu penso que Union[SomeType, None] é mais explícito sobre o que ele significa.
Isso é apenas sobre palavras e nomes. Mas estas palavras podem afetar como os seus colegas de trabalho pensam sobre o código.
O paâmetro name é definido como Optional[str], mas ele não é opcional, você não pode chamar a função sem o parâmetro:
say_hi()# Oh, no, this throws an error! 😱
O parâmetro nameainda é obrigatório (não opicional) porque ele não possui um valor padrão. Mesmo assim, name aceita None como valor:
say_hi(name=None)# This works, None is valid 🎉
A boa notícia é, quando você estiver no Python 3.10 você não precisará se preocupar mais com isso, pois você poderá simplesmente utilizar o | para definir uniões de tipos:
Esses tipos que usam parâmetros de tipo entre colchetes são chamados tipos genéricos ou genéricos. Por exemplo:
Você pode utilizar os mesmos tipos internos como genéricos (com colchetes e tipos dentro):
list
tuple
set
dict
E o mesmo como no Python 3.8, do módulo typing:
Union
Optional (o mesmo que com o 3.8)
...entro outros.
No Python 3.10, como uma alternativa para a utilização dos genéricos Union e Optional, você pode usar a barra vertical (|) para declarar uniões de tipos. Isso é muito melhor e mais simples.
Você pode utilizar os mesmos tipos internos como genéricos (com colchetes e tipos dentro):
O Pydantic é uma biblioteca Python para executar a validação de dados.
Você declara a "forma" dos dados como classes com atributos.
E cada atributo tem um tipo.
Em seguida, você cria uma instância dessa classe com alguns valores e ela os validará, os converterá para o tipo apropriado (se for esse o caso) e fornecerá um objeto com todos os dados.
E você recebe todo o suporte do editor com esse objeto resultante.
O Pydantic tem um comportamento especial quando você usa Optional ou Union[Something, None] sem um valor padrão. Você pode ler mais sobre isso na documentação do Pydantic sobre campos Opcionais Obrigatórios.
O Python possui uma funcionalidade que nos permite incluir metadados adicionais nos type hints utilizando Annotated.
No Python 3.9, Annotated é parte da biblioteca padrão, então você pode importá-lo de typing.
fromtypingimportAnnotateddefsay_hello(name:Annotated[str,"this is just metadata"])->str:returnf"Hello {name}"
Em versões abaixo do Python 3.9, você importa Annotated de typing_extensions.
Ele já estará instalado com o FastAPI.
fromtyping_extensionsimportAnnotateddefsay_hello(name:Annotated[str,"this is just metadata"])->str:returnf"Hello {name}"
O Python em si não faz nada com este Annotated. E para editores e outras ferramentas, o tipo ainda é str.
Mas você pode utilizar este espaço dentro do Annotated para fornecer ao FastAPI metadata adicional sobre como você deseja que a sua aplicação se comporte.
O importante aqui de se lembrar é que o primeiro type parameter que você informar ao Annotated é o tipo de fato. O resto é apenas metadado para outras ferramentas.
Por hora, você precisa apenas saber que o Annotated existe, e que ele é Python padrão. 😎
Mais tarde você verá o quão poderoso ele pode ser.
Dica
O fato de que isso é Python padrão significa que você ainda obtém a melhor experiência de desenvolvedor possível no seu editor, com as ferramentas que você utiliza para analisar e refatorar o seu código, etc. ✨
E também que o seu código será muito compatível com diversas outras ferramentas e bibliotecas Python. 🚀
O FastAPI aproveita esses type hints para fazer várias coisas.
Com o FastAPI, você declara parâmetros com type hints e obtém:
Suporte ao editor.
Verificações de tipo.
... e o FastAPI usa as mesmas declarações para:
Definir requisitos: dos parâmetros de rota, parâmetros da consulta, cabeçalhos, corpos, dependências, etc.
Converter dados: da solicitação para o tipo necessário.
Validar dados: provenientes de cada solicitação:
Gerando erros automáticos retornados ao cliente quando os dados são inválidos.
Documentar a API usando OpenAPI:
que é usado pelas interfaces de usuário da documentação interativa automática.
Tudo isso pode parecer abstrato. Não se preocupe. Você verá tudo isso em ação no Tutorial - Guia do usuário.
O importante é que, usando tipos padrão de Python, em um único local (em vez de adicionar mais classes, decoradores, etc.), o FastAPI fará muito trabalho para você.
Informação
Se você já passou por todo o tutorial e voltou para ver mais sobre os tipos, um bom recurso é a "cheat sheet" do mypy.