{"id":48607946,"url":"https://github.com/vishvish/zotero_rs","last_synced_at":"2026-04-09T00:12:52.301Z","repository":{"id":345199094,"uuid":"1184879568","full_name":"vishvish/zotero_rs","owner":"vishvish","description":"My Zotero API Client, extracted from my web publishing codebase","archived":false,"fork":false,"pushed_at":"2026-03-18T09:17:59.000Z","size":80,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-18T19:30:04.798Z","etag":null,"topics":["api","bibliography","library","rust","zotero","zotero-api"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vishvish.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-18T02:44:11.000Z","updated_at":"2026-03-18T03:33:54.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/vishvish/zotero_rs","commit_stats":null,"previous_names":["vishvish/zotero_rs"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/vishvish/zotero_rs","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vishvish%2Fzotero_rs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vishvish%2Fzotero_rs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vishvish%2Fzotero_rs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vishvish%2Fzotero_rs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vishvish","download_url":"https://codeload.github.com/vishvish/zotero_rs/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vishvish%2Fzotero_rs/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31579150,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-08T14:31:17.711Z","status":"ssl_error","status_checked_at":"2026-04-08T14:31:17.202Z","response_time":54,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","bibliography","library","rust","zotero","zotero-api"],"created_at":"2026-04-09T00:12:52.157Z","updated_at":"2026-04-09T00:12:52.283Z","avatar_url":"https://github.com/vishvish.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# zotero-rs\n\nA secure, typed Rust client for the Zotero Web API v3.\n\n## Status\n\nUsable, decomposed client with endpoint calls split into operation files.\n\n## Security posture\n\n- HTTPS-only and restricted API host (`api.zotero.org`)\n- Default `Zotero-API-Version: 3` and explicit `User-Agent`\n- No `unsafe` code in library\n- Secret-aware auth types (`secrecy`)\n- CI gates for format, clippy, tests, advisories, and license policy\n- Path-segment encoding for key-based endpoints\n- Conditional read/write headers for Zotero versioning semantics\n- Retry policy for safe reads (`GET`) with `Retry-After`/`Backoff` support\n- HTTPS-only remote upload targets (localhost HTTP allowed only in test builds)\n\n## Quick start\n\n```rust\nuse zotero_api_rs::{ClientOptions, LibraryScope, WriteOptions, ZoteroClient};\nuse zotero_api_rs::requests::list_items_request::ListItemsRequest;\n\nlet client = ZoteroClient::new(ClientOptions::default())?;\nlet scope = LibraryScope::User(12345);\n\nlet page = client.list_items(scope, \u0026ListItemsRequest::default()).await?;\nlet item = client.get_item(scope, \"ABCD1234\", None).await?;\nlet _created = client\n    .create_items(scope, \u0026[], \u0026WriteOptions::default())\n    .await?;\n```\n\n## Endpoint organization\n\nAPI calls are intentionally decomposed so each operation is easy to find:\n\n- `src/api/items/*` for item operations\n- `src/api/collections/*` for collection operations\n- `src/api/searches/*` for saved search operations\n- `src/api/tags/*` for tag operations\n- `src/api/deleted/*` for sync deleted-key operations\n\n## Hardening test coverage\n\n- Retry behavior: safe-read retry, write no-retry default, and `rel=next` traversal\n- OAuth parsing and signature-base determinism\n- File upload action validation and full authorize/upload/register orchestration\n- URL/path safety checks for endpoint key segments\n\n## Local secrets\n\n- Keep real API tokens in `.envrc.local` (git-ignored).\n- `.envrc` should only source `.envrc.local` and must never contain raw secrets.\n\n## Live account smoke testing (Phase 6)\n\n1. Create a local env file from the template:\n```bash\ncp .envrc.local.example .envrc.local\n```\n2. Set real values in `.envrc.local`:\n```bash\nexport ZOTERO_API_KEY=\"...\"\nexport ZOTERO_USER_ID=\"1234567\"\nexport ZOTERO_COLLECTION_NAME=\"example-collection-name\"\nexport ZOTERO_TOP_LEVEL_ONLY=\"1\"\nexport ZOTERO_INCLUDE_TRASHED=\"0\"\n```\n3. Run the ignored live integration smoke test:\n```bash\nset -a; source .envrc.local; set +a\nZOTERO_LIVE_TESTS=1 cargo test --test live_smoke -- --ignored\n```\n4. Or run the live example:\n```bash\nset -a; source .envrc.local; set +a\ncargo run --example live_smoke\n```\n\nNotes:\n- These commands are intentionally local-only and are not run in CI.\n- Never commit `.envrc.local` or real credentials.\n\n## Examples\n\n- `live_smoke`: fetches first page of items from your library and prints basic item info.\n- `read_collection_by_name`: finds a collection by name and prints structured metadata objects for each returned item.\n\nRun:\n```bash\nset -a; source .envrc.local; set +a\ncargo run --example live_smoke\n```\n\n```bash\nset -a; source .envrc.local; set +a\ncargo run --example read_collection_by_name\n```\n\nDummy sample output for `live_smoke`:\n```text\nFetched 5 item(s)\n- A1B2C3D4 v120 [attachment] Snapshot\n- E5F6G7H8 v121 [webpage] Notes on Typed API Clients\n- I9J0K1L2 v122 [blogPost] The Geometry of Infinity\n- M3N4O5P6 v123 [film] The Medium and the Message\n- Q7R8S9T0 v124 [journalArticle] Broad Spectrum Lighting and Vision\n```\n\nDummy sample output for `read_collection_by_name`:\n```text\nCollection \"example-collection-name\" =\u003e key COL1ECTN\nReading top-level items in collection (includeTrashed=false)\nI9J0K1L2 v122 [blogPost] The Geometry of Infinity\nM3N4O5P6 v123 [film] The Medium and the Message\nQ7R8S9T0 v124 [journalArticle] Broad Spectrum Lighting and Vision\nTotal items read: 3\n```\n\nDummy sample structured object returned by `read_collection_by_name`:\n```json\n{\n  \"key\": \"Q7R8S9T0\",\n  \"version\": 124,\n  \"item_type\": \"journalArticle\",\n  \"title\": \"Broad Spectrum Lighting and Vision\",\n  \"url\": \"https://example.org/articles/broad-spectrum-lighting\",\n  \"abstract_note\": \"A study of visual performance under broad spectrum illumination.\",\n  \"creators\": [\n    {\n      \"creator_type\": \"author\",\n      \"first_name\": \"Alex\",\n      \"last_name\": \"Rivera\",\n      \"name\": null\n    },\n    {\n      \"creator_type\": \"author\",\n      \"first_name\": \"Sam\",\n      \"last_name\": \"Lee\",\n      \"name\": null\n    }\n  ],\n  \"authors\": [\n    \"Alex Rivera\",\n    \"Sam Lee\"\n  ],\n  \"raw_data\": {\n    \"itemType\": \"journalArticle\",\n    \"title\": \"Broad Spectrum Lighting and Vision\",\n    \"url\": \"https://example.org/articles/broad-spectrum-lighting\",\n    \"abstractNote\": \"A study of visual performance under broad spectrum illumination.\",\n    \"creators\": [\n      {\n        \"creatorType\": \"author\",\n        \"firstName\": \"Alex\",\n        \"lastName\": \"Rivera\"\n      },\n      {\n        \"creatorType\": \"author\",\n        \"firstName\": \"Sam\",\n        \"lastName\": \"Lee\"\n      }\n    ]\n  }\n}\n```\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvishvish%2Fzotero_rs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvishvish%2Fzotero_rs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvishvish%2Fzotero_rs/lists"}