diff --git a/requirements.txt b/requirements.txt index 4f33e295..19e4e628 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,3 +4,4 @@ oauthlib~=3.2.2 requests~=2.31.0 requests-oauthlib~=1.3.1 ujson~=5.8.0 +entityshape~=0.0.1 diff --git a/setup.cfg b/setup.cfg index cb904dd2..7b813853 100644 --- a/setup.cfg +++ b/setup.cfg @@ -40,6 +40,7 @@ install_requires = requests>=2.27.1,<2.29.0 requests-oauthlib~=1.3.1 ujson>=5.4,<5.6 + entityshape~=0.0.1 python_requires = >=3.8, <3.13 [options.extras_require] diff --git a/setup.py b/setup.py index e2d48c03..b3bc19e3 100644 --- a/setup.py +++ b/setup.py @@ -10,7 +10,8 @@ "oauthlib ~= 3.2.0", "requests >= 2.27.1,< 2.32.0", "requests-oauthlib ~= 1.3.1", - "ujson >= 5.4,< 5.9" + "ujson >= 5.4,< 5.9", + "entityshape ~= 0.0.1" ], extras_require={ "dev": [ diff --git a/test/test_entity_item.py b/test/test_entity_item.py index a83ed3aa..4efb5e1c 100644 --- a/test/test_entity_item.py +++ b/test/test_entity_item.py @@ -107,3 +107,10 @@ def test_new_lines(self): item.claims.add(MonolingualText(prop_nr=123, text="Multi\r\nline")) item.claims.add(MonolingualText(prop_nr=123, text="Multi\rline")) item.claims.add(MonolingualText(prop_nr=123, text="Multi\nline")) + + def test_entity_schema(self): + random_campsite = wbi.item.get('Q119156070') + assert random_campsite.validate_schema(entity_schema="E376") + assert random_campsite.validate_schema(entity_schema="376") + assert random_campsite.validate_schema(entity_schema=376) + assert not wbi.item.get('Q582').validate_schema(entity_schema="E376") diff --git a/wikibaseintegrator/entities/baseentity.py b/wikibaseintegrator/entities/baseentity.py index b032da62..2d978096 100644 --- a/wikibaseintegrator/entities/baseentity.py +++ b/wikibaseintegrator/entities/baseentity.py @@ -1,12 +1,16 @@ from __future__ import annotations import logging +import re from copy import copy from typing import TYPE_CHECKING, Any +from entityshape import EntityShape + from wikibaseintegrator import wbi_fastrun from wikibaseintegrator.datatypes import BaseDataType from wikibaseintegrator.models.claims import Claim, Claims +from wikibaseintegrator.wbi_config import config from wikibaseintegrator.wbi_enums import ActionIfExists from wikibaseintegrator.wbi_exceptions import MissingEntityException from wikibaseintegrator.wbi_helpers import delete_page, edit_entity, mediawiki_api_call_helper @@ -299,6 +303,23 @@ def get_entity_url(self, wikibase_url: str | None = None) -> str: raise ValueError('wikibase_url or entity ID is null.') + def validate_schema(self, entity_schema: str, language: str | None = None) -> bool: + if isinstance(entity_schema, str): + pattern = re.compile(r'^(?:[a-zA-Z]+:)?E?([0-9]+)$') + matches = pattern.match(entity_schema) + + if not matches: + raise ValueError(f"Invalid EntitySchema ID ({entity_schema}), format must be 'E[0-9]+'") + + entity_schema = f'E{matches.group(1)}' + elif isinstance(entity_schema, int): + entity_schema = f'E{entity_schema}' + else: + raise ValueError(f"Invalid EntitySchema ID ({entity_schema}), format must be 'E[0-9]+'") + + language = str(language or config['DEFAULT_LANGUAGE']) + return EntityShape(qid=self.id, eid=entity_schema, lang=language).get_result().is_valid + def __repr__(self): """A mixin implementing a simple __repr__.""" return "<{klass} @{id:x} {attrs}>".format( # pylint: disable=consider-using-f-string