Requests: O que É e Como Funciona | Python Brasil
Aprenda a usar Requests em Python: requisicoes HTTP, GET, POST, headers, autenticacao, sessoes e boas praticas para consumir APIs e servicos web.
O que e Requests?
Requests e a biblioteca HTTP mais popular do Python, projetada para tornar requisicoes web simples e elegantes. Com o lema “HTTP for Humans”, ela abstrai a complexidade do protocolo HTTP, oferecendo uma API intuitiva para enviar requisicoes GET, POST, PUT, DELETE e outros metodos. Requests e usada por milhoes de projetos para consumir APIs REST, fazer web scraping, automatizar interacoes com servicos web e muito mais.
Embora o Python tenha o modulo embutido urllib, Requests e vastamente preferida pela comunidade por sua simplicidade e poder.
Instalacao e Primeiro Uso
# Instalacao
# pip install requests
import requests
# Requisicao GET simples
response = requests.get('https://api.github.com')
print(response.status_code) # 200
print(response.headers['content-type']) # application/json
print(response.json()) # dicionario Python
print(response.text) # conteudo como string
Metodos HTTP
import requests
BASE_URL = 'https://jsonplaceholder.typicode.com'
# GET — buscar dados
response = requests.get(f'{BASE_URL}/posts/1')
post = response.json()
print(post['title'])
# GET com parametros de query
response = requests.get(f'{BASE_URL}/posts', params={'userId': 1, '_limit': 5})
print(response.url) # .../posts?userId=1&_limit=5
posts = response.json()
# POST — criar dados
novo_post = {
'title': 'Meu Post',
'body': 'Conteudo do post',
'userId': 1,
}
response = requests.post(f'{BASE_URL}/posts', json=novo_post)
print(response.status_code) # 201
print(response.json())
# PUT — atualizar dados (completo)
atualizado = {'title': 'Titulo Atualizado', 'body': 'Novo conteudo', 'userId': 1}
response = requests.put(f'{BASE_URL}/posts/1', json=atualizado)
# PATCH — atualizar dados (parcial)
response = requests.patch(f'{BASE_URL}/posts/1', json={'title': 'Novo Titulo'})
# DELETE — remover dados
response = requests.delete(f'{BASE_URL}/posts/1')
print(response.status_code) # 200
Headers e Autenticacao
import requests
# Headers customizados
headers = {
'Authorization': 'Bearer meu_token_aqui',
'Content-Type': 'application/json',
'Accept-Language': 'pt-BR',
'User-Agent': 'MinhaApp/1.0',
}
response = requests.get('https://api.exemplo.com/dados', headers=headers)
# Autenticacao basica
response = requests.get(
'https://api.exemplo.com/privado',
auth=('usuario', 'senha'),
)
# Autenticacao com token Bearer
response = requests.get(
'https://api.exemplo.com/dados',
headers={'Authorization': 'Bearer meu_token'},
)
Tratamento de Erros
import requests
from requests.exceptions import (
ConnectionError, Timeout, HTTPError, RequestException
)
def buscar_dados(url: str) -> dict | None:
"""Busca dados de uma URL com tratamento de erros."""
try:
response = requests.get(url, timeout=10)
response.raise_for_status() # gera HTTPError se status >= 400
return response.json()
except Timeout:
print('A requisicao excedeu o tempo limite')
except ConnectionError:
print('Falha na conexao com o servidor')
except HTTPError as e:
print(f'Erro HTTP: {e.response.status_code}')
if e.response.status_code == 404:
print('Recurso nao encontrado')
elif e.response.status_code == 500:
print('Erro interno do servidor')
except RequestException as e:
print(f'Erro na requisicao: {e}')
return None
# Verificacao manual de status
response = requests.get('https://api.exemplo.com/dados')
if response.ok: # True se status < 400
dados = response.json()
else:
print(f'Erro: {response.status_code} - {response.reason}')
Sessoes
Sessoes permitem reutilizar configuracoes e manter cookies entre requisicoes.
import requests
# Usando sessao para reutilizar configuracoes
session = requests.Session()
session.headers.update({
'Authorization': 'Bearer meu_token',
'User-Agent': 'MinhaApp/1.0',
})
# Todas as requisicoes da sessao herdam os headers
response1 = session.get('https://api.exemplo.com/usuarios')
response2 = session.get('https://api.exemplo.com/produtos')
# Sessao como context manager
with requests.Session() as s:
# Login
s.post('https://site.com/login', data={'user': 'ana', 'pass': 'senha'})
# Requisicoes autenticadas (cookies mantidos)
perfil = s.get('https://site.com/perfil')
pedidos = s.get('https://site.com/pedidos')
Upload e Download de Arquivos
import requests
from pathlib import Path
# Upload de arquivo
with open('documento.pdf', 'rb') as f:
response = requests.post(
'https://api.exemplo.com/upload',
files={'arquivo': ('documento.pdf', f, 'application/pdf')},
)
# Download de arquivo pequeno
response = requests.get('https://exemplo.com/imagem.png')
Path('imagem.png').write_bytes(response.content)
# Download de arquivo grande (streaming)
with requests.get('https://exemplo.com/video.mp4', stream=True) as r:
r.raise_for_status()
with open('video.mp4', 'wb') as f:
for chunk in r.iter_content(chunk_size=8192):
f.write(chunk)
Retry e Resiliencia
import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
def criar_sessao_resiliente(
retries: int = 3,
backoff_factor: float = 0.3,
status_forcelist: tuple = (500, 502, 503, 504),
) -> requests.Session:
"""Cria sessao com retry automatico."""
session = requests.Session()
retry = Retry(
total=retries,
read=retries,
connect=retries,
backoff_factor=backoff_factor,
status_forcelist=status_forcelist,
)
adapter = HTTPAdapter(max_retries=retry)
session.mount('http://', adapter)
session.mount('https://', adapter)
return session
# Usar
session = criar_sessao_resiliente()
response = session.get('https://api.exemplo.com/dados')
Erros Comuns
O erro mais perigoso e nao definir timeout nas requisicoes, o que pode fazer o programa travar indefinidamente aguardando resposta de um servidor que nao responde. Outro erro e nao verificar o status da resposta, assumindo que toda requisicao foi bem-sucedida. Tambem e comum nao usar sessoes quando se faz multiplas requisicoes ao mesmo servidor, perdendo o beneficio de reutilizacao de conexoes TCP. Enviar dados sensiveis como tokens em URLs (query params) em vez de headers e um problema de seguranca frequente.
Boas Praticas
Sempre defina timeout em todas as requisicoes. Use response.raise_for_status() para tratar erros HTTP. Use sessoes para multiplas requisicoes ao mesmo servidor. Implemente retry com backoff exponencial para resiliencia. Nunca inclua credenciais diretamente no codigo — use variaveis de ambiente. Para APIs assincronas, considere httpx como alternativa que suporta async/await.
Quando Usar
Requests e ideal para consumir APIs REST, fazer web scraping, automatizar interacoes com servicos web e qualquer operacao que envolva requisicoes HTTP sincronas. Para aplicacoes assincronas de alta concorrencia, considere aiohttp ou httpx. Para testes, responses ou httpx.MockTransport permitem simular respostas HTTP.
Clientes HTTP em outras linguagens: Go possui um cliente HTTP poderoso na biblioteca padrão, e Rust com reqwest oferece requisições HTTP assíncronas e tipadas.