Como Usar a API da B3 com Python: Guia Prático 2025

Aprenda a integrar a API brapi.dev com Python usando requests. Exemplos práticos com classes, Pandas, Flask e exportação para CSV/Excel.

Categoria:Tutoriais e Integrações • Desenvolvimento Python
8 min
Atualizado em:
Expertise: Desenvolvimento Python para análise financeira - 7+ anos
Tags:
PythonAPIRequestsPandasFlaskAutomação

Neste artigo

Como Integrar a API da B3 com Python

Guia completo para buscar cotações de ações, ETFs e outros ativos da B3 usando Python e a biblioteca requests.

Publicado em 12 de Outubro de 2025

Por Que Python para Análise Financeira?

Python é a linguagem preferida para análise de dados e finanças por ser:

  • Simples de aprender - Sintaxe clara e intuitiva
  • Poderosa - Bibliotecas como Pandas, NumPy e Matplotlib
  • Popular - Grande comunidade e recursos
  • Versátil - Desde scripts até aplicações web

Instalação

pip install requests

Exemplo Básico

import requests

token = 'SEU_TOKEN'
ticker = 'PETR4'
url = f'https://brapi.dev/api/quote/{ticker}?token={token}'

response = requests.get(url)
data = response.json()

quote = data['results'][0]
print(f"{quote['symbol']}: R$ {quote['regularMarketPrice']:.2f}")

Classe Cliente Profissional

import requests
from typing import Dict, List, Optional
from dataclasses import dataclass

@dataclass
class Quote:
    """Representa uma cotação de ativo"""
    symbol: str
    short_name: str
    regular_market_price: float
    regular_market_change_percent: float
    currency: str
    
    @classmethod
    def from_dict(cls, data: Dict) -> 'Quote':
        return cls(
            symbol=data['symbol'],
            short_name=data['shortName'],
            regular_market_price=data['regularMarketPrice'],
            regular_market_change_percent=data['regularMarketChangePercent'],
            currency=data['currency']
        )

class BrapiClient:
    """Cliente para a API brapi.dev"""
    
    BASE_URL = 'https://brapi.dev/api'
    
    def __init__(self, token: str):
        self.token = token
        self.session = requests.Session()
        self.session.headers.update({
            'User-Agent': 'Python BrapiClient/1.0'
        })
    
    def get_quote(self, ticker: str) -> Optional[Quote]:
        """Busca cotação de um ativo"""
        url = f'{self.BASE_URL}/quote/{ticker}'
        params = {'token': self.token}
        
        try:
            response = self.session.get(url, params=params, timeout=10)
            response.raise_for_status()
            data = response.json()
            
            if data.get('results'):
                return Quote.from_dict(data['results'][0])
            return None
        except requests.exceptions.RequestException as e:
            print(f'Erro ao buscar {ticker}: {e}')
            return None
    
    def get_multiple_quotes(self, tickers: List[str]) -> List[Quote]:
        """Busca cotações de múltiplos ativos"""
        tickers_param = ','.join(tickers)
        url = f'{self.BASE_URL}/quote/{tickers_param}'
        params = {'token': self.token}
        
        try:
            response = self.session.get(url, params=params, timeout=10)
            response.raise_for_status()
            data = response.json()
            
            return [Quote.from_dict(item) for item in data.get('results', [])]
        except requests.exceptions.RequestException as e:
            print(f'Erro ao buscar cotações: {e}')
            return []
    
    def __enter__(self):
        return self
    
    def __exit__(self, *args):
        self.session.close()

# Uso
with BrapiClient('SEU_TOKEN') as client:
    quote = client.get_quote('PETR4')
    if quote:
        print(f'{quote.symbol}: R$ {quote.regular_market_price:.2f}')

Integração com Pandas

import pandas as pd

def get_quotes_dataframe(tickers: List[str], token: str) -> pd.DataFrame:
    """Retorna cotações como DataFrame"""
    with BrapiClient(token) as client:
        quotes = client.get_multiple_quotes(tickers)
        
        if not quotes:
            return pd.DataFrame()
        
        data = [{
            'symbol': q.symbol,
            'name': q.short_name,
            'price': q.regular_market_price,
            'change_percent': q.regular_market_change_percent,
            'currency': q.currency
        } for q in quotes]
        
        return pd.DataFrame(data)

# Uso
df = get_quotes_dataframe(['PETR4', 'VALE3', 'ITUB4'], 'SEU_TOKEN')
print(df)

