SDK oficial da brapi para Python 3.8 ou superior. Cobre a API REST com type hints completos e clientes síncrono e assíncrono.
Os type hints cobrem toda a API, então o editor autocompleta parâmetros e campos de resposta, e o mypy pega erro antes de rodar.
Você escolhe entre cliente síncrono e assíncrono. O transporte padrão é o httpx, com HTTP/2 e pool de conexões. Para carga assíncrona pesada, o SDK também aceita aiohttp.
O cliente já traz retry e exceções separadas por status HTTP. O código é gerado com Stainless a partir do OpenAPI, então ele acompanha a API sem passo manual.
pip install brapiCom suporte a aiohttp (opcional, para melhor performance async):
pip install brapi[aiohttp]import os
from brapi import Brapi
client = Brapi(
api_key=os.environ.get("BRAPI_API_KEY"),
)
# Buscar cotação
quote = client.quote.retrieve(tickers="PETR4")
print(quote.results[0].regular_market_price)
# Múltiplas ações
quotes = client.quote.retrieve(tickers="PETR4,VALE3,ITUB4")
for stock in quotes.results:
print(f"{stock.symbol}: R$ {stock.regular_market_price}")import os
import asyncio
from brapi import AsyncBrapi
client = AsyncBrapi(
api_key=os.environ.get("BRAPI_API_KEY"),
)
async def main():
quote = await client.quote.retrieve(tickers="PETR4")
print(quote.results[0].regular_market_price)
asyncio.run(main())Recomendamos usar python-dotenv para gerenciar variáveis de ambiente:
pip install python-dotenvCrie um arquivo .env:
BRAPI_API_KEY=seu_token_aquiNo seu código:
import os
from dotenv import load_dotenv
from brapi import Brapi
load_dotenv()
client = Brapi(
api_key=os.environ.get("BRAPI_API_KEY"),
)client = Brapi(
api_key="seu_token",
environment="production", # 'production' ou 'sandbox'
max_retries=2, # Número de tentativas (padrão: 2)
timeout=60.0, # Timeout em segundos (padrão: 60)
)# Cotação única
quote = client.quote.retrieve(tickers="PETR4")
stock = quote.results[0]
print(f"Símbolo: {stock.symbol}")
print(f"Nome: {stock.short_name}")
print(f"Preço: R$ {stock.regular_market_price}")
print(f"Variação: {stock.regular_market_change_percent}%")
# Com módulos adicionais
quote_with_data = client.quote.retrieve(
tickers="PETR4",
modules="summaryProfile,balanceSheetHistory"
)# Todas as ações disponíveis
stocks = client.quote.list()
for stock in stocks.stocks:
print(f"{stock.stock}: {stock.name} ({stock.type})")
# Com paginação
stocks_page = client.quote.list(page=1, limit=50)# Cotação de cripto
crypto = client.crypto.retrieve(coin="BTC")
print(f"Bitcoin: ${crypto.currency}")
# Lista de criptos disponíveis
cryptos = client.crypto.available()
for coin in cryptos.coins:
print(f"{coin.coin}: {coin.name}")# Cotação de moeda
currency = client.currency.retrieve(currency="USD-BRL")
print(f"Dólar: R$ {currency.ask}")
# Lista de moedas disponíveis
currencies = client.currency.available()# Dados de inflação do Brasil
inflation = client.inflation.retrieve(country="brazil")
print(f"IPCA: {inflation.IPCA}")
# Países disponíveis
countries = client.inflation.available()# Taxa SELIC
selic = client.prime_rate.retrieve(country="brazil")
print(f"SELIC: {selic.value}%")
# Países disponíveis
countries = client.prime_rate.available()import asyncio
from brapi import AsyncBrapi
async def main():
client = AsyncBrapi(api_key="seu_token")
# Todas as operações usam await
quote = await client.quote.retrieve(tickers="PETR4")
print(quote.results[0].regular_market_price)
# Não esqueça de fechar o cliente
await client.close()
asyncio.run(main())import asyncio
from brapi import AsyncBrapi
async def main():
async with AsyncBrapi(api_key="seu_token") as client:
quote = await client.quote.retrieve(tickers="PETR4")
print(quote.results[0].regular_market_price)
# Cliente fechado automaticamente
asyncio.run(main())import asyncio
from brapi import AsyncBrapi, DefaultAioHttpClient
async def main():
async with AsyncBrapi(
api_key="seu_token",
http_client=DefaultAioHttpClient(),
) as client:
quote = await client.quote.retrieve(tickers="PETR4")
print(quote.results[0].regular_market_price)
asyncio.run(main())import asyncio
from brapi import AsyncBrapi
async def get_multiple_quotes():
async with AsyncBrapi(api_key="seu_token") as client:
# Buscar várias cotações em paralelo
tasks = [
client.quote.retrieve(tickers="PETR4"),
client.quote.retrieve(tickers="VALE3"),
client.quote.retrieve(tickers="ITUB4"),
]
results = await asyncio.gather(*tasks)
for quote in results:
stock = quote.results[0]
print(f"{stock.symbol}: R$ {stock.regular_market_price}")
asyncio.run(get_multiple_quotes())from brapi import Brapi
from brapi import (
APIError,
BadRequestError,
AuthenticationError,
NotFoundError,
RateLimitError,
)
client = Brapi(api_key="seu_token")
try:
quote = client.quote.retrieve(tickers="INVALID")
except NotFoundError as e:
print(f"Ticker não encontrado: {e}")
except RateLimitError as e:
print(f"Limite de requisições: {e}")
except AuthenticationError as e:
print(f"Token inválido: {e}")
except APIError as e:
print(f"Erro na API: {e}")| Exception | Status | Descrição |
|---|---|---|
BadRequestError | 400 | Requisição inválida |
AuthenticationError | 401 | Token inválido |
PermissionDeniedError | 403 | Sem permissão |
NotFoundError | 404 | Recurso não encontrado |
UnprocessableEntityError | 422 | Dados inválidos |
RateLimitError | 429 | Limite de requisições |
InternalServerError | 5xx | Erro no servidor |
APIConnectionError | N/A | Erro de conexão |
from flask import Flask, jsonify
from brapi import Brapi
app = Flask(__name__)
client = Brapi(api_key="seu_token")
@app.route('/api/quote/<ticker>')
def get_quote(ticker):
try:
quote = client.quote.retrieve(tickers=ticker)
return jsonify({
'symbol': quote.results[0].symbol,
'price': quote.results[0].regular_market_price,
})
except NotFoundError:
return jsonify({'error': 'Ticker not found'}), 404
if __name__ == '__main__':
app.run()from fastapi import FastAPI, HTTPException
from brapi import AsyncBrapi, NotFoundError
app = FastAPI()
client = AsyncBrapi(api_key="seu_token")
@app.get("/api/quote/{ticker}")
async def get_quote(ticker: str):
try:
quote = await client.quote.retrieve(tickers=ticker)
return {
'symbol': quote.results[0].symbol,
'price': quote.results[0].regular_market_price,
}
except NotFoundError:
raise HTTPException(status_code=404, detail="Ticker not found")
@app.on_event("shutdown")
async def shutdown():
await client.close()import pandas as pd
from brapi import Brapi
client = Brapi(api_key="seu_token")
def get_quotes_dataframe(tickers: list[str]) -> pd.DataFrame:
"""Retorna cotações como DataFrame"""
tickers_str = ','.join(tickers)
quote = client.quote.retrieve(tickers=tickers_str)
data = []
for stock in quote.results:
data.append({
'symbol': stock.symbol,
'name': stock.short_name,
'price': stock.regular_market_price,
'change_percent': stock.regular_market_change_percent,
})
return pd.DataFrame(data)
# Uso
df = get_quotes_dataframe(['PETR4', 'VALE3', 'ITUB4'])
print(df)
# Salvar em Excel
df.to_excel('cotacoes.xlsx', index=False)# Timeout global
client = Brapi(
api_key="seu_token",
timeout=10.0, # 10 segundos
)
# Timeout por requisição
quote = client.quote.retrieve(
tickers="PETR4",
timeout=5.0, # 5 segundos
)# Configurar retries
client = Brapi(
api_key="seu_token",
max_retries=3, # Tenta até 3 vezes
)
# Desabilitar retries
client = Brapi(
api_key="seu_token",
max_retries=0, # Sem retry
)A SDK inclui type hints completos para todas as operações:
from brapi import Brapi
from brapi.types import QuoteRetrieveResponse
client: Brapi = Brapi(api_key="seu_token")
# Type checking automático
quote: QuoteRetrieveResponse = client.quote.retrieve(tickers="PETR4")
# Autocomplete no IDE
price: float = quote.results[0].regular_market_price# ✅ Bom - Crie uma instância e reutilize
from brapi import Brapi
client = Brapi(api_key="seu_token")
def get_quote(ticker):
return client.quote.retrieve(tickers=ticker)
# ❌ Ruim - Criar nova instância a cada uso
def get_quote(ticker):
client = Brapi(api_key="seu_token") # Não faça isso
return client.quote.retrieve(tickers=ticker)# ✅ Bom
import os
from brapi import Brapi
client = Brapi(api_key=os.environ.get("BRAPI_API_KEY"))
# ❌ Ruim - Nunca hardcode o token
client = Brapi(api_key="meu-token-secreto") # Não faça isso!# ✅ Bom
async with AsyncBrapi(api_key="seu_token") as client:
quote = await client.quote.retrieve(tickers="PETR4")
# Cliente fechado automaticamente
# ❌ Ruim
client = AsyncBrapi(api_key="seu_token")
quote = await client.quote.retrieve(tickers="PETR4")
# Esqueceu de fechar!Precisa de ajuda? Entre em contato:
Contribuições são bem-vindas! Veja o guia de contribuição.
MIT License - veja LICENSE para detalhes.