Skip to content

feat: add native Zotero Local API resolution#13

Merged
917Dhj merged 5 commits into
917Dhj:developfrom
KumamuKuma:feat/zotero-local-api
Jul 23, 2026
Merged

feat: add native Zotero Local API resolution#13
917Dhj merged 5 commits into
917Dhj:developfrom
KumamuKuma:feat/zotero-local-api

Conversation

@KumamuKuma

Copy link
Copy Markdown
Contributor

Summary

  • add a private, read-only Zotero Local API v3 client using only the Python standard library
  • resolve DOI, arXiv, title, and exact item-key inputs against the local personal library before web providers
  • safely reuse local PDF attachments and expose auto, off, and required lookup policies through the resolver and pipeline
  • report Local API readiness in the existing environment diagnostics and document the built-in workflow in English and Chinese

Resolution behavior

  • auto (default): prefer a unique local match; fall back to existing providers for title, DOI, and arXiv misses
  • off: make no Local API request and preserve the previous resolution path
  • required: require a unique Zotero match, while trusted JSON artifacts and explicit local PDFs remain authoritative
  • ambiguous local identities and unverifiable explicit Zotero keys fail closed
  • missing or ambiguous attachments do not invalidate uniquely confirmed parent metadata
  • group-library select links are rejected explicitly rather than being queried against the wrong library

Safety

  • fixed loopback-only endpoint with proxies and redirects disabled
  • read-only GET requests, no API key, no SQLite access, and bounded response sizes
  • strict local file:// validation rejects remote UNC paths, ports, queries, fragments, invalid UTF-8, and encoded NULs
  • attachment keys remain distinct from parent bibliographic item keys

Testing

  • python -m pytest -q756 passed, 1 skipped
  • Ruff passed for all changed Python implementation and focused test files
  • git diff --check origin/develop...HEAD

@KumamuKuma
KumamuKuma force-pushed the feat/zotero-local-api branch from be57378 to 924ddaa Compare July 20, 2026 09:32
@917Dhj

917Dhj commented Jul 21, 2026

Copy link
Copy Markdown
Owner

Thanks for the substantial contribution — the Local API integration, safety boundaries, documentation, and test coverage are thoughtfully implemented.
Before merging, I found three identity-safety issues that need to be addressed:

  1. Fuzzy title matching can accept a wrong paper as the canonical Zotero identity. For example, Deep Learning for Cats matches Deep Learning for Dogs at the current 0.84 threshold. Non-exact title matches need independent author/year evidence or should fail closed.
  2. When a Zotero item has no DOI, title-based web enrichment can attach a DOI from a different same-title paper and replace the final paper_id. Strong identifiers should only be backfilled after author/year validation.
  3. A malformed attachment URL can make urlsplit() raise an uncaught ValueError, causing an already-confirmed parent item to fail. Attachment URL errors should be converted to zotero_unsafe_file_url while preserving the parent metadata.
    The macOS and Windows CI checks pass, so these are behavioral edge cases rather than general test failures. Once these three cases are fixed with regression tests, I’d be happy to review the update.

@KumamuKuma

Copy link
Copy Markdown
Contributor Author

@917Dhj Thanks for the detailed review. I’ve addressed all three identity-safety issues in separate commits:

44807e4 — Title-based Zotero lookup now requires an exact normalized title match, preventing fuzzy matches such as “Cats” vs. “Dogs”.

d4fb86f — Strong identifiers from title-based web enrichment are accepted only after title, leading-author, and publication-year validation.

ea44e4d — Malformed attachment URLs are converted to zotero_unsafe_file_url without discarding the already-confirmed parent metadata.

I also added regression tests for each case. The local suite passes with 761 passed, 1 skipped, and both the macOS and Windows CI jobs are green.

@917Dhj
917Dhj merged commit a187941 into 917Dhj:develop Jul 23, 2026
2 checks passed
@917Dhj 917Dhj mentioned this pull request Jul 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants