Skip to main content

Comprehensive Python SDK for Readwise with high-level workflow abstractions. Supports V2 (highlights/books) and V3 (Reader) APIs with managers, workflows, and CLI.

Project description

readwise-plus

CI coverage PyPI version Python versions License

Comprehensive Python SDK for Readwise with high-level workflow abstractions. Supports both the Readwise API (v2) for highlights/books and the Reader API (v3) for documents.

Table of Contents

Features

  • V2 API (Readwise): Full support for highlights, books, tags, and daily review
  • V3 API (Reader): Full support for documents, inbox, reading list, and archive
  • Managers: High-level abstractions for common operations
  • Workflows: Pre-built workflows for digests, tagging, and syncing
  • Contrib: Convenience interfaces for common integration patterns
  • CLI: Command-line interface for quick operations

Installation

pip install readwise-plus

With CLI support:

pip install readwise-plus[cli]

Quick Start

from readwise_sdk import ReadwiseClient

# Initialize with your API token
client = ReadwiseClient(api_key="your_token_here")

# Or use environment variable READWISE_API_KEY
client = ReadwiseClient()

# Validate your token
client.validate_token()

# Get all highlights
for highlight in client.v2.highlights.list():
    print(highlight.text)

# Get Reader inbox
for doc in client.v3.documents.list(location="new"):
    print(doc.title)

Architecture

The SDK is organized into layers of increasing abstraction:

readwise-plus/
├── Core Layer
│   ├── V2 Client      → client.v2.*     (Readwise API)
│   └── V3 Client      → client.v3.*     (Reader API)
├── Manager Layer
│   ├── HighlightManager   → Highlight operations
│   ├── BookManager        → Book operations
│   ├── DocumentManager    → Document operations
│   └── SyncManager        → Sync state tracking
├── Workflow Layer
│   ├── DigestBuilder      → Create highlight digests
│   ├── ReadingInbox       → Inbox management
│   ├── TagWorkflow        → Auto-tagging
│   └── BackgroundPoller   → Background sync
└── Contrib Layer
    ├── HighlightPusher    → Push highlights to Readwise
    ├── DocumentImporter   → Import documents to Reader
    └── BatchSync          → Batch synchronization

Core API Usage

V2 API (Readwise Highlights)

from readwise_sdk import ReadwiseClient
from datetime import datetime

client = ReadwiseClient()

# List highlights with filtering
highlights = client.v2.highlights.list(
    book_id=123,
    updated_after=datetime(2024, 1, 1),
)

# Get a specific highlight
highlight = client.v2.highlights.get(highlight_id=456)

# Create a highlight
new_highlight = client.v2.highlights.create(
    text="Important quote from the book",
    title="Book Title",
    author="Author Name",
    source_type="book",
)

# Export all highlights with full book metadata
for book in client.v2.export_highlights():
    print(f"{book.title}: {len(book.highlights)} highlights")
    for h in book.highlights:
        print(f"  - {h.text[:50]}...")

# Get daily review highlights
review = client.v2.get_daily_review()
for highlight in review.highlights:
    print(highlight.text)

V3 API (Reader Documents)

# List inbox documents
for doc in client.v3.documents.list(location="new"):
    print(f"{doc.title} ({doc.category})")

# Save a URL to Reader
result = client.v3.save_url("https://example.com/article")
print(f"Saved: {result.id}")

# Get document with full content
doc = client.v3.documents.get(doc_id, with_html=True)
print(doc.html)

# Move document to archive
client.v3.documents.update(doc_id, location="archive")

# Filter by category
articles = client.v3.documents.list(category="article")
pdfs = client.v3.documents.list(category="pdf")

Managers

Managers provide higher-level operations with better ergonomics.

HighlightManager

from readwise_sdk.managers import HighlightManager

highlights = HighlightManager(client)

# Get recent highlights
recent = highlights.get_highlights_since(days=7)

# Search highlights
results = highlights.search("python programming")

# Bulk operations
highlights.bulk_tag(highlight_ids, "to-review")
highlights.bulk_delete(highlight_ids)

# Get highlights by book
book_highlights = highlights.get_by_book(book_id=123)

BookManager

from readwise_sdk.managers import BookManager

books = BookManager(client)

# List all books
all_books = books.list()

# Get books by category
articles = books.get_by_category("articles")

# Get book with highlights
book = books.get_with_highlights(book_id=123)

DocumentManager

from readwise_sdk.managers import DocumentManager

docs = DocumentManager(client)

# Get inbox
inbox = docs.get_inbox()

# Archive a document
docs.archive(doc_id)

# Get reading stats
stats = docs.get_stats()
print(f"Inbox: {stats.inbox_count}, Archive: {stats.archive_count}")

Workflows

Pre-built workflows for common use cases.

DigestBuilder

from readwise_sdk.workflows import DigestBuilder

digest = DigestBuilder(client)

# Daily digest
daily = digest.build_daily()
print(daily.to_markdown())

# Weekly digest
weekly = digest.build_weekly()

# Book-specific digest
book_digest = digest.build_for_book(book_id=123)
book_digest.save("book-notes.md")

TagWorkflow

from readwise_sdk.workflows.tags import TagWorkflow, TagPattern

workflow = TagWorkflow(client)

