Laboratório: API de IA Conversacional com Anthropic e OpenAI em Python, FastAPI e Pydantic
Você vai construir uma API REST local que recebe perguntas e retorna respostas dos modelos Claude (Anthropic) e GPT (OpenAI), alternando o fornecedor por parâmetro. Em cerca de 2 horas, terá um serviço pronto para integrar a aplicações internas.

Roteiro para estudo em ambiente de laboratório ou de teste. Execute apenas em equipamentos, redes e contas que você tenha autorização para usar, com backup e homologação próprios. Comandos podem causar indisponibilidade ou perda de dados. Software e marcas citados pertencem aos seus titulares. Termos de Uso.
- Duração estimada
- 120 min
- Passos
- 12
- Validações
- 5
- Versões da documentação consultada
- Python 3.10+ · FastAPI a versão estável atual · Uvicorn a versão estável atual · Pydantic a versão estável atual · anthropic a versão estável atual · openai a versão estável atual · httpx a versão estável atual
Demonstrar, de ponta a ponta, como expor modelos de linguagem da Anthropic e OpenAI via uma API REST própria, usando FastAPI e contratos Pydantic. O laboratório cobre autenticação segura, versionamento de prompt, uso dos SDKs oficiais, streaming de resposta, logging e estrutura para testes e tracing. O objetivo é que você entenda como trocar de fornecedor sem reescrever o serviço, seguindo boas práticas de segurança e observabilidade.
Topologia
O usuário faz requisições HTTP para a API local (FastAPI, 192.168.56.10:8000). A API, ao receber um POST /chat, consulta o modelo Claude (Anthropic) ou GPT (OpenAI) na nuvem, conforme o parâmetro recebido, e retorna a resposta. O serviço roda em uma VM Linux, com acesso à internet para as APIs externas. Segredos ficam em variáveis de ambiente.
Usuário HTTP
|
v
[FastAPI (192.168.56.10:8000)]
| |
v v
Claude API OpenAI API
(nuvem) (nuvem)
Equipamentos e software
| Item | Requisito, licença ou versão |
|---|---|
| VM Linux x86_64 | 2 vCPU, 2GB RAM, 1 porta aberta (8000/tcp), Python 3.10+ |
| Python | PSF · 3.10+ |
| FastAPI | MIT · a versão estável atual |
| Uvicorn | BSD · a versão estável atual |
| Pydantic | MIT · a versão estável atual |
| anthropic | Apache-2.0 · a versão estável atual |
| openai | MIT · a versão estável atual |
| httpx | BSD · a versão estável atual |
Roteiro
- Preparar o ambiente Python
Crie um ambiente virtual para isolar dependências. Isso evita conflitos e facilita a remoção posterior.
python3 -m venv venv source venv/bin/activateO que você deve ver: (venv) no prompt
- Instalar dependências
Instale FastAPI, Uvicorn, Pydantic, os SDKs oficiais anthropic e openai, e httpx para chamadas HTTP assíncronas.
pip install fastapi uvicorn pydantic anthropic openai httpxO que você deve ver: Pacotes instalados sem erro
- Configurar variáveis de ambiente para segredos
Nunca coloque chaves de API no código. Exporte as chaves da Anthropic e OpenAI como variáveis de ambiente.
export ANTHROPIC_API_KEY='sua-chave-anthropic' export OPENAI_API_KEY='sua-chave-openai'O que você deve ver: Variáveis disponíveis na sessão (use 'echo $ANTHROPIC_API_KEY' para conferir)
- Criar o contrato Pydantic para entrada e saída
Defina um modelo claro para a requisição e resposta. Isso garante validação automática e documentação.
Consulte docs.pydantic.dev para detalhes. Exemplo: # models.py from pydantic import BaseModel class ChatRequest(BaseModel): provider: str # 'anthropic' ou 'openai' prompt: str class ChatResponse(BaseModel): provider: str model: str response: strO que você deve ver: Arquivo models.py criado
- Implementar o roteador FastAPI
Crie um arquivo main.py com um endpoint POST /chat que recebe ChatRequest, chama o modelo correto e retorna ChatResponse. Isso separa lógica de negócio e facilita manutenção.
# main.py from fastapi import FastAPI, HTTPException from models import ChatRequest, ChatResponse import os import anthropic import openai app = FastAPI() ANTHROPIC_KEY = os.getenv('ANTHROPIC_API_KEY') OPENAI_KEY = os.getenv('OPENAI_API_KEY') @app.post('/chat', response_model=ChatResponse) async def chat(req: ChatRequest): if req.provider == 'anthropic': client = anthropic.Anthropic(api_key=ANTHROPIC_KEY) response = await client.messages.create( model='claude-haiku-4-5', max_tokens=1024, messages=[{"role": "user", "content": req.prompt}] ) return ChatResponse(provider='anthropic', model='claude-haiku-4-5', response=response.content[0].text) elif req.provider == 'openai': client = openai.AsyncOpenAI(api_key=OPENAI_KEY) resp = await client.chat.completions.create( model='gpt-5.6-terra', messages=[{"role": "user", "content": req.prompt}] ) return ChatResponse(provider='openai', model='gpt-5.6-terra', response=resp.choices[0].message.content) else: raise HTTPException(status_code=400, detail='provider inválido')O que você deve ver: Arquivo main.py criado
- Adicionar logging e tracing básico
Inclua logs para cada requisição, modelo usado e tempo de resposta. Isso permite rastrear problemas e medir desempenho.
# No início de main.py import logging logging.basicConfig(level=logging.INFO) # Dentro do endpoint: import time start = time.time() # ... chamada do modelo ... logging.info(f"{req.provider} - {req.prompt[:30]}... - {time.time()-start:.2f}s")O que você deve ver: Logs aparecem no terminal a cada requisição
- Versionar o prompt de sistema
Inclua um prompt de sistema fixo e versionado para cada fornecedor. Isso garante rastreabilidade e facilita rollback.
# main.py, antes das chamadas: SYSTEM_PROMPT = { 'anthropic': 'Você é um assistente Upnetix, versão 2024-06.', 'openai': 'You are an Upnetix assistant, version 2024-06.' } # Na chamada anthropic: messages=[{"role": "system", "content": SYSTEM_PROMPT['anthropic']}, {"role": "user", "content": req.prompt}] # Na chamada openai: messages=[{"role": "system", "content": SYSTEM_PROMPT['openai']}, {"role": "user", "content": req.prompt}]O que você deve ver: Prompt de sistema incluído nas requisições
- Rodar o serviço localmente
Inicie o servidor FastAPI com Uvicorn, ouvindo na porta 8000.
uvicorn main:app --host 0.0.0.0 --port 8000O que você deve ver: Servidor ouvindo em http://0.0.0.0:8000
- Testar a API com curl
Envie uma requisição POST para /chat alternando entre 'anthropic' e 'openai'. Isso valida o roteamento e a integração.
curl -X POST http://localhost:8000/chat -H 'Content-Type: application/json' -d '{"provider": "anthropic", "prompt": "Qual a capital do Amazonas?"}' curl -X POST http://localhost:8000/chat -H 'Content-Type: application/json' -d '{"provider": "openai", "prompt": "Qual a capital do Amazonas?"}'O que você deve ver: Respostas diferentes, ambas mencionando Manaus
- Implementar streaming de resposta (opcional)
Para respostas longas, implemente streaming via FastAPI StreamingResponse. Isso reduz latência percebida.
Consulte fastapi.tiangolo.com/advanced/streaming/ e a documentação dos SDKs para detalhes. Adapte o endpoint para retornar StreamingResponse.O que você deve ver: Resposta começa a chegar antes de terminar o processamento
- Adicionar testes automáticos
Crie um arquivo test_api.py com casos de teste usando httpx. Isso garante que mudanças futuras não quebrem o serviço.
# test_api.py import httpx import pytest @pytest.mark.asyncio async def test_anthropic(): async with httpx.AsyncClient() as client: resp = await client.post('http://localhost:8000/chat', json={"provider": "anthropic", "prompt": "Teste"}) assert resp.status_code == 200 assert 'response' in resp.json() @pytest.mark.asyncio async def test_openai(): async with httpx.AsyncClient() as client: resp = await client.post('http://localhost:8000/chat', json={"provider": "openai", "prompt": "Teste"}) assert resp.status_code == 200 assert 'response' in resp.json()O que você deve ver: Testes passam sem erro
- Registrar e revisar ações irreversíveis (simulação)
Implemente logging de todas as ações e simule uma revisão humana antes de executar comandos destrutivos. Isso é obrigatório para conformidade e segurança.
# No endpoint, antes de executar qualquer ação sensível: logging.info(f"Ação irreversível solicitada: {req.prompt}") # Simule revisão humana com um input() ou flag de aprovação (em produção, use workflow externo)O que você deve ver: Logs de ações sensíveis aparecem antes da execução
Como saber que funcionou
| Teste | Comando | Critério |
|---|---|---|
| Requisição para /chat com provider=anthropic | curl -X POST http://localhost:8000/chat -H 'Content-Type: application/json' -d '{"provider": "anthropic", "prompt": "Quem fundou Manaus?"}' | Resposta JSON com provider='anthropic' e resposta coerente |
| Requisição para /chat com provider=openai | curl -X POST http://localhost:8000/chat -H 'Content-Type: application/json' -d '{"provider": "openai", "prompt": "Quem fundou Manaus?"}' | Resposta JSON com provider='openai' e resposta coerente |
| Resposta a prompt inválido (provider desconhecido) | curl -X POST http://localhost:8000/chat -H 'Content-Type: application/json' -d '{"provider": "foo", "prompt": "Teste"}' | HTTP 400 com mensagem de erro |
| Logs de tracing | tail -f uvicorn.log | Cada requisição gera uma linha de log com provider, prompt e tempo |
| Testes automáticos | pytest test_api.py | Todos os testes passam |
Troubleshooting
| Sintoma | Causa provável | Correção |
|---|---|---|
| HTTP 401/403 ao chamar a API externa | Chave de API inválida ou não exportada | Confirme as variáveis ANTHROPIC_API_KEY e OPENAI_API_KEY e se a conta tem permissão |
| Timeout ou erro de conexão | Sem acesso à internet ou firewall bloqueando saída | Teste conectividade com ping e libere portas de saída |
| Erro 'provider inválido' | Valor de provider não é 'anthropic' nem 'openai' | Envie apenas valores aceitos |
| Resposta vazia ou truncada | Limite de tokens muito baixo ou erro de parsing | Aumente max_tokens e revise parsing da resposta |
| Falha ao importar anthropic ou openai | Dependências não instaladas ou ambiente virtual não ativado | Ative o venv e reinstale os pacotes |
Segurança e hardening
- Nunca exponha as chaves de API em logs, código-fonte ou respostas HTTP
- Restrinja o acesso à porta 8000 apenas à rede interna ou localhost
- Implemente revisão humana para comandos destrutivos ou ações irreversíveis
- Faça logging seguro, sem dados sensíveis do usuário
- Siga o princípio do mínimo privilégio para as contas de API
- Desabilite debug em produção
Checklist final
Referências
- Anthropic Python SDK · GitHub (repositório oficial do projeto) (github.com)
- Anthropic API Reference · Platform.claude (platform.claude.com)
- OpenAI Python Library · GitHub (repositório oficial do projeto) (github.com)
- OpenAI API Reference · Developers.openai (developers.openai.com)
- FastAPI Documentation · FastAPI (fastapi.tiangolo.com)
- Pydantic Documentation · Docs.pydantic (docs.pydantic.dev)
- LGPD - Lei 13.709/2018 · Presidência da República (Planalto) (planalto.gov.br)
- Publicado
- 13/09/2026
- Última revisão
- 13/09/2026
- Versão do conteúdo
- 1.0
- Referências
- 7 oficiais · 1 de normas ou órgãos
- Revisão técnica
- redação e revisão por IA, URLs conferidas na publicação
- Status
- Atual
