(+351) 21 24 10006  ·  info@bconcepts.pt
Carnaxide, Lisboa

Como autenticar numa API REST com OAuth 2.0 em Python

João Barros 05 de July de 2026 4 min de leitura

As APIs de dados mais robustas não estão abertas ao público: exigem autenticação. Em cenários servidor a servidor, o padrão mais comum é o OAuth 2.0 com o fluxo client credentials, e dominá-lo é essencial para construir pipelines de dados fiáveis. Este guia mostra, passo a passo, como obter um access token e chamar um endpoint protegido em Python.

Pré-requisitos

  • Python 3.8 ou superior instalado.
  • A biblioteca requests (instala-se com pip install requests).
  • As credenciais da API: client_id e client_secret, fornecidos pelo portal do fornecedor.
  • O URL do token endpoint (onde se pedem os tokens) e o URL do recurso protegido que queres consumir.

Passo 1: Entender o fluxo client credentials

O OAuth 2.0 define vários fluxos. O de client credentials é o indicado quando é a tua aplicação — e não um utilizador — a aceder aos dados, como acontece num script de ETL ou num serviço agendado. A ideia é simples: a aplicação apresenta o seu client_id e o seu client_secret a um token endpoint, recebe em troca um access token temporário e usa esse token para autenticar cada pedido à API. Não há ecrãs de login nem intervenção humana, o que o torna ideal para automação.

Passo 2: Obter o access token

O primeiro pedido é um POST ao token endpoint, indicando grant_type=client_credentials. A resposta é um JSON com o token e o seu tempo de validade em segundos (expires_in). Repara que as credenciais vão no corpo do pedido, sobre HTTPS, e nunca no URL.

import requests

TOKEN_URL = "https://auth.example.com/oauth/token"
CLIENT_ID = "your-client-id"
CLIENT_SECRET = "your-client-secret"

def get_token():
    response = requests.post(TOKEN_URL, data={
        "grant_type": "client_credentials",
        "client_id": CLIENT_ID,
        "client_secret": CLIENT_SECRET,
        "scope": "data.read",
    }, timeout=10)
    response.raise_for_status()
    return response.json()["access_token"]

token = get_token()
print("Access token obtained")

O método raise_for_status() garante que um erro de credenciais (HTTP 401) interrompe logo o script, em vez de continuar com um token inválido.

Passo 3: Chamar o endpoint protegido

Com o token em mãos, cada pedido à API leva o cabeçalho Authorization: Bearer <token>. É assim que o servidor sabe que estás autorizado.

API_URL = "https://api.example.com/v1/customers"

def get_data(token):
    headers = {"Authorization": f"Bearer {token}"}
    response = requests.get(API_URL, headers=headers, timeout=10)
    response.raise_for_status()
    return response.json()

records = get_data(token)
print(f"Received {len(records)} records")

Passo 4: Reutilizar o token e tratar a expiração

Pedir um token novo a cada chamada é lento e, muitas vezes, está sujeito a limites. O melhor é guardar o token e o seu instante de expiração, renovando-o apenas quando falta pouco tempo. Uma classe simples resolve o problema:

import time

class APIClient:
    def __init__(self):
        self._token = None
        self._expires_at = 0

    def valid_token(self):
        # Refresh 60 seconds before expiry, to be safe
        if not self._token or time.time() > self._expires_at - 60:
            response = requests.post(TOKEN_URL, data={
                "grant_type": "client_credentials",
                "client_id": CLIENT_ID,
                "client_secret": CLIENT_SECRET,
            }, timeout=10)
            response.raise_for_status()
            payload = response.json()
            self._token = payload["access_token"]
            self._expires_at = time.time() + payload["expires_in"]
        return self._token

client = APIClient()
headers = {"Authorization": f"Bearer {client.valid_token()}"}

Assim, o mesmo token é reutilizado enquanto for válido e renovado automaticamente quando necessário.

Verificar o resultado

Para confirmar que tudo funciona, corre o script e verifica dois sinais: o pedido do token devolve HTTP 200 e a chamada à API devolve dados em vez de um erro 401. Se receberes um 401, revê o client_id, o client_secret e o scope. Um erro 403 significa que o token é válido mas não tem permissões para aquele recurso — nesse caso, o problema está nas scopes atribuídas à aplicação.

Conclusão

Com estes passos tens uma base sólida para autenticar qualquer API de dados que use OAuth 2.0 client credentials, desde a obtenção do token até à sua renovação automática. O próximo passo natural é combinar isto com paginação e escrita numa base de dados, transformando estas chamadas num pipeline completo. Que API vais integrar primeiro?