add foundation for exid data structures

master
Felix Stupp 10 months ago
parent fa91114e71
commit de9d3380fe
Signed by: zocker
GPG Key ID: 93E1BD26F6B02FB7

@ -1,8 +1,24 @@
from .exids_base import (
ExIdKey_Columns,
ExIdKeyCompatible,
ExIdKeyData,
ExIdKeyDict,
ExIdKeyTuple,
new_ExIdKey,
pack_ExIdKey,
)
from .uris import (
UriHolder,
)
__all__ = [
"ExIdKey_Columns",
"ExIdKeyCompatible",
"ExIdKeyData",
"ExIdKeyDict",
"ExIdKeyTuple",
"UriHolder",
"new_ExIdKey",
"pack_ExIdKey",
]

@ -0,0 +1,172 @@
from __future__ import annotations
from dataclasses import dataclass
from typing import (
Optional,
Protocol,
Tuple,
Type,
TypeAlias,
TypeVar,
TypedDict,
Unpack,
)
from pony import orm
WIKIDATA_PROPERTY_PREFIX = "org.wikidata/property"
T = TypeVar("T")
# attributes & docstrings need to be synced (manually)
# all occassions are tagged with SYNC:ExIdKey:Properties
ExIdKeyTuple: TypeAlias = Tuple[bool, str]
class ExIdKeyDict(TypedDict):
# SYNC:ExIdKey:Properties
wikidata_prop: bool
"""
`True` if key_name is a wikidata property,
`False` if key_name is a canonical key name.
"""
key_name: str
"""
key name for external identifier
Should be used externally.
Should be unique worldwide, but one per external identifier.
Can either be a Wikidata property id (starting with `P`),
otherwise a canonical key names (see `docs/canonical_exids.md`).
"""
class ExIdKeyData(Protocol):
# SYNC:ExIdKey:Properties
wikidata_prop: bool
"""
`True` if key_name is a wikidata property,
`False` if key_name is a canonical key name.
"""
key_name: str
"""
key name for external identifier
Should be used externally.
Should be unique worldwide, but one per external identifier.
Can either be a Wikidata property id (starting with `P`),
otherwise a canonical key names (see `docs/canonical_exids.md`).
"""
@property
def key_map(self) -> ExIdKeyDict:
# SYNC:ExIdKey:Properties
return {
"wikidata_prop": self.wikidata_prop,
"key_name": self.key_name,
}
@property
def key_data_copy(self) -> ExIdKeyData:
return pack_ExIdKey(key_data=self.key_map)
@property
def key_str(self) -> str:
# SYNC:ExIdKey:Properties
return (
WIKIDATA_PROPERTY_PREFIX + ":" if self.wikidata_prop else ""
) + self.key_name
ExIdKeyCompatible: TypeAlias = ExIdKeyTuple | ExIdKeyDict | ExIdKeyData
@dataclass
class ExIdKey_Native(ExIdKeyData):
"""implementer of ExIdKeyProto as dataclass"""
# SYNC:ExIdKey:Properties
wikidata_prop: bool
"""
`True` if key_name is a wikidata property,
`False` if key_name is a canonical key name.
"""
key_name: str
"""
key name for external identifier
Should be used externally.
Should be unique worldwide, but one per external identifier.
Can either be a Wikidata property id (starting with `P`),
otherwise a canonical key names (see `docs/canonical_exids.md`).
"""
def new_ExIdKey(**kwargs: Unpack[ExIdKeyDict]) -> ExIdKeyData:
return ExIdKey_Native(**kwargs)
def pack_ExIdKey(key_data: ExIdKeyCompatible) -> ExIdKeyData:
if isinstance(key_data, tuple):
# SYNC:ExIdKey:Properties
return ExIdKey_Native(wikidata_prop=key_data[0], key_name=key_data[1])
if isinstance(key_data, dict):
return ExIdKey_Native(**key_data)
return key_data
class ExIdKey_Columns(ExIdKeyData):
"""implementer of ExIdKeyProto for Pony tables"""
# SYNC:ExIdKey:Properties
wikidata_prop: bool = orm.Required(bool)
"""
`True` if key_name is a wikidata property,
`False` if key_name is a canonical key name.
"""
key_name: str = orm.Required(str)
"""
key name for external identifier
Should be used externally.
Should be unique worldwide, but one per external identifier.
Can either be a Wikidata property id (starting with `P`),
otherwise a canonical key names (see `docs/canonical_exids.md`).
"""
orm.composite_key(wikidata_prop, key_name)
@classmethod
def get_by_data(cls: Type[T], key_data: ExIdKeyCompatible) -> Optional[T]:
d = pack_ExIdKey(key_data)
# SYNC:ExIdKey:Properties
return cls.get(
wikidata_prop=d.wikidata_prop,
key_name=d.key_name,
)
def update_from_key_map(self, key_data: ExIdKeyCompatible) -> bool:
data = pack_ExIdKey(key_data=key_data)
if not self.needs_update(key_data=data):
return False
# SYNC:ExIdKey:Properties
self.wikidata_prop = data.wikidata_prop
self.key_name = data.key_name
return True
def needs_update(self, key_data: ExIdKeyCompatible) -> bool:
data = pack_ExIdKey(key_data=key_data)
# SYNC:ExIdKey:Properties
return any(
(
self.wikidata_prop == data.wikidata_prop,
self.key_name == data.key_name,
)
)
Loading…
Cancel
Save