Official Python SDK for Ready APIs — curated REST APIs and composite signals.
Project description
readyapis
Official Python SDK for Ready APIs — curated REST APIs and composite signals.
pip install readyapis
Six hero APIs (geo, tax, fx, email, calendar, intel) plus identity / catalog metadata, in one tiny typed client. No Pydantic, no codegen — just httpx and the standard library.
Quick start
from readyapis import Client
# Demo mode — no key needed. Hits /demo/api/v1/* with allowlisted params.
client = Client()
zip_data = client.geo.zip("30301")
print(zip_data.city, zip_data.state) # "Atlanta" "GA"
tax = client.tax.calculate(income=125000, state="NY", year=2026, filing_status="single")
print(tax.federal["tax"], tax.taxable_income) # 18733.42 108900.0
fx = client.fx.convert(amount=100, from_="USD", to="EUR")
print(fx.converted) # 85.4555
Authentication
Set an API key as an environment variable (recommended) or pass it explicitly:
export READYAPIS_API_KEY=ra_live_...
from readyapis import Client
client = Client() # reads READYAPIS_API_KEY
client = Client(api_key="ra_live_...") # explicit override
Get a key at https://readyapis.com/register. Free tier: 1,000 credits/month.
Demo mode
If no API key is configured, the client enters demo mode automatically. It hits /demo/api/v1/* routes, which require no auth but only accept a small set of allowlisted parameters (ZIP 30301, email hello@stripe.com, etc.) — perfect for tinkering and CI.
client = Client()
assert client.is_demo
# Demo allowlist: 10001, 30301, 30303, 60601, 78701, 94105, 98101.
client.geo.zip("30301") # OK
client.geo.zip("12345") # raises ApiError (demo_parameter_not_allowed)
Namespaces
client.geo.zip("30301")
client.geo.city(name="Atlanta", state="GA")
client.geo.ip("8.8.8.8")
client.geo.enrich(zip="30301")
client.geo.nearby(lat=33.7488, lon=-84.3877, radius_miles=10)
client.tax.calculate(income=125000, state="NY", year=2026, filing_status="single")
client.tax.brackets(year=2026) # federal
client.tax.brackets(year=2026, state="NY") # state
client.tax.deductions(year=2026, filing_status="single")
client.fx.rates(base="USD")
client.fx.rates(base="USD", symbols=["EUR", "GBP", "JPY"])
client.fx.convert(amount=100, from_="USD", to="EUR")
client.email.validate("hello@stripe.com")
client.calendar.holidays(country="US", year=2026)
client.calendar.business_days(start="2026-01-01", end="2026-01-31")
client.intel.site_risk(zip="30301", site_profile="insurance_underwriting")
client.meta.whoami() # requires API key
client.meta.catalog() # free
The full list of demo-allowed site_profile values: data_center_site, insurance_underwriting, remote_office, retail_storefront, small_office, warehouse_distribution. Production mode accepts more.
Response shape
Every response is wrapped in a Response object that proxies the JSON:API-flavored envelope. You can use ergonomic attribute access, dict-style lookup, or get the raw payload.
r = client.geo.zip("30301")
r.city # "Atlanta" — flattened from data.attributes
r.state # "GA"
r["county"] # "Fulton" — dict-style works too
r.data # the full data dict
r.attributes # just the attributes dict
r.meta # {credits_used, source, ...}
r.raw # the full underlying JSON
For list responses, iterate or index:
holidays = client.calendar.holidays(country="US", year=2026)
assert holidays.is_list
for h in holidays:
print(h.date, h.name)
Errors
All errors inherit from ApiError. Specific subclasses let you branch on common cases:
from readyapis import Client, ApiError, AuthError, RateLimitError, NotFoundError
try:
client.geo.zip("99999")
except RateLimitError as e:
print(f"slow down — retry in {e.retry_after}s")
except AuthError as e:
print(f"bad key: {e.code}")
except NotFoundError as e:
print(f"not found: {e.message}")
except ApiError as e:
print(f"{e.status_code} {e.code}: {e.message}")
print(e.body) # full error envelope
Every ApiError exposes .status_code, .code, .message, .body, and (for 429s) .retry_after.
Retry behavior
The client automatically retries 429, 500, 502, 503, and 504 responses with exponential backoff (0.5s, 1s, 2s — three attempts total) plus small jitter. On 429, it honors Retry-After if present. Disable per-client:
client = Client(retry=False)
Idempotency
POST endpoints accept an idempotency_key keyword. The server treats two requests with the same key (within the idempotency window) as the same logical operation — safe to retry from the client.
client.intel.rank(
candidates=[...],
objective="enterprise_buyer",
idempotency_key="run-2026-05-14-abc",
)
Configuration
Client(
api_key=None, # str | None — falls back to READYAPIS_API_KEY env
base_url="https://readyapis.com", # override for staging/local
timeout=30.0, # per-request seconds
retry=True, # retry 429 + 5xx with backoff
user_agent=None, # override the UA string
http_client=None, # bring your own httpx.Client
)
Compatibility
Python 3.9 and later. Only runtime dependency is httpx >= 0.24, < 1.0.
License
MIT
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 readyapis-0.1.0.tar.gz.
File metadata
- Download URL: readyapis-0.1.0.tar.gz
- Upload date:
- Size: 16.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
30fcf7d7b34fef47e55cf20a94c47184dd2eb62f087c6d016b4b4706bee1236c
|
|
| MD5 |
287f7b616cfec5f90fa50a3f35e2fda3
|
|
| BLAKE2b-256 |
a4b40ec1e90128025bf826a92177f5adaf3b43914aec477773c9e23fe05ef383
|
File details
Details for the file readyapis-0.1.0-py3-none-any.whl.
File metadata
- Download URL: readyapis-0.1.0-py3-none-any.whl
- Upload date:
- Size: 19.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ee259fb511b25e2aa35ef1016d3f4055453b06acbdcfdb5652f3648cc085d54c
|
|
| MD5 |
9b40d8ad33eb8e16007e7d771ba20db7
|
|
| BLAKE2b-256 |
78331c3e6e6a34e1578e61f0010b7398942891d102f365640fb71373ee19fd55
|