zotero-rs
A secure, typed Rust client for the Zotero Web API v3.
Status
Usable, decomposed client with endpoint calls split into operation files.
Security posture
- HTTPS-only and restricted API host (
api.zotero.org) - Default
Zotero-API-Version: 3and explicitUser-Agent - No
unsafecode in library - Secret-aware auth types (
secrecy) - CI gates for format, clippy, tests, advisories, and license policy
- Path-segment encoding for key-based endpoints
- Conditional read/write headers for Zotero versioning semantics
- Retry policy for safe reads (
GET) withRetry-After/Backoffsupport - HTTPS-only remote upload targets (localhost HTTP allowed only in test builds)
Quick start
use ;
use ListItemsRequest;
let client = new?;
let scope = User;
let page = client.list_items.await?;
let item = client.get_item.await?;
let _created = client
.create_items
.await?;
Endpoint organization
API calls are intentionally decomposed so each operation is easy to find:
src/api/items/*for item operationssrc/api/collections/*for collection operationssrc/api/searches/*for saved search operationssrc/api/tags/*for tag operationssrc/api/deleted/*for sync deleted-key operations
Hardening test coverage
- Retry behavior: safe-read retry, write no-retry default, and
rel=nexttraversal - OAuth parsing and signature-base determinism
- File upload action validation and full authorize/upload/register orchestration
- URL/path safety checks for endpoint key segments
Local secrets
- Keep real API tokens in
.envrc.local(git-ignored). .envrcshould only source.envrc.localand must never contain raw secrets.
Live account smoke testing (Phase 6)
- Create a local env file from the template:
- Set real values in
.envrc.local:
- Run the ignored live integration smoke test:
; ;
ZOTERO_LIVE_TESTS=1
- Or run the live example:
; ;
Notes:
- These commands are intentionally local-only and are not run in CI.
- Never commit
.envrc.localor real credentials.
Examples
live_smoke: fetches first page of items from your library and prints basic item info.read_collection_by_name: finds a collection by name and prints structured metadata objects for each returned item.
Run:
; ;
; ;
Dummy sample output for live_smoke:
Fetched 5 item(s)
- A1B2C3D4 v120 [attachment] Snapshot
- E5F6G7H8 v121 [webpage] Notes on Typed API Clients
- I9J0K1L2 v122 [blogPost] The Geometry of Infinity
- M3N4O5P6 v123 [film] The Medium and the Message
- Q7R8S9T0 v124 [journalArticle] Broad Spectrum Lighting and Vision
Dummy sample output for read_collection_by_name:
Collection "example-collection-name" => key COL1ECTN
Reading top-level items in collection (includeTrashed=false)
I9J0K1L2 v122 [blogPost] The Geometry of Infinity
M3N4O5P6 v123 [film] The Medium and the Message
Q7R8S9T0 v124 [journalArticle] Broad Spectrum Lighting and Vision
Total items read: 3
Dummy sample structured object returned by read_collection_by_name:
License
MIT