# Salvar em Excel
df.to_excel('cotacoes.xlsx', index=False)

# Salvar em CSV
df.to_csv('cotacoes.csv', index=False)

Análise de Dados

# Estatísticas básicas
print(df['price'].describe())

# Filtrar ações com variação positiva
df_positivas = df[df['change_percent'] > 0]

# Ordenar por variação
df_sorted = df.sort_values('change_percent', ascending=False)

# Calcular média de preços
media_preco = df['price'].mean()

Aplicação Flask

from flask import Flask, jsonify
import os

app = Flask(__name__)
BRAPI_TOKEN = os.environ.get('BRAPI_TOKEN')

@app.route('/api/quote/<ticker>')
def get_quote_api(ticker):
    """Endpoint para buscar cotação"""
    with BrapiClient(BRAPI_TOKEN) as client:
        quote = client.get_quote(ticker)
        
        if not quote:
            return jsonify({'error': 'Quote not found'}), 404
        
        return jsonify({
            'symbol': quote.symbol,
            'name': quote.short_name,
            'price': quote.regular_market_price,
            'change_percent': quote.regular_market_change_percent
        })

if __name__ == '__main__':
    app.run(debug=True)

Script de Monitoramento

import time
from datetime import datetime

def monitor_stocks(tickers: List[str], token: str, interval: int = 60):
    """Monitora ações em tempo real"""
    print(f"Monitorando {len(tickers)} ativos...")
    
    while True:
        with BrapiClient(token) as client:
            quotes = client.get_multiple_quotes(tickers)
            
            print(f"\n=== {datetime.now().strftime('%H:%M:%S')} ===")
            for quote in quotes:
                color = '\033[92m' if quote.regular_market_change_percent > 0 else '\033[91m'
                reset = '\033[0m'
                print(f"{quote.symbol}: R$ {quote.regular_market_price:.2f} "
                      f"{color}{quote.regular_market_change_percent:+.2f}%{reset}")
        
        time.sleep(interval)

# Uso
monitor_stocks(['PETR4', 'VALE3', 'ITUB4'], 'SEU_TOKEN', interval=60)

Salvando Histórico em CSV

import csv
from datetime import datetime

def save_quotes_to_csv(tickers: List[str], token: str, filename: str):
    """Salva cotações em arquivo CSV"""
    with BrapiClient(token) as client:
        quotes = client.get_multiple_quotes(tickers)
        
        if not quotes:
            print('Nenhuma cotação obtida')
            return
        
        with open(filename, 'a', newline='', encoding='utf-8') as csvfile:
            fieldnames = ['timestamp', 'symbol', 'name', 'price', 'change_percent']
            writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
            
            # Escreve cabeçalho se arquivo estiver vazio
            if csvfile.tell() == 0:
                writer.writeheader()
            
            timestamp = datetime.now().isoformat()
            for quote in quotes:
                writer.writerow({
                    'timestamp': timestamp,
                    'symbol': quote.symbol,
                    'name': quote.short_name,
                    'price': quote.regular_market_price,
                    'change_percent': quote.regular_market_change_percent
                })
        
        print(f'Cotações salvas em {filename}')

# Uso - executa diariamente
save_quotes_to_csv(['PETR4', 'VALE3', 'ITUB4'], 'SEU_TOKEN', 'historico.csv')

Boas Práticas

1. Use Variáveis de Ambiente

import os
from dotenv import load_dotenv

load_dotenv()  # Carrega .env

token = os.environ.get('BRAPI_TOKEN')
if not token:
    raise ValueError('BRAPI_TOKEN não configurado')

Arquivo .env:

BRAPI_TOKEN=seu_token_aqui

2. Implemente Tratamento de Erros

try:
    quote = client.get_quote('PETR4')
except requests.exceptions.Timeout:
    print('Timeout na requisição')
except requests.exceptions.ConnectionError:
    print('Erro de conexão')
except Exception as e:
    print(f'Erro inesperado: {e}')

3. Use Context Managers

with BrapiClient(token) as client:
    # As conexões são fechadas automaticamente
    quote = client.get_quote('PETR4')

Próximos Passos

Conclusão

Python é uma excelente escolha para trabalhar com dados da B3. Com requests e Pandas, você pode criar análises poderosas, automações e até aplicações web completas.

Comece agora: Copie o código acima e adapte para suas necessidades!

Artigos Relacionados