# Define tagging patterns
patterns = [
    TagPattern(r"\bpython\b", "python", case_sensitive=False),
    TagPattern(r"\bmachine learning\b", "ml", case_sensitive=False),
    TagPattern(r"TODO:", "actionable", search_in_notes=True),
]

# Auto-tag highlights
result = workflow.auto_tag_highlights(patterns, dry_run=True)
print(f"Would tag {result.matched_count} highlights")

# Apply tags
result = workflow.auto_tag_highlights(patterns, dry_run=False)

# Rename a tag
workflow.rename_tag(old_name="todo", new_name="actionable")

ReadingInbox

from readwise_sdk.workflows import ReadingInbox

inbox = ReadingInbox(client)

# Get prioritized inbox
prioritized = inbox.get_prioritized(limit=10)

# Triage inbox items
for doc in inbox.get_untriaged():
    if doc.word_count < 500:
        inbox.archive(doc.id)
    else:
        inbox.move_to_later(doc.id)

Contrib Interfaces

Simplified interfaces for common integration patterns.

HighlightPusher

from readwise_sdk.contrib import HighlightPusher

pusher = HighlightPusher(client)

# Push a single highlight
pusher.push(
    text="Great quote from the article",
    title="Article Title",
    source_url="https://example.com/article",
)

# Push multiple highlights
pusher.push_batch([
    {"text": "Quote 1", "title": "Book 1"},
    {"text": "Quote 2", "title": "Book 2"},
])

DocumentImporter

from readwise_sdk.contrib import DocumentImporter

importer = DocumentImporter(client)

# Import a URL
doc = importer.import_url("https://example.com/article")

# Import with tags
doc = importer.import_url(
    "https://example.com/article",
    tags=["to-read", "python"],
)

BatchSync

from readwise_sdk.contrib import BatchSync, BatchSyncConfig

config = BatchSyncConfig(
    batch_size=100,
    state_file="sync_state.json",
)
sync = BatchSync(client, config=config)

# Sync with callback
def on_highlight(highlight):
    save_to_database(highlight)

result = sync.sync_highlights(on_item=on_highlight)
print(f"Synced {result.synced_count} highlights")

CLI

The CLI provides quick access to common operations.

Highlights

# List recent highlights
readwise highlights list --limit 10

# Show a specific highlight
readwise highlights show 123456

# Export highlights
readwise highlights export -f markdown -o highlights.md
readwise highlights export -f json -o highlights.json

Books

# List books
readwise books list --limit 20

# Show book details
readwise books show 123

Reader

# View inbox
readwise reader inbox --limit 50

# Save a URL
readwise reader save "https://example.com/article"

# Archive a document
readwise reader archive abc123

# Get reading stats
readwise reader stats

Digests

# Generate daily digest
readwise digest daily -f markdown

# Generate weekly digest
readwise digest weekly -o weekly.md

# Generate book digest
readwise digest book 12345 -o book-notes.md

Sync

# Full sync
readwise sync full --output-dir ./data

# Incremental sync
readwise sync incremental --state-file sync.json

Development

# Clone the repository
git clone https://github.com/EvanOman/readwise-plus.git
cd readwise-plus

# Install dependencies
just install

# Run all checks (format, lint, type-check, test)
just fc

# Run tests only
just test

# Run specific test file
uv run pytest tests/v2/test_client.py

Contributing

Contributions are welcome! Please follow these guidelines:

  1. Fork the repository and create a feature branch
  2. Follow conventional commits for commit messages:
    • feat(scope): add new feature
    • fix(scope): fix a bug
    • docs: update documentation
  3. Run just fc before committing to ensure all checks pass
  4. Write tests for new functionality
  5. Submit a pull request with a clear description

See AGENTS.md for detailed development guidelines.

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

readwise_plus-0.2.1.tar.gz (183.1 kB view details)

Uploaded Source

Built Distribution

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

readwise_plus-0.2.1-py3-none-any.whl (67.0 kB view details)

Uploaded Python 3

File details

Details for the file readwise_plus-0.2.1.tar.gz.

File metadata

  • Download URL: readwise_plus-0.2.1.tar.gz
  • Upload date:
  • Size: 183.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.2 {"installer":{"name":"uv","version":"0.10.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for readwise_plus-0.2.1.tar.gz
Algorithm Hash digest
SHA256 078295af58532f8fb43482ef12eee392c09e023ca9b5290f2dcfc7930e3f9db9
MD5 0cf8b8a29c45c3f2306a669d59febfa1
BLAKE2b-256 2e60a8bda31cdd9f8d22e213b18cb9ed2ca269e945cea60ee39a4417c5491db6

See more details on using hashes here.

File details

Details for the file readwise_plus-0.2.1-py3-none-any.whl.

File metadata

  • Download URL: readwise_plus-0.2.1-py3-none-any.whl
  • Upload date:
  • Size: 67.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.2 {"installer":{"name":"uv","version":"0.10.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for readwise_plus-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 887776b87b7ec5ca142df60a97581dab0c3d9bc97a4fe8178c7906df10285a38
MD5 7e06f1806ba44605a471c838163f8558
BLAKE2b-256 833169d77c9c31c69fc34af704722c6756d725fad0844e9e5d366820475ae705

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