Skip to content

Commit

Permalink
support different ontologies
Browse files Browse the repository at this point in the history
  • Loading branch information
jnussbaum committed Oct 26, 2024
1 parent 51c7bee commit bd64e63
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 22 deletions.
49 changes: 34 additions & 15 deletions dsp_permissions_scripts/doap/doap_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from pydantic import BaseModel
from pydantic import model_validator

from dsp_permissions_scripts.models.group import PREFIXED_IRI_REGEX
from dsp_permissions_scripts.models.group import Group
from dsp_permissions_scripts.models.scope import PermissionScope

Expand All @@ -26,7 +27,8 @@ class GroupDoapTarget(BaseModel):
class EntityDoapTarget(BaseModel):
"""
Note that the resclass IRIs and property IRIs are in the environment-agnostic format
"http://www.knora.org/ontology/<shortcode>/<ontoname>#<classname_or_property_name>"
"http://www.knora.org/ontology/<shortcode>/<ontoname>#<classname_or_property_name>" or
"http://api.knora.org/ontology/knora-api/v2#<knora_base_class>"
"""

project_iri: str
Expand All @@ -41,12 +43,22 @@ def _validate(self) -> Self:

@model_validator(mode="after")
def _validate_iri_format(self) -> Self:
rgx = r"http://www\.knora\.org/ontology/[A-Fa-f0-9]{4}/[^/#]+#[^/#]+"
iri_format = "http://www.knora.org/ontology/<shortcode>/<ontoname>#<classname_or_property_name>"
if self.resclass_iri and not re.search(rgx, self.resclass_iri):
raise ValueError(f"The IRI must be in the format '{iri_format}', but you provided {self.resclass_iri}")
if self.property_iri and not re.search(rgx, self.property_iri):
raise ValueError(f"The IRI must be in the format '{iri_format}', but you provided {self.property_iri}")
regexes = [
r"^http://www\.knora\.org/ontology/[A-Fa-f0-9]{4}/[^/#]+#[^/#]+$",
r"^http://api\.knora\.org/ontology/knora-api/v2#[^/#]+$",
]
iri_formats = [
"http://www.knora.org/ontology/<shortcode>/<ontoname>#<classname_or_property_name>",
"http://api.knora.org/ontology/knora-api/v2#<knora_base_class>",
]
if self.resclass_iri and not any(re.search(r, self.resclass_iri) for r in regexes):
raise ValueError(
f"The IRI must be in one of the formats {iri_formats}, but you provided {self.resclass_iri}"
)
if self.property_iri and not any(re.search(r, self.property_iri) for r in regexes):
raise ValueError(
f"The IRI must be in one of the formats {iri_formats}, but you provided {self.property_iri}"
)
return self


Expand All @@ -59,20 +71,27 @@ class NewGroupDoapTarget(BaseModel):
class NewEntityDoapTarget(BaseModel):
"""Represents the target of a DOAP that is yet to be created."""

onto_name: str
resclass_name: str | None = None
property_name: str | None = None
prefixed_class: str | None = None
prefixed_prop: str | None = None

@model_validator(mode="after")
def _validate(self) -> Self:
if self.resclass_name is None and self.property_name is None:
if self.prefixed_class is None and self.prefixed_prop is None:
raise ValueError("At least one of resource_class or property must be set")
return self

@model_validator(mode="after")
def _validate_name_format(self) -> Self:
if self.resclass_name and any([x in self.resclass_name for x in ["#", "/", "knora.org", "dasch.swiss"]]):
raise ValueError(f"The resource class name must not be a full IRI, but you provided {self.resclass_name}")
if self.property_name and any([x in self.property_name for x in ["#", "/", "knora.org", "dasch.swiss"]]):
raise ValueError(f"The property name must not be a full IRI, but you provided {self.property_name}")
if self.prefixed_class and any([x in self.prefixed_class for x in ["#", "/", "knora.org", "dasch.swiss"]]):
raise ValueError(f"The resource class name must not be a full IRI, but you provided {self.prefixed_class}")
if self.prefixed_class and not re.search(PREFIXED_IRI_REGEX, self.prefixed_class):
raise ValueError(
"The resource class name must be in the format 'onto:resclass_name', "
f"but you provided {self.prefixed_class}"
)
if self.prefixed_prop and any([x in self.prefixed_prop for x in ["#", "/", "knora.org", "dasch.swiss"]]):
raise ValueError(f"The property name must not be a full IRI, but you provided {self.prefixed_prop}")
if self.prefixed_prop and not re.search(PREFIXED_IRI_REGEX, self.prefixed_prop):
msg = f"The property name must be in the format 'onto:resclass_name', but you provided {self.prefixed_prop}"
raise ValueError(msg)
return self
15 changes: 9 additions & 6 deletions dsp_permissions_scripts/doap/doap_set.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,11 @@ def create_new_doap_on_server(
if isinstance(target, NewGroupDoapTarget):
forGroup = get_full_iri_from_prefixed_iri(target.group.prefixed_iri)
forResourceClass = None
if isinstance(target, NewEntityDoapTarget) and target.resclass_name:
forResourceClass = _get_internal_iri_from_name(target.resclass_name, shortcode, target.onto_name)
if isinstance(target, NewEntityDoapTarget) and target.prefixed_class:
forResourceClass = _get_internal_iri_from_name(target.prefixed_class, shortcode)
forProperty = None
if isinstance(target, NewEntityDoapTarget) and target.property_name:
forProperty = _get_internal_iri_from_name(target.property_name, shortcode, target.onto_name)
if isinstance(target, NewEntityDoapTarget) and target.prefixed_prop:
forProperty = _get_internal_iri_from_name(target.prefixed_prop, shortcode)
payload = {
"forGroup": forGroup,
"forProject": proj_iri,
Expand All @@ -73,5 +73,8 @@ def create_new_doap_on_server(
return None


def _get_internal_iri_from_name(name: str, proj_shortcode: str, ontoname: str) -> str:
return f"http://www.knora.org/ontology/{proj_shortcode}/{ontoname}#{name}"
def _get_internal_iri_from_name(prefixed_name: str, proj_shortcode: str) -> str:
onto, name = prefixed_name.split(":")
if onto == "knora-api":
return f"http://api.knora.org/ontology/knora-api/v2#{name}"
return f"http://www.knora.org/ontology/{proj_shortcode}/{onto}#{name}"
2 changes: 1 addition & 1 deletion tests/test_doap_set.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ def test_create_doap_for_resclass(
) -> None:
dsp_client = Mock(post=Mock(return_value=response_for_resclass))
_ = create_new_doap_on_server(
target=NewEntityDoapTarget(onto_name=ONTO_NAME, resclass_name=MY_RESCLASS_NAME),
target=NewEntityDoapTarget(prefixed_class=f"{ONTO_NAME}:{MY_RESCLASS_NAME}"),
shortcode=SHORTCODE,
scope=PermissionScope.create(V=[group.UNKNOWN_USER]),
dsp_client=dsp_client,
Expand Down

0 comments on commit bd64e63

Please sign in to comment.