Python + IA: Fundamentos e Projetos Práticos
Um projeto Python pode funcionar perfeitamente no seu computador e falhar assim que chega à máquina de outra pessoa, ao servidor ou ao pipeline de integração contínua. Na maioria das vezes, o problema não está no código: está na versão do Python, nas dependências instaladas globalmente ou em bibliotecas que foram atualizadas sem controle.
Nesta aula, você vai montar um fluxo moderno e reproduzível com uv, pyproject.toml, ambiente virtual e lockfile. A proposta não é trocar uma lista de comandos por outra, mas entender o papel de cada arquivo para que seu próximo projeto seja fácil de instalar, executar e manter.
O problema que um ambiente reproduzível resolve
Aplicações diferentes podem exigir versões incompatíveis da mesma biblioteca. É exatamente por isso que o Python oferece o módulo venv: cada projeto recebe um diretório isolado, com seu próprio interpretador e seus próprios pacotes. A documentação oficial do Python recomenda esse isolamento para evitar que a atualização de um projeto afete os demais.
O ambiente virtual, porém, resolve apenas uma parte. Ainda precisamos declarar quais bibliotecas o projeto usa, registrar as versões efetivamente resolvidas e oferecer um comando previsível para executar tudo. É aqui que entram três componentes:
pyproject.toml: descreve o projeto, a versão mínima do Python e suas dependências diretas;.venv: contém o ambiente isolado criado para aquele projeto;uv.lock: registra a resolução completa das dependências, incluindo pacotes indiretos.
O uv coordena essas peças. Ao executar um comando do projeto, ele verifica o arquivo de configuração, atualiza o lockfile quando necessário e sincroniza o ambiente antes de iniciar o programa.
Instale o uv e crie o primeiro projeto
O uv funciona no Windows, macOS e Linux. Use sempre um método listado na documentação oficial de instalação. No Windows, uma opção simples é o WinGet:
winget install --id=astral-sh.uv -e
uv --version
No macOS com Homebrew:
brew install uv
uv --version
No Linux ou macOS, o instalador independente também é disponibilizado oficialmente:
curl -LsSf https://astral.sh/uv/install.sh | sh
Depois, crie uma aplicação:
uv init leitor-api
cd leitor-api
uv run main.py
O comando uv init cria uma estrutura inicial com main.py, README.md, pyproject.toml e um arquivo que indica a versão do Python. Na primeira sincronização ou execução, o uv cria também .venv e uv.lock.
Você não precisa ativar o ambiente para usar uv run. O comando localiza o projeto, prepara o ambiente e executa o programa dentro dele. Isso reduz diferenças entre o terminal do desenvolvedor, o editor e a automação de deploy.
Como ler o pyproject.toml
O pyproject.toml é o ponto central da configuração moderna de projetos Python. O Python Packaging User Guide explica que ele pode reunir metadados do projeto e configurações de ferramentas como formatadores, linters e verificadores de tipos.
Uma aplicação criada pelo uv começa com uma estrutura semelhante a esta:
[project]
name = "leitor-api"
version = "0.1.0"
description = "Consulta dados de uma API pública"
readme = "README.md"
requires-python = ">=3.12"
dependencies = []
O campo requires-python define a faixa aceita pelo projeto. Ele não instala qualquer versão aleatoriamente; estabelece uma regra que o gerenciador deve respeitar. A lista dependencies guarda somente o que sua aplicação declara diretamente. As bibliotecas exigidas por essas dependências ficam registradas no lockfile.
Para quem veio de scripts soltos, esse é um avanço importante. Assim como você aprendeu a organizar dados ao trabalhar com arquivos em Python, agora passa a organizar o próprio ambiente que executa esses arquivos.
Dependências e lockfile no fluxo diário
Evite abrir o pyproject.toml para digitar versões manualmente durante o uso cotidiano. O comando uv add adiciona a biblioteca, atualiza a configuração e resolve o lockfile:
uv add httpx
uv run main.py
Para remover uma dependência:
uv remove httpx
Quando outra pessoa clonar o repositório, basta executar:
uv sync
Segundo a documentação de locking e sincronização do uv, o lockfile representa a resolução das dependências, enquanto a sincronização instala no ambiente o conjunto correspondente. Por isso, versionamos pyproject.toml e uv.lock, mas nunca enviamos a pasta .venv para o Git.
Para checar o que será instalado sem perder a visão do conjunto, use:
uv tree
uv lock --check
Em integração contínua, uv sync --locked é útil porque falha quando o lockfile não corresponde ao projeto, em vez de atualizá-lo silenciosamente. Assim, uma alteração esquecida aparece durante a validação e não depois do deploy.
Projeto prático: cliente de API com execução previsível
Vamos aplicar o fluxo em um programa curto. Depois de adicionar httpx, substitua o conteúdo de main.py:
import httpx
def buscar_post(post_id: int) -> dict:
url = f"https://jsonplaceholder.typicode.com/posts/{post_id}"
resposta = httpx.get(url, timeout=10.0)
resposta.raise_for_status()
return resposta.json()
def main() -> None:
post = buscar_post(1)
print(f"{post['id']}: {post['title']}")
if __name__ == "__main__":
main()
Execute com:
uv run main.py
O ganho não está apenas em receber uma resposta da API. Qualquer pessoa que tenha o código e o lockfile consegue reconstruir um ambiente compatível sem adivinhar quais pacotes foram instalados na sua máquina.
Esse mesmo padrão serve como base para projetos maiores. Você pode adicionar pandas e evoluir para o conteúdo de análise de dados com Python, ou integrar testes e ferramentas de qualidade sem misturá-los às dependências necessárias em produção.
Para dependências de desenvolvimento, use um grupo separado:
uv add --dev pytest ruff
uv run pytest
uv run ruff check .
Isso comunica intenção: a aplicação precisa de httpx para funcionar, enquanto testes e análise estática apoiam o desenvolvimento.
Checklist para migrar um projeto existente
Se você já possui um projeto com requirements.txt, migre com calma. Não apague o ambiente antigo antes de confirmar que a nova configuração funciona.
- Crie uma branch ou cópia de segurança do projeto.
- Execute
uv initna raiz se ainda não existir umpyproject.toml. - Adicione somente as dependências diretas com
uv add nome-do-pacote. - Defina uma faixa de Python compatível em
requires-python. - Rode os testes com
uv run pytestou execute o fluxo principal da aplicação. - Confirme que
.venv/está ignorada pelo Git. - Versione
pyproject.tomleuv.lockjuntos. - Reproduza o ambiente em uma pasta limpa usando
uv sync --locked.
Um erro comum é copiar para o novo projeto todo o resultado de pip freeze. Essa lista mistura dependências diretas e transitivas, dificultando a manutenção. Declare o que seu código realmente importa e deixe o resolvedor registrar o restante no lockfile.
Conclusão: transforme o ambiente em parte do projeto
Um bom projeto Python não é apenas um conjunto de arquivos .py. Ele inclui regras claras para escolher o interpretador, instalar bibliotecas e repetir a execução com segurança. O ambiente virtual isola; o pyproject.toml declara; o uv.lock registra; e o uv mantém tudo sincronizado.
Seu próximo passo é simples: escolha um script que hoje depende de instalações globais, inicialize-o com uv, adicione suas dependências e teste a reconstrução em uma pasta limpa. Depois, continue explorando a trilha Python + IA: Fundamentos e Projetos Práticos para transformar essa base reproduzível em projetos de dados, automação e inteligência artificial.