API Documentation
This part of the project documentation focuses on
an information-oriented approach. Use it as a
reference for the technical implementation of the
pylobid
project code.
pylobid
main module
GNDAPIError
Bases: Exception
Broad exception if something unexpected happens.
Source code in pylobid/pylobid.py
class GNDAPIError(Exception):
"""Broad exception if something unexpected happens."""
GNDIdError
Bases: ValueError
Exception raised if the GND-ID is invalid.
Source code in pylobid/pylobid.py
class GNDIdError(ValueError):
"""Exception raised if the GND-ID is invalid."""
GNDNotFoundError
Bases: Exception
Exception raised if the API returns Not Found for a GND-ID.
Source code in pylobid/pylobid.py
class GNDNotFoundError(Exception):
"""Exception raised if the API returns Not Found for a GND-ID."""
PyLobidClient
Main Class to interact with LOBID-API.
Source code in pylobid/pylobid.py
class PyLobidClient:
"""Main Class to interact with LOBID-API."""
def factory(self):
"""Return a matching instance for the GND URL or ID.
- Type `PlaceOrGeographicName` returns a `PyLobidPlace` instance.
- Type `CorporateBody` returns a `PyLobidOrg` instance.
- Type `Person` returns a `PyLobidPerson` instance.
- Type `Work` returns a `PyLobidWork` instance.
- All other types a `PyLobidPerson` instance
:return: An matching object for the GND URL or Id
:rtype: `PyLobidPlace`, `PyLobidOrg`, `PyLobidPerson`, `PyLobidPerson`
"""
if self.ent_dict == {}:
raise ValueError(f"No data found for {self.gnd_url}")
if not self.ent_type:
raise ValueError(f"Unknown type for {self.gnd_url}")
if self.is_person:
output = PyLobidPerson(gnd_id=None, fetch_related=self.fetch_related)
output.process_data(data=self.ent_dict)
elif self.is_org:
output = PyLobidOrg(gnd_id=None)
output.process_data(data=self.ent_dict)
elif self.is_work:
output = PyLobidWork(gnd_id=None)
output.process_data(data=self.ent_dict)
elif self.is_place:
output = PyLobidPlace(gnd_id=None)
output.process_data(data=self.ent_dict)
else:
return self
return output
@property
def gnd_id(self) -> str:
"""Return the GND ID, e.g. 118650130."""
return self.__gnd_id
@property
def gnd_url(self) -> str:
"""Return the GND URL e.g. http://d-nb.info/gnd/118650130"""
return f"{self.BASE_URL}/{self.gnd_id}" if self.gnd_id is not None else False
@property
def is_place(self) -> bool:
"""Return True if this instance is a place entity, False otherwise."""
return "PlaceOrGeographicName" in self.ent_type
@property
def is_org(self) -> bool:
"""Return True if this instance is an organization entity, False otherwise."""
return "CorporateBody" in self.ent_type
@property
def is_person(self) -> bool:
"""Return True if this instance is a person entity, False otherwise."""
return "Person" in self.ent_type
@property
def is_work(self) -> bool:
"""Return True if this instance is a work entity, False otherwise."""
return "Work" in self.ent_type
@property
def ent_type(self) -> list:
"""Return the entity type."""
return self.ent_dict.get("type", [])
@property
def same_as(self) -> list:
"""Return a list of alternative norm-data-ids."""
return self.get_same_as()
@property
def alt_names(self) -> list:
"""Return a list of alternative names."""
return self.get_alt_names()
@property
def pref_name(self) -> str:
"""Return the preferred name."""
return self.get_pref_name()
def extract_id(self, url: str) -> str:
"""Extract the GND-ID from an GND-URL.
:param url: A GND-URL, e.g. http://d-nb.info/gnd/118650130
:type url: str
:raises: GNDIdError if no GND-ID is found.
:return: The GND-ID, e.g. 118650130
:rtype: str
"""
gnd_id = re.search(self.ID_PATTERN, url)
if gnd_id is None:
raise GNDIdError(f'Could not find GND-ID in "{url}"')
return gnd_id.group()
def get_entity_lobid_url(self, url: str) -> str:
"""creates a lobid-entity URL from an GND-URL
:param url: A GND-URL, e.g. http://d-nb.info/gnd/118650130
:type url: str
:return: A LOBID-ENTITY-URL, e.g. http://lobid.org/gnd/116000562
:rtype: str
"""
self.__gnd_id = self.extract_id(url)
return self.gnd_url
def get_entity_json(self, url: str = None) -> dict:
"""Get the LOBID-JSON response of a given GND-URL.
:param url: A GND_URL
:type url: str, optional
:raises: GNDNotFoundError, GNDAPIError
:return: The matching JSON representation fetched from LOBID
:rtype: dict
"""
url = self.gnd_url if url is None else self.get_entity_lobid_url(url)
response = requests.get(url, headers={"Accept": "application/json"})
if response.status_code == 404:
raise GNDNotFoundError(
f'Could not find a GND Entity for ID "{self.gnd_id}"'
)
if not response.ok:
raise GNDAPIError(f"GND API error code: {response.status_code}")
return response.json()
def get_same_as(self) -> list:
"""Get the list of alternative norm-data-ids.
:return: A list of tuples like ('GeoNames', 'http://sws.geonames.org/2782067'),
:rtype: list
"""
return [
(x["collection"].get("abbr", "no_abbr"), x["id"])
for x in self.ent_dict["sameAs"]
]
def get_pref_name(self) -> str:
"""Get the preferred name.
:return: The preferred Name vale, e.g. 'Assmann, Richard'
:rtype: str
"""
result = self.ent_dict.get("preferredName", "")
return result
def get_alt_names(self) -> list:
"""Get the list of alternative names.
:return: a list of alternative names
:rtype: list
"""
ent_dict = self.ent_dict
return next(
iter([match.value for match in self.pref_alt_names_xpath.find(ent_dict)]),
[],
)
def __str__(self) -> str:
return self.BASE_URL
def __repr__(self) -> str:
return f"<PyLobidClient {self.gnd_url}>"
def __init__(self, gnd_id: str = None, fetch_related: bool = False) -> None:
"""Class constructor."""
self.BASE_URL = "http://lobid.org/gnd"
self.ID_PATTERN = r"([0-9]\w*-*[0-9]\w*)"
self.coords_xpath = parse("$..hasGeometry")
self.coords_regex = r"[+|-]\d+(?:\.\d*)?"
self.pref_alt_names_xpath = parse("$.variantName")
self.fetch_related = fetch_related
self.__gnd_id = None
self.ent_dict = {}
self.process_data(gnd_id=gnd_id)
def process_data(self, gnd_id: str = None, data: dict = None) -> None:
"""Fetch and/or process entity data.
The arguments `gnd_id` and `data` are mutually exclusive.
:param gnd_id: any kind of GND_URI/URL
:type gnd_id: str, optional
:param data: an already fetched ent_dict
:type data: dict, optional
"""
if data is not None and gnd_id is not None:
raise ValueError("gnd_id and data mutually exclusive parameters")
if data is not None and "id" in data:
_ = self.get_entity_lobid_url(data.get("id"))
self.ent_dict = data
elif gnd_id is not None:
_ = self.get_entity_lobid_url(gnd_id)
self.ent_dict = self.get_entity_json()
alt_names: list
property
Return a list of alternative names.
ent_type: list
property
Return the entity type.
gnd_id: str
property
Return the GND ID, e.g. 118650130.
gnd_url: str
property
Return the GND URL e.g. http://d-nb.info/gnd/118650130
is_org: bool
property
Return True if this instance is an organization entity, False otherwise.
is_person: bool
property
Return True if this instance is a person entity, False otherwise.
is_place: bool
property
Return True if this instance is a place entity, False otherwise.
is_work: bool
property
Return True if this instance is a work entity, False otherwise.
pref_name: str
property
Return the preferred name.
same_as: list
property
Return a list of alternative norm-data-ids.
__init__(gnd_id=None, fetch_related=False)
Class constructor.
Source code in pylobid/pylobid.py
def __init__(self, gnd_id: str = None, fetch_related: bool = False) -> None:
"""Class constructor."""
self.BASE_URL = "http://lobid.org/gnd"
self.ID_PATTERN = r"([0-9]\w*-*[0-9]\w*)"
self.coords_xpath = parse("$..hasGeometry")
self.coords_regex = r"[+|-]\d+(?:\.\d*)?"
self.pref_alt_names_xpath = parse("$.variantName")
self.fetch_related = fetch_related
self.__gnd_id = None
self.ent_dict = {}
self.process_data(gnd_id=gnd_id)
extract_id(url)
Extract the GND-ID from an GND-URL.
:param url: A GND-URL, e.g. http://d-nb.info/gnd/118650130 :type url: str
:raises: GNDIdError if no GND-ID is found. :return: The GND-ID, e.g. 118650130 :rtype: str
Source code in pylobid/pylobid.py
def extract_id(self, url: str) -> str:
"""Extract the GND-ID from an GND-URL.
:param url: A GND-URL, e.g. http://d-nb.info/gnd/118650130
:type url: str
:raises: GNDIdError if no GND-ID is found.
:return: The GND-ID, e.g. 118650130
:rtype: str
"""
gnd_id = re.search(self.ID_PATTERN, url)
if gnd_id is None:
raise GNDIdError(f'Could not find GND-ID in "{url}"')
return gnd_id.group()
factory()
Return a matching instance for the GND URL or ID.
- Type
PlaceOrGeographicName
returns aPyLobidPlace
instance. - Type
CorporateBody
returns aPyLobidOrg
instance. - Type
Person
returns aPyLobidPerson
instance. - Type
Work
returns aPyLobidWork
instance. - All other types a
PyLobidPerson
instance
:return: An matching object for the GND URL or Id
:rtype: PyLobidPlace
, PyLobidOrg
, PyLobidPerson
, PyLobidPerson
Source code in pylobid/pylobid.py
def factory(self):
"""Return a matching instance for the GND URL or ID.
- Type `PlaceOrGeographicName` returns a `PyLobidPlace` instance.
- Type `CorporateBody` returns a `PyLobidOrg` instance.
- Type `Person` returns a `PyLobidPerson` instance.
- Type `Work` returns a `PyLobidWork` instance.
- All other types a `PyLobidPerson` instance
:return: An matching object for the GND URL or Id
:rtype: `PyLobidPlace`, `PyLobidOrg`, `PyLobidPerson`, `PyLobidPerson`
"""
if self.ent_dict == {}:
raise ValueError(f"No data found for {self.gnd_url}")
if not self.ent_type:
raise ValueError(f"Unknown type for {self.gnd_url}")
if self.is_person:
output = PyLobidPerson(gnd_id=None, fetch_related=self.fetch_related)
output.process_data(data=self.ent_dict)
elif self.is_org:
output = PyLobidOrg(gnd_id=None)
output.process_data(data=self.ent_dict)
elif self.is_work:
output = PyLobidWork(gnd_id=None)
output.process_data(data=self.ent_dict)
elif self.is_place:
output = PyLobidPlace(gnd_id=None)
output.process_data(data=self.ent_dict)
else:
return self
return output
get_alt_names()
Get the list of alternative names.
:return: a list of alternative names :rtype: list
Source code in pylobid/pylobid.py
def get_alt_names(self) -> list:
"""Get the list of alternative names.
:return: a list of alternative names
:rtype: list
"""
ent_dict = self.ent_dict
return next(
iter([match.value for match in self.pref_alt_names_xpath.find(ent_dict)]),
[],
)
get_entity_json(url=None)
Get the LOBID-JSON response of a given GND-URL.
:param url: A GND_URL :type url: str, optional
:raises: GNDNotFoundError, GNDAPIError :return: The matching JSON representation fetched from LOBID :rtype: dict
Source code in pylobid/pylobid.py
def get_entity_json(self, url: str = None) -> dict:
"""Get the LOBID-JSON response of a given GND-URL.
:param url: A GND_URL
:type url: str, optional
:raises: GNDNotFoundError, GNDAPIError
:return: The matching JSON representation fetched from LOBID
:rtype: dict
"""
url = self.gnd_url if url is None else self.get_entity_lobid_url(url)
response = requests.get(url, headers={"Accept": "application/json"})
if response.status_code == 404:
raise GNDNotFoundError(
f'Could not find a GND Entity for ID "{self.gnd_id}"'
)
if not response.ok:
raise GNDAPIError(f"GND API error code: {response.status_code}")
return response.json()
get_entity_lobid_url(url)
creates a lobid-entity URL from an GND-URL
:param url: A GND-URL, e.g. http://d-nb.info/gnd/118650130 :type url: str
:return: A LOBID-ENTITY-URL, e.g. http://lobid.org/gnd/116000562 :rtype: str
Source code in pylobid/pylobid.py
def get_entity_lobid_url(self, url: str) -> str:
"""creates a lobid-entity URL from an GND-URL
:param url: A GND-URL, e.g. http://d-nb.info/gnd/118650130
:type url: str
:return: A LOBID-ENTITY-URL, e.g. http://lobid.org/gnd/116000562
:rtype: str
"""
self.__gnd_id = self.extract_id(url)
return self.gnd_url
get_pref_name()
Get the preferred name.
:return: The preferred Name vale, e.g. 'Assmann, Richard' :rtype: str
Source code in pylobid/pylobid.py
def get_pref_name(self) -> str:
"""Get the preferred name.
:return: The preferred Name vale, e.g. 'Assmann, Richard'
:rtype: str
"""
result = self.ent_dict.get("preferredName", "")
return result
get_same_as()
Get the list of alternative norm-data-ids.
:return: A list of tuples like ('GeoNames', 'http://sws.geonames.org/2782067'), :rtype: list
Source code in pylobid/pylobid.py
def get_same_as(self) -> list:
"""Get the list of alternative norm-data-ids.
:return: A list of tuples like ('GeoNames', 'http://sws.geonames.org/2782067'),
:rtype: list
"""
return [
(x["collection"].get("abbr", "no_abbr"), x["id"])
for x in self.ent_dict["sameAs"]
]
process_data(gnd_id=None, data=None)
Fetch and/or process entity data.
The arguments gnd_id
and data
are mutually exclusive.
:param gnd_id: any kind of GND_URI/URL :type gnd_id: str, optional :param data: an already fetched ent_dict :type data: dict, optional
Source code in pylobid/pylobid.py
def process_data(self, gnd_id: str = None, data: dict = None) -> None:
"""Fetch and/or process entity data.
The arguments `gnd_id` and `data` are mutually exclusive.
:param gnd_id: any kind of GND_URI/URL
:type gnd_id: str, optional
:param data: an already fetched ent_dict
:type data: dict, optional
"""
if data is not None and gnd_id is not None:
raise ValueError("gnd_id and data mutually exclusive parameters")
if data is not None and "id" in data:
_ = self.get_entity_lobid_url(data.get("id"))
self.ent_dict = data
elif gnd_id is not None:
_ = self.get_entity_lobid_url(gnd_id)
self.ent_dict = self.get_entity_json()
PyLobidOrg
Bases: PyLobidClient
A python class representing an Organisation Entity.
Source code in pylobid/pylobid.py
class PyLobidOrg(PyLobidClient):
"""A python class representing an Organisation Entity."""
@property
def located_in(self) -> list:
"""Return a list of locations."""
return self.ent_dict.get("placeOfBusiness", [])
def __repr__(self) -> str:
return f"<PyLobidOrg {self.gnd_url}>"
located_in: list
property
Return a list of locations.
PyLobidPerson
Bases: PyLobidClient
A python class representing a Person Entity.
Source code in pylobid/pylobid.py
class PyLobidPerson(PyLobidClient):
"""A python class representing a Person Entity."""
def get_life_dates(self) -> dict:
"""Get birth- and death dates.
:return: A dict with keys birth_date_str and death_date_str
:rtype: dict
"""
return {
"birth_date_str": next(iter(self.ent_dict.get("dateOfBirth", [])), ""),
"death_date_str": next(iter(self.ent_dict.get("dateOfDeath", [])), ""),
}
def place_of_values(self, place_of: str = "Birth") -> dict:
"""Find values for PlaceOfBirth/Death.
:param place_of: Passed in value concatenates to 'PlaceOfBirth|Death' \
defaults to 'Birth'
:type place_of: str
:return: The ID of the Place
:rtype: dict
"""
value = f"placeOf{place_of}"
result = self.ent_dict.get(value, False)
return result[0] if isinstance(result, list) else {}
def place_of_dict(self, place_of: str = "Birth") -> dict:
"""Get the LOBID-JSON of a PlaceOfBirth|Death (if present).
:param place_of: Passed in value concatenates to 'PlaceOfBirth|Death' \
defaults to 'Birth'
:type place_of: str
:return: The LOBID-JSON of the PlaceOfBirth|Death
:rtype: dict
"""
place_id = self.place_of_values(place_of).get("id")
return {} if place_id is None else PyLobidPlace(place_id).ent_dict
def get_coords_str(self, place_of: str = "Birth") -> str:
"""Get a string of coordinates.
:param place_of: Passed in value concatenates to 'PlaceOfBirth|Death' \
defaults to 'Birth'
:type place_of: str
:return: A string containing coordinates
:rtype: str
"""
place_of_key = "pylobid_born" if place_of == "Birth" else "pylobid_died"
ent_dict = self.ent_dict.get(place_of_key, {})
coords_str = f"{[match.value for match in self.coords_xpath.find(ent_dict)]}"
return coords_str
def get_coords(self, place_of: str = "Birth") -> list:
"""Get a list of coordinates.
:param place_of: Passed in value concatenates to 'PlaceOfBirth|Death' \
defaults to 'Birth'
:type place_of: str
:return: A list of longitude, latitude coords like ['+009.689780', '+051.210970']
:rtype: list
"""
coords_str = self.get_coords_str(place_of=place_of)
return extract_coords(coords_str)
def get_place_alt_name(self, place_of: str = "Birth") -> list:
"""Get the list of alternative names.
:param place_of: Passed in value concatenates to 'PlaceOfBirth|Death' \
defaults to 'Birth'
:type place_of: str
:return: a list of alternative names
:rtype: list
"""
place_of_key = "pylobid_born" if place_of == "Birth" else "pylobid_died"
ent_dict = self.ent_dict.get(place_of_key, {})
return next(
iter([match.value for match in self.pref_alt_names_xpath.find(ent_dict)]),
[],
)
def __str__(self) -> str:
return self.gnd_url
def __repr__(self) -> str:
return f"<PyLobidPerson {self.gnd_url}>"
def process_data(self, gnd_id: str = None, data: dict = None) -> None:
"""Fetch and/or process entity data.
The arguments `gnd_id` and `data` are mutually exclusive.
:param gnd_id: any kind of GND_URI/URL
:type gnd_id: str, optional
:param data: an already fetched ent_dict
:type data: dict, optional
"""
super().process_data(gnd_id=gnd_id, data=data)
if self.ent_dict == {}:
return
if self.is_person:
self.ent_dict.update(pylobid_born={}, pylobid_died={})
self.pref_name_xpath = parse("$.preferredName")
if self.fetch_related and self.is_person:
self.ent_dict["pylobid_born"] = self.place_of_dict()
if self.place_of_values().get("id", "") == self.place_of_values(
place_of="Death"
).get("id", ""):
self.ent_dict["pylobid_died"] = self.ent_dict["pylobid_born"]
else:
self.ent_dict["pylobid_died"] = self.place_of_dict(place_of="Death")
self.birth_place = {
"person_id": self.gnd_id,
"name": self.place_of_values().get("label", ""),
"id": self.place_of_values().get("id", ""),
"coords": self.get_coords(),
"alt_names": self.get_place_alt_name(),
}
self.death_place = {
"person_id": self.gnd_id,
"name": self.place_of_values(place_of="Death").get("label", ""),
"id": self.place_of_values(place_of="Death").get("id", ""),
"coords": self.get_coords(place_of="Death"),
"alt_names": self.get_place_alt_name(place_of="Death"),
}
self.life_span = self.get_life_dates()
get_coords(place_of='Birth')
Get a list of coordinates.
:param place_of: Passed in value concatenates to 'PlaceOfBirth|Death' defaults to 'Birth' :type place_of: str
:return: A list of longitude, latitude coords like ['+009.689780', '+051.210970'] :rtype: list
Source code in pylobid/pylobid.py
def get_coords(self, place_of: str = "Birth") -> list:
"""Get a list of coordinates.
:param place_of: Passed in value concatenates to 'PlaceOfBirth|Death' \
defaults to 'Birth'
:type place_of: str
:return: A list of longitude, latitude coords like ['+009.689780', '+051.210970']
:rtype: list
"""
coords_str = self.get_coords_str(place_of=place_of)
return extract_coords(coords_str)
get_coords_str(place_of='Birth')
Get a string of coordinates.
:param place_of: Passed in value concatenates to 'PlaceOfBirth|Death' defaults to 'Birth' :type place_of: str
:return: A string containing coordinates :rtype: str
Source code in pylobid/pylobid.py
def get_coords_str(self, place_of: str = "Birth") -> str:
"""Get a string of coordinates.
:param place_of: Passed in value concatenates to 'PlaceOfBirth|Death' \
defaults to 'Birth'
:type place_of: str
:return: A string containing coordinates
:rtype: str
"""
place_of_key = "pylobid_born" if place_of == "Birth" else "pylobid_died"
ent_dict = self.ent_dict.get(place_of_key, {})
coords_str = f"{[match.value for match in self.coords_xpath.find(ent_dict)]}"
return coords_str
get_life_dates()
Get birth- and death dates.
:return: A dict with keys birth_date_str and death_date_str :rtype: dict
Source code in pylobid/pylobid.py
def get_life_dates(self) -> dict:
"""Get birth- and death dates.
:return: A dict with keys birth_date_str and death_date_str
:rtype: dict
"""
return {
"birth_date_str": next(iter(self.ent_dict.get("dateOfBirth", [])), ""),
"death_date_str": next(iter(self.ent_dict.get("dateOfDeath", [])), ""),
}
get_place_alt_name(place_of='Birth')
Get the list of alternative names.
:param place_of: Passed in value concatenates to 'PlaceOfBirth|Death' defaults to 'Birth' :type place_of: str
:return: a list of alternative names :rtype: list
Source code in pylobid/pylobid.py
def get_place_alt_name(self, place_of: str = "Birth") -> list:
"""Get the list of alternative names.
:param place_of: Passed in value concatenates to 'PlaceOfBirth|Death' \
defaults to 'Birth'
:type place_of: str
:return: a list of alternative names
:rtype: list
"""
place_of_key = "pylobid_born" if place_of == "Birth" else "pylobid_died"
ent_dict = self.ent_dict.get(place_of_key, {})
return next(
iter([match.value for match in self.pref_alt_names_xpath.find(ent_dict)]),
[],
)
place_of_dict(place_of='Birth')
Get the LOBID-JSON of a PlaceOfBirth|Death (if present).
:param place_of: Passed in value concatenates to 'PlaceOfBirth|Death' defaults to 'Birth' :type place_of: str
:return: The LOBID-JSON of the PlaceOfBirth|Death :rtype: dict
Source code in pylobid/pylobid.py
def place_of_dict(self, place_of: str = "Birth") -> dict:
"""Get the LOBID-JSON of a PlaceOfBirth|Death (if present).
:param place_of: Passed in value concatenates to 'PlaceOfBirth|Death' \
defaults to 'Birth'
:type place_of: str
:return: The LOBID-JSON of the PlaceOfBirth|Death
:rtype: dict
"""
place_id = self.place_of_values(place_of).get("id")
return {} if place_id is None else PyLobidPlace(place_id).ent_dict
place_of_values(place_of='Birth')
Find values for PlaceOfBirth/Death.
:param place_of: Passed in value concatenates to 'PlaceOfBirth|Death' defaults to 'Birth' :type place_of: str
:return: The ID of the Place :rtype: dict
Source code in pylobid/pylobid.py
def place_of_values(self, place_of: str = "Birth") -> dict:
"""Find values for PlaceOfBirth/Death.
:param place_of: Passed in value concatenates to 'PlaceOfBirth|Death' \
defaults to 'Birth'
:type place_of: str
:return: The ID of the Place
:rtype: dict
"""
value = f"placeOf{place_of}"
result = self.ent_dict.get(value, False)
return result[0] if isinstance(result, list) else {}
process_data(gnd_id=None, data=None)
Fetch and/or process entity data.
The arguments gnd_id
and data
are mutually exclusive.
:param gnd_id: any kind of GND_URI/URL :type gnd_id: str, optional :param data: an already fetched ent_dict :type data: dict, optional
Source code in pylobid/pylobid.py
def process_data(self, gnd_id: str = None, data: dict = None) -> None:
"""Fetch and/or process entity data.
The arguments `gnd_id` and `data` are mutually exclusive.
:param gnd_id: any kind of GND_URI/URL
:type gnd_id: str, optional
:param data: an already fetched ent_dict
:type data: dict, optional
"""
super().process_data(gnd_id=gnd_id, data=data)
if self.ent_dict == {}:
return
if self.is_person:
self.ent_dict.update(pylobid_born={}, pylobid_died={})
self.pref_name_xpath = parse("$.preferredName")
if self.fetch_related and self.is_person:
self.ent_dict["pylobid_born"] = self.place_of_dict()
if self.place_of_values().get("id", "") == self.place_of_values(
place_of="Death"
).get("id", ""):
self.ent_dict["pylobid_died"] = self.ent_dict["pylobid_born"]
else:
self.ent_dict["pylobid_died"] = self.place_of_dict(place_of="Death")
self.birth_place = {
"person_id": self.gnd_id,
"name": self.place_of_values().get("label", ""),
"id": self.place_of_values().get("id", ""),
"coords": self.get_coords(),
"alt_names": self.get_place_alt_name(),
}
self.death_place = {
"person_id": self.gnd_id,
"name": self.place_of_values(place_of="Death").get("label", ""),
"id": self.place_of_values(place_of="Death").get("id", ""),
"coords": self.get_coords(place_of="Death"),
"alt_names": self.get_place_alt_name(place_of="Death"),
}
self.life_span = self.get_life_dates()
PyLobidPlace
Bases: PyLobidClient
A python class representing a Place Entity.
Source code in pylobid/pylobid.py
class PyLobidPlace(PyLobidClient):
"""A python class representing a Place Entity."""
def get_coords_str(self) -> str:
"""Get a string of coordinates.
:return: A string containing coordinates
:rtype: str
"""
coords_str = (
f"{[match.value for match in self.coords_xpath.find(self.ent_dict)]}"
)
return coords_str
def get_coords(self) -> list:
"""Get a list of coordinates.
:return: A list of longitude, latitude coords like ['+009.689780', '+051.210970']
:rtype: list
"""
coords_str = self.get_coords_str()
return extract_coords(coords_str)
@property
def coords(self) -> list:
"""Return a list of coordinates."""
return self.get_coords()
def __repr__(self) -> str:
return f"<PyLobidPlace {self.gnd_url}>"
coords: list
property
Return a list of coordinates.
get_coords()
Get a list of coordinates.
:return: A list of longitude, latitude coords like ['+009.689780', '+051.210970'] :rtype: list
Source code in pylobid/pylobid.py
def get_coords(self) -> list:
"""Get a list of coordinates.
:return: A list of longitude, latitude coords like ['+009.689780', '+051.210970']
:rtype: list
"""
coords_str = self.get_coords_str()
return extract_coords(coords_str)
get_coords_str()
Get a string of coordinates.
:return: A string containing coordinates :rtype: str
Source code in pylobid/pylobid.py
def get_coords_str(self) -> str:
"""Get a string of coordinates.
:return: A string containing coordinates
:rtype: str
"""
coords_str = (
f"{[match.value for match in self.coords_xpath.find(self.ent_dict)]}"
)
return coords_str
PyLobidWork
Bases: PyLobidClient
A python class representing a Work Entity
Source code in pylobid/pylobid.py
class PyLobidWork(PyLobidClient):
"""A python class representing a Work Entity"""
@property
def creators(self) -> list:
"""provides a list of dicts providing information of all persons
involved in the creation of the work and their role
Returns:
list: _description_
"""
creators = []
for y in ["firstAuthor", "author", "firstComposer", "librettist"]:
for x in self.ent_dict.get(y, []):
x["role"] = y
creators.append(x)
return creators
@property
def date_of_creation(self) -> str:
"""returns the date of the works creations using `dateOfPublication`
if `dateOfPublication` is not provided `dateOfProduction` is used
Returns:
str: the prodcution or publication date of the work
"""
date = ""
for x in ["dateOfPublication", "dateOfProduction"]:
try:
date = self.ent_dict[x][0]
break
except (KeyError, IndexError):
continue
return date
@property
def date_of_production(self) -> str:
"""returns the date of the works creations using `dateOfProduction`
Returns:
str: the prodcution date of the work
"""
return self.ent_dict.get("dateOfProduction", [""])[0]
@property
def date_of_publication(self) -> str:
"""returns the date of the works creations using `dateOfPublication`
Returns:
str: the publication date of the work
"""
return self.ent_dict.get("dateOfPublication", [""])[0]
creators: list
property
provides a list of dicts providing information of all persons involved in the creation of the work and their role
Returns: |
|
---|
date_of_creation: str
property
returns the date of the works creations using dateOfPublication
if dateOfPublication
is not provided dateOfProduction
is used
Returns: |
|
---|
date_of_production: str
property
returns the date of the works creations using dateOfProduction
Returns: |
|
---|
date_of_publication: str
property
returns the date of the works creations using dateOfPublication
Returns: |
|
---|
pylobid.utils
some (one) utility function
extract_coords(some_str)
Utility function to extract coordinates from a (WKT) string
:param some_str: A string providing coordinates :type some_str: str
:return: A list with the coordinates :rtype: list
Source code in pylobid/utils.py
def extract_coords(some_str: str) -> list:
"""Utility function to extract coordinates from a (WKT) string
:param some_str: A string providing coordinates
:type some_str: str
:return: A list with the coordinates
:rtype: list
"""
regex = r"[+|-]\d+(?:\.\d*)?"
matches = re.findall(regex, some_str, re.MULTILINE)
return matches
pylobid.validators
WTForms GND validator module.
WTForms GND validator module.
GNDOrgEntity
Bases: GNDValidator
Validator for org. entities.
:param: Message to display if validation fails. :raises: ValidationError is the GND type does not match the set entity type.
Source code in pylobid/validators.py
class GNDOrgEntity(GNDValidator):
"""Validator for org. entities.
:param: Message to display if validation fails.
:raises: ValidationError is the GND type does not match the set entity type.
"""
def __init__(self, message: str = None) -> None:
"""Class constructor."""
super().__init__(entity_flag="is_org", message=message)
self.message = message or "The provided GND ID is not an organization entity"
__init__(message=None)
Class constructor.
Source code in pylobid/validators.py
def __init__(self, message: str = None) -> None:
"""Class constructor."""
super().__init__(entity_flag="is_org", message=message)
self.message = message or "The provided GND ID is not an organization entity"
GNDPersonEntity
Bases: GNDValidator
Validator class for person entities.
:param: Message to display if validation fails. :raises: ValidationError is the GND type does not match the set entity type.
Source code in pylobid/validators.py
class GNDPersonEntity(GNDValidator):
"""Validator class for person entities.
:param: Message to display if validation fails.
:raises: ValidationError is the GND type does not match the set entity type.
"""
def __init__(self, message: str = None) -> None:
"""Class constructor."""
super().__init__(entity_flag="is_person")
self.message = message or "The provided GND ID is not a person entity"
__init__(message=None)
Class constructor.
Source code in pylobid/validators.py
def __init__(self, message: str = None) -> None:
"""Class constructor."""
super().__init__(entity_flag="is_person")
self.message = message or "The provided GND ID is not a person entity"
GNDPlaceEntity
Bases: GNDValidator
Validator class for place entities.
:param: Message to display if validation fails. :raises: ValidationError is the GND type does not match the set entity type.
Source code in pylobid/validators.py
class GNDPlaceEntity(GNDValidator):
"""Validator class for place entities.
:param: Message to display if validation fails.
:raises: ValidationError is the GND type does not match the set entity type.
"""
def __init__(self, message: str = None) -> None:
"""Class constructor."""
super().__init__(entity_flag="is_place")
self.message = message or "The provided GND ID is not a place entity"
__init__(message=None)
Class constructor.
Source code in pylobid/validators.py
def __init__(self, message: str = None) -> None:
"""Class constructor."""
super().__init__(entity_flag="is_place")
self.message = message or "The provided GND ID is not a place entity"
GNDValidator
Base class for GND validators.
:param: Message to display if validation fails. :raises: ValidationError is the GND type does not match the set entity type.
Source code in pylobid/validators.py
class GNDValidator:
"""Base class for GND validators.
:param: Message to display if validation fails.
:raises: ValidationError is the GND type does not match the set entity type.
"""
def __init__(self, entity_flag: str = None, message: str = None) -> None:
"""Class constructor."""
self.entity_flag = entity_flag
self.message = message
def __call__(self, form: wtforms.form.Form, field: GNDWTFormsFields) -> None:
"""Class call method.
:param form: A WTForms Form instance.
:param field: A WTForm Form Field instance.
:raises: ValidationError is the GND type does not match the set entity type.
"""
try:
gnd_entity = pylobid.PyLobidClient(field.data).factory()
except pylobid.GNDIdError as error:
raise wtforms.validators.ValidationError(
f"{field.data} is not a valid GND Id/URL"
) from error
except pylobid.GNDNotFoundError as error:
raise wtforms.validators.ValidationError(error) from error
if not gnd_entity.ent_type:
raise wtforms.validators.ValidationError(
f"Unknown GND type for {gnd_entity.gnd_url}"
)
if self.entity_flag is not None and not getattr(
gnd_entity, self.entity_flag, False
):
self.message = f"Entity type {gnd_entity.ent_type}"
raise wtforms.validators.ValidationError(self.message)
__call__(form, field)
Class call method.
:param form: A WTForms Form instance. :param field: A WTForm Form Field instance. :raises: ValidationError is the GND type does not match the set entity type.
Source code in pylobid/validators.py
def __call__(self, form: wtforms.form.Form, field: GNDWTFormsFields) -> None:
"""Class call method.
:param form: A WTForms Form instance.
:param field: A WTForm Form Field instance.
:raises: ValidationError is the GND type does not match the set entity type.
"""
try:
gnd_entity = pylobid.PyLobidClient(field.data).factory()
except pylobid.GNDIdError as error:
raise wtforms.validators.ValidationError(
f"{field.data} is not a valid GND Id/URL"
) from error
except pylobid.GNDNotFoundError as error:
raise wtforms.validators.ValidationError(error) from error
if not gnd_entity.ent_type:
raise wtforms.validators.ValidationError(
f"Unknown GND type for {gnd_entity.gnd_url}"
)
if self.entity_flag is not None and not getattr(
gnd_entity, self.entity_flag, False
):
self.message = f"Entity type {gnd_entity.ent_type}"
raise wtforms.validators.ValidationError(self.message)
__init__(entity_flag=None, message=None)
Class constructor.
Source code in pylobid/validators.py
def __init__(self, entity_flag: str = None, message: str = None) -> None:
"""Class constructor."""
self.entity_flag = entity_flag
self.message = message