Source code for data.citoid
#
# (C) Pywikibot team, 2025-2026
#
# Distributed under the terms of the MIT license.
#
"""Citoid Query interface.
.. version-added:: 10.6
"""
from __future__ import annotations
import urllib.parse
from dataclasses import dataclass
from typing import Any
from pywikibot.comms import http
from pywikibot.exceptions import ApiNotAvailableError, CitoidError
from pywikibot.site import BaseSite
VALID_FORMAT = [
'mediawiki', 'wikibase', 'zotero', 'bibtex', 'mediawiki-basefields'
]
[docs]
@dataclass(eq=False)
class CitoidClient:
"""Citoid client class.
This class allows to call the Citoid API used in production.
"""
site: BaseSite
[docs]
def get_citation(
self,
response_format: str,
ref_url: str
) -> dict[str, Any]:
"""Get a citation from the citoid service.
.. version-changed:: 11.7
Raise :exc:`CitoidError` if the Citoid service returns an
error with the response dict.
:param response_format: Return format, e.g. 'bibtex', 'wikibase',
etc.
:param ref_url: The URL to get the citation for.
:return: A dictionary with the citation data.
:raises ApiNotAvailableError: Citoid endpoint not configured for
the given site.
:raises CitoidError: Raised with the error returned by the
Citoid service.
:raises ValueError: Invalid format for *response_format*.
"""
if response_format not in VALID_FORMAT:
raise ValueError(f'Invalid format {response_format}, '
f'must be one of {VALID_FORMAT}')
if (not hasattr(self.site.family, 'citoid_endpoint')
or not self.site.family.citoid_endpoint):
raise ApiNotAvailableError(
f'Citoid endpoint not configured for {self.site.family.name}')
base_url = self.site.family.citoid_endpoint
ref_url = urllib.parse.quote(ref_url, safe='')
api_url = urllib.parse.urljoin(base_url,
f'{response_format}/{ref_url}')
data = http.request(self.site, api_url).json()
if 'error' in data:
raise CitoidError(data['error'])
return data