Skip to main content

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


Download files

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

Source Distribution

readyapis-0.1.0.tar.gz (16.0 kB view details)

Uploaded Source

Built Distribution

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

readyapis-0.1.0-py3-none-any.whl (19.1 kB view details)

Uploaded Python 3

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

Hashes for readyapis-0.1.0.tar.gz
Algorithm Hash digest
SHA256 30fcf7d7b34fef47e55cf20a94c47184dd2eb62f087c6d016b4b4706bee1236c
MD5 287f7b616cfec5f90fa50a3f35e2fda3
BLAKE2b-256 a4b40ec1e90128025bf826a92177f5adaf3b43914aec477773c9e23fe05ef383

See more details on using hashes here.

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

Hashes for readyapis-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 ee259fb511b25e2aa35ef1016d3f4055453b06acbdcfdb5652f3648cc085d54c
MD5 9b40d8ad33eb8e16007e7d771ba20db7
BLAKE2b-256 78331c3e6e6a34e1578e61f0010b7398942891d102f365640fb71373ee19fd55

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