Skip to main content

Official Python SDK for Partnr API v2 - Brazilian financial data

Project description

partnr-api

Official Python SDK for Partnr API v2 - Brazilian financial data.

Installation

pip install partnr-api
# or
poetry add partnr-api
# or
uv add partnr-api

Quickstart

from partnr import PartnrClient

# Auto-detects PARTNR_API_KEY from environment
client = PartnrClient()

# Or provide explicitly
client = PartnrClient(api_key="your-api-key")

# Get company details
company = client.companies.get("PETR3")
print(company.trading_name)  # PETROBRAS

# Get historical quotes
quotes = client.quotes.get_historical_quotes("PETR4")
print(quotes[0].close_price)

Configuration

client = PartnrClient(
    api_key="your-api-key",      # Required
    base_url="https://data.partnr.ai/v2/",  # Optional, default
    timeout=30.0,                 # Optional, default 30s
    max_retries=2,               # Optional, default 2
    headers={                    # Optional extra headers
        "X-Custom-Header": "value",
    },
)

# Use as context manager
with PartnrClient(api_key="your-api-key") as client:
    company = client.companies.get("PETR3")

Examples

List Companies

# List all companies
companies = client.companies.list()

# With optional fields
companies = client.companies.list(
    show_sector=True,
    show_market_cap=True,
)

# Access sector and market cap
for company in companies:
    print(company.symbol, company.sector.name if company.sector else None)
    print(company.market_cap.value if company.market_cap else None)

Get Company by Identifier

# You can use symbol, company_id (CNPJ), or ticker
company = client.companies.get("PETR3")
company2 = client.companies.get("PETR")
company3 = client.companies.get("33000167000101")

# With optional fields
company_full = client.companies.get(
    "PETR3",
    show_market_cap=True,
    show_logo=True,
    show_company_details=True,
)

# Market cap is an object with value and format
print(company_full.market_cap.value)   # 497465651767
print(company_full.market_cap.format)  # "BRL 497,465,651,767"

Historical Quotes

# Get historical quote data
quotes = client.quotes.get_historical_quotes(
    "PETR4",
    start_date="2024-01-01",
    end_date="2024-12-31",
    adjusted=True,  # Adjust for dividends and corporate actions
)

for quote in quotes:
    print(f"{quote.date}: {quote.close_price} (vol: {quote.volume})")

List and Get News

# List recent news
news = client.news.list(limit=10)

# Filter by entity (ticker, sector, etc.)
petr_news = client.news.list(query="PETR4", limit=5)

# Get full article with summary and entities
article = client.news.get(news[0].id)
print(article.summary)
print(article.key_points)

Paginate Through News

# Using iterator
for article in client.news.iterate(limit=20):
    print(article.title)
    # Automatically fetches next page when needed

Run Screener with Filters

results = client.screener.run(
    order_by="droplet:PRICE_TO_EARNINGS",
    order="asc",
    limit=10,
    primary_only=True,
    filters=[
        {"type": "close_price", "op": ">=", "value": 5},
        {"type": "sector", "in": ["BANKING", "TECHNOLOGY"]},
        {"type": "droplet:PRICE_TO_EARNINGS", "op": "<", "value": 15},
    ],
)

for item in results.data:
    print(f"{item.ticker}: R$ {item.current_price}")

Financial Reports and Ratios

# Get standardized reports
reports = client.companies.get_reports(
    "PETR3",
    section="INCOME_STATEMENT",
    frequency="QUARTERLY",
    aggregation="CONSOLIDATED",
)

# Get financial ratios
ratios = client.companies.get_ratios(
    "PETR3",
    ids="EBITDA_MARGIN,ROE,NET_MARGIN",
    frequency="TTM",
)

# Get valuation ratios
valuation = client.companies.get_valuation_ratios(
    "PETR3",
    ids="PRICE_TO_EARNINGS,PRICE_TO_BOOK",
)

Traded Funds (FIIs, ETFs)

# List all traded funds
funds = client.traded_funds.list()

# Iterate through all funds
for fund in client.traded_funds.iterate():
    print(f"{fund.symbol}: {fund.name}")

# Get fund details
hglg = client.traded_funds.get("HGLG11")
print(hglg.dividend_yield_12m)

Macroeconomic Indicators

