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)
Compatibility imports are also supported:
from partnr import PartnrClient
# or
from partnr_api import PartnrClient
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-Afterheader (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
Metadata
Release files for partnr-api 0.2.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| partnr_api-0.2.2.tar.gz | 34.7 kB | Without provenance | Details for partnr_api-0.2.2.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| partnr_api-0.2.2-py3-none-any.whl | Python 3 | none | any | Details for partnr_api-0.2.2-py3-none-any.whl |
Total release size: 101.7 kB
Release files / partnr_api-0.2.2.tar.gz
| Download URL | partnr_api-0.2.2.tar.gz |
|---|---|
| Size | 34.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a052d0c09364d6783f044c36eec94a30452dfc3a0bfd0285da96c3957e2b0338
|
|
BLAKE2b-256 checksum How to use checksums |
5c3c32fd58a5b0a5f943240462a605833f1cd2bcf2f0c7444332fec3eec96f0f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.3
|
Release files / partnr_api-0.2.2-py3-none-any.whl
| Download URL | partnr_api-0.2.2-py3-none-any.whl |
|---|---|
| Size | 66.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
dcfdf1f7f7f89f488aaa153ba7920e205e56a10753395329cf74cc3f1a14edaf
|
|
BLAKE2b-256 checksum How to use checksums |
16e3b911658250dc06839388d6dd87670ec9085a71da2c3732a7d5fbdc986827
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.3
|
Security for partnr-api 0.2.2
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.