Use Cases (Atualizado: 02/06/2026)

Python com Claude Code: guia com uv, pytest, Ruff e FastAPI

Crie um projeto Python verificável com Claude Code, uv, pyproject.toml, pytest, Ruff, FastAPI e iteração segura.

Python com Claude Code: guia com uv, pytest, Ruff e FastAPI

O primeiro desafio ao usar Claude Code com Python não é gerar um arquivo. O desafio é saber se o projeto está realmente pronto para evoluir: ambiente reproduzível, imports funcionando, testes executando, formatação consistente e comandos claros para provar cada mudança.

Este guia cria uma base pequena para iniciantes. Vamos usar uv ou venv, concentrar regras em pyproject.toml, implementar uma API mínima com FastAPI, adicionar uma CLI opcional, escrever testes com pytest e revisar com ruff. O objetivo é usar Claude Code para iterações seguras, não para aceitar um backend grande sem entender.

Use documentação oficial como referência: Claude Code, Python Packaging para escrever pyproject.toml, instalação do uv, pytest, Ruff e os primeiros passos do FastAPI.

Defina um alvo pequeno

Não peça autenticação, banco de dados, Docker e CI no primeiro prompt. Para aprender, o primeiro alvo precisa ser verificável.

  • uv run pytest passa
  • uv run ruff check . e uv run ruff format . executam
  • FastAPI cria e lista uma tarefa
  • A CLI adiciona uma tarefa pelo terminal
  • Claude Code informa os comandos executados
flowchart LR
  A["Brief da tarefa"] --> B["uv ou venv"]
  B --> C["pyproject.toml"]
  C --> D["Implementação em src"]
  D --> E["pytest"]
  E --> F["ruff"]
  F --> G["Pequena iteração com Claude Code"]

O brief é a ordem de trabalho do agente. Ele deve conter objetivo, arquivos permitidos, versão do Python e comandos de verificação. Para regras permanentes, use também boas práticas de CLAUDE.md. Para crescer a API, veja desenvolvimento de API com Claude Code e estratégias de testes.

Prompt inicial

Este prompt dá limites claros.

Adicione a este repositório uma pequena API de tarefas para Python 3.12.

Condições:
- Use uv para dependências e concentre a configuração em pyproject.toml.
- Coloque o código em src/task_api/ e os testes em tests/.
- Implemente POST /tasks e GET /tasks com FastAPI.
- Escreva testes pytest para o fluxo feliz e um caso 404.
- ruff check e ruff format devem passar.
- Antes de editar, mostre o plano. Depois, informe os comandos executados.