# List available indicators
indicators = client.macroeconomics.list_indicators()

# Get indicator series
selic = client.macroeconomics.get_indicator_series(
    "INTEREST_RATE",
    country="BRA",
    unit="ANNUAL",
    limit=12,
)

for point in selic:
    print(f"{point.date}: {point.value}%")

Daily Variations

variations = client.stocks.get_variations()

print("Top gainers:")
for stock in variations.highs[:5]:
    print(f"{stock.ticker}: +{stock.variation * 100:.2f}%")

print("Top losers:")
for stock in variations.lows[:5]:
    print(f"{stock.ticker}: {stock.variation * 100:.2f}%")

Error Handling

All errors include the request_id for debugging with Partnr support.

from partnr import (
    PartnrClient,
    ApiError,
    AuthenticationError,
    NotFoundError,
    RateLimitError,
    ValidationError,
    ServerError,
)

try:
    company = client.companies.get("INVALID")
except AuthenticationError:
    print("Invalid API key")
except NotFoundError:
    print("Company not found")
except RateLimitError:
    print("Rate limit exceeded, try again later")
except ValidationError:
    print("Invalid request parameters")
except ServerError:
    print("Server error, try again later")
except ApiError as e:
    print(f"API Error: {e.message}")
    print(f"Request-Id: {e.request_id}")
    print(f"Status: {e.status}")
    print(f"Code: {e.code}")

Retries

The SDK automatically retries on:

  • 429 (Rate Limit) - respects Retry-After header (supports both seconds and HTTP-date format)
  • 5xx (Server Errors)
  • Network timeouts and failures

No retries on 4xx errors (except 429).

client = PartnrClient(
    api_key="your-api-key",
    max_retries=3,  # Retry up to 3 times
    timeout=60.0,   # 60s timeout
)

Async Support

Full async support for high-performance applications:

from partnr import AsyncPartnrClient

async def main():
    async with AsyncPartnrClient(api_key="your-api-key") as client:
        # All methods are async
        company = await client.companies.get("PETR3")
        
        # Async iteration
        async for article in client.news.iterate(limit=10):
            print(article.title)

# Run with asyncio
import asyncio
asyncio.run(main())

Request/Response Hooks

Add logging, metrics, or custom behavior:

# Sync client
def log_request(url, options):
    print(f"[{options['method']}] {url}")

def log_response(url, response, duration_ms):
    print(f"[{response.status_code}] {url} - {duration_ms:.0f}ms")

client.set_request_hook(log_request)
client.set_response_hook(log_response)

# Async client (use async functions)
async def async_log_request(url, options):
    print(f"[{options['method']}] {url}")

async_client.set_request_hook(async_log_request)

Type Hints

Full type hints with Pydantic models:

from partnr.models import (
    Company,
    CompanyListItem,
    Quote,
    NewsArticle,
    ScreenerResponse,
    TradedFund,
    MacroIndicator,
)

Requirements

  • Python >= 3.9
  • httpx >= 0.25.0
  • pydantic >= 2.0.0

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

partnr_api-0.2.0.tar.gz (4.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

partnr_api-0.2.0-py3-none-any.whl (4.1 kB view details)

Uploaded Python 3

File details

Details for the file partnr_api-0.2.0.tar.gz.

File metadata

  • Download URL: partnr_api-0.2.0.tar.gz
  • Upload date:
  • Size: 4.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.10

File hashes

Hashes for partnr_api-0.2.0.tar.gz
Algorithm Hash digest
SHA256 80a696494dc8ea47e2bd4a184d37f7f7408ba4bf9160841e26fcf6d2e696b6a6
MD5 94e2a988dea0604394aece8d85a314e9
BLAKE2b-256 574ed8ae65d26b805c041ea193957942985e10c573db61b3c826c327e2841e27

See more details on using hashes here.

File details

Details for the file partnr_api-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: partnr_api-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 4.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.10

File hashes

Hashes for partnr_api-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 0a669f66d0f4249ad2bd45677667473b099a2e0d9156f980317acf04deb01ebd
MD5 d382a2d8b39c19c02c5561c6581e3322
BLAKE2b-256 08c341099843e3ca9fe65364da828ead09b30ba55d3bc194559f0b34ab5e47e2

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page