urschrei / pyzotero

Pyzotero: a Python client for the Zotero API
https://pyzotero.readthedocs.org
Other
908 stars 99 forks source link

How to adapt pyzotero to use local API server? #179

Closed xxie-xd closed 3 months ago

xxie-xd commented 3 months ago

As is shown in this page: https://groups.google.com/g/zotero-dev/c/ElvHhIFAXrY/m/fA7SKKwsAgAJ Zotero has already set up a local API server since Zotero 7 beta 88, and the local API shares almost the same interfaces with online server API. I'm going to access my local zotero user library via pyzotero, and luckily found that the API endpoint in pyzotero can be accessed and set as another url base address (https://github.com/urschrei/pyzotero/blob/9ca972620cd7927d9de265c1b7c3ce270e5ef9d3/src/pyzotero/zotero.py#L270). As is shown in the local server code (https://github.com/zotero/zotero/blob/main/chrome/content/zotero/xpcom/localAPI/server_localAPI.js), the local API server can be accessed at http://localhost:21339/api/ . However, when I have set zotero.Zotero.endpoint to http:///localhost:23119/api/, the request URL is not properly generated:

from pyzotero import zotero

zot = zotero.Zotero(ZOTERO_LIBRARY_ID, "user", ZOTERO_LOCAL_API_KEY)
zot.endpoint = "http://localhost:23119/api/"
items = zot.top(limit=10)

Has caused:

Traceback (most recent call last):
  File "C:\Users\xxxx\miniforge3\envs\MinerU\lib\site-packages\pyzotero\zotero.py", line 401, in _retrieve_data
    self.request.raise_for_status()
  File "C:\Users\xxxx\miniforge3\envs\MinerU\lib\site-packages\requests\models.py", line 1024, in raise_for_status
    raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 404 Client Error: Not Found for url: http://localhost:23119/users/0000000/items/top?limit=10&format=json

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "F:\paper-qa-utils\zot.py", line 9, in <module>
    items = zot.top(limit=10)
  File "C:\Users\xxxx\miniforge3\envs\MinerU\lib\site-packages\pyzotero\zotero.py", line 154, in wrapped_f
    retrieved = self._retrieve_data(func(self, *args))
  File "C:\Users\xxxx\miniforge3\envs\MinerU\lib\site-packages\pyzotero\zotero.py", line 403, in _retrieve_data
    error_handler(self, self.request, exc)
  File "C:\Users\xxxx\miniforge3\envs\MinerU\lib\site-packages\pyzotero\zotero.py", line 1635, in error_handler
    raise error_codes.get(req.status_code)(err_msg(req)) from exc
pyzotero.zotero_errors.ResourceNotFound:
Code: 404
URL: http://localhost:23119/users/000000/items/top?limit=10&format=json
Method: GET
Response: No endpoint found

Diving into the process of URL generation of pyzotero, it seems that the endpoint, path and query parameters will be parsed into different blocks and joined together (done by urllib/parser.py), and the "/api/" path is dropped.

Question:

Any comment is appreciated.

urschrei commented 3 months ago

Briefly, you need to make sure that the /api/ section is preserved. This fork (particularly the code added at line 72) has an attempt that might work: https://github.com/urschrei/pyzotero/compare/master...nick8325:pyzotero:master

xxie-xd commented 3 months ago

Thank you. I'll give it a try.