🌗 ← Índice

🐍 Python P15 — Consumindo APIs com requests


Data: 14/08/2026

Nível: Intermediário (Mês 2 — POO)




🎯 Objetivos





📖 Teoria


O que é uma API REST


Uma API (Interface de Programação de Aplicações) expõe recursos via HTTP:


MétodoAçãoExemplo
GETLer`GET /usuarios`
POSTCriar`POST /usuarios`
PUTAtualizar (completo)`PUT /usuarios/1`
DELETERemover`DELETE /usuarios/1`

Primeira chamada com requests



import requests

resposta = requests.get("https://api.github.com/users/hugocosta-dev")
print(resposta.status_code)     # 200
print(resposta.json())          # dict com os dados

Parâmetros de URL (query string)



# https://api.github.com/search/repositories?q=python&sort=stars
resposta = requests.get(
    "https://api.github.com/search/repositories",
    params={"q": "python", "sort": "stars", "per_page": 5},
)
dados = resposta.json()
for repo in dados["items"]:
    print(repo["full_name"], "⭐", repo["stargazers_count"])

Headers e autenticação



headers = {"Authorization": "Bearer SEU_TOKEN", "Accept": "application/json"}
resposta = requests.get("https://api.exemplo.com/dados", headers=headers)

⚠️ **Nunca** coloque tokens no código! Use variáveis de ambiente (`.env`).


import os
from dotenv import load_dotenv

load_dotenv()
token = os.getenv("API_TOKEN")

Tratamento de erros



import requests

try:
    resposta = requests.get(
        "https://api.exemplo.com/endpoint",
        timeout=10,                     # ⚠️ SEMPRE defina timeout!
    )
    resposta.raise_for_status()         # levanta exceção p/ 4xx/5xx
    dados = resposta.json()
except requests.exceptions.Timeout:
    print("A API demorou demais para responder")
except requests.exceptions.HTTPError as erro:
    print(f"Erro HTTP: {erro} (status {resposta.status_code})")
except requests.exceptions.RequestException as erro:
    print(f"Falha na requisição: {erro}")

Sessões (reutilizar conexão)



sessao = requests.Session()
sessao.headers.update({"Authorization": f"Bearer {token}"})

r1 = sessao.get("https://api.exemplo.com/perfil")
r2 = sessao.get("https://api.exemplo.com/pedidos")   # mesma sessão/headers

💡 `Session` reutiliza conexões TCP — mais rápido e eficiente para várias chamadas.

POST com JSON



payload = {"nome": "Hugo", "email": "hugo@exemplo.com"}
resposta = requests.post(
    "https://api.exemplo.com/usuarios",
    json=payload,                    # serializa dict → JSON automaticamente
    timeout=10,
)
print(resposta.status_code)          # 201 = Created
print(resposta.json())



✍️ Exercícios


  1. 1. Faça GET em `https://api.github.com/repos/hugocosta-dev/agente_ia_buymais` e imprima: nome, descrição, estrelas e linguagem principal.
  2. 2. Use `params` para buscar 3 repositórios Python no GitHub com mais estrelas e imprima nome + estrelas.
  3. 3. Trate os erros: chame uma URL inexistente (ex: `https://httpbin.org/status/404`) e capture a exceção `HTTPError`, imprimindo o status.



🧪 Desafio


Crie uma classe ClienteGitHub que encapsula o acesso à API do GitHub:



class ClienteGitHub:
    def __init__(self, token=None): ...
    def buscar_repos(self, query, limite=5) -> list[dict]: ...
    def repo_info(self, dono, repo) -> dict: ...

Requisitos:


Teste: cliente = ClienteGitHub() → cliente.buscar_repos("langchain") deve listar repositórios.




✅ Correção



import requests


class ClienteGitHub:
    def __init__(self, token=None):
        self.sessao = requests.Session()
        self.sessao.headers.update({"Accept": "application/vnd.github+json"})
        if token:
            self.sessao.headers.update({"Authorization": f"Bearer {token}"})

    def buscar_repos(self, query, limite=5):
        try:
            resposta = self.sessao.get(
                "https://api.github.com/search/repositories",
                params={"q": query, "per_page": limite},
                timeout=10,
            )
            resposta.raise_for_status()
        except requests.exceptions.RequestException as erro:
            print(f"Erro ao buscar repositórios: {erro}")
            return []

        itens = resposta.json().get("items", [])
        return [
            {
                "nome": repo["full_name"],
                "descricao": repo.get("description"),
                "estrelas": repo["stargazers_count"],
                "linguagem": repo.get("language"),
                "url": repo["html_url"],
            }
            for repo in itens
        ]

    def repo_info(self, dono, repo):
        try:
            resposta = self.sessao.get(
                f"https://api.github.com/repos/{dono}/{repo}",
                timeout=10,
            )
            resposta.raise_for_status()
            dados = resposta.json()
            return {
                "nome": dados["full_name"],
                "descricao": dados.get("description"),
                "estrelas": dados["stargazers_count"],
                "linguagem": dados.get("language"),
                "url": dados["html_url"],
            }
        except requests.exceptions.RequestException as erro:
            print(f"Erro ao buscar {dono}/{repo}: {erro}")
            return {}


cliente = ClienteGitHub()
repos = cliente.buscar_repos("langchain", limite=3)
for repo in repos:
    print(repo["nome"], "⭐", repo["estrelas"])

💡 Boa prática: encapsular a API numa classe facilita testar, reutilizar e trocar de provedor depois.





HB Estudos · ← Voltar ao índice de Python