Page MenuHomePhabricator

Pywikibot cannot create new property
Closed, ResolvedPublic

Description

Hello,

I think this is not a bug, I guess I'm doing something wrong ...

I want to create a new Property on a own Wikidata instance. Here is the code:

1 wikibase_item = pywikibot.PropertyPage(wikibase_repo, datatype='wikibase-item')
2 wikibase_item.editLabels(labels={'en': 'My new property'}, summary='Setting labels')
3 print(wikibase_item)

I can create entities without problems, but this fails at line 2 with

WARNING: API error failed-save: The save has failed.
Traceback (most recent call last):
  File "/Users/Dennis/Library/Python/3.6/lib/python/site-packages/pywikibot/page.py", line 113, in handle
    func(self, *args, **kwargs)
  File "/Users/Dennis/Library/Python/3.6/lib/python/site-packages/pywikibot/page.py", line 4259, in editEntity
    baserevid=baserevid, **kwargs)
  File "/Users/Dennis/Library/Python/3.6/lib/python/site-packages/pywikibot/tools/__init__.py", line 1738, in wrapper
    return obj(*__args, **__kw)
  File "/Users/Dennis/Library/Python/3.6/lib/python/site-packages/pywikibot/site.py", line 1322, in callee
    return fn(self, *args, **kwargs)
  File "/Users/Dennis/Library/Python/3.6/lib/python/site-packages/pywikibot/site.py", line 7911, in editEntity
    data = req.submit()
  File "/Users/Dennis/Library/Python/3.6/lib/python/site-packages/pywikibot/data/api.py", line 2079, in submit
    raise APIError(**result['error'])