Arquivos permitidos:
- pyproject.toml
- src/task_api/**
- tests/**

Assim Claude Code trabalha com um contrato. Se ele mexer em arquivos fora do escopo ou não rodar testes, o problema fica fácil de detectar.

Ambiente com uv ou venv

Para projetos novos, uv é uma boa escolha por ser rápido e simples. Em máquinas corporativas sem permissão para instalar ferramentas, venv resolve. O importante é escolher uma rota e documentar.

macOS ou Linux:

mkdir task-api
cd task-api
uv init --app --python 3.12
uv add "fastapi[standard]"
uv add --dev pytest ruff
mkdir -p src/task_api tests
touch src/task_api/__init__.py

Windows PowerShell:

mkdir task-api
cd task-api
uv init --app --python 3.12
uv add "fastapi[standard]"
uv add --dev pytest ruff
New-Item -ItemType Directory -Force src/task_api, tests
New-Item -ItemType File -Force src/task_api/__init__.py

Alternativa com venv:

python -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install "fastapi[standard]" pytest ruff
python -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install --upgrade pip
python -m pip install "fastapi[standard]" pytest ruff

Centralize o pyproject.toml

Um iniciante se perde quando dependências, testes e lint ficam espalhados. Este arquivo reúne o essencial.

[project]
name = "task-api"
version = "0.1.0"
description = "Small FastAPI and CLI sample for Claude Code practice"
requires-python = ">=3.11"
dependencies = [
  "fastapi[standard]>=0.115.0",
]

[project.scripts]
task-api = "task_api.cli:main"

[dependency-groups]
dev = [
  "pytest>=8.0.0",
  "ruff>=0.8.0",
]

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[tool.hatch.build.targets.wheel]
packages = ["src/task_api"]

[tool.pytest.ini_options]
testpaths = ["tests"]
pythonpath = ["src"]

[tool.ruff]
line-length = 100
target-version = "py311"

[tool.ruff.lint]
select = ["E", "F", "I", "B", "UP"]

FastAPI e CLI mínimos

Salve em src/task_api/main.py. O armazenamento é em memória, então não é produção. Ele serve para aprender rotas, validação e erros antes do banco.

from fastapi import FastAPI, HTTPException
from pydantic import BaseModel, Field

app = FastAPI(title="Task API")


class TaskCreate(BaseModel):
    title: str = Field(min_length=1, max_length=80)


class Task(BaseModel):
    id: int
    title: str
    done: bool = False


_tasks: dict[int, Task] = {}
_next_id = 1


@app.post("/tasks", response_model=Task, status_code=201)
def create_task(payload: TaskCreate) -> Task:
    global _next_id
    task = Task(id=_next_id, title=payload.title)
    _tasks[task.id] = task
    _next_id += 1
    return task


@app.get("/tasks", response_model=list[Task])
def list_tasks() -> list[Task]:
    return list(_tasks.values())


@app.patch("/tasks/{task_id}/done", response_model=Task)
def mark_done(task_id: int) -> Task:
    task = _tasks.get(task_id)
    if task is None:
        raise HTTPException(status_code=404, detail="Task not found")
    updated = task.model_copy(update={"done": True})
    _tasks[task_id] = updated
    return updated
uv run fastapi dev src/task_api/main.py

Para CLI, crie src/task_api/cli.py.

import argparse
import json
from pathlib import Path

DB_PATH = Path("tasks.json")


def load_tasks() -> list[dict[str, object]]:
    if not DB_PATH.exists():
        return []
    return json.loads(DB_PATH.read_text(encoding="utf-8"))


def save_tasks(tasks: list[dict[str, object]]) -> None:
    DB_PATH.write_text(json.dumps(tasks, ensure_ascii=False, indent=2), encoding="utf-8")


def add_task(title: str) -> dict[str, object]:
    tasks = load_tasks()
    task = {"id": len(tasks) + 1, "title": title, "done": False}
    tasks.append(task)
    save_tasks(tasks)
    return task


def main() -> None:
    parser = argparse.ArgumentParser(description="Task CLI")
    subparsers = parser.add_subparsers(dest="command", required=True)
    add_parser = subparsers.add_parser("add")
    add_parser.add_argument("title")
    args = parser.parse_args()
    if args.command == "add":
        task = add_task(args.title)
        print(f"Added #{task['id']}: {task['title']}")


if __name__ == "__main__":
    main()
uv run task-api add "write pytest"

Proteja com pytest e Ruff

Crie tests/test_main.py e mantenha os mesmos comandos em toda mudança.

import pytest
from fastapi.testclient import TestClient

from task_api import main
from task_api.main import app


@pytest.fixture(autouse=True)
def clean_tasks() -> None:
    main._tasks.clear()
    main._next_id = 1


def test_create_and_list_tasks() -> None:
    client = TestClient(app)
    response = client.post("/tasks", json={"title": "Write pytest"})
    assert response.status_code == 201
    assert response.json()["title"] == "Write pytest"
    list_response = client.get("/tasks")
    assert list_response.status_code == 200
    assert len(list_response.json()) == 1


def test_mark_done_returns_404_for_missing_task() -> None:
    client = TestClient(app)
    response = client.patch("/tasks/999/done")
    assert response.status_code == 404
    assert response.json()["detail"] == "Task not found"
uv run pytest
uv run ruff check .
uv run ruff format .

Casos de uso reais

O primeiro caso é uma API de aprendizado com rotas, Pydantic, OpenAPI, testes e formatação. O segundo é uma CLI para automação de negócio, como limpar CSV, renomear arquivos ou montar relatórios. O terceiro é adicionar testes a scripts legados antes de refatorar. O quarto é criar uma base de treinamento para que todos no time comecem do mesmo ponto.

Para continuar, use produtos Claude Code quando os prompts se repetirem, ou treinamento e consultoria quando houver risco de equipe, revisão ou produção.

Erros comuns

Não deixe o gerenciador de pacotes implícito. Misturar pip, poetry, uv e requirements.txt cria confusão. Não adicione banco e JWT antes da versão em memória funcionar. Revise diffs do Ruff. Garanta pythonpath = ["src"] ou instalação correta do pacote. Nunca cole segredos, dados de clientes ou URLs de produção no prompt.

Resultado verificado

Nesta atualização, segui a ordem que Masa usa em materiais para iniciantes: ambiente, pyproject.toml, FastAPI pequeno, testes e Ruff. O resultado é que cada falha fica localizável. Claude Code se torna mais útil quando o projeto tem comandos claros do que quando gera uma aplicação grande sem prova.

#Claude Code #Python #uv #pytest #FastAPI
Grátis

PDF grátis: cheatsheet do Claude Code

Informe seu e-mail e baixe uma página com comandos, hábitos de revisão e workflows seguros.

Cuidamos dos seus dados e não enviamos spam.

Masa

Sobre o autor

Masa

Engenheiro focado em workflows práticos com Claude Code.