"""Vocabulary Models for Ontology Sources"""
import datetime
from typing import TYPE_CHECKING, List, Optional
from pydantic import ConfigDict, BaseModel, Field
from ...models.base import LogLevel
if TYPE_CHECKING:
from . import Vocabulary, IdType, LoggingLevel
[docs]class DependencyStatement(BaseModel):
"""Information about one dependency statement in the source
A dependency is a reference of one iri in an other entity definition
"""
source_iri: str = Field(
default="",
description="Iri of the source containing the statement")
source_name: str = Field(
default="",
description="Name of the source containing the statement")
type: str = Field(
description="Possible types: Parent Class, Relation Property, "
"Relation Target")
class_iri: str = Field(
description="Iri of the class containing the statement")
dependency_iri: str = Field(description="Entity Iri of the dependency")
fulfilled: bool = Field(
description="True if the dependency_iri is registered in the "
"vocabulary")
[docs]class ParsingError(BaseModel):
"""Object represents one issue that arose while parsing a source,
and holds all relevant details for that issue"""
model_config = ConfigDict(use_enum_values=True)
level: LogLevel = Field(description="Severity of error")
source_iri: str = Field(description=
"Iri of the source containing the error")
source_name: Optional[str] = Field(
default=None,
description="Name of the source, only set in get_function"
)
entity_type: str = Field(
description="Type of the problematic entity: Class, Individual,.."
"ID_type in string form"
)
entity_iri: str = Field(description="Iri of the problematic entity")
entity_label: Optional[str] = Field(
default=None,
description="Name of the source, only set in get_function"
)
message: str = Field(
description="Message describing the error"
)
[docs]class Source(BaseModel):
"""
A source represent one file that was provided via file upload or link to the
project and is parsed into the
vocabulary
"""
id: str = Field(default="",
description="unique ID of the source; for internal use")
source_name: str = Field(default="",
description="Name of the source ")
content: str = Field(
default="",
description="File content of the provided ontology file")
parsing_log: List['ParsingError'] = Field(
default=[],
description="Log containing all issues that were discovered while "
"parsing")
dependency_statements: List[DependencyStatement] = Field(
default=[],
description="List of all statements in source")
timestamp: datetime.datetime = Field(
description="timestamp when the source was added to the project")
ontology_iri: str = Field(
default=None,
description="Iri of the ontology of the source")
predefined: bool = Field(
default=False,
description="Stating if the source is a predefined source; "
"a predefined source is added to each project containing "
"owl:Thing and predefined Datatypes")
[docs] def get_number_of_id_type(self, vocabulary: 'Vocabulary',
id_type: 'IdType') -> int:
"""Get the number how many entities of a given type are created by or
influenced by this source
Args:
vocabulary (Vocabulary): Vocabulary of this project
id_type (IdType): Idtype that should be counted
Returns:
int
"""
from . import IdType
id_func = "/"
iri_list = []
if id_type is IdType.class_:
id_func = vocabulary.get_class_by_iri
iri_list = vocabulary.classes
elif id_type is IdType.object_property:
id_func = vocabulary.get_object_property
iri_list = vocabulary.object_properties
elif id_type is IdType.data_property:
id_func = vocabulary.get_data_property
iri_list = vocabulary.data_properties
elif id_type is IdType.individual:
id_func = vocabulary.get_individual
iri_list = vocabulary.individuals
elif id_type is IdType.datatype:
id_func = vocabulary.get_datatype
iri_list = vocabulary.datatypes
if id_func == "/":
return -1
counter = 0
for iri in iri_list:
entity = id_func(iri)
if self.id in entity.source_ids:
counter += 1
return counter
[docs] def get_name(self) -> str:
"""Get the name of the source
Returns:
str
"""
return self.source_name
[docs] def treat_dependency_statements(self, vocabulary: 'Vocabulary'):
"""
Log and purge all pointers/iris in entities that are not contained
in the vocabulary
Args:
vocabulary (Vocabulary): Vocabulary of this project
Returns:
None
"""
dependency_statements = []
for class_ in vocabulary.get_classes():
if self.id in class_.source_ids:
dependency_statements.extend(
class_.treat_dependency_statements(vocabulary))
for individual_iri in vocabulary.individuals:
individual = vocabulary.get_individual(individual_iri)
if self.id in individual.source_ids:
dependency_statements.extend(
individual.treat_dependency_statements(vocabulary))
for statement in dependency_statements:
statement.source_iri = self.ontology_iri
statement.source_name = self.source_name
self.dependency_statements = dependency_statements
[docs] def add_parsing_log_entry(self, level: 'LoggingLevel', entity_type: 'IdType',
entity_iri: str, msg: str):
"""
Add a parsing log entry for an entity, if an issue in parsing
was discovered
Args:
level (LoggingLevel): Logging level of the entry
entity_type (IdType): Type of the enitity (Class, Individual,..)
entity_iri (str): iri of the entity
msg (str): message to display in log
Returns:
None
"""
from . import ParsingError
self.parsing_log.append(ParsingError(
level=level,
entity_type=str(entity_type),
entity_iri=entity_iri,
message=msg,
source_iri=self.ontology_iri
))
[docs] def get_parsing_log(self, vocabulary: 'Vocabulary') -> List['ParsingError']:
"""Get the Parsinglog, where the labels of the entities are filled in
Args:
vocabulary (Vocabulary): Vocabulary of this project
Returns:
List[Dict[str, Union[LoggingLevel,'IdType',str]]]
"""
for entry in self.parsing_log:
entry.source_name = self.source_name
try:
label = vocabulary.get_label_for_entity_iri(entry.entity_iri)
entry.entity_label = label
except Exception:
pass
return self.parsing_log
[docs] def clear(self):
"""Clear all logging and dependency data of the source
Returns:
None
"""
self.parsing_log = []
self.dependency_statements = []