Official Python client for the Neudata Developer API.
Project description
neudata-api-client
A Python client for the Neudata Developer API. It
lets you search and retrieve dataset metadata, additional datasets, filters, and
DDQs — and ships with resilient defaults: it retries dropped connections,
backs off and honours Retry-After on rate limits (429), and
auto-paginates list endpoints.
Installation
pip install neudata-api-client
For development (using uv):
git clone https://github.com/neudata/neudata-api-client
cd neudata-api-client
uv sync
Authentication
The API authenticates with two headers, Email and Api-Token. Your token is
available at https://www.neudata.co/users/edit.
Provide them via environment variables (recommended):
export NEUDATA_EMAIL="you@example.com"
export NEUDATA_API_TOKEN="your-api-token"
…or pass them directly to the client:
from neudata import NeudataClient
client = NeudataClient(email="you@example.com", api_token="your-api-token")
A .env.example is included as a template.
Quickstart
from neudata import NeudataClient
with NeudataClient() as client:
# Search a single page of datasets
results = client.search_datasets(q="satellite", per_page=10)
# Or iterate over *every* matching dataset (pagination handled for you)
for dataset in client.iter_datasets(equity_region=["uk", "europe"]):
print(dataset["id"], dataset["title"])
# Fetch the full detail record for one dataset
detail = client.get_dataset(1234)
API reference
| Method | Endpoint | Description |
|---|---|---|
search_datasets(**filters) |
GET /datasets |
One page of dataset search results |
iter_datasets(per_page=99, **filters) |
GET /datasets |
Iterate all datasets across pages |
get_dataset(id) |
GET /datasets/{id} |
Full dataset detail |
list_filters() |
GET /filters |
Available filter parameter names |
get_filter_options(name) |
GET /filters/{name} |
Allowable options for a filter |
search_additional_datasets(**filters) |
GET /additional-datasets |
One page of additional datasets |
iter_additional_datasets(per_page=99, **filters) |
GET /additional-datasets |
Iterate all additional datasets |
get_additional_dataset(id) |
GET /additional-datasets/{id} |
Full additional-dataset detail |
list_ddqs(page, per_page) |
GET /ddqs |
List DDQs (Sentry subscribers) |
iter_ddqs(per_page=99) |
GET /ddqs |
Iterate all DDQs |
get_ddq(id) |
GET /ddqs/{id} |
DDQ detail + 10-minute download URL |
Filters
Search methods accept the documented query parameters as keyword arguments, e.g.
q, page, per_page, sort, sort_by, source, from_date,
data_provider_id, and the array filters equity_region, asset_class,
combined_dataset_types, frequency, history, subscription_price,
report_type, feed_type, output_format, esg_topics, filter_labels,
ticker_indices, and more.
Array filters are passed as Python lists and serialized into the repeated
name[] form the API expects:
client.search_datasets(asset_class=["public-equity", "fixed-income"])
# -> GET /datasets?asset_class[]=public-equity&asset_class[]=fixed-income
Use client.list_filters() and client.get_filter_options(name) to discover the
valid values for each filter at runtime.
Resilience: retries, backoff & rate limits
The client is configured on construction:
NeudataClient(
timeout=30, # per-request timeout (seconds)
max_retries=5, # retries for dropped connections / 5xx
backoff_factor=0.5, # exponential backoff base
max_backoff=60, # cap on any single backoff sleep
max_rate_limit_retries=10, # retries specifically for 429 responses
requests_per_minute=90, # client-side throttle (0 disables it)
)
- Dropped/closed connections (and timeouts and
5xxserver errors) are retried up tomax_retriestimes with jittered exponential backoff. 429rate limits are retried up tomax_rate_limit_retriestimes. TheRetry-Afterheader is honoured when present; otherwise exponential backoff is used. When retries are exhausted aRateLimitErroris raised.- A built-in client-side throttle keeps the sustained request rate below
requests_per_minute(the API guideline is ~100/min) so bulk jobs avoid tripping the limiter in the first place.
Enable logging to see retry/backoff activity:
import logging
logging.getLogger("neudata").setLevel(logging.INFO)
Exceptions
All exceptions derive from neudata.NeudataError:
AuthenticationError—401/403(bad credentials; not retried)NotFoundError—404RateLimitError—429retries exhausted (carriesretry_after)NeudataAPIError— other unexpected API responses (carriesstatus_code,response_body)
Example: download the whole catalogue
A console script is installed with the package:
# Dump all datasets + additional datasets to neudata_export.json
neudata-download
# Custom output, only datasets, with full per-item detail records
neudata-download --output datasets.json --datasets-only --details
# Filter by date or free text
neudata-download --from-date 2026-01-01 --query "credit card"
Run neudata-download --help for all options. A minimal, readable version using
the library directly is in examples/download_all.py:
python examples/download_all.py out.json
The output JSON has the shape:
{
"datasets": [ ... ],
"additional_datasets": [ ... ]
}
Development
uv sync # create the venv and install deps + dev tools
uv run pytest # run the test suite (no network calls)
Tests use responses to mock the API
and a monkeypatched sleep, so they run instantly and offline.
There is also an opt-in live smoke test that hits every endpoint against the real API. It is excluded from the default run and requires credentials:
export NEUDATA_EMAIL="you@example.com"
export NEUDATA_API_TOKEN="your-api-token"
uv run pytest -m smoke -v # hits the real Neudata API
(The DDQ checks skip automatically if your account isn't a Sentry subscriber.)
Releasing to PyPI
uv build # build sdist + wheel into dist/
uvx twine check dist/* # validate metadata / long description
# Test upload first
uv publish --publish-url https://test.pypi.org/legacy/ --token "$TEST_PYPI_TOKEN"
# Then the real thing
uv publish --token "$PYPI_TOKEN"
License
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 neudata_api_client-0.2.0.tar.gz.
File metadata
- Download URL: neudata_api_client-0.2.0.tar.gz
- Upload date:
- Size: 11.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.8.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fcea3504e5002c5d3c78a4c63a37e892c201dff160be30ffe0b7f85eac07214b
|
|
| MD5 |
a7d1c31a277355d14a4c7d1ce3773eed
|
|
| BLAKE2b-256 |
769d4685d16ec258fdd22cd33822a4ab45dfafbeb9562bfc26b9f8a9c53391e4
|
File details
Details for the file neudata_api_client-0.2.0-py3-none-any.whl.
File metadata
- Download URL: neudata_api_client-0.2.0-py3-none-any.whl
- Upload date:
- Size: 14.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.8.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4f620f613d3212eb12435f4cc67bc64656a5d1f51583305691098596420ddc01
|
|
| MD5 |
083b9e1569526fb591bb1d4425c49be7
|
|
| BLAKE2b-256 |
52ed96c7193516c9d7a6dbb907c08bc927a60d1497db1b0ae087d3a41b14785c
|