jenkins-bot has submitted this change. ( https://gerrit.wikimedia.org/r/c/pywikibot/core/+/959755 )
Change subject: Give visible error to user when there are no rights. ......................................................................
Give visible error to user when there are no rights.
Currently bot does not give user-visible output when user is not logged in or user does not have permissions. Instead of silently failing inform user of a problem.
Bug: T345342 Change-Id: I3b7135a0e6ea6fb5c6280f611610b5c60376bbb2 --- M pywikibot/data/sparql.py M tests/sparql_tests.py 2 files changed, 66 insertions(+), 6 deletions(-)
Approvals: Xqt: Looks good to me, approved jenkins-bot: Verified
diff --git a/pywikibot/data/sparql.py b/pywikibot/data/sparql.py index 23ffb1d..3417e32 100644 --- a/pywikibot/data/sparql.py +++ b/pywikibot/data/sparql.py @@ -4,7 +4,6 @@ # # Distributed under the terms of the MIT license. # -from contextlib import suppress from typing import Optional from urllib.parse import quote
@@ -14,7 +13,7 @@ from pywikibot.backports import Dict, List, removeprefix from pywikibot.comms import http from pywikibot.data import WaitingMixin -from pywikibot.exceptions import Error +from pywikibot.exceptions import Error, NoUsernameError
try: @@ -144,17 +143,36 @@ if headers is None: headers = DEFAULT_HEADERS
+ # force cleared + self.last_response = None + url = f'{self.endpoint}?query={quote(query)}' while True: try: self.last_response = http.fetch(url, headers=headers) + break except Timeout: self.wait() - continue
- with suppress(JSONDecodeError): - return self.last_response.json() - break + try: + return self.last_response.json() + except JSONDecodeError: + # There is no proper error given but server returns HTML page + # in case login isn't valid sotry to guess what the problem is + # and notify user instead of silently ignoring it. + # This could be made more reliable by fixing the backend. + # Note: only raise error when response starts with HTML, + # not in case the response otherwise might have it in between + strcontent = self.last_response.content.decode() + if (strcontent.startswith('<!DOCTYPE html>') + and 'https://commons-query.wikimedia.org' in url): + if ('Special:UserLogin' in strcontent + or 'Special:OAuth' in strcontent): + message = ('You need to log in to Wikimedia Commons ' + 'and give OAUTH permission. ' + 'Open https://commons-query.wikimedia.org ' + 'with browser to login and give permission.') + raise NoUsernameError('User not logged in. ' + message)
return None
diff --git a/tests/sparql_tests.py b/tests/sparql_tests.py index 706da60..a14f4f0 100755 --- a/tests/sparql_tests.py +++ b/tests/sparql_tests.py @@ -14,6 +14,7 @@ import pywikibot.data.sparql as sparql from tests.aspects import TestCase, WikidataTestCase from tests.utils import skipping +from pywikibot.exceptions import NoUsernameError
# See: https://www.w3.org/TR/2013/REC-sparql11-results-json-20130321/ @@ -181,6 +182,33 @@ self.assertFalse(res)
+class TestCommonsQueryService(TestCase): + """Test Commons Query Service auth.""" + + family = 'commons' + code = 'commons' + + def testLoginAndOauthPermisson(self): + """Commons Query Service Login and Oauth permission.""" + # Define the SPARQL query + query = 'SELECT ?a ?b WHERE { ?a wdt:P9478 ?b } LIMIT 4' + + # Set up the SPARQL endpoint and entity URL + # Note: https://commons-query.wikimedia.org + # requires user to be logged in + + entity_url = 'https://commons.wikimedia.org/entity/' + endpoint = 'https://commons-query.wikimedia.org/sparql' + + # Create a SparqlQuery object + query_object = sparql.SparqlQuery(endpoint=endpoint, + entity_url=entity_url) + + # Execute the SPARQL query and retrieve the data user not logged in + with self.assertRaisesRegex(NoUsernameError, 'User not logged in'): + query_object.select(query, full_data=False) + + class Shared: """Shared test placeholder."""
pywikibot-commits@lists.wikimedia.org