pywikibot.data.api.APIError: failed-save: The save has failed. [help:See http://localhost:8181/w/api.php for API usage. Subscribe to the mediawiki-api-announce mailing list at <https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce> for notice of API deprecations and breaking changes.]

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/Dennis/PycharmProjects/wikibaseEditor/main.py", line 26, in <module>
    wikibase_item.editLabels(labels={'en': 'My new property'}, summary='Setting labels')
  File "/Users/Dennis/Library/Python/3.6/lib/python/site-packages/pywikibot/page.py", line 4279, in editLabels
    self.editEntity(data, **kwargs)
  File "/Users/Dennis/Library/Python/3.6/lib/python/site-packages/pywikibot/page.py", line 134, in wrapper
    handle(func, self, *args, **kwargs)
  File "/Users/Dennis/Library/Python/3.6/lib/python/site-packages/pywikibot/page.py", line 126, in handle
    raise pywikibot.OtherPageSaveError(self, err)
pywikibot.exceptions.OtherPageSaveError: Edit to page [[my:Property:-1]] failed:
failed-save: The save has failed. [help:See http://localhost:8181/w/api.php for API usage. Subscribe to the mediawiki-api-announce mailing list at &lt;https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce&gt; for notice of API deprecations and breaking changes.]
CRITICAL: Exiting due to uncaught exception <class 'pywikibot.exceptions.OtherPageSaveError'>

Do you have any clue? I have given the bot full rights, so it should not be that.

Merci
D063520

Event Timeline

Ahhhh, I got it. The problem is that a property with this label is already existing. But the error message is really not clear. I only understood it after sending the same request over the API sandbox. Is there a way to ignore this check and create the property anyway?

Alternatively, is there an option to get the id of the existing Item/Property?

Ok, to give back the error message to the user I propose the following change:

if I modify these lines:
https://github.com/wikimedia/pywikibot/blob/26deab88936cbf85aa24e1ddfc9b62e81d80a9bb/pywikibot/data/api.py#L2040

to

print("result2 ", result)
# Phab. tickets T48535, T64126, T68494, T68619
if code == 'failed-save' and \
   self.action == 'wbeditentity' and \
   self._is_wikibase_error_retryable(result['error']):
   self.wait()
   continue
print("result 3 ", result)

I get:

result2  {'error': {'code': 'failed-save', 'info': 'The save has failed.', 'messages': [{'name': 'wikibase-api-failed-save', 'parameters': [], 'html': {'*': 'The save has failed.'}}, {'name': 'wikibase-validator-label-conflict', 'parameters': ['localisation administrative', 'fr', '[[Property:P27|P27]]'], 'html': {'*': 'Property <a href="/wiki/Property:P27" title="Property:P27">P27</a> already has label "localisation administrative" associated with language code fr.'}}, {'name': 'wikibase-validator-label-conflict', 'parameters': ['located in the administrative territorial entity', 'en', '[[Property:P27|P27]]'], 'html': {'*': 'Property <a href="/wiki/Property:P27" ......................
result 3  {'error': {'code': 'failed-save', 'info': 'The save has failed.', 'help': 'See http://localhost:8181/w/api.php for API usage. Subscribe to the mediawiki-api-announce mailing list at &lt;https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce&gt; for notice of API deprecations and breaking changes.'}}

So the message is eaten up. This happens in the self._is_wikibase_error_retryable function:

https://github.com/wikimedia/pywikibot/blob/26deab88936cbf85aa24e1ddfc9b62e81d80a9bb/pywikibot/data/api.py#L1615

There a pop is used to retrieve the message which is then lost afterwords. Can someone fix this?

I suggest to replace this line:

https://github.com/wikimedia/pywikibot/blob/26deab88936cbf85aa24e1ddfc9b62e81d80a9bb/pywikibot/data/api.py#L1615

with:

messages = None
if 'messages' in error:
            messages = error['messages']
        #messages = error.pop('messages', None)

I suggest to replace this line:

https://github.com/wikimedia/pywikibot/blob/26deab88936cbf85aa24e1ddfc9b62e81d80a9bb/pywikibot/data/api.py#L1615

with:

messages = None
if 'messages' in error:
            messages = error['messages']

Don't see any difference in the result against the current implementation.

Xqt triaged this task as Medium priority.Oct 17 2019, 6:09 AM

The difference is the following .... if you try to put in the wiki twice the same property:

wikibase_property =  pywikibot.PropertyPage(wikibase_repo, "P100", datatype='wikibase-item')
wikibase_property.get()
wikibase_property.editLabels(labels={'en': 'test123'}, summary='Setting labels')

wikibase_property =  pywikibot.PropertyPage(wikibase_repo, "P101", datatype='wikibase-item')
wikibase_property.get()
wikibase_property.editLabels(labels={'en': 'test123'}, summary='Setting labels')

in the new case:

messages = None
if 'messages' in error:
            messages = error['messages']

the error contains the following information:

failed-save: The save has failed. [messages:[{'name': 'wikibase-api-failed-save', 'parameters': [], 'html': {'*': 'The save has failed.'}}, {'name': 'wikibase-validator-label-conflict', 'parameters': ['test123', 'en', '[[Property:P100|P100]]'], 'html': {'*': 'Property <a href="/wiki/Property:P100" title="Property:P100">P100</a> already has label "test123" associated with language code en.'}}]; help:See http://localhost:8181/w/api.php for API usage. Subscribe to the mediawiki-api-announce mailing list at &lt;https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce&gt; for notice of API deprecations and breaking changes.]

in the old case:

messages = error.pop('messages', None)

the error says:

failed-save: The save has failed. [help:See http://localhost:8181/w/api.php for API usage. Subscribe to the mediawiki-api-announce mailing list at &lt;https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce&gt; for notice of API deprecations and breaking changes.]

So the message is removed!!!!!!!!!!!!!!!!!!!!!!
Without message it is difficult to understand what happens and the message contains the entity that is clashing!

The reason is that .pop removes the key "messages" from error (https://www.programiz.com/python-programming/methods/list/pop) while the new implementation does not.

Hello, could we push this change forward?

Nothing to do with Wikibase Release Strategy.
I'm not a pywikibot dev, but this patch looks good.

@Xqt : hi, would you consider again this patch, currently I make this modification locally to have some code running

@Xqt : hi, would you consider again this patch, currently I make this modification locally to have some code running

You can submit patches directly:
https://www.mediawiki.org/wiki/Manual:Pywikibot/Development

They will be reviewed and you will get feedback.

Change 559532 had a related patch set uploaded (by D063520; owner: D063520):
[pywikibot/core@master] Better error message handling, the error is not removed but kept. This was discussed also in https://phabricator.wikimedia.org/T235500.

https://gerrit.wikimedia.org/r/559532

Change 559546 had a related patch set uploaded (by D063520; owner: D063520):
[pywikibot/core@master] Better error message handling, the error is not removed but kept. This was discussed also in https://phabricator.wikimedia.org/T235500.

https://gerrit.wikimedia.org/r/559546

Change 559556 had a related patch set uploaded (by D063520; owner: D063520):
[pywikibot/core@master] Better error message handling, the error is not removed but kept. This was discussed also in https://phabricator.wikimedia.org/T235500.

https://gerrit.wikimedia.org/r/559556

Change 559546 abandoned by Dvorapa:
Better error message handling, the error is not removed but kept. This was discussed also in https://phabricator.wikimedia.org/T235500.

Reason:
Duplicite

https://gerrit.wikimedia.org/r/559546

Change 559556 abandoned by Dvorapa:
Better error message handling, the error is not removed but kept. This was discussed also in https://phabricator.wikimedia.org/T235500.

Reason:
Duplicite

https://gerrit.wikimedia.org/r/559556

Change 559532 had a related patch set uploaded (by Xqt; owner: D063520):
[pywikibot/core@master] Better error message handling, the error is not removed but kept

https://gerrit.wikimedia.org/r/559532

Change 559532 merged by jenkins-bot:
[pywikibot/core@master] Better error message handling, the error is not removed but kept

https://gerrit.wikimedia.org/r/559532