Wikidata:Pywikibot - Python 3 Tutorial/Setting sources

This chapter will introduce the concept of adding, removing and modifying sources.

Danger Zone edit

Make sure before running the examples that the bot is editing test.wikidata.org.

Check your user-config.py

family = 'wikidata'
mylang = 'test'
usernames['wikidata']['test'] = u'YOUR_BOT_OR_USER_NAME'

Check your login (note the wikidata:test):

$ python3 pwb.py login
Logged in on wikidata:test as YOUR_BOT_OR_USER_NAME.

Then make sure that each script calls the test-site:

site = pywikibot.Site("test", "wikidata")

All examples use the Wikidata Sandbox (Q4115189) item to further prevent accidental vandalism to Wikidata-proper by people copy-pasting code. Because the item does not exist on test.wikidata you can just create a new item (https://test.wikidata.org/wiki/Special:NewItem) for your practice edits. If you copy-paste the examples and run them, two things might happen: You will edit Wikidata Sandbox (Q4115189) or you will see an error message of test.wikidata that tells you that the item does not exist on that site.

pywikibot.data.api.APIError: no-such-entity: Could not find such an entity (Can't access entity Q4115189, revision may have been deleted.) [help:See https://test.wikidata.org/w/api.php for API usage; messages:[{'parameters': [], 'html': {'*': 'Could not find such an entity'}, 'name': 'wikibase-api-no-such-entity'}]]

ID's of properties and values do differ between test and live, so unexpected errors (like: ValueError: wikidata:test:Q101352 is not type <class 'str'>.) may arise if you use property and qualifier ID's from live.

Simple Example edit

# -*- coding: utf-8  -*-
import pywikibot
import time
"""
Adding sources to newly-created claim/statement
"""
site = pywikibot.Site("test", "wikidata")
repo = site.data_repository()
item = pywikibot.ItemPage(repo, "Q4115189")

#CLAIM
claim = pywikibot.Claim(repo, u'P131') #Adding located in the administrative territorial entity (P131)
target = pywikibot.ItemPage(repo, u"Q4546") #Connecting P131 with Cambridge (Q350), that is a Q-id.
claim.setTarget(target) #Set the target value in the local object.
item.addClaim(claim, summary=u'Adding claim to Q4115189') #Inserting value with summary to Q4115189

#ADDS TWO REFERENCES
#FIRST REF.
today = date.today() #Date today
ref = pywikibot.Claim(repo, u'P248') #stated in (P248)
ref.setTarget(pywikibot.ItemPage(repo, 'Q648625')) #Connecting P248 with Google Knowledge Graph (Q648625), that is a Q-id. example stated in -> Google Knowledge Graph).

#SECOND REF.
retrieved = pywikibot.Claim(repo, u'P813') #retrieved (P813). Data type: Point in time
dateCre = pywikibot.WbTime(year=int(today.strftime("%Y")), month=int(today.strftime("%m")), day=int(today.strftime("%d"))) #retrieved -> %DATE TODAY%. Example retrieved -> 29.11.2020
retrieved.setTarget(dateCre) #Inserting value

claim.addSources([ref, retrieved], summary=u'Adding sources to administrative territorial entity (P131).')

Simple example on how to use addSources() on a newly-created claim/statement. Make your own tests to make sure that it is added correctly.

Adding sources to existing statements/claims edit

# -*- coding: utf-8  -*-
import pywikibot
from datetime import date
"""
Add source to existing statement/claim.
"""

site = pywikibot.Site("test", "wikidata")
repo = site.data_repository()
item = pywikibot.ItemPage(repo, "Q4115189") # https://test.wikidata.org/wiki/Q4115189
item.get()

if item.claims['P131']:
    for claim in item.claims['P131']: # Loop through items
        already = False
        try:
            srcs = claim.getSources() # Gets all of the source on the claim
        except:
            continue
        for src in srcs: # Loop through sources
            if "P74" in src: # If someone is using P74 already change variable "already" to TRUE
                already = True
        if already: # If True skip this claim
            print("Claim has already P74 as source! skipping!")
            continue
        #ADD A REF.
        today = date.today() #Date today
        retrieved = pywikibot.Claim(repo, u'P74', is_reference=True) # retrieved (P813 - wikidata) or date (P74 - test wd) . Data type: Point in time
        dateCre = pywikibot.WbTime(year=int(today.strftime("%Y")), month=int(today.strftime("%m")), day=int(today.strftime("%d"))) # retrieved -> %DATE TODAY%. Example retrieved -> 29.11.2020
        retrieved.setTarget(dateCre) #Inserting value
    
        claim.addSource(retrieved, summary=u'Adding source.')
        print('Source added!')
        break # Make your own logic for finding the correct claim. In this example we just takes the first
else:
    print("missing P131 on item!")

Simple example on how to use addSource() on an existing claim/statement. Make your own tests to make sure that it is added correctly. The example only adds to the first claim.

Remove sources from statements/claims edit

Remove all sources from existing statements/claims edit

# -*- coding: utf-8  -*-
import pywikibot
"""
Remove sources on existing statement/claim.
"""

site = pywikibot.Site("test", "wikidata")
repo = site.data_repository()
item = pywikibot.ItemPage(repo, "Q4115189") # https://test.wikidata.org/wiki/Q4115189
item.get()

if item.claims['P131']: # Check if it has the the property P131 on the item
    for claim in item.claims['P131']: # Loop through claims
        if not claim.sources: # If empty list/no source on the claim
            print("Claim has no source(s)")
            continue # Continue to next claim
        sources = [] # list of all the source(s) on the claim
        for source in claim.sources: # Loop through sources on claim
            for value in source.values():  # Loop through source values on claim
                sources.extend(value) # add it to the list
        claim.removeSources(sources, summary=u'Removed source(s).') # Remove all of the source(s) added in the list
        print('Source(s) removed!')
        break # Make your own logic for finding the correct source(s) in this example we just takes the first
else:
    print("Missing P131 on item!")

Simple example on how to use removeSources() on an existing claim/statement. Make your own tests to make sure that it is added correctly. The example only adds to the first claim with source(s).