pinboard-tools
A Python library for syncing and managing Pinboard bookmarks.
Features
- Efficient incremental sync with Pinboard.in API (only fetches changed bookmarks)
- Bidirectional sync with configurable conflict resolution strategies
- SQLite database with normalized tag storage and full-text search
- Thread-safe database singleton with proper locking
- Error recovery for failed sync operations with retry support
- Tag analysis and similarity detection
- Tag consolidation for merging duplicate tags
- Exponential backoff on API rate limits with max retry protection
- Rate limiting and optimized API usage
- Chunking utilities for LLM processing
Installation
pip install pinboard-tools
Quick Start
from pinboard_tools import (
init_database,
get_session,
BidirectionalSync,
)
# Initialize database
init_database("bookmarks.db")
# Create sync engine
db = get_session()
sync = BidirectionalSync(db=db, api_token="your-pinboard-api-token")
# Perform efficient incremental sync
stats = sync.sync()
print(f"Local to remote: {stats['local_to_remote']}")
print(f"Remote to local: {stats['remote_to_local']}")
print(f"Conflicts resolved: {stats['conflicts_resolved']}")
Core Components
Database Models
Bookmark- Bookmark entity with all Pinboard fieldsTag- Tag entity with normalizationBookmarkTag- Many-to-many relationshipSyncStatus- Track sync state (synced,pending_local,pending_remote,conflict,error)
Sync Engine
PinboardAPI- API client with rate limiting, exponential backoff, and JSON error handlingBidirectionalSync- Efficient incremental sync with conflict resolution, error recovery, and remote-to-local mirroring throughupsert_pinboard_postupsert_pinboard_post- Mirror a Pinboard API post into the local database
Tag Analysis
TagSimilarityDetector- Find similar tagsTagConsolidator- Merge duplicate tags
Utilities
chunk_bookmarks_for_llm- Prepare data for LLM processing- DateTime helpers for Pinboard format
Database Schema
The library uses a normalized SQLite schema with full-text search:
-- Core tables (see pinboard_tools/data/schema.sql for complete structure)
bookmarks (href, description, extended, hash, time, sync_status, ...)
tags (name)
bookmark_tags (bookmark_id, tag_id)
sync_metadata (key, timestamp)
-- Convenience view
bookmarks_with_tags -- joins bookmarks with their tags as space-separated string
API Reference
Initialization
# Initialize database with schema
init_database(db_path: str)
# Get database session
with get_session() as session:
# Use session for queries
Syncing
# Create sync client
sync = BidirectionalSync(db=session, api_token="your-token")
# Efficient incremental sync (only fetches changed bookmarks)
stats = sync.sync()
# Sync only local changes to remote
stats = sync.sync(direction=SyncDirection.LOCAL_TO_REMOTE)
# Sync only remote changes to local
stats = sync.sync(direction=SyncDirection.REMOTE_TO_LOCAL)
# Retry bookmarks that previously failed to sync
retried = sync.retry_failed_bookmarks()
if retried > 0:
stats = sync.sync() # re-sync the retried bookmarks
Local mirroring
Use upsert_pinboard_post when another application has already written a
bookmark to Pinboard and wants to keep the local SQLite database in step without
running a full sync:
from pinboard_tools import PinboardAPI, get_session, init_database, upsert_pinboard_post
init_database("bookmarks.db")
db = get_session()
api = PinboardAPI("your-token")
api.add_post(
url="https://example.com",
description="Example",
extended="A useful example.",
tags="examples docs",
)
posts = api.get_post(url="https://example.com")
if posts:
upsert_pinboard_post(db, posts[0])
The mirrored bookmark is marked synced, tags are normalized through the same
tag tables as sync, and last_synced_at is updated.
Tag Analysis
# Find similar tags
detector = TagSimilarityDetector(session)
similar_groups = detector.find_similar_tags(threshold=0.8)
# Consolidate tags
consolidator = TagConsolidator(session)
consolidator.consolidate_tags(old_tag="python3", new_tag="python")
License
Apache License 2.0 - see LICENSE file for details
Metadata
Release files for pinboard-tools 0.1.11
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| pinboard_tools-0.1.11.tar.gz | 105.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pinboard_tools-0.1.11-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 138.8 kB
Release files / pinboard_tools-0.1.11.tar.gz
| Download URL | pinboard_tools-0.1.11.tar.gz |
|---|---|
| Size | 105.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f9a342494504b2eaecb58fb5cc8e0eacfa673981b726c47c8888a3afe0ce3013
|
|
BLAKE2b-256 checksum How to use checksums |
7491b449ee2e62be58d0b9ea5294837a361c93320de99e829a651984ea97ed8a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 3, 2026.
Transparency logRelease files / pinboard_tools-0.1.11-py3-none-any.whl
| Download URL | pinboard_tools-0.1.11-py3-none-any.whl |
|---|---|
| Size | 33.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
28a9aab63788bb92c47feb07960ed3f301528de1985cb66ea49f2b7b13d6e296
|
|
BLAKE2b-256 checksum How to use checksums |
826b0aa62015d6f6357b26f299952507c166f06ac53f2aa5b5b540e87dc85d2c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 3, 2026.
Transparency log