jenkins-bot has submitted this change. ( https://gerrit.wikimedia.org/r/c/pywikibot/core/+/1195215?usp=email )
Change subject: Add Citoid API to pywikibot ...................................................................... Add Citoid API to pywikibot Bug: T401690 Change-Id: I272a838d604967d8b84c70a03c92e1f4aaa91029 Signed-off-by: Strainu <[email protected]> --- A pywikibot/data/citoid.py M pywikibot/exceptions.py M pywikibot/families/wikipedia_family.py A tests/citoid_tests.py 4 files changed, 127 insertions(+), 0 deletions(-) Approvals: jenkins-bot: Verified Xqt: Looks good to me, approved diff --git a/pywikibot/data/citoid.py b/pywikibot/data/citoid.py new file mode 100644 index 0000000..ee4a930 --- /dev/null +++ b/pywikibot/data/citoid.py @@ -0,0 +1,59 @@ +"""Superset Query interface. + +.. versionadded:: 10.6 +""" +# +# (C) Pywikibot team, 2025 +# +# Distributed under the terms of the MIT license. +# +from __future__ import annotations + +import urllib.parse + +import pywikibot +from pywikibot.comms import http +from pywikibot.exceptions import ApiNotAvailableError, Error +from pywikibot.site import BaseSite + + +VALID_FORMAT = [ + 'mediawiki', 'wikibase', 'zotero', 'bibtex', 'mediawiki-basefields' +] + + +class CitoidClient: + + """Citoid client class. + + This class allows to call the Citoid API used in production. + """ + + def __init__(self, site: BaseSite): + """Initialize the CitoidClient.""" + self.site = site + + def get_citation(self, response_format: str, ref_url: str) -> dict: + """Get a citation from the citoid service. + + :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. + """ + 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}') + try: + json = http.request(self.site, api_url).json() + return json + except Error as e: + pywikibot.log(f'Caught pywikibot error {e}') + raise diff --git a/pywikibot/exceptions.py b/pywikibot/exceptions.py index 00f1a26..d1a095a 100644 --- a/pywikibot/exceptions.py +++ b/pywikibot/exceptions.py @@ -728,6 +728,11 @@ """Request failed with a maxlag timeout error.""" +class ApiNotAvailableError(Error): + + """API is not available, e.g. due to a network error or configuration.""" + + wrapper = ModuleDeprecationWrapper(__name__) wrapper.add_deprecated_attr( 'Server414Error', Client414Error, since='8.1.0') diff --git a/pywikibot/families/wikipedia_family.py b/pywikibot/families/wikipedia_family.py index cb80610..8f960fe 100644 --- a/pywikibot/families/wikipedia_family.py +++ b/pywikibot/families/wikipedia_family.py @@ -223,6 +223,8 @@ 'ro': ('Arhivă',), } + citoid_endpoint = '/api/rest_v1/data/citation/' + @classmethod def __post_init__(cls) -> None: """Add 'yue' code alias due to :phab:`T341960`. diff --git a/tests/citoid_tests.py b/tests/citoid_tests.py new file mode 100755 index 0000000..b4a6c96 --- /dev/null +++ b/tests/citoid_tests.py @@ -0,0 +1,61 @@ +#!/usr/bin/env python3 +"""Unit tests for citoid script.""" +# +# (C) Pywikibot team, 2025 +# +# Distributed under the terms of the MIT license. +# +from __future__ import annotations + +import datetime + +import pywikibot +from pywikibot.data import citoid +from pywikibot.exceptions import ApiNotAvailableError +from tests.aspects import TestCase + + +class TestCitoid(TestCase): + + """Test the Citoid client.""" + + family = 'wikipedia' + code = 'test' + login = False + + def test_citoid_positive(self): + """Test citoid script.""" + client = citoid.CitoidClient(self.site) + resp = client.get_citation( + 'mediawiki', + 'https://ro.wikipedia.org/wiki/România' + ) + self.assertLength(resp, 1) + self.assertEqual(resp[0]['title'], 'România') + self.assertEqual( + resp[0]['rights'], + 'Creative Commons Attribution-ShareAlike License' + ) + self.assertIsNotEmpty(resp[0]['url']) + self.assertEqual( + resp[0]['accessDate'], + datetime.datetime.now().strftime('%Y-%m-%d') + ) + + def test_citoid_no_config(self): + """Test citoid script with no citoid endpoint configured.""" + client = citoid.CitoidClient(pywikibot.Site('pl', 'wikiquote')) + with self.assertRaises(ApiNotAvailableError): + client.get_citation( + 'mediawiki', + 'https://ro.wikipedia.org/wiki/România' + ) + + def test_citoid_no_valid_format(self): + """Test citoid script with invalid format provided.""" + client = citoid.CitoidClient(self.site) + with self.assertRaises(ValueError): + client.get_citation( + 'mediawiki2', + 'https://ro.wikipedia.org/wiki/România' + ) -- To view, visit https://gerrit.wikimedia.org/r/c/pywikibot/core/+/1195215?usp=email To unsubscribe, or for help writing mail filters, visit https://gerrit.wikimedia.org/r/settings?usp=email Gerrit-MessageType: merged Gerrit-Project: pywikibot/core Gerrit-Branch: master Gerrit-Change-Id: I272a838d604967d8b84c70a03c92e1f4aaa91029 Gerrit-Change-Number: 1195215 Gerrit-PatchSet: 8 Gerrit-Owner: Strainu <[email protected]> Gerrit-Reviewer: Xqt <[email protected]> Gerrit-Reviewer: jenkins-bot
_______________________________________________ Pywikibot-commits mailing list -- [email protected] To unsubscribe send an email to [email protected]
