httpx & requests
requests é o cliente HTTP síncrono clássico; httpx é seu sucessor moderno com suporte a async, HTTP/2 e padrões mais rigorosos. Ambos pertencem ao kit de ferramentas de todo desenvolvedor Python para APIs, webhooks e chamadas de serviço a serviço.
Receita
import httpx
with httpx.Client(timeout=httpx.Timeout(5.0, connect=2.0)) as client:
response = client.get("https://httpbin.org/get", params={"q": "python"})
response.raise_for_status()
data = response.json()Quando usar isso:
- Chamando APIs REST/JSON de scripts, workers ou tarefas em segundo plano do FastAPI
- Necessidade de HTTP assíncrono em rotas
asyncio(AsyncClientdo httpx) - Upload de arquivos ou streaming de respostas grandes
- Substituindo chamadas
urllibad-hoc por código legível e testável
Exemplo de Trabalho
from __future__ import annotations
import httpx
from pydantic import BaseModel
class User(BaseModel):
id: int
email: str
def fetch_user(user_id: int) -> User:
timeout = httpx.Timeout(10.0, connect=3.0)
with httpx.Client(base_url="https://api.example.com", timeout=timeout) as client:
response = client.get(f"/users/{user_id}")
response.raise_for_status()
return User.model_validate(response.json())
async def fetch_user_async(user_id: int) -> User:
timeout = httpx.Timeout(10.0, connect=3.0)
async with httpx.AsyncClient(base_url="https://api.example.com", timeout=timeout) as client:
response = await client.get(f"/users/{user_id}")
response.raise_for_status()
return User.model_validate(response.json())
if __name__ == "__main__":
print(fetch_user(1))O que isso demonstra:
base_urlevita repetir prefixos de hostTimeoutexplícito divide os limites de conexão e leituraraise_for_status()transforma 4xx/5xx em exceções- Pydantic valida payloads JSON na fronteira
- O mesmo padrão funciona síncrono (
Client) e assíncrono (AsyncClient)
Mergulho Profundo
Como Funciona
- Pooling de Conexão - Reutilizar um
Clientmantém as sessões TCP/TLS ativas;httpx.get()isolado cria um novo pool a cada chamada. - Timeouts -
httpx.Timeoutaceita limites de conexão, leitura, escrita e pool; valores não definidos usam o padrão (5s no httpx). - Redirecionamentos - Seguidos por padrão; desabilite com
follow_redirects=Falsepara OAuth ou URLs assinadas. - Streaming -
client.stream("GET", url)produz pedaços sem carregar o corpo completo na memória.
Ciclo de Vida do Cliente
| Padrão | Usar Quando |
|---|---|
with httpx.Client() | Scripts, ferramentas de linha de comando, workers síncronos |
| Cliente em nível de módulo (inicialização do aplicativo) | Aplicativos FastAPI/Flask com reutilização de conexão |
AsyncClient por solicitação | Raro; prefira um cliente por ciclo de vida do aplicativo |
httpx.get() de uso único | Apenas para testes rápidos no REPL |
Notas Python
# Mapeie erros de transporte para sua camada de domínio
try:
response = client.post("/orders", json=payload)
response.raise_for_status()
except httpx.TimeoutException as exc:
raise ServiceUnavailable("timeout do upstream") from exc
except httpx.HTTPStatusError as exc:
if exc.response.status_code == 404:
raise NotFound("pedido não encontrado")
raiseArmadilhas
- Nenhum timeout definido - Congelamentos infinitos paralisam workers e obscurecem interrupções. Correção: sempre passe
timeout=. - Criar um novo cliente por solicitação - Destrói o pooling e retarda as negociações TLS. Correção: reutilize
Client/AsyncClient. - Confiar em JSON sem validação - Desvios de esquema causam
KeyErrorprofundamente na lógica de negócios. Correção: valide com Pydantic na fronteira HTTP. - Bloquear
requestsdentro de rotas assíncronas - Bloqueia o loop de eventos sob carga. Correção: usehttpx.AsyncClientouasyncio.to_thread. - Ignorar redirecionamentos em POST - Algumas APIs retornam 302 para um host diferente. Correção: registre
response.historyao depurar fluxos de autenticação. - Segredos codificados em URLs - Tokens de consulta acabam em logs. Correção: use cabeçalhos (
Authorization) e censure em middleware de log.
Alternativas
| Alternativa | Usar Quando | Não Usar Quando |
|---|---|---|
urllib.request (stdlib) | Scripts sem dependências em ambientes restritos | Você precisa de timeouts, retentativas ou ergonomia JSON |
aiohttp | Ecossistema assíncrono maduro já no projeto | O padrão da equipe é httpx/FastAPI |
requests | Bases de código legadas com uso pesado de requests | Iniciando serviços assíncronos do zero |
| HTTP do SDK da Nuvem (boto3 botocore) | APIs de serviço AWS com assinatura | REST genérico para terceiros |
FAQs
Novos projetos devem usar httpx ou requests?
Prefira httpx para código novo - mesma ergonomia mais async e HTTP/2. Mantenha requests apenas onde o custo de migração exceder o benefício.
Como compartilho um AsyncClient entre rotas FastAPI?
Crie o cliente em um manipulador de ciclo de vida e armazene-o em app.state, depois injete via Depends nas rotas.
O httpx verifica certificados TLS?
Sim, por padrão. Passe verify=False apenas em desenvolvimento local com certificados autoassinados - nunca em produção.
Como envio uploads de arquivos multipart?
with open("report.pdf", "rb") as f:
client.post("/upload", files={"file": ("report.pdf", f, "application/pdf")})E quanto ao HTTP/2?
Habilite com httpx.Client(http2=True) quando o servidor suportar - útil para gateways de API multiplexados.
Como faço mock de HTTP em testes?
Use httpx.MockTransport ou pytest-httpx para retornar respostas pré-definidas sem E/S de rede.
Devo tentar novamente requisições falhas automaticamente?
Não dentro do cliente por padrão - envolva com tenacity ou lógica de retentativa em nível de aplicativo que respeite a idempotência.
Como defino um User-Agent personalizado?
Passe headers={"User-Agent": "my-service/1.0"} ou defina client.headers na instância do cliente.
Posso usar httpx com Django?
Sim para chamadas de saída síncronas em views ou comandos de gerenciamento. Para views Django assíncronas, use AsyncClient.
Como registro corpos de requisição/resposta com segurança?
Registre método, URL, status e duração - censure cabeçalhos Authorization e nunca registre payloads completos de cartão/PII.
Relacionados
- tenacity - retentativas e backoff para upstreams instáveis
- pydantic-settings - configuração tipada para URLs base de API
- FastAPI Basics - rotas assíncronas que chamam APIs externas
- beautifulsoup4 & lxml - análise de HTML obtido via HTTP
Versões da Pilha: Esta página foi escrita para Python 3.14.0 (estável 3.14, manutenção 3.13), FastAPI 0.115+, Django 5.2, Flask 3.1, Pydantic 2, PyTorch 2.6+, pandas 2.2+, Polars 1.x, ruff 0.9+ e uv 0.6+.