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
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
- Installation
- Quick Start
- Architecture
- Core API Usage
- Managers
- Workflows
- Contrib Interfaces
- CLI
- Development
- Contributing
- License
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:
- Fork the repository and create a feature branch
- Follow conventional commits for commit messages:
feat(scope): add new featurefix(scope): fix a bugdocs: update documentation
- Run
just fcbefore committing to ensure all checks pass - Write tests for new functionality
- 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
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 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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
078295af58532f8fb43482ef12eee392c09e023ca9b5290f2dcfc7930e3f9db9
|
|
| MD5 |
0cf8b8a29c45c3f2306a669d59febfa1
|
|
| BLAKE2b-256 |
2e60a8bda31cdd9f8d22e213b18cb9ed2ca269e945cea60ee39a4417c5491db6
|
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
887776b87b7ec5ca142df60a97581dab0c3d9bc97a4fe8178c7906df10285a38
|
|
| MD5 |
7e06f1806ba44605a471c838163f8558
|
|
| BLAKE2b-256 |
833169d77c9c31c69fc34af704722c6756d725fad0844e9e5d366820475ae705
|