Skip to main content

Python SDK for the Reader API

Project description

reader-py

Python SDK for the Reader API — content extraction for LLMs. Wraps POST /v1/read, parses responses into Pydantic models, raises typed exceptions, and auto-polls async jobs to completion.

Version: 0.2.0 · Python: 3.9+

Install

pip install reader-py

Quick start (sync)

import os
from reader_py import ReaderClient

reader = ReaderClient(api_key=os.environ["READER_KEY"])

result = reader.read(url="https://example.com")
if result.kind == "scrape":
    print(result.data.markdown)

Quick start (async)

import asyncio
import os
from reader_py import AsyncReaderClient

async def main():
    async with AsyncReaderClient(api_key=os.environ["READER_KEY"]) as reader:
        result = await reader.read(url="https://example.com")
        if result.kind == "scrape":
            print(result.data.markdown)

asyncio.run(main())

reader.read(...) returns a discriminated union (Pydantic):

  • ScrapeReadResult(kind="scrape", data=ScrapeResult) — single-URL requests, returned immediately
  • JobReadResult(kind="job", data=Job) — batch and crawl requests, auto-polled to completion

Features

  • Sync and async clientsReaderClient (blocking, backed by httpx.Client) and AsyncReaderClient (backed by httpx.AsyncClient). Same method surface.
  • Typed errors for all 11 Reader error codes. InsufficientCreditsError, RateLimitedError, UrlBlockedError, ScrapeTimeoutError, and more. Each subclass exposes the relevant fields (e.g. err.required, err.retry_after_seconds).
  • Automatic retries with exponential backoff for transient codes. Honors the Retry-After header on 429.
  • Pagination-aware job collection. wait_for_job() returns the full job with every page result.
  • SSE streaming. for event in reader.stream(job_id) (sync) or async for (async) yields ProgressEvent / PageEvent / ErrorEvent / DoneEvent.
  • Pydantic models everywhere — all responses are parsed into typed models with IDE autocomplete.
  • Request ID tracing. Every error carries the x-request-id header value on err.request_id for support tickets.

Browser Sessions

Launch a stealthed Chrome and connect Playwright:

session = reader.sessions.create()

from playwright.sync_api import sync_playwright
with sync_playwright() as p:
    browser = p.chromium.connect_over_cdp(session.ws_endpoint)
    page = browser.contexts[0].new_page()
    page.goto("https://example.com")
    print(page.title())
    browser.close()

reader.sessions.stop(session.session_id)

Async:

session = await reader.sessions.create()
# ... use async playwright ...
await reader.sessions.stop(session.session_id)

Methods: reader.sessions.create(), .get(id), .stop(id), .list()

Errors

from reader_py import (
    ReaderApiError,
    InsufficientCreditsError,
    RateLimitedError,
    UrlBlockedError,
)

try:
    reader.read(url=url)
except InsufficientCreditsError as err:
    print(f"Need {err.required}, have {err.available}")
except RateLimitedError as err:
    print(f"Retry after {err.retry_after_seconds}s")
except UrlBlockedError as err:
    print(f"Blocked: {err.reason}")
except ReaderApiError as err:
    print(f"[{err.code}] {err} — see {err.docs_url}")

ReaderError is re-exported as an alias for ReaderApiError so code written against the 0.1 SDK continues to work. New code should use ReaderApiError.

Full catalog of error codes: https://reader.dev/docs/home/concepts/errors

Links

Development

python -m venv .venv && source .venv/bin/activate
pip install -e .[dev]
pytest

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

reader_py-0.3.1.tar.gz (14.3 kB view details)

Uploaded Source

Built Distribution

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

reader_py-0.3.1-py3-none-any.whl (14.9 kB view details)

Uploaded Python 3

File details

Details for the file reader_py-0.3.1.tar.gz.

File metadata

  • Download URL: reader_py-0.3.1.tar.gz
  • Upload date:
  • Size: 14.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.2

File hashes

Hashes for reader_py-0.3.1.tar.gz
Algorithm Hash digest
SHA256 3315677917a68d5057693d0f43feb14d861aa60f64c929e227652c47d4d3b26f
MD5 8cd21271e6cb5fbdced8c0a7896b406c
BLAKE2b-256 d93dd47434d9c33ae673dd73a37634c363ef8d22c0bd9acd66be77c63f2a1e33

See more details on using hashes here.

File details

Details for the file reader_py-0.3.1-py3-none-any.whl.

File metadata

  • Download URL: reader_py-0.3.1-py3-none-any.whl
  • Upload date:
  • Size: 14.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.2

File hashes

Hashes for reader_py-0.3.1-py3-none-any.whl
Algorithm Hash digest
SHA256 a81391a3eaeca778bb9f3483d645a451306a347e3520066bf875c2c3cb590f1a
MD5 da4437b9f3d6b23d67193b38b62e61c2
BLAKE2b-256 08c3632af7a60fcd300d0a2c9b5c7a65484d98a1a42f7d83471f4f8c8b8d9277

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