Python SDK for the Tellimer API
Project description
Tellimer Python SDK
A Python client library for accessing Tellimer's data through their REST API. This SDK provides convenient access to macroeconomic data, parallel FX data, probability of default data, news, and other financial datasets.
Installation
pip install tellimer
Quick Start
import tellimer
# Initialize the client with your API key
api_key = "your_api_key_here"
client = tellimer.Client(api_key=api_key)
# Get macroeconomic data
result = client.data.macro_data.get(
countries=["ARG"],
indicators=["PCPIPCH"], # Inflation rate
start_date="2020-01-01",
end_date="2023-12-31"
)
result.data
# Search for news semantically, then fetch the full items
hits = client.news.search("Eurobond restructuring", limit=5)
items = client.news.get(news_ids=[h["id"] for h in hits[:2]])
Authentication
The SDK requires an API key for authentication. You can obtain an API key from your Tellimer account dashboard.
client = tellimer.Client(
api_key="your_api_key_here",
timeout=30 # Optional: request timeout in seconds
)
Core Components
Client
The main client class that provides access to all API endpoints.
Parameters
api_key(str): Your Tellimer API keytimeout(float, optional): Request timeout in seconds (default: 30)
Result
A data class that contains the response from data requests.
Attributes
data(pandas.DataFrame): The requested data in DataFrame format with multi-level columnsmetadata(list[dict]): Metadata about the indicators and countries
Data Access
Available Datasets
The SDK currently supports the following datasets:
macro_data: Macroeconomic indicators (searchable)parallel_fx: Parallel foreign exchange dataprobability_default: Probability of default data with optional contribution breakdowns
# List all available datasets
datasets = client.data.list_datasets()
datasets # ['macro_data', 'parallel_fx']
Macroeconomic Data (macro_data)
The macro data client provides access to searchable macroeconomic indicators.
Search Indicators
Search for available indicators using natural language queries:
# Basic search
indicators = client.data.macro_data.search(
query="inflation",
limit=5
)
# Search with filters
from tellimer import Filter
source_filter = Filter(field="source_name").equals("IMFWEO")
country_filter = Filter(field="country_iso").equals("ARG")
indicators = client.data.macro_data.search(
query="inflation",
limit=10,
filters=[source_filter, country_filter]
)
Get Data
Retrieve actual data for specific indicators and countries:
# Get data for specific indicators and countries
result = client.data.macro_data.get(
countries=["ARG", "BRA", "MEX"],
indicators=["PCPIPCH", "NGDP_RPCH"], # Inflation and GDP growth
start_date="2020-01-01",
end_date="2023-12-31"
)
# Access the data
df = result.data # pandas DataFrame with multi-level columns
metadata = result.metadata # List of indicator metadata
Parallel FX Data (parallel_fx)
Access parallel foreign exchange rate data:
# Get available countries for parallel FX data
countries = client.data.parallel_fx.available_countries()
# Get parallel FX data
result = client.data.parallel_fx.get(
countries=["ARG", "PAK"],
start_date="2025-07-01",
end_date="2025-09-01"
)
result.data.head()
Probability of Default Data (probability_default)
Access probability of default data across multiple tenor horizons (1-year, 3-year, 5-year) with optional contribution breakdowns:
# Get available countries for probability of default data
countries = client.data.probability_default.available_countries()
# Get 1-year probability of default (default)
result = client.data.probability_default.get(
countries=["ARG", "BRA"],
start_date="2024-01-01",
end_date="2024-12-31"
)
result.data.head()
# DataFrame with columns: date, probability_of_default, country
Tenor Horizons
The tenors parameter controls which PD horizons to fetch. It accepts a single tenor string or a list of tenors. Valid values: "1y", "3y", "5y". Defaults to "1y".
# Single tenor (3-year)
result = client.data.probability_default.get(
countries=["ARG"],
tenors="3y"
)
# DataFrame columns: date, probability_of_default_3y, country
# Multiple tenors
result = client.data.probability_default.get(
countries=["ARG"],
tenors=["1y", "3y", "5y"]
)
# DataFrame columns: date, probability_of_default, probability_of_default_3y, probability_of_default_5y, country
| Tenor | DataFrame Column |
|---|---|
"1y" |
probability_of_default |
"3y" |
probability_of_default_3y |
"5y" |
probability_of_default_5y |
Note: 3-year and 5-year tenors require the
pd_multiyear:readscope. If your API key lacks this permission, the API returns a 403 error indicating the missing scope.
Including Contribution Breakdowns
You can request additional contribution data that breaks down the probability of default into component factors. Contributions are shared across all tenors:
# Get probability of default with contribution breakdowns
result = client.data.probability_default.get(
countries=["ARG"],
include_contributions=True,
start_date="2024-01-01",
end_date="2024-12-31"
)
df = result.data
print(df.columns.tolist())
# ['date', 'probability_of_default', 'country', 'gdp_growth', 'debt_gdp', ...]
Fetching All Countries
If no countries are specified, data for all available countries is returned:
# Get probability of default data for all available countries
result = client.data.probability_default.get()
result.data.head()
News
The news client exposes two methods:
client.news.search(...)— semantic search over news content, powered by Weaviate. Use this to discover relevant items.client.news.get(...)— fetch full news items by ID(s), country code(s), and/or apublished_atdate range.
The typical workflow is search → get: run a semantic query to surface relevant items, then call get() with the IDs you care about (see Example 8).
Get News
get() fetches news filtered by any combination of IDs, country codes, and a published-date range. At least one of news_ids, countries, start_date, or end_date must be provided. Results are returned newest first.
# --- By ID ---
items = client.news.get(news_ids="abc-123") # single (string ok)
items = client.news.get(news_ids=["abc-123", "def-456"]) # multiple
# --- By country (ISO alpha-3) ---
items = client.news.get(countries="NGA") # single
items = client.news.get(countries=["NGA", "AGO"]) # multiple
# --- By date range ---
items = client.news.get(start_date="2026-05-11") # everything since
items = client.news.get(start_date="2026-05-01", end_date="2026-05-14") # explicit window
# --- Combined: today's news from Nigeria and Angola ---
items = client.news.get(
countries=["NGA", "AGO"],
start_date="2026-05-14",
end_date="2026-05-14",
)
You generally won't know news IDs ahead of time — they come from search() results (see below).
Parameters
news_ids(str | list[str] | None): A single news ID or list of IDs.countries(str | list[str] | None): ISO alpha-3 country code(s) (e.g."NGA",["NGA", "AGO"]).start_date(str | date | datetime | None): Earliestpublished_at(inclusive). AcceptsYYYY-MM-DD,YYYY/MM/DD, ordate/datetimeobjects.end_date(str | date | datetime | None): Latestpublished_at(inclusive). Same formats asstart_date.limit(int): Maximum number of items returned (default50).
Response
get() returns a list[dict]. Each item has the following fields:
| Key | Type | Notes |
|---|---|---|
id |
str |
News item ID |
title |
str |
|
url |
str |
Source URL |
language |
str |
ISO language code |
original_text |
str | None |
Body in source language |
text |
str | None |
Translated body (when available) |
published_at |
str |
ISO timestamp |
author |
str | None |
|
country_code |
str | None |
ISO alpha-3 |
news_source_id |
str |
|
company_id |
int | None |
|
relevance |
int |
Search News
Semantic search runs your query against a Weaviate index of news content chunks and returns the most relevant items. Each result includes the news id, which you can pass to get() to fetch the full item.
results = client.news.search(query="Eurobond restructuring", limit=10)
# Pluck the IDs of the top 3 hits and fetch their full content
top_ids = [r["id"] for r in results[:3]]
items = client.news.get(news_ids=top_ids)
Parameters
query(str): The text query.limit(int): Maximum number of results to return (default10).
Filtering
The Filter class allows you to create complex filters for searching indicators:
Available Filter Operations
from tellimer import Filter
# Equality
filter1 = Filter("source_name").equals("IMFWEO")
filter2 = Filter("country_iso").not_equals("NGA")
Date Filtering
get functions allows optional start_date and end_date arguments, which can be iso format strings, date or datetime objects. Either or both can also be left blank:
from datetime import date, datetime
# String formats
start_date = "2025-05-01" # YYYY-MM-DD
start_date = "2025/05/01" # YYYY/MM/DD
# Python date objects
start_date = date(2025, 5, 1)
start_date = datetime(2025, 5, 1, 12, 0, 0)
# Set to `None` or can just be left blank
end_date = None
result = client.data.parallel_fx.get(
countries=["ARG", "PAK"],
start_date=start_date,
end_date=end_date,
)
Working with Results
Data Structure
The returned data is structured as a pandas DataFrame with multi-level columns:
result = client.data.macro_data.get(
countries=["ARG", "NGA"],
indicators=["PCPIPCH", "NGDP_RPCH"]
)
# The DataFrame has a multi-level column structure
# Level 0: Indicator codes
# Level 1: Country codes
# Index: Dates
df = result.data
print(df.columns) # MultiIndex with (indicator, country) pairs
print(df.index) # DatetimeIndex
# Access specific series
argentina_inflation = df[("PCPIPCH", "ARG")]
nigeria_gdp_growth = df[("NGDP_RPCH", "NGA")]
Metadata
Each result includes metadata about the indicators:
result = client.data.macro_data.get(countries=["ARG"], indicators=["PCPIPCH"])
for meta in result.metadata:
print(f"Indicator: {meta['indicator']}")
print(f"Country: {meta['country']}")
print(f"Name: {meta.get('name', 'N/A')}")
print(f"Source: {meta.get('source_name', 'N/A')}")
print("---")
Advanced Usage
Error Handling
The SDK provides specific error classes for different types of API errors. These errors are automatically raised based on HTTP status codes:
# Import specific error classes from the errors module
from tellimer.errors import (
AuthError,
BadRequestError,
ForbiddenError,
NotFoundError,
MethodNotAllowedError,
RateLimitError,
InternalServerError,
BadGatewayError,
ServiceUnavailableError,
GatewayTimeoutError
)
try:
result = client.data.macro_data.get(
countries=["INVALID"],
indicators=["INVALID_INDICATOR"]
)
except AuthError:
print("Invalid API key")
except BadRequestError:
print("Invalid request parameters")
except NotFoundError:
print("Resource not found")
except RateLimitError:
print("Rate limit exceeded - please wait before making more requests")
except InternalServerError:
print("Server error - please try again later")
except Exception as e:
print(f"Unexpected error: {e}")
Error Types
The SDK maps HTTP status codes to specific error classes:
400 Bad Request→BadRequestError: Invalid request parameters401 Unauthorized→AuthError: Invalid or missing API key403 Forbidden→ForbiddenError: Access denied404 Not Found→NotFoundError: Resource not found405 Method Not Allowed→MethodNotAllowedError: HTTP method not allowed429 Too Many Requests→RateLimitError: Rate limit exceeded500 Internal Server Error→InternalServerError: Server error502 Bad Gateway→BadGatewayError: Bad gateway503 Service Unavailable→ServiceUnavailableError: Service unavailable504 Gateway Timeout→GatewayTimeoutError: Gateway timeout
Handling Specific Errors
import tellimer
from tellimer.errors import AuthError, RateLimitError, NotFoundError
client = tellimer.Client(api_key=api_key)
try:
result = client.data.macro_data.get(
countries=["ARG"],
indicators=["PCPIPCH"]
)
except AuthError:
print("Please check your API key")
except RateLimitError:
print("Rate limit exceeded. Please wait before making more requests.")
except NotFoundError:
print("The requested data was not found")
except Exception as e:
print(f"An unexpected error occurred: {e}")
Custom Timeouts
Configure request timeouts for your specific needs:
# Short timeout for quick operations
client = tellimer.Client(api_key=api_key, timeout=10)
# Longer timeout for large data requests
client = tellimer.Client(api_key=api_key, timeout=60)
Data Export
Since results are pandas DataFrames, you can easily export to various formats:
result = client.data.macro_data.get(countries=["ARG"], indicators=["PCPIPCH"])
# Export to CSV
result.data.to_csv("argentina_inflation.csv")
# Export to Excel
result.data.to_excel("argentina_inflation.xlsx")
# Export to JSON
result.data.to_json("argentina_inflation.json")
Examples
Example 1: Inflation Analysis
import tellimer
import matplotlib.pyplot as plt
client = tellimer.Client(api_key=api_key)
# Get inflation data for Latin American countries
result = client.data.macro_data.get(
countries=["ARG", "BRA", "MEX", "COL", "CHL"],
indicators=["PCPIPCH"], # Inflation, average consumer prices
start_date="2020-01-01",
end_date="2023-12-31"
)
# Plot the data
df = result.data
df.plot(kind='line', figsize=(12, 6))
plt.title('Inflation Rates - Latin America')
plt.ylabel('Inflation Rate (%)')
plt.show()
Example 2: GDP Growth Comparison
# Search for GDP growth indicators
indicators = client.data.macro_data.search(
query="GDP growth real",
limit=5
)
# Get the data
result = client.data.macro_data.get(
countries=["ARG", "BRA", "MEX", "COL", "CHL"],
indicators=["NGDP_RPCH"], # Real GDP growth
start_date="2015-01-01"
)
# Calculate average growth rates
df = result.data
avg_growth = df.mean()
print("Average GDP Growth Rates:")
print(avg_growth)
Example 3: Filtered Search
# Create filters for World Bank data on emerging markets
source_filter = Filter("source_name").equals("World Bank")
# Search for unemployment data
indicators = client.data.macro_data.search(
query="unemployment rate",
limit=10,
filters=[source_filter]
)
print(f"Found {len(indicators)} unemployment indicators from World Bank")
Example 4: Probability of Default Analysis
import tellimer
import matplotlib.pyplot as plt
client = tellimer.Client(api_key=api_key)
# Get available countries for probability of default data
countries = client.data.probability_default.available_countries()
print(f"Available countries: {countries}")
# Get probability of default data for emerging market countries
result = client.data.probability_default.get(
countries=["ARG", "BRA", "TUR", "ZAF"],
start_date="2024-01-01",
end_date="2024-12-31"
)
# Plot probability of default over time
df = result.data
df.pivot(index="date", columns="country", values="probability_of_default").plot()
plt.title('Probability of Default (1Y) - Emerging Markets')
plt.ylabel('Probability of Default')
plt.xlabel('Date')
plt.legend(title='Country')
plt.show()
Example 5: Multi-Tenor Probability of Default Comparison
import tellimer
import matplotlib.pyplot as plt
client = tellimer.Client(api_key=api_key)
# Fetch 1-year, 3-year, and 5-year PD for Argentina
result = client.data.probability_default.get(
countries=["ARG"],
tenors=["1y", "3y", "5y"],
start_date="2024-01-01",
end_date="2024-12-31"
)
df = result.data
df = df.set_index("date")
df[["probability_of_default", "probability_of_default_3y", "probability_of_default_5y"]].plot()
plt.title('Argentina - PD Term Structure')
plt.ylabel('Probability of Default')
plt.legend(["1Y", "3Y", "5Y"])
plt.show()
Example 6: Probability of Default with Contribution Breakdown
import tellimer
client = tellimer.Client(api_key=api_key)
# Get probability of default with contribution breakdown
result = client.data.probability_default.get(
countries=["ARG"],
include_contributions=True,
start_date="2024-01-01",
end_date="2024-06-30"
)
df = result.data
print("Available columns:")
print(df.columns.tolist())
# ['date', 'probability_of_default', 'country', 'gdp_growth', 'debt_gdp', ...]
Example 7: Comparing Probability of Default Across Regions
import tellimer
import pandas as pd
client = tellimer.Client(api_key=api_key)
# Get data for all available countries
result = client.data.probability_default.get(
start_date="2024-06-01",
end_date="2024-06-30"
)
df = result.data
# Calculate average probability of default for each country
avg_pod = df.groupby("country")["probability_of_default"].mean().sort_values(ascending=False)
print("Average Probability of Default by Country:")
print(avg_pod)
# Identify highest risk countries
high_risk = avg_pod[avg_pod > avg_pod.median()]
print(f"\nCountries with above-median risk: {high_risk.index.tolist()}")
Example 8: News Discovery and Retrieval
A two-step workflow: find relevant news via semantic search, then fetch the full content for the items you care about.
import tellimer
client = tellimer.Client(api_key=api_key)
# Step 1: Discover relevant items via semantic search
hits = client.news.search(
query="emerging market sovereign debt restructuring",
limit=10,
)
for h in hits:
print(f"{h['id']}: {h['title']}")
# Step 2: Fetch the full content for the top 3 hits
top_ids = [h["id"] for h in hits[:3]]
items = client.news.get(news_ids=top_ids)
for item in items:
print(f"\n--- {item['title']} ({item['country_code']}, {item['published_at']}) ---")
print((item["text"] or item["original_text"] or "")[:500])
You can also skip the search step entirely if you just want a feed by country and/or date:
# Today's news from Nigeria and Angola
todays = client.news.get(
countries=["NGA", "AGO"],
start_date="2026-05-14",
end_date="2026-05-14",
)
# Everything published in the last 3 days (regardless of country)
recent = client.news.get(start_date="2026-05-11")
API Reference
Client Class
class Client:
def __init__(self, api_key: str, timeout: float = 30)
# Sub-clients
data: DataClient
news: NewsClient
DataClient Class
class DataClient:
def list_datasets() -> list[str]
# Dataset-specific clients
macro_data: _BaseSearchableDataset
parallel_fx: _BaseDataset
probability_default: ProbabilityDefaultClient
NewsClient Class
class NewsClient:
def get(news_ids: list[str] | str | None = None,
countries: list[str] | str | None = None,
start_date: str | date | datetime | None = None,
end_date: str | date | datetime | None = None,
limit: int = 50) -> list[dict]
def search(query: str, limit: int = 10) -> list[dict]
Dataset Methods
# For searchable datasets (macro_data)
class _BaseSearchableDataset:
def search(query: str, limit: int = 5, filters: list[Filter] = None) -> list[dict]
def get(countries: list[str] | str, indicators: list[str] | str = None,
start_date: str = None, end_date: str = None) -> Result
# For non-searchable datasets (parallel_fx)
class _BaseDataset:
def available_countries() -> list[str]
def get(countries: list[str] | str, start_date: str = None,
end_date: str = None) -> Result
# For probability of default data
class ProbabilityDefaultClient:
def available_countries() -> list[str]
def get(countries: list[str] | str | None = None,
include_contributions: bool = False,
start_date: str = None, end_date: str = None,
tenors: list["1y"|"3y"|"5y"] | str = "1y") -> Result
Filter Class
class Filter:
def __init__(field: str)
def equals(value: str) -> Filter
def not_equals(value: str) -> Filter
def greater_than(value: str) -> Filter
def greater_than_or_equal_to(value: str) -> Filter
def less_than(value: str) -> Filter
def less_than_or_equal_to(value: str) -> Filter
Requirements
- Python >= 3.10
- httpx >= 0.24.1
- pandas >= 2.0.0
Support
For support, please contact the Tellimer team or refer to the API documentation.
Version
Current version: 0.5.1
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file tellimer-0.5.1.tar.gz.
File metadata
- Download URL: tellimer-0.5.1.tar.gz
- Upload date:
- Size: 13.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.8.17
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
517a481663365d6cbe53c43e5664015e9e439a2a86b5896c7b80ec0b59271739
|
|
| MD5 |
c5133f5b6385da43e1fe73beecbb75cb
|
|
| BLAKE2b-256 |
a3c5ae0b340ee7d028049ae467376a5b4247afa08bc6b6a5ef01713f0d36bce4
|
File details
Details for the file tellimer-0.5.1-py3-none-any.whl.
File metadata
- Download URL: tellimer-0.5.1-py3-none-any.whl
- Upload date:
- Size: 17.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.8.17
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
60df746a6f2d5073977069f8e429817fd8540738e17d20a670c1b84d950420f1
|
|
| MD5 |
a01c6daf2521258bc8a53905201146ff
|
|
| BLAKE2b-256 |
cc5dd5bdeccb540d6615b73be796b58f151d634426cdfe320bf82fabaf980e47
|