from __future__ import annotations
import re
from typing import Any
from wikibaseintegrator.entities.baseentity import BaseEntity
from wikibaseintegrator.models.aliases import Aliases
from wikibaseintegrator.models.descriptions import Descriptions
from wikibaseintegrator.models.labels import Labels
from wikibaseintegrator.wbi_enums import WikibaseDatatype
[docs]
class PropertyEntity(BaseEntity):
ETYPE = 'property'
[docs]
def __init__(self, datatype: str | WikibaseDatatype | None = None, labels: Labels | None = None, descriptions: Descriptions | None = None, aliases: Aliases | None = None, **kwargs: Any):
super().__init__(**kwargs)
# Property specific
self.datatype = datatype
# Item, Property and MediaInfo specific
self.labels: Labels = labels or Labels()
self.descriptions: Descriptions = descriptions or Descriptions()
self.aliases = aliases or Aliases()
@BaseEntity.id.setter # type: ignore
def id(self, value: None | str | int):
if isinstance(value, str):
pattern = re.compile(r'^(?:[a-zA-Z]+:)?P?([0-9]+)$')
matches = pattern.match(value)
if not matches:
raise ValueError(f"Invalid property ID ({value}), format must be 'P[0-9]+'")
value = f'P{matches.group(1)}'
elif isinstance(value, int):
value = f'P{value}'
elif value is None:
pass
else:
raise ValueError(f"Invalid property ID ({value}), format must be 'P[0-9]+'")
BaseEntity.id.fset(self, value) # type: ignore
@property
def datatype(self) -> str | WikibaseDatatype | None:
return self.__datatype
@datatype.setter
def datatype(self, value: str | WikibaseDatatype | None):
if isinstance(value, str):
self.__datatype: str | WikibaseDatatype | None = WikibaseDatatype(value)
else:
self.__datatype = value
@property
def labels(self) -> Labels:
return self.__labels
@labels.setter
def labels(self, labels: Labels):
if not isinstance(labels, Labels):
raise TypeError
self.__labels = labels
@property
def descriptions(self) -> Descriptions:
return self.__descriptions
@descriptions.setter
def descriptions(self, descriptions: Descriptions):
if not isinstance(descriptions, Descriptions):
raise TypeError
self.__descriptions = descriptions
@property
def aliases(self) -> Aliases:
return self.__aliases
@aliases.setter
def aliases(self, aliases: Aliases):
if not isinstance(aliases, Aliases):
raise TypeError
self.__aliases = aliases
[docs]
def new(self, **kwargs: Any) -> PropertyEntity:
return PropertyEntity(api=self.api, **kwargs)
[docs]
def get(self, entity_id: str | int, **kwargs: Any) -> PropertyEntity:
if isinstance(entity_id, str):
pattern = re.compile(r'^(?:[a-zA-Z]+:)?P?([0-9]+)$')
matches = pattern.match(entity_id)
if not matches:
raise ValueError(f"Invalid property ID ({entity_id}), format must be 'P[0-9]+'")
entity_id = int(matches.group(1))
if entity_id < 1:
raise ValueError("Property ID must be greater than 0")
entity_id = f'P{entity_id}'
json_data = super()._get(entity_id=entity_id, **kwargs)
return PropertyEntity(api=self.api).from_json(json_data=json_data['entities'][entity_id])
[docs]
def get_json(self) -> dict[str, str | Any]:
json = {
'labels': self.labels.get_json(),
'descriptions': self.descriptions.get_json(),
'aliases': self.aliases.get_json(),
**super().get_json()
}
if self.datatype and isinstance(self.datatype, WikibaseDatatype):
json.update({'datatype': self.datatype.value})
return json
[docs]
def from_json(self, json_data: dict[str, Any]) -> PropertyEntity:
super().from_json(json_data=json_data)
if 'datatype' in json_data:
self.datatype = json_data['datatype']
if 'labels' in json_data:
self.labels = Labels().from_json(json_data['labels'])
if 'descriptions' in json_data:
self.descriptions = Descriptions().from_json(json_data['descriptions'])
if 'aliases' in json_data:
self.aliases = Aliases().from_json(json_data['aliases'])
return self
[docs]
def write(self, **kwargs: Any) -> PropertyEntity:
"""
Write the PropertyEntity data to the Wikibase instance and return the PropertyEntity object returned by the instance.
:param data: The serialized object that is used as the data source. A newly created entity will be assigned an 'id'.
:param summary: A summary of the edit
:param login: A login instance
:param allow_anonymous: Force a check if the query can be anonymous or not
:param clear: Clear the existing entity before updating
:param is_bot: Add the bot flag to the query
:param kwargs: More arguments for Python requests
:return: an PropertyEntity of the response from the instance
"""
json_data = super()._write(data=self.get_json(), **kwargs)
return self.from_json(json_data=json_data)