Commons-query.wikipedia.org requires that user has been logged in and has authorized the use of Commons-query.wikipedia.org. However, currently the SPARQL-query returns None if there is any error. However, code should throw an exception and error message if there is authorization error from "Commons-query.wikipedia.org". In other cases keep returing None for backwards compability.
**Pywikibot developing **
Documentation
* https://www.mediawiki.org/wiki/Manual:Pywikibot/Gerrit#For_developers
* Commit messages: https://www.mediawiki.org/wiki/Gerrit/Commit_message_guidelines
* Zache's notes: https://docs.google.com/document/d/1DU8Y4GhsGeusrqh1xqxDTfqtGc6YG4AMaOrvDD36MIs/edit
**Howto Install development enviroment **
```
python -m venv venv
source venv/bin/activate
git clone --recursive ssh://WIKITECH_USERNAME@gerrit.wikimedia.org:29418/pywikibot/core.git pywikibot-git
cd pywikibot-git
pip install --upgrade pip
pip install -r requirements.txt
cp user-config.py.sample user-config.py
```
And update user-config.py with correct Wikimedia Commons user name
**Howto toggle OAUTH permissions**
* Give permission: Login to Wikimedia Commons and go to https://commons-query.wikimedia.org using web browser
* Revoke permission: Login to Wikimedia Commons and remove permission using https://commons.wikimedia.org/wiki/Special:OAuthManageMyGrants page
**Example code for sparql query **
```
import pywikibot
from pywikibot.data import sparql
site = pywikibot.Site('commons', 'commons')
## Login or logout when needed
#site.logout()
#site.login()
# Define the SPARQL query
query = "SELECT ?item ?finna_id WHERE { ?item wdt:P9478 ?finna_id } 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
data = query_object.select(query, full_data=False)
print(data)
```
Sparql queres are executed in SparqlQuery class function query() in pywikibot/data/sparql.py:
* https://github.com/wikimedia/pywikibot/blob/master/pywikibot/data/sparql.py#L138
**Error messages **
Note. Server returns valid HTTP 200 OK messages and not errors so login status need to be detected from `self.last_response.content` . (ie. if it contains a string "You need to log in" then user is not logged in. Similarly if it asks OAUTH authorization then oauth is missing.)
Suitable error message for user not logged in could be
```
message='You need to log in to Wikimedia Commons and give OAUTH permission. Open https://commons-query.wikimedia.org using web browser to login and give permission.'
raise NoUsernameError('User not logged in. ' + message)
```
And for logged in user but with missing OAUTH permission
```
message='You need to log in to Wikimedia Commons and give OAUTH permission. Open https://commons-query.wikimedia.org using web browser to login and give permission.'
raise UserRightsError('User OAUTH authorization is missing. ' + message)
```
For other sites than commons-query.wikimedia.org keep existing return None for backwards compability
**Tests **
Add test case for testing missing oauth permission to Pywikibot tests to tests/sparql_tests.py
- https://github.com/wikimedia/pywikibot/blob/master/tests/sparql_tests.py
```
python -m unittest -v tests.sparql_tests
```