Wikidata:Pywikibot - Python 3 Tutorial/Setting statements

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

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

You probably remember that we first need to call the site, the repo and then the item to look at a Wikidata-Item. We used print(dir(item)) to get a list of all the methods with which we can interact with the item. Just as a reminder here is the list:

['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__unicode__', '__weakref__', '_cache_attrs', '_cmpkey', '_cosmetic_changes_hook', '_defined_by', '_diff_to', '_getInternals', '_get_parsed_page', '_latest_cached_revision', '_link', '_namespace', '_normalizeData', '_normalizeLanguages', '_revisions', '_save', 'addClaim', 'applicable_protections', 'aslink', 'autoFormat', 'backlinks', 'botMayEdit', 'canBeEdited', 'categories', 'change_category', 'clear_cache', 'concept_uri', 'concept_url', 'content_model', 'contributingUsers', 'contributors', 'coordinates', 'create_short_link', 'data_item', 'data_repository', 'defaultsort', 'delete', 'depth', 'editAliases', 'editDescriptions', 'editEntity', 'editLabels', 'editTime', 'embeddedin', 'encoding', 'entity_type', 'exists', 'expand_text', 'extlinks', 'fromPage', 'from_entity_uri', 'fullVersionHistory', 'full_url', 'get', 'getCategoryRedirectTarget', 'getCreator', 'getDeletedRevision', 'getID', 'getLatestEditors', 'getMovedTarget', 'getOldVersion', 'getRedirectTarget', 'getReferences', 'getRestrictions', 'getSitelink', 'getTemplates', 'getVersionHistory', 'getVersionHistoryTable', 'getdbName', 'id', 'image_repository', 'imagelinks', 'interwiki', 'isAutoTitle', 'isCategory', 'isCategoryRedirect', 'isDisambig', 'isEmpty', 'isFlowPage', 'isImage', 'isIpEdit', 'isRedirectPage', 'isStaticRedirect', 'isTalkPage', 'is_categorypage', 'is_filepage', 'is_flow_page', 'is_valid_id', 'iterlanglinks', 'iterlinks', 'itertemplates', 'langlinks', 'lastNonBotUser', 'latestRevision', 'latest_revision', 'latest_revision_id', 'linkedPages', 'loadDeletedRevisions', 'markDeletedRevision', 'mergeInto', 'merge_history', 'move', 'moved_target', 'namespace', 'oldest_revision', 'pageAPInfo', 'page_image', 'pageid', 'permalink', 'preloadText', 'previousRevision', 'previous_revision_id', 'properties', 'protect', 'protection', 'purge', 'put', 'put_async', 'removeClaims', 'removeSitelink', 'removeSitelinks', 'repo', 'revision_count', 'revisions', 'save', 'section', 'sectionFreeTitle', 'setSitelink', 'setSitelinks', 'set_redirect_target', 'site', 'templates', 'text', 'title', 'titleForFilename', 'titleWithoutNamespace', 'title_pattern', 'toJSON', 'toggleTalkPage', 'touch', 'undelete', 'urlname', 'userName', 'version', 'watch']

As you can see, we are interested in addClaim(), removeClaims() in this chapter. We will look at the whole example because it should be easy to figure out what the lines do. Then run the example (let it fail the first time to make sure your using test.wikidata):

# -*- coding: utf-8  -*-
import pywikibot
"""
Adds claim to item
"""
site = pywikibot.Site("test", "wikidata")
repo = site.data_repository()
item = pywikibot.ItemPage(repo, "Q210194")

claim = pywikibot.Claim(repo, u'P131') #Adding located in the administrative territorial entity (P131)
target = pywikibot.ItemPage(repo, u"Q350") #Connecting P131 with Cambridge (Q350), who is a Q-id.
claim.setTarget(target) #Set the target value in the local object.

item.addClaim(claim, summary=u'Adding claim to Q210194') #Inserting value with summary to Q210194

Simple example on how to use addClaim(). If the code is excecuted multiple times it will just just add the same value over and over again.

Adding string, coordinates & date statements/claims edit

String and coordinates edit

# -*- coding: utf-8  -*-
import pywikibot
"""
Adding claims with string (IMDb ID (P345) and coordinate (coordinate location (P625)) datatypes (URL is the same as string)
"""
site = pywikibot.Site("test", "wikidata")
repo = site.data_repository()
item = pywikibot.ItemPage(repo, u"Q42")

stringclaim = pywikibot.Claim(repo, u'P345') #Adding IMDb ID (P345)
stringclaim.setTarget(u"nm0010930") #Using a string
item.addClaim(stringclaim, summary=u'Adding string claim')

coordinateclaim  = pywikibot.Claim(repo, u'P625') #Adding coordinate location (P625)
coordinate = pywikibot.Coordinate(lat=52.208, lon=0.1225, precision=0.001, site=site) #With location markes
coordinateclaim.setTarget(coordinate)
item.addClaim(coordinateclaim, summary=u'Adding coordinate claim')

Single value string edit

# -*- coding: utf-8  -*-
import pywikibot
"""
First check if P2373 already exists for Q15935. If not add claim P2373 with the string 'Kanye_west'.
This works for claims that only allow a single value.
"""
site = pywikibot.Site("wikidata", "wikidata")
repo = site.data_repository()
item = pywikibot.ItemPage(repo, u"Q15935") #Kanye West (Q15935)
claims = item.get(u'claims') #Get all the existing claims

if u'P2373' in claims[u'claims']: #Genius artist ID (P2373) only allow single values. So if a value is presented already, print error.
    pywikibot.output(u'Error: Already have a Genius artist ID!')
else:
    stringclaim = pywikibot.Claim(repo, u'P2373') #Else, add the value
    stringclaim.setTarget('Kanye_west')
    item.addClaim(stringclaim, summary=u'Adding a Genius artist ID')

Example of how to check for if a value for a property already exists for the item.

Time/date edit

# -*- coding: utf-8  -*-
import pywikibot
"""
Adding value for data type: Point in time.
"""
site = pywikibot.Site("test", "wikidata")
repo = site.data_repository()
item = pywikibot.ItemPage(repo, u"Q210194")

dateclaim = pywikibot.Claim(repo, u'P95197')
dateOfBirth = pywikibot.WbTime(year=1977, month=6, day=8)
dateclaim.setTarget(dateOfBirth)
item.addClaim(dateclaim, summary=u'Adding dateOfBirth')

Removing statements/claims edit

# -*- coding: utf-8  -*-
import pywikibot
"""
Remove all claims of P95197
"""
site = pywikibot.Site("test", "wikidata")
repo = site.data_repository()
item = pywikibot.ItemPage(repo, u"Q210194")
item.get() #To access item.claims

for claim in item.claims['P95197']: #Iterate over every statement of P95197
    item.removeClaims(claim, summary=u'Removing dateOfBirth') #Removing claim