Skip to main content

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 key
  • timeout (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 columns
  • metadata (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 data
  • probability_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:read scope. 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 a published_at date 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): Earliest published_at (inclusive). Accepts YYYY-MM-DD, YYYY/MM/DD, or date/datetime objects.
  • end_date (str | date | datetime | None): Latest published_at (inclusive). Same formats as start_date.
  • limit (int): Maximum number of items returned (default 50).

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 (default 10).

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 RequestBadRequestError: Invalid request parameters
  • 401 UnauthorizedAuthError: Invalid or missing API key
  • 403 ForbiddenForbiddenError: Access denied
  • 404 Not FoundNotFoundError: Resource not found
  • 405 Method Not AllowedMethodNotAllowedError: HTTP method not allowed
  • 429 Too Many RequestsRateLimitError: Rate limit exceeded
  • 500 Internal Server ErrorInternalServerError: Server error
  • 502 Bad GatewayBadGatewayError: Bad gateway
  • 503 Service UnavailableServiceUnavailableError: Service unavailable
  • 504 Gateway TimeoutGatewayTimeoutError: 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


Download files

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

Source Distribution

tellimer-0.5.1.tar.gz (13.1 kB view details)

Uploaded Source

Built Distribution

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

tellimer-0.5.1-py3-none-any.whl (17.4 kB view details)

Uploaded Python 3

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

Hashes for tellimer-0.5.1.tar.gz
Algorithm Hash digest
SHA256 517a481663365d6cbe53c43e5664015e9e439a2a86b5896c7b80ec0b59271739
MD5 c5133f5b6385da43e1fe73beecbb75cb
BLAKE2b-256 a3c5ae0b340ee7d028049ae467376a5b4247afa08bc6b6a5ef01713f0d36bce4

See more details on using hashes here.

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

Hashes for tellimer-0.5.1-py3-none-any.whl
Algorithm Hash digest
SHA256 60df746a6f2d5073977069f8e429817fd8540738e17d20a670c1b84d950420f1
MD5 a01c6daf2521258bc8a53905201146ff
BLAKE2b-256 cc5dd5bdeccb540d6615b73be796b58f151d634426cdfe320bf82fabaf980e47

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