diff --git a/src/dsp_tools/models/group.py b/src/dsp_tools/models/group.py
index b90ef73f7..36f191de6 100644
--- a/src/dsp_tools/models/group.py
+++ b/src/dsp_tools/models/group.py
@@ -94,7 +94,7 @@ def __init__(
self._name = str(name) if name is not None else None
self._descriptions = LangString(descriptions)
if project is not None and isinstance(project, Project):
- self._project = project.id
+ self._project = project.iri
else:
self._project = str(project) if project is not None else None
self._selfjoin = bool(selfjoin) if selfjoin is not None else None
@@ -152,12 +152,6 @@ def status(self, value: bool) -> None:
self._status = value
self._changed.add("status")
- def has_changed(self) -> bool:
- if self._changed:
- return True
- else:
- return False
-
@classmethod
def fromJsonObj(cls, con: Connection, json_obj: Any):
group_id = json_obj.get("id")
diff --git a/src/dsp_tools/models/listnode.py b/src/dsp_tools/models/listnode.py
index 93bd8a010..ef39cb963 100644
--- a/src/dsp_tools/models/listnode.py
+++ b/src/dsp_tools/models/listnode.py
@@ -181,7 +181,7 @@ def __init__(
super().__init__(con)
- self._project = project.id if isinstance(project, Project) else str(project) if project else None
+ self._project = project.iri if isinstance(project, Project) else str(project) if project else None
self._id = iri
self._label = LangString(label)
self._comments = LangString(comments) if comments else None
@@ -356,12 +356,6 @@ def rootNodeIri(self) -> Optional[str]:
def rootNodeIri(self, value: str):
raise BaseError("rootNodeIri cannot be set!")
- def has_changed(self) -> bool:
- if self._changed:
- return True
- else:
- return False
-
@classmethod
def fromJsonObj(cls, con: Connection, json_obj: Any) -> Any:
"""
diff --git a/src/dsp_tools/models/model.py b/src/dsp_tools/models/model.py
index 77f022d9b..b014f34eb 100644
--- a/src/dsp_tools/models/model.py
+++ b/src/dsp_tools/models/model.py
@@ -11,9 +11,3 @@ def __init__(self, con: Connection):
raise BaseError('"con"-parameter must be an instance of Connection')
self._con = con
self._changed = set()
-
- def has_changed(self) -> bool:
- if self._changed:
- return True
- else:
- return False
diff --git a/src/dsp_tools/models/ontology.py b/src/dsp_tools/models/ontology.py
index 1834cf33c..0c56517ed 100644
--- a/src/dsp_tools/models/ontology.py
+++ b/src/dsp_tools/models/ontology.py
@@ -73,7 +73,7 @@ def __init__(
super().__init__(con)
self._iri = iri
if isinstance(project, Project):
- self._project = project.id
+ self._project = project.iri
else:
self._project = project
self._name = name
diff --git a/src/dsp_tools/models/permission.py b/src/dsp_tools/models/permission.py
index 1e73dfba2..4f14d82d4 100644
--- a/src/dsp_tools/models/permission.py
+++ b/src/dsp_tools/models/permission.py
@@ -22,26 +22,6 @@ def __str__(self):
return tmp[self.value]
-class PermissionsIterator:
- _permissions: "Permissions"
- _group: list[str]
- _index: int
-
- def __init__(self, permissions: "Permissions"):
- self._permissions = permissions
- self._index = 0
-
- def __next__(self):
- if len(self._permissions.permissions) == 0 and self._index == 0:
- return None, None
- elif self._index < len(self._permissions.permissions):
- tmp = self._prefixes[self._index]
- self._index += 1
- return tmp, self._permissions.permissions[tmp]
- else:
- raise StopIteration
-
-
class Permissions:
_permissions: Union[dict[PermissionValue, list[str]], None]
@@ -63,9 +43,6 @@ def __delitem__(self, key: PermissionValue) -> None:
def __missing__(self, key: PermissionValue) -> None:
return None
- def __iter__(self) -> PermissionsIterator:
- return PermissionsIterator(self)
-
def __contains__(self, key: PermissionValue) -> bool:
return key in self._permissions
diff --git a/src/dsp_tools/models/project.py b/src/dsp_tools/models/project.py
index 809036c87..e7e012e17 100644
--- a/src/dsp_tools/models/project.py
+++ b/src/dsp_tools/models/project.py
@@ -1,17 +1,3 @@
-from __future__ import annotations
-
-import json
-from pprint import pprint
-from typing import Any, Optional, Union
-from urllib.parse import quote_plus
-
-from dsp_tools.models.connection import Connection
-from dsp_tools.models.exceptions import BaseError
-from dsp_tools.models.helpers import Actions
-from dsp_tools.models.langstring import LangString, Languages
-from dsp_tools.models.model import Model
-from dsp_tools.models.set_encoder import SetEncoder
-
"""
This module implements the handling (CRUD) of DSP projects.
@@ -20,7 +6,7 @@
* Call the ``create``-method on the instance
READ:
- * Instantiate a new object with ``id``(IRI of project) given
+ * Instantiate a new object with ``iri`` given
* Call the ``read``-method on the instance
* Access the information that has been provided to the instance
@@ -30,12 +16,25 @@
* Call the ``update```method on the instance
DELETE
- * Instantiate a new objects with ``id``(IRI of project) given, or use any instance that has the id set
+ * Instantiate a new objects with ``iri`` given, or use any instance that has the iri set
* Call the ``delete``-method on the instance
In addition there is a static methods ``getAllProjects`` which returns a list of all projects
"""
+from __future__ import annotations
+
+import json
+from typing import Any, Optional, Union
+from urllib.parse import quote_plus
+
+from dsp_tools.models.connection import Connection
+from dsp_tools.models.exceptions import BaseError
+from dsp_tools.models.helpers import Actions
+from dsp_tools.models.langstring import LangString, Languages
+from dsp_tools.models.model import Model
+from dsp_tools.models.set_encoder import SetEncoder
+
class Project(Model):
"""
@@ -47,7 +46,7 @@ class Project(Model):
con : Connection
A Connection instance to a DSP server
- id : str
+ iri : str
IRI of the project [readonly, cannot be modified after creation of instance]
shortcode : str
@@ -100,7 +99,7 @@ class Project(Model):
ROUTE: str = "/admin/projects"
IRI: str = ROUTE + "/iri/"
- _id: str
+ _iri: str
_shortcode: str
_shortname: str
_longname: str
@@ -116,7 +115,7 @@ class Project(Model):
def __init__(
self,
con: Connection,
- id: Optional[str] = None,
+ iri: Optional[str] = None,
shortcode: Optional[str] = None,
shortname: Optional[str] = None,
longname: Optional[str] = None,
@@ -131,8 +130,8 @@ def __init__(
Constructor for Project
:param con: Connection instance
- :param id: IRI of the project [required for CREATE, READ]
- :param shortcode: Shortcode of the project. String inf the form 'XXXX' where each X is a hexadezimal sign 0-1,A,B,C,D,E,F. [required for CREATE]
+ :param iri: IRI of the project [required for CREATE, READ]
+ :param shortcode: Shortcode of the project. Four-digit hexadecimal number. [required for CREATE]
:param shortname: Shortname of the project [required for CREATE]
:param longname: Longname of the project [required for CREATE]
:param description: LangString instance containing the description [required for CREATE]
@@ -143,7 +142,7 @@ def __init__(
:param logo: Path to logo image file [optional] NOT YET USED
"""
super().__init__(con)
- self._id = id
+ self._iri = iri
self._shortcode = shortcode
self._shortname = shortname
self._longname = longname
@@ -157,19 +156,19 @@ def __init__(
self._logo = logo
def __str__(self):
- tmpstr = self._id + "\n " + self._shortcode + "\n " + self._shortname
+ tmpstr = self._iri + "\n " + self._shortcode + "\n " + self._shortname
return tmpstr
#
# Here follows a list of getters/setters
#
@property
- def id(self) -> Optional[str]:
- return self._id
+ def iri(self) -> Optional[str]:
+ return self._iri
- @id.setter
- def id(self, value: str) -> None:
- raise BaseError("Project id cannot be modified!")
+ @iri.setter
+ def iri(self, value: str) -> None:
+ raise BaseError("Project iri cannot be modified!")
@property
def shortcode(self) -> Optional[str]:
@@ -224,7 +223,7 @@ def rmDescription(self, lang: Union[Languages, str]) -> None:
"""
Remove a description from a project (executed at next update)
- :param lang: The language the description to be removed is in, either a string "EN", "DE", "FR", "IT" or a Language instance
+ :param lang: language of the description, either "EN", "DE", "FR", "IT", "RM", or a Language instance
:return: None
"""
@@ -269,7 +268,7 @@ def rmKeyword(self, value: str):
try:
self._keywords.remove(value)
except KeyError as ke:
- raise BaseError('Keyword "' + value + '" is not in keyword set')
+ raise BaseError('Keyword "' + value + '" is not in keyword set') from ke
self._changed.add("keywords")
@property
@@ -321,9 +320,9 @@ def fromJsonObj(cls, con: Connection, json_obj: Any) -> Project:
:param json_obj: JSON data returned by DSP as python3 object
:return: Project instance
"""
- id = json_obj.get("id")
- if id is None:
- raise BaseError("Project id is missing")
+ iri = json_obj.get("id")
+ if iri is None:
+ raise BaseError("Project iri is missing")
shortcode = json_obj.get("shortcode")
if shortcode is None:
raise BaseError("Shortcode is missing")
@@ -349,7 +348,7 @@ def fromJsonObj(cls, con: Connection, json_obj: Any) -> Project:
logo = json_obj.get("logo")
return cls(
con=con,
- id=id,
+ iri=iri,
shortcode=shortcode,
shortname=shortname,
longname=longname,
@@ -439,8 +438,8 @@ def read(self) -> Project:
:return: JSON-object from DSP
"""
result = None
- if self._id is not None:
- result = self._con.get(Project.IRI + quote_plus(self._id))
+ if self._iri is not None:
+ result = self._con.get(Project.IRI + quote_plus(self._iri))
elif self._shortcode is not None:
result = self._con.get(Project.ROUTE + "/shortcode/" + quote_plus(self._shortcode))
elif self._shortname is not None:
@@ -449,7 +448,7 @@ def read(self) -> Project:
return Project.fromJsonObj(self._con, result["project"])
else:
raise BaseError(
- f"ERROR: Could not read project '{self.shortname}' ({self.shortcode}) with IRI {self._id} "
+ f"ERROR: Could not read project '{self.shortname}' ({self.shortcode}) with IRI {self._iri} "
f"from DSP server."
)
@@ -462,7 +461,7 @@ def update(self) -> Project:
jsonobj = self.toJsonObj(Actions.Update)
jsondata = json.dumps(jsonobj, cls=SetEncoder)
- result = self._con.put(Project.IRI + quote_plus(self.id), jsondata)
+ result = self._con.put(Project.IRI + quote_plus(self.iri), jsondata)
return Project.fromJsonObj(self._con, result["project"])
def delete(self) -> Project:
@@ -472,44 +471,9 @@ def delete(self) -> Project:
:return: DSP response
"""
- result = self._con.delete(Project.IRI + quote_plus(self._id))
+ result = self._con.delete(Project.IRI + quote_plus(self._iri))
return Project.fromJsonObj(self._con, result["project"])
- def set_default_permissions(self, group_id: str) -> None:
- permobj = {
- "forGroup": "http://www.knora.org/ontology/knora-admin#ProjectMember",
- "forProject": self._id,
- "hasPermissions": [
- {
- "additionalInformation": None,
- "name": "ProjectResourceCreateAllPermission",
- "permissionCode": None,
- }
- ],
- }
- jsondata = json.dumps(permobj, indent=4)
- print(jsondata)
- result = self._con.post("/admin/permissions/ap", jsondata)
- pprint(result)
-
- return
- permobj = {
- "forGroup": group_id,
- "forProject": self._id,
- "forProperty": None,
- "forResourceClass": None,
- "hasPermissions": [
- {
- "additionalInformation": "http://www.knora.org/ontology/knora-admin#ProjectMember",
- "name": "D",
- "permissionCode": 7,
- }
- ],
- }
- jsondata = json.dumps(permobj)
- result = self._con.post("/admin/permissions/ap", jsondata)
- pprint(result)
-
@staticmethod
def getAllProjects(con: Connection) -> list[Project]:
"""
@@ -531,7 +495,7 @@ def print(self) -> None:
"""
print("Project Info:")
- print(" Id: {}".format(self._id))
+ print(" IRI: {}".format(self._iri))
print(" Shortcode: {}".format(self._shortcode))
print(" Shortname: {}".format(self._shortname))
print(" Longname: {}".format(self._longname))
diff --git a/src/dsp_tools/models/projectContext.py b/src/dsp_tools/models/projectContext.py
index 03501a5a4..b2b6f79b5 100644
--- a/src/dsp_tools/models/projectContext.py
+++ b/src/dsp_tools/models/projectContext.py
@@ -20,8 +20,8 @@ class ProjectContext:
def __init__(self, con: Connection, shortcode: Optional[str] = None):
self._shortcode = shortcode
self._projects = Project.getAllProjects(con=con)
- self._project_map: dict[str, str] = {x.shortname: x.id for x in self._projects}
- self._inv_project_map: dict[str, str] = {x.id: x.shortname for x in self._projects}
+ self._project_map: dict[str, str] = {x.shortname: x.iri for x in self._projects}
+ self._inv_project_map: dict[str, str] = {x.iri: x.shortname for x in self._projects}
try:
self._groups = Group.getAllGroups(con=con)
except BaseError:
diff --git a/src/dsp_tools/models/propertyclass.py b/src/dsp_tools/models/propertyclass.py
index edbb97b5d..6bc06bbe0 100644
--- a/src/dsp_tools/models/propertyclass.py
+++ b/src/dsp_tools/models/propertyclass.py
@@ -16,12 +16,12 @@ class PropertyClass(Model):
ROUTE: str = "/v2/ontologies/properties"
_context: Context
- _id: str
+ _iri: str
_name: str
_ontology_id: str
_superproperties: list[str]
- _object: str
- _subject: str
+ _rdf_object: str
+ _rdf_subject: str
_gui_element: str
_gui_attributes: dict[str, str]
_label: LangString
@@ -33,12 +33,12 @@ def __init__(
self,
con: Connection,
context: Context,
- id: Optional[str] = None,
+ iri: Optional[str] = None,
name: Optional[str] = None,
ontology_id: Optional[str] = None,
superproperties: Optional[Sequence[Union["PropertyClass", str]]] = None,
- object: Optional[str] = None,
- subject: Optional[str] = None,
+ rdf_object: Optional[str] = None,
+ rdf_subject: Optional[str] = None,
gui_element: Optional[str] = None,
gui_attributes: Optional[dict[str, str]] = None,
label: Optional[Union[LangString, str]] = None,
@@ -50,15 +50,15 @@ def __init__(
if not isinstance(context, Context):
raise BaseError('"context"-parameter must be an instance of Context')
self._context = context
- self._id = id
+ self._iri = iri
self._name = name
self._ontology_id = ontology_id
if isinstance(superproperties, PropertyClass):
- self._superproperties = list(map(lambda a: a.id, superproperties))
+ self._superproperties = list(map(lambda a: a.iri, superproperties))
else:
self._superproperties = superproperties
- self._object = object
- self._subject = subject
+ self._rdf_object = rdf_object
+ self._rdf_subject = rdf_subject
self._gui_element = gui_element
self._gui_attributes = gui_attributes
#
@@ -101,12 +101,12 @@ def name(self, value: str) -> None:
raise BaseError('"name" cannot be modified!')
@property
- def id(self) -> Optional[str]:
- return self._id
+ def iri(self) -> Optional[str]:
+ return self._iri
- @id.setter
- def id(self, value: str) -> None:
- raise BaseError('"id" cannot be modified!')
+ @iri.setter
+ def iri(self, value: str) -> None:
+ raise BaseError('"iri" cannot be modified!')
@property
def ontology_id(self) -> Optional[str]:
@@ -125,48 +125,29 @@ def superproperties(self, value: str) -> None:
raise BaseError('"superproperties" cannot be modified!')
@property
- def object(self) -> Optional[str]:
- return self._object
+ def rdf_object(self) -> Optional[str]:
+ return self._rdf_object
- @object.setter
- def object(self, value: Any):
- raise BaseError('"object" cannot be modified!')
+ @rdf_object.setter
+ def rdf_object(self, value: Any):
+ raise BaseError('"rdf_object" cannot be modified!')
@property
- def subject(self) -> Optional[str]:
- return self._subject
+ def rdf_subject(self) -> Optional[str]:
+ return self._rdf_subject
- @subject.setter
- def subject(self, value: Any):
- raise BaseError('"subject" cannot be modified!')
+ @rdf_subject.setter
+ def rdf_subject(self, value: Any):
+ raise BaseError('"rdf_subject" cannot be modified!')
@property
def gui_element(self) -> Optional[str]:
return self._gui_element
- @gui_element.setter
- def gui_element(self, value: str) -> None:
- self._gui_element = value
- self._changed.append("gui_element")
-
@property
def gui_attributes(self) -> Optional[dict[str, str]]:
return self._gui_attributes
- @gui_attributes.setter
- def gui_attributes(self, value: list[dict[str, str]]) -> None:
- self._gui_attributes = value
- self._changed.append("gui_attributes")
-
- def addGuiAttribute(self, key: str, value: str) -> None:
- self._gui_attributes[key] = value
- self._changed.append("gui_attributes")
-
- def rmGuiAttribute(self, key: str) -> None:
- if self._gui_attributes.get(key) is not None:
- del self._gui_attributes[key]
- self._changed.append("gui_attributes")
-
@property
def label(self) -> LangString:
return self._label
@@ -234,26 +215,23 @@ def linkvalue(self) -> None:
raise BaseError('"linkvalue" cannot be modified!')
@classmethod
- def fromJsonObj(cls, con: Connection, context: Context, json_obj: Any) -> Any:
+ def fromJsonObj(cls, con: Connection, context: Context, json_obj: Any) -> "PropertyClass":
if isinstance(json_obj, list):
- json_obj = json_obj[0] # TODO: Is it possible to have more than one element in the list??
+ json_obj = json_obj[0]
if not isinstance(con, Connection):
raise BaseError('"con"-parameter must be an instance of Connection')
if not isinstance(context, Context):
raise BaseError('"context"-parameter must be an instance of Context')
- rdf = context.prefix_from_iri("http://www.w3.org/1999/02/22-rdf-syntax-ns#")
rdfs = context.prefix_from_iri("http://www.w3.org/2000/01/rdf-schema#")
- owl = context.prefix_from_iri("http://www.w3.org/2002/07/owl#")
- xsd = context.prefix_from_iri("http://www.w3.org/2001/XMLSchema#")
knora_api = context.prefix_from_iri("http://api.knora.org/ontology/knora-api/v2#")
salsah_gui = context.prefix_from_iri("http://api.knora.org/ontology/salsah-gui/v2#")
- if not (json_obj.get(knora_api + ":isResourceProperty")):
+ if not json_obj.get(knora_api + ":isResourceProperty"):
raise BaseError("This is not a property!")
if json_obj.get("@id") is None:
raise BaseError('Property class has no "@id"!')
tmp_id = json_obj.get("@id").split(":")
- id = context.iri_from_prefix(tmp_id[0]) + "#" + tmp_id[1]
+ iri = context.iri_from_prefix(tmp_id[0]) + "#" + tmp_id[1]
ontology_id = tmp_id[0]
name = tmp_id[1]
superproperties_obj = json_obj.get(rdfs + ":subPropertyOf")
@@ -264,8 +242,8 @@ def fromJsonObj(cls, con: Connection, context: Context, json_obj: Any) -> Any:
superproperties = [x["@id"] for x in superproperties_obj if x and x.get("@id")]
else:
superproperties = None
- object = WithId(json_obj.get(knora_api + ":objectType")).str()
- subject = WithId(json_obj.get(knora_api + ":subjectType")).str()
+ rdf_object = WithId(json_obj.get(knora_api + ":objectType")).str()
+ rdf_subject = WithId(json_obj.get(knora_api + ":subjectType")).str()
label = LangString.fromJsonLdObj(json_obj.get(rdfs + ":label"))
comment = LangString.fromJsonLdObj(json_obj.get(rdfs + ":comment"))
gui_element = None
@@ -291,12 +269,12 @@ def fromJsonObj(cls, con: Connection, context: Context, json_obj: Any) -> Any:
return cls(
con=con,
context=context,
- id=id,
+ iri=iri,
name=name,
ontology_id=ontology_id,
superproperties=superproperties,
- object=object,
- subject=subject,
+ rdf_object=rdf_object,
+ rdf_subject=rdf_subject,
gui_element=gui_element,
gui_attributes=gui_attributes,
label=label,
@@ -355,10 +333,10 @@ def resolve_propref(resref: str):
}
if self._comment:
tmp["@graph"][0]["rdfs:comment"] = self._comment.toJsonLdObj()
- if self._subject:
- tmp["@graph"][0]["knora-api:subjectType"] = resolve_propref(self._subject)
- if self._object:
- tmp["@graph"][0]["knora-api:objectType"] = resolve_propref(self._object)
+ if self._rdf_subject:
+ tmp["@graph"][0]["knora-api:subjectType"] = resolve_propref(self._rdf_subject)
+ if self._rdf_object:
+ tmp["@graph"][0]["knora-api:objectType"] = resolve_propref(self._rdf_object)
if self._gui_element:
tmp["@graph"][0]["salsah-gui:guiElement"] = {"@id": self._gui_element}
if self._gui_attributes:
@@ -393,7 +371,7 @@ def create(self, last_modification_date: DateTimeStamp) -> tuple[DateTimeStamp,
last_modification_date = DateTimeStamp(result["knora-api:lastModificationDate"])
return last_modification_date, PropertyClass.fromJsonObj(self._con, self._context, result["@graph"])
- def update(self, last_modification_date: DateTimeStamp) -> tuple[DateTimeStamp, "ResourceClass"]:
+ def update(self, last_modification_date: DateTimeStamp) -> tuple[DateTimeStamp, "PropertyClass"]:
#
# Note: DSP is able to change only one thing per call, either label or comment!
#
@@ -418,7 +396,7 @@ def update(self, last_modification_date: DateTimeStamp) -> tuple[DateTimeStamp,
def delete(self, last_modification_date: DateTimeStamp) -> DateTimeStamp:
result = self._con.delete(
- PropertyClass.ROUTE + "/" + quote_plus(self._id) + "?lastModificationDate=" + str(last_modification_date)
+ PropertyClass.ROUTE + "/" + quote_plus(self._iri) + "?lastModificationDate=" + str(last_modification_date)
)
return DateTimeStamp(result["knora-api:lastModificationDate"])
@@ -430,24 +408,24 @@ def createDefinitionFileObj(self, context: Context, shortname: str):
:param shortname: Shortname of the ontology
:return: Python object to be jsonfied
"""
- property = {"name": self.name}
- if self.object:
- property["name"] = self.name
+ def_file_obj = {"name": self.name}
+ if self.rdf_object:
+ def_file_obj["name"] = self.name
if self.superproperties:
superprops = []
for sc in self.superproperties:
superprops.append(context.reduce_iri(sc, shortname))
- property["super"] = superprops
- if self.subject:
- property["subject"] = context.reduce_iri(self.subject, shortname)
- if self.object:
- property["object"] = context.reduce_iri(self.object, shortname)
+ def_file_obj["super"] = superprops
+ if self.rdf_subject:
+ def_file_obj["subject"] = context.reduce_iri(self.rdf_subject, shortname)
+ if self.rdf_object:
+ def_file_obj["object"] = context.reduce_iri(self.rdf_object, shortname)
if not self.label.isEmpty():
- property["labels"] = self.label.createDefinitionFileObj()
+ def_file_obj["labels"] = self.label.createDefinitionFileObj()
if not self.comment.isEmpty():
- property["comments"] = self.comment.createDefinitionFileObj()
+ def_file_obj["comments"] = self.comment.createDefinitionFileObj()
if self.gui_element:
- property["gui_element"] = context.reduce_iri(self.gui_element, shortname)
+ def_file_obj["gui_element"] = context.reduce_iri(self.gui_element, shortname)
if self.gui_attributes:
gui_elements = {}
for attname, attvalue in self.gui_attributes.items():
@@ -479,8 +457,8 @@ def createDefinitionFileObj(self, context: Context, shortname: str):
gui_elements[attname] = float(attvalue)
else:
gui_elements[attname] = str(attvalue)
- property["gui_attributes"] = gui_elements
- return property
+ def_file_obj["gui_attributes"] = gui_elements
+ return def_file_obj
def print(self, offset: int = 0):
blank = " "
@@ -494,10 +472,10 @@ def print(self, offset: int = 0):
if self._label is not None:
print(f"{blank:>{offset + 2}}Labels:")
self._label.print(offset + 4)
- if self._subject is not None:
- print(f"{blank:>{offset + 4}}Subject: {self._subject}")
- if self._object is not None:
- print(f"{blank:>{offset + 4}}Object: {self._object}")
+ if self._rdf_subject is not None:
+ print(f"{blank:>{offset + 4}}rdf_subject: {self._rdf_subject}")
+ if self._rdf_object is not None:
+ print(f"{blank:>{offset + 4}}rdf_object: {self._rdf_object}")
if self._gui_element is not None:
print(f"{blank:>{offset + 4}}Guielement: {self._gui_element}")
if self._gui_attributes is not None:
diff --git a/src/dsp_tools/models/propertyelement.py b/src/dsp_tools/models/propertyelement.py
index ad670efb1..47239f9e5 100644
--- a/src/dsp_tools/models/propertyelement.py
+++ b/src/dsp_tools/models/propertyelement.py
@@ -3,6 +3,8 @@
from dsp_tools.models.exceptions import BaseError
+# pylint: disable=line-too-long
+
@dataclass(frozen=True)
class PropertyElement:
diff --git a/src/dsp_tools/models/resource.py b/src/dsp_tools/models/resource.py
index b757f7b89..b446ace98 100644
--- a/src/dsp_tools/models/resource.py
+++ b/src/dsp_tools/models/resource.py
@@ -38,14 +38,14 @@
class KnoraStandoffXmlEncoder(json.JSONEncoder):
"""Classes used as wrapper for DSP standoff-XML"""
- def default(self, obj) -> str:
- if isinstance(obj, KnoraStandoffXml):
- return '\n' + str(obj) + ""
- elif isinstance(obj, OntoIri):
- return obj.iri + "#" if obj.hashtag else ""
- elif isinstance(obj, DateTimeStamp):
- return str(obj)
- return json.JSONEncoder.default(self, obj)
+ def default(self, o) -> str:
+ if isinstance(o, KnoraStandoffXml):
+ return '\n' + str(o) + ""
+ elif isinstance(o, OntoIri):
+ return o.iri + "#" if o.hashtag else ""
+ elif isinstance(o, DateTimeStamp):
+ return str(o)
+ return json.JSONEncoder.default(self, o)
@dataclass
@@ -124,7 +124,8 @@ def __init__(
)
if self.baseclass not in self.baseclasses_with_bitstream and bitstream:
raise BaseError(
- f"ERROR in resource with label '{self._label}': Baseclass '{self.baseclass}' does not allow a bitstream value"
+ f"ERROR in resource with label '{self._label}': "
+ f"Baseclass '{self.baseclass}' does not allow a bitstream value"
)
if self.baseclass in self.baseclasses_with_bitstream and bitstream:
self._bitstream = bitstream
@@ -139,19 +140,20 @@ def __init__(
value = values.get(property_name)
if value:
# property has multiple values
- if type(value) is list:
+ if isinstance(value, list):
self._values[property_name] = []
for val in value:
# check if cardinality allows multiple values for a property
if cardinality == Cardinality.C_0_1 or cardinality == Cardinality.C_1:
raise BaseError(
- f"ERROR in resource with label '{self._label}': Ontology does not allow multiple values for '{property_name}'"
+ f"ERROR in resource with label '{self._label}': "
+ f"Ontology does not allow multiple values for '{property_name}'"
)
- if type(val) is Value:
+ if isinstance(val, Value):
self._values[property_name].append(val)
- elif type(val) is dict:
+ elif isinstance(val, dict):
if value_type is ListValue:
val["lists"] = self.lists
self._values[property_name].append(value_type(**val))
@@ -162,10 +164,10 @@ def __init__(
self._values[property_name].append(value_type(val))
# property has one value
else:
- if type(value) is Value:
+ if isinstance(value, Value):
self._values[property_name] = value
- elif type(value) is dict:
+ elif isinstance(value, dict):
if value_type is ListValue:
value["lists"] = self.lists
self._values[property_name] = value_type(**value)
@@ -179,13 +181,15 @@ def __init__(
else:
if cardinality == Cardinality.C_1 or cardinality == Cardinality.C_1_n:
raise BaseError(
- f"ERROR in resource with label '{self._label}': The ontology requires at least one value for '{property_name}'"
+ f"ERROR in resource with label '{self._label}': "
+ f"The ontology requires at least one value for '{property_name}'"
)
for property_name in values:
if property_name not in self.knora_properties and not self.properties.get(property_name):
raise BaseError(
- f"ERROR in resource with label '{self._label}': Property '{property_name}' is not part of ontology"
+ f"ERROR in resource with label '{self._label}': "
+ f"Property '{property_name}' is not part of ontology"
)
def value(self, item) -> Optional[list[Value]]:
@@ -223,19 +227,14 @@ def vark(self) -> str:
def clone(self) -> "ResourceInstance":
return deepcopy(self)
- def fromJsonLdObj(self, con: Connection, jsonld_obj: Any) -> "ResourceInstance":
+ def fromJsonLdObj(self, jsonld_obj: dict[str, Any]) -> "ResourceInstance":
newinstance = self.clone()
newinstance._iri = jsonld_obj.get("@id")
- resclass = jsonld_obj.get("@type")
- context = Context(jsonld_obj.get("@context"))
newinstance._label = jsonld_obj.get("rdfs:label")
newinstance._ark = Value.get_typed_value("knora-api:arkUrl", jsonld_obj)
newinstance._version_ark = Value.get_typed_value("knora-api:versionArkUrl", jsonld_obj)
newinstance._permissions = Permissions.fromString(jsonld_obj.get("knora-api:hasPermissions"))
newinstance._user_permission = PermissionValue[jsonld_obj.get("knora-api:userHasPermission", jsonld_obj)]
- creation_date = Value.get_typed_value("knora-api:creationDate", jsonld_obj)
- user = Value.get_typed_value("knora-api:attachedToUser", jsonld_obj)
- project = Value.get_typed_value("knora-api:attachedToProject", jsonld_obj)
to_be_ignored = [
"@id",
"@type",
@@ -251,7 +250,6 @@ def fromJsonLdObj(self, con: Connection, jsonld_obj: Any) -> "ResourceInstance":
]
if id is None:
raise BaseError('Resource "id" is missing in JSON-LD from DSP-API')
- type = jsonld_obj.get("@type")
newinstance._values: dict[str, Union[Value, list[Value]]] = {}
for key, obj in jsonld_obj.items():
if key in to_be_ignored:
@@ -264,7 +262,7 @@ def fromJsonLdObj(self, con: Connection, jsonld_obj: Any) -> "ResourceInstance":
else:
newinstance._values[key] = fromJsonLdObj(obj)
except KeyError as kerr:
- raise BaseError('Invalid data in JSON-LD: "{}" has value class "{}"!'.format(key, obj.get("@type")))
+ raise BaseError(f'Invalid data in JSON-LD: "{key}" has value class "{obj.get("@type")}"!') from kerr
return newinstance
def toJsonLdObj(self, action: Actions) -> Any:
@@ -310,15 +308,15 @@ def toJsonLdObj(self, action: Actions) -> Any:
for property_name, value in self._values.items():
# if the property has several values
- if type(value) is list:
- if type(value[0]) is LinkValue:
+ if isinstance(value, list):
+ if isinstance(value[0], LinkValue):
property_name += "Value"
# append all values to that property
tmp[property_name] = []
for vt in value:
tmp[property_name].append(vt.toJsonLdObj(action))
# if property is a link
- elif type(value) is LinkValue:
+ elif isinstance(value, LinkValue):
property_name += "Value"
tmp[property_name] = value.toJsonLdObj(action)
else:
@@ -342,7 +340,7 @@ def create(self) -> "ResourceInstance":
def read(self) -> "ResourceInstance":
result = self._con.get(ResourceInstance.ROUTE + "/" + quote_plus(self._iri))
- return self.fromJsonLdObj(con=self._con, jsonld_obj=result)
+ return self.fromJsonLdObj(result)
def update(self):
pass
@@ -361,7 +359,6 @@ def print(self):
if isinstance(val, list):
tmp = [str(x) for x in val]
print(name, ":", " | ".join(tmp))
- pass
else:
print(name, ":", str(val))
@@ -386,11 +383,11 @@ def __init__(self, con: Connection, projident: str) -> None:
raise BaseError("Invalid project identification!")
self._project = project.read()
- self._lists = [x.getAllNodes() for x in ListNode.getAllLists(con=con, project_iri=self._project.id)]
+ self._lists = [x.getAllNodes() for x in ListNode.getAllLists(con=con, project_iri=self._project.iri)]
- tmp_ontologies = Ontology.getProjectOntologies(con=con, project_id=self._project.id)
+ tmp_ontologies = Ontology.getProjectOntologies(con=con, project_id=self._project.iri)
shared_project = Project(con=con, shortcode="0000").read()
- shared_ontologies = Ontology.getProjectOntologies(con=con, project_id=shared_project.id)
+ shared_ontologies = Ontology.getProjectOntologies(con=con, project_id=shared_project.iri)
tmp_ontologies.extend(shared_ontologies)
knora_api_onto = [x for x in Ontology.getAllOntologies(con=con) if x.name == "knora-api"][0]
tmp_ontologies.append(knora_api_onto)
@@ -414,9 +411,9 @@ def lists(self) -> list[ListNode]:
def get_resclass_names(self) -> list[str]:
resclass_names: list[str] = []
- for name, onto in self._ontologies.items():
+ for _, onto in self._ontologies.items():
for resclass in onto.resource_classes:
- resclass_names.append(onto.context.get_prefixed_iri(resclass.id))
+ resclass_names.append(onto.context.get_prefixed_iri(resclass.iri))
return resclass_names
def _get_baseclass(self, superclasses: list[str]) -> Union[str, None]:
@@ -490,7 +487,7 @@ def get_resclass_type(self, prefixedresclass: str) -> Type:
valtype=valtype, cardinality=has_property.cardinality, gui_order=has_property.gui_order
)
elif has_property.ptype == HasProperty.Ptype.other:
- valtype = switcher.get(self._properties[propname].object)
+ valtype = switcher.get(self._properties[propname].rdf_object)
if valtype == LinkValue:
continue # we have the Link to the LinkValue which we do not use
if valtype is None:
@@ -499,7 +496,7 @@ def get_resclass_type(self, prefixedresclass: str) -> Type:
valtype=valtype,
cardinality=has_property.cardinality,
gui_order=has_property.gui_order,
- attributes=self._properties[propname].object,
+ attributes=self._properties[propname].rdf_object,
)
else:
props[propname] = Propinfo(
@@ -509,7 +506,7 @@ def get_resclass_type(self, prefixedresclass: str) -> Type:
resclass_name,
(ResourceInstance,),
{
- "project": self._project.id,
+ "project": self._project.iri,
"classname": prefixedresclass,
"baseclass": baseclass,
"context": self._context,
diff --git a/src/dsp_tools/models/resourceclass.py b/src/dsp_tools/models/resourceclass.py
index 149a7c533..0b28e1976 100644
--- a/src/dsp_tools/models/resourceclass.py
+++ b/src/dsp_tools/models/resourceclass.py
@@ -1,3 +1,10 @@
+"""
+This model implements the handling of resource classes. It contains two classes that work closely together:
+ * "HasProperty" deals with the association of Property-instances with the Resource-instances. This association
+ is done using the "cardinality"-clause
+ * "ResourceClass" is the main class representing a DSP resource class.
+"""
+
import json
import re
from enum import Enum
@@ -11,13 +18,6 @@
from dsp_tools.models.model import Model
from dsp_tools.models.set_encoder import SetEncoder
-"""
-This model implements the handling of resource classes. It contains two classes that work closely together:
- * "HasProperty" deals with the association of Property-instances with the Resource-instances. This association
- is done using the "cardinality"-clause
- * "ResourceClass" is the main class representing a DSP resource class.
-"""
-
class HasProperty(Model):
ROUTE: str = "/v2/ontologies/cardinalities"
@@ -81,7 +81,7 @@ def property_id(self) -> Optional[str]:
@property_id.setter
def property_id(self, value: str) -> None:
- raise BaseError('property_id "{}" cannot be modified!'.format(self._property_id))
+ raise BaseError(f'property_id "{self._property_id}" cannot be modified!')
@property
def resclass_id(self) -> Optional[str]:
@@ -123,7 +123,6 @@ def fromJsonObj(cls, con: Connection, context: Context, jsonld_obj: Any) -> tupl
rdf = context.prefix_from_iri("http://www.w3.org/1999/02/22-rdf-syntax-ns#")
rdfs = context.prefix_from_iri("http://www.w3.org/2000/01/rdf-schema#")
owl = context.prefix_from_iri("http://www.w3.org/2002/07/owl#")
- xsd = context.prefix_from_iri("http://www.w3.org/2001/XMLSchema#")
knora_api = context.prefix_from_iri("http://api.knora.org/ontology/knora-api/v2#")
salsah_gui = context.prefix_from_iri("http://api.knora.org/ontology/salsah-gui/v2#")
@@ -267,13 +266,8 @@ def update(self, last_modification_date: DateTimeStamp) -> tuple[DateTimeStamp,
jsondata = json.dumps(jsonobj, indent=4, cls=SetEncoder)
result = self._con.put(HasProperty.ROUTE, jsondata)
last_modification_date = DateTimeStamp(result["knora-api:lastModificationDate"])
- # TODO: self._changed = str()
return last_modification_date, ResourceClass.fromJsonObj(self._con, self._context, result["@graph"])
- def delete(self, last_modification_date: DateTimeStamp) -> DateTimeStamp:
- raise BaseError("Cannot remove a single property from a class!")
- # ToDo: Check with Ben if we could add this feature...
-
def createDefinitionFileObj(self, context: Context, shortname: str):
cardinality = {}
if self._ptype == HasProperty.Ptype.other or self.property_id in [
@@ -313,7 +307,7 @@ class ResourceClass(Model):
con : Connection
A Connection instance to a DSP server
- id : str
+ iri : str
IRI of the ResourceClass [readonly, cannot be modified after creation of instance]
name: str
@@ -387,7 +381,7 @@ class ResourceClass(Model):
ROUTE: str = "/v2/ontologies/classes"
_context: Context
- _id: str
+ _iri: str
_name: str
_ontology_id: str
_superclasses: list[str]
@@ -400,7 +394,7 @@ def __init__(
self,
con: Connection,
context: Context,
- id: Optional[str] = None,
+ iri: Optional[str] = None,
name: Optional[str] = None,
ontology_id: Optional[str] = None,
superclasses: Optional[Sequence[Union["ResourceClass", str]]] = None,
@@ -414,7 +408,7 @@ def __init__(
:param con:
:param context:
- :param id:
+ :param iri:
:param name:
:param ontology_id:
:param superclasses:
@@ -429,12 +423,12 @@ def __init__(
if not isinstance(context, Context):
raise BaseError('"context"-parameter must be an instance of Context')
self._context = context
- self._id = id
+ self._iri = iri
self._name = name
if ontology_id is not None:
self._ontology_id = context.iri_from_prefix(ontology_id)
if isinstance(superclasses, ResourceClass):
- self._superclasses = list(map(lambda a: a.id, superclasses))
+ self._superclasses = list(map(lambda a: a.iri, superclasses))
else:
self._superclasses = superclasses
#
@@ -477,12 +471,12 @@ def name(self, value: str) -> None:
raise BaseError('"name" cannot be modified!')
@property
- def id(self) -> Optional[str]:
- return self._id
+ def iri(self) -> Optional[str]:
+ return self._iri
- @id.setter
- def id(self, value: str) -> None:
- raise BaseError('"id" cannot be modified!')
+ @iri.setter
+ def iri(self, value: str) -> None:
+ raise BaseError('"iri" cannot be modified!')
@property
def ontology_id(self) -> Optional[str]:
@@ -585,13 +579,13 @@ def addProperty(
context=self._context,
ontology_id=self._ontology_id,
property_id=property_id,
- resclass_id=self.id,
+ resclass_id=self.iri,
cardinality=cardinality,
gui_order=gui_order,
).create(last_modification_date)
hp = resclass.getProperty(property_id)
- hp._ontology_id = self._context.iri_from_prefix(self._ontology_id)
- hp._resclass_id = self._id
+ hp.ontology_id = self._context.iri_from_prefix(self._ontology_id)
+ hp.resclass_id = self._iri
self._has_properties[hp.property_id] = hp
return latest_modification_date
else:
@@ -610,7 +604,7 @@ def updateProperty(
# onto_id = has_properties.ontology_id # save for later user
# rescl_id = has_properties.resclass_id # save for later user
has_properties.ontology_id = self._ontology_id
- has_properties.resclass_id = self._id
+ has_properties.resclass_id = self._iri
if cardinality:
has_properties.cardinality = cardinality
if gui_order:
@@ -618,7 +612,7 @@ def updateProperty(
latest_modification_date, resclass = has_properties.update(last_modification_date)
hp = resclass.getProperty(property_id)
hp.ontology_id = self._ontology_id # self.__context.iri_from_prefix(onto_id) # restore value
- hp.resclass_id = self._id # rescl_id # restore value
+ hp.resclass_id = self._iri # rescl_id # restore value
self._has_properties[hp.property_id] = hp
return latest_modification_date
else:
@@ -627,17 +621,14 @@ def updateProperty(
@classmethod
def fromJsonObj(cls, con: Connection, context: Context, json_obj: Any) -> Any:
if isinstance(json_obj, list):
- json_obj = json_obj[0] # TODO: Is it possible to have more than one element in the list??
+ json_obj = json_obj[0]
if not isinstance(con, Connection):
raise BaseError('"con"-parameter must be an instance of Connection')
if not isinstance(context, Context):
raise BaseError('"context"-parameter must be an instance of Context')
- rdf = context.prefix_from_iri("http://www.w3.org/1999/02/22-rdf-syntax-ns#")
rdfs = context.prefix_from_iri("http://www.w3.org/2000/01/rdf-schema#")
owl = context.prefix_from_iri("http://www.w3.org/2002/07/owl#")
- xsd = context.prefix_from_iri("http://www.w3.org/2001/XMLSchema#")
knora_api = context.prefix_from_iri("http://api.knora.org/ontology/knora-api/v2#")
- salsah_gui = context.prefix_from_iri("http://api.knora.org/ontology/salsah-gui/v2#")
if not (json_obj.get(knora_api + ":isResourceClass") or json_obj.get(knora_api + ":isStandoffClass")):
raise BaseError("This is not a resource!")
@@ -645,7 +636,7 @@ def fromJsonObj(cls, con: Connection, context: Context, json_obj: Any) -> Any:
if json_obj.get("@id") is None:
raise BaseError('Resource class has no "@id"!')
tmp_id = json_obj.get("@id").split(":")
- id = context.iri_from_prefix(tmp_id[0]) + "#" + tmp_id[1]
+ iri = context.iri_from_prefix(tmp_id[0]) + "#" + tmp_id[1]
ontology_id = tmp_id[0]
name = tmp_id[1]
superclasses_obj = json_obj.get(rdfs + ":subClassOf")
@@ -675,7 +666,7 @@ def fromJsonObj(cls, con: Connection, context: Context, json_obj: Any) -> Any:
con=con,
context=context,
name=name,
- id=id,
+ iri=iri,
ontology_id=ontology_id,
superclasses=superclasses,
label=label,
@@ -786,7 +777,7 @@ def update(self, last_modification_date: DateTimeStamp) -> tuple[DateTimeStamp,
def delete(self, last_modification_date: DateTimeStamp) -> DateTimeStamp:
result = self._con.delete(
- ResourceClass.ROUTE + "/" + quote_plus(self._id) + "?lastModificationDate=" + str(last_modification_date)
+ ResourceClass.ROUTE + "/" + quote_plus(self._iri) + "?lastModificationDate=" + str(last_modification_date)
)
return DateTimeStamp(result["knora-api:lastModificationDate"])
@@ -805,7 +796,7 @@ def createDefinitionFileObj(self, context: Context, shortname: str, skiplist: li
resource["comments"] = self._comment.createDefinitionFileObj()
if self._has_properties:
cardinalities = []
- for pid, hp in self._has_properties.items():
+ for _, hp in self._has_properties.items():
if hp.property_id in skiplist:
continue
if hp.ptype == HasProperty.Ptype.other or hp.property_id in [
@@ -838,5 +829,5 @@ def print(self, offset: int = 0):
if self._has_properties is not None:
print(f"{blank:>{offset + 2}}Has properties:")
if self._has_properties is not None:
- for pid, hp in self._has_properties.items():
+ for _, hp in self._has_properties.items():
hp.print(offset + 4)
diff --git a/src/dsp_tools/models/set_encoder.py b/src/dsp_tools/models/set_encoder.py
index 56c145afd..e690ebd25 100644
--- a/src/dsp_tools/models/set_encoder.py
+++ b/src/dsp_tools/models/set_encoder.py
@@ -4,11 +4,11 @@
class SetEncoder(json.JSONEncoder):
- def default(self, obj):
- if isinstance(obj, set):
- return list(obj)
- elif isinstance(obj, Context):
- return obj.toJsonObj()
- elif isinstance(obj, OntoIri):
- return {"iri": obj.iri, "hashtag": obj.hashtag}
- return json.JSONEncoder.default(self, obj)
+ def default(self, o):
+ if isinstance(o, set):
+ return list(o)
+ elif isinstance(o, Context):
+ return o.toJsonObj()
+ elif isinstance(o, OntoIri):
+ return {"iri": o.iri, "hashtag": o.hashtag}
+ return json.JSONEncoder.default(self, o)
diff --git a/src/dsp_tools/models/sipi.py b/src/dsp_tools/models/sipi.py
index da6ce34bf..308c3bcfb 100644
--- a/src/dsp_tools/models/sipi.py
+++ b/src/dsp_tools/models/sipi.py
@@ -27,7 +27,11 @@ def upload_bitstream(self, filepath: str) -> dict[Any, Any]:
files = {
"file": (os.path.basename(filepath), bitstream_file),
}
- response = requests.post(self.sipi_server + "/upload?token=" + self.token, files=files)
+ response = requests.post(
+ self.sipi_server + "/upload?token=" + self.token,
+ files=files,
+ timeout=5 * 60,
+ )
check_for_api_error(response)
res: dict[Any, Any] = response.json()
return res
diff --git a/src/dsp_tools/models/user.py b/src/dsp_tools/models/user.py
index a9e75277e..3f88a8668 100644
--- a/src/dsp_tools/models/user.py
+++ b/src/dsp_tools/models/user.py
@@ -1,27 +1,3 @@
-from __future__ import annotations
-
-import json
-import os
-import sys
-import urllib.parse
-from typing import Any, Optional, Union
-from urllib.parse import quote_plus
-
-from dsp_tools.models.connection import Connection
-from dsp_tools.models.exceptions import BaseError
-from dsp_tools.models.group import Group
-from dsp_tools.models.helpers import Actions
-from dsp_tools.models.langstring import Languages
-from dsp_tools.models.model import Model
-from dsp_tools.models.project import Project
-
-path = os.path.abspath(os.path.dirname(__file__))
-(head, tail) = os.path.split(path)
-if not head in sys.path:
- sys.path.insert(0, head)
-if not path in sys.path:
- sys.path.insert(0, path)
-
"""
This module implements the handling (CRUD) of DSP users.
@@ -30,7 +6,7 @@
* Call the ``create``-method on the instance to create the new user
READ:
- * Instantiate a new objects with ``id``(IRI of user) given
+ * Instantiate a new objects with ``iri`` given
* Call the ``read``-method on the instance
* Access the information that has been ptovided to the instance
@@ -40,12 +16,27 @@
* Call the ``update```method on the instance
DELETE
- * Instantiate a new objects with ``id``(IRI of user) given, or use any instance that has the id set
+ * Instantiate a new objects with ``iri`` given, or use any instance that has the iri set
* Call the ``delete``-method on the instance
In addition there is a static methods ``getAllProjects`` which returns a list of all projects
"""
+from __future__ import annotations
+
+import json
+import urllib.parse
+from typing import Any, Optional, Union
+from urllib.parse import quote_plus
+
+from dsp_tools.models.connection import Connection
+from dsp_tools.models.exceptions import BaseError
+from dsp_tools.models.group import Group
+from dsp_tools.models.helpers import Actions
+from dsp_tools.models.langstring import Languages
+from dsp_tools.models.model import Model
+from dsp_tools.models.project import Project
+
class User(Model):
"""
@@ -54,7 +45,7 @@ class User(Model):
Attributes
----------
- id : str
+ iri : str
IRI of the user [readonly, cannot be modified after creation of instance]
username : str
@@ -138,7 +129,7 @@ class User(Model):
PROJECT_ADMIN_MEMBERSHIPS: str = "/project-admin-memberships/"
GROUP_MEMBERSHIPS: str = "/group-memberships/"
- _id: str
+ _iri: str
_username: str
_email: str
_givenName: str
@@ -158,7 +149,7 @@ class User(Model):
def __init__(
self,
con: Connection,
- id: Optional[str] = None,
+ iri: Optional[str] = None,
username: Optional[str] = None,
email: Optional[str] = None,
givenName: Optional[str] = None,
@@ -176,7 +167,7 @@ def __init__(
The constructor is user internally or externally, when a new user should be created in DSP.
:param con: Connection instance [required]
- :param id: IRI of the user [required for CREATE, READ]
+ :param iri: IRI of the user [required for CREATE, READ]
:param username: Username [required for CREATE]
:param email: Email address [required for CREATE]
:param givenName: Given name (firstname) of user [required for CREATE]
@@ -189,7 +180,7 @@ def __init__(
:param in_groups: Set with group-IRI's the user should belong to [optional]
"""
super().__init__(con)
- self._id = str(id) if id is not None else None
+ self._iri = iri
self._username = str(username) if username is not None else None
self._email = str(email) if email is not None else None
self._givenName = str(givenName) if givenName is not None else None
@@ -225,12 +216,12 @@ def __init__(
self._rm_from_group = set()
@property
- def id(self) -> Optional[str]:
- return self._id
+ def iri(self) -> Optional[str]:
+ return self._iri
- @id.setter
- def id(self, value: str) -> None:
- raise BaseError("User id cannot be modified!")
+ @iri.setter
+ def iri(self, value: str) -> None:
+ raise BaseError("User iri cannot be modified!")
@property
def username(self) -> Optional[str]:
@@ -443,9 +434,6 @@ def unmakeProjectAdmin(self, value: str):
def changed(self) -> set[str]:
return self._changed
- def has_changed(self, name: str):
- return name in self._changed
-
@classmethod
def fromJsonObj(cls, con: Connection, json_obj: Any) -> User:
"""
@@ -458,9 +446,9 @@ def fromJsonObj(cls, con: Connection, json_obj: Any) -> User:
:return: User instance
"""
- id = json_obj.get("id")
- if id is None:
- raise BaseError('User "id" is missing in JSON from DSP')
+ iri = json_obj.get("id")
+ if iri is None:
+ raise BaseError('User "iri" is missing in JSON from DSP')
email = json_obj.get("email")
if email is None:
raise BaseError('User "email" is missing in JSON from DSP')
@@ -493,7 +481,7 @@ def fromJsonObj(cls, con: Connection, json_obj: Any) -> User:
in_groups.add(group)
return cls(
con=con,
- id=id,
+ iri=iri,
username=username,
email=email,
givenName=givenName,
@@ -568,33 +556,33 @@ def create(self) -> Any:
jsonobj = self.toJsonObj(Actions.Create)
jsondata = json.dumps(jsonobj)
result = self._con.post(User.ROUTE, jsondata)
- id = result["user"]["id"]
+ iri = result["user"]["id"]
if self._in_projects is not None:
for project in self._in_projects:
- result = self._con.post(User.IRI + quote_plus(id) + User.PROJECT_MEMBERSHIPS + quote_plus(project))
+ result = self._con.post(User.IRI + quote_plus(iri) + User.PROJECT_MEMBERSHIPS + quote_plus(project))
if self._in_projects[project]:
result = self._con.post(
- User.IRI + quote_plus(id) + User.PROJECT_ADMIN_MEMBERSHIPS + quote_plus(project)
+ User.IRI + quote_plus(iri) + User.PROJECT_ADMIN_MEMBERSHIPS + quote_plus(project)
)
if self._in_groups is not None:
for group in self._in_groups:
- result = self._con.post(User.IRI + quote_plus(id) + User.GROUP_MEMBERSHIPS + quote_plus(group))
+ result = self._con.post(User.IRI + quote_plus(iri) + User.GROUP_MEMBERSHIPS + quote_plus(group))
return User.fromJsonObj(self._con, result["user"])
def read(self) -> Any:
"""
- Read the user information from DSP. The User object must have a valid id or email!
+ Read the user information from DSP. The User object must have a valid iri or email!
:return: JSON-object from DSP
"""
- if self._id is not None:
- result = self._con.get(User.IRI + quote_plus(self._id))
+ if self._iri is not None:
+ result = self._con.get(User.IRI + quote_plus(self._iri))
elif self._email is not None:
result = self._con.get(User.ROUTE + "/email/" + quote_plus(self._email))
elif self._username is not None:
result = self._con.get(User.ROUTE + "/username/" + quote_plus(self._username))
else:
- raise BaseError("Either user-id or email is required!")
+ raise BaseError("Either user-iri or email is required!")
return User.fromJsonObj(self._con, result["user"])
def update(self, requesterPassword: Optional[str] = None) -> Any:
@@ -608,52 +596,44 @@ def update(self, requesterPassword: Optional[str] = None) -> Any:
jsonobj = self.toJsonObj(Actions.Update)
if jsonobj:
jsondata = json.dumps(jsonobj)
- result = self._con.put(User.IRI + quote_plus(self.id) + "/BasicUserInformation", jsondata)
+ self._con.put(User.IRI + quote_plus(self.iri) + "/BasicUserInformation", jsondata)
if "status" in self._changed:
jsonobj = {"status": self._status}
jsondata = json.dumps(jsonobj)
- result = self._con.put(User.IRI + quote_plus(self.id) + "/Status", jsondata)
+ self._con.put(User.IRI + quote_plus(self.iri) + "/Status", jsondata)
if "password" in self._changed:
if requesterPassword is None:
raise BaseError("Requester's password is missing!")
jsonobj = {"requesterPassword": requesterPassword, "newPassword": self._password}
jsondata = json.dumps(jsonobj)
- result = self._con.put(User.IRI + quote_plus(self.id) + "/Password", jsondata)
+ self._con.put(User.IRI + quote_plus(self.iri) + "/Password", jsondata)
if "sysadmin" in self._changed:
jsonobj = {"systemAdmin": self._sysadmin}
jsondata = json.dumps(jsonobj)
- result = self._con.put(User.IRI + quote_plus(self.id) + "/SystemAdmin", jsondata)
+ self._con.put(User.IRI + quote_plus(self.iri) + "/SystemAdmin", jsondata)
for p in self._add_to_project.items():
- result = self._con.post(User.IRI + quote_plus(self._id) + User.PROJECT_MEMBERSHIPS + quote_plus(p[0]))
+ self._con.post(User.IRI + quote_plus(self._iri) + User.PROJECT_MEMBERSHIPS + quote_plus(p[0]))
if p[1]:
- result = self._con.post(
- User.IRI + quote_plus(self._id) + User.PROJECT_ADMIN_MEMBERSHIPS + quote_plus(p[0])
- )
+ self._con.post(User.IRI + quote_plus(self._iri) + User.PROJECT_ADMIN_MEMBERSHIPS + quote_plus(p[0]))
for p in self._rm_from_project:
if self._in_projects.get(p) is not None and self._in_projects[p]:
- result = self._con.delete(
- User.IRI + quote_plus(self._id) + User.PROJECT_ADMIN_MEMBERSHIPS + quote_plus(p)
- )
- result = self._con.delete(User.IRI + quote_plus(self._id) + User.PROJECT_MEMBERSHIPS + quote_plus(p))
+ self._con.delete(User.IRI + quote_plus(self._iri) + User.PROJECT_ADMIN_MEMBERSHIPS + quote_plus(p))
+ self._con.delete(User.IRI + quote_plus(self._iri) + User.PROJECT_MEMBERSHIPS + quote_plus(p))
for p in self._change_admin.items():
if not p[0] in self._in_projects:
raise BaseError("user must be member of project!")
if p[1]:
- result = self._con.post(
- User.IRI + quote_plus(self._id) + User.PROJECT_ADMIN_MEMBERSHIPS + quote_plus(p[0])
- )
+ self._con.post(User.IRI + quote_plus(self._iri) + User.PROJECT_ADMIN_MEMBERSHIPS + quote_plus(p[0]))
else:
- result = self._con.delete(
- User.IRI + quote_plus(self._id) + User.PROJECT_ADMIN_MEMBERSHIPS + quote_plus(p[0])
- )
+ self._con.delete(User.IRI + quote_plus(self._iri) + User.PROJECT_ADMIN_MEMBERSHIPS + quote_plus(p[0]))
for p in self._add_to_group:
- result = self._con.post(User.IRI + quote_plus(self._id) + User.GROUP_MEMBERSHIPS + quote_plus(p))
+ self._con.post(User.IRI + quote_plus(self._iri) + User.GROUP_MEMBERSHIPS + quote_plus(p))
for p in self._rm_from_group:
- result = self._con.delete(User.IRI + quote_plus(self._id) + User.GROUP_MEMBERSHIPS + quote_plus(p))
- user = User(con=self._con, id=self._id).read()
+ self._con.delete(User.IRI + quote_plus(self._iri) + User.GROUP_MEMBERSHIPS + quote_plus(p))
+ user = User(con=self._con, iri=self._iri).read()
return user
def delete(self):
@@ -661,7 +641,7 @@ def delete(self):
Delete the user in nore (NOT YET IMPLEMENTED)
:return: None
"""
- result = self._con.delete(User.IRI + quote_plus(self._id))
+ result = self._con.delete(User.IRI + quote_plus(self._iri))
return User.fromJsonObj(self._con, result["user"])
@staticmethod
@@ -736,7 +716,7 @@ def print(self) -> None:
"""
print("User info:")
- print(" Id: {}".format(self._id))
+ print(" IRI: {}".format(self._iri))
print(" Username: {}".format(self._username))
print(" Family name: {}".format(self._familyName))
print(" Given name: {}".format(self._givenName))
diff --git a/src/dsp_tools/models/value.py b/src/dsp_tools/models/value.py
index 0ca8c3fba..b8d8badc4 100644
--- a/src/dsp_tools/models/value.py
+++ b/src/dsp_tools/models/value.py
@@ -122,7 +122,7 @@ def get_typed_value(key: str, jsonld_obj: Any) -> Union[str, float]:
elif tmp.get("@id"):
result = tmp["@id"]
else:
- raise BaseError('Invalid data type in JSON-LD: "{}"!'.format(tmp["@type"]))
+ raise BaseError(f'Invalid data type in JSON-LD: "{tmp["@type"]}')
return result
except KeyError as kerr:
raise BaseError("Error in JSON-LD returned!") from kerr
@@ -279,11 +279,12 @@ def __init__(
# A DSP date value
#
m = re.match(
- r"^(GREGORIAN:|JULIAN:)?(CE:|BCE:)?(\d{4})(-\d{1,2})?(-\d{1,2})?((:CE|:BCE)?(:\d{4})(-\d{1,2})?(-\d{1,2})?)?$",
+ r"^(GREGORIAN:|JULIAN:)?(CE:|BCE:)?(\d{4})(-\d{1,2})?(-\d{1,2})?"
+ r"((:CE|:BCE)?(:\d{4})(-\d{1,2})?(-\d{1,2})?)?$",
str(value),
)
if not m:
- raise BaseError('Invalid date format: "{}"!'.format(str(value)))
+ raise BaseError(f'Invalid date format: "{value}"!')
dp = m.groups()
self._calendar = "GREGORIAN" if dp[0] is None else dp[0].strip("-: ")
self._e1 = "CE" if dp[1] is None else dp[1].strip("-: ")
@@ -635,7 +636,7 @@ def __init__(
ark_url: Optional[str] = None,
vark_url: Optional[str] = None,
):
- if type(value) is bool:
+ if isinstance(value, bool):
self._value = value
else:
if value == 1 or value.upper() == "TRUE" or value == "1":
@@ -733,10 +734,6 @@ def __str__(self) -> str:
class TimeValue(Value):
_value: str
- @property
- def value(self) -> str:
- return self._value
-
def __init__(
self,
value: str,
@@ -895,7 +892,7 @@ def find_listnode(nodes: list[ListNode], name: str) -> Optional[str]:
if node_iri is not None:
self._value = node_iri
else:
- raise BaseError('Listnode "{}" not found'.format(value))
+ raise BaseError(f'Listnode "{value}" not found')
super().__init__(
iri=iri,
comment=comment,
diff --git a/src/dsp_tools/models/xmlallow.py b/src/dsp_tools/models/xmlallow.py
index c7c70ab35..96b1a9704 100644
--- a/src/dsp_tools/models/xmlallow.py
+++ b/src/dsp_tools/models/xmlallow.py
@@ -30,7 +30,7 @@ def __init__(self, node: etree.Element, project_context: ProjectContext) -> None
else:
self._group = project_context.group_map.get(node.attrib["group"])
if self._group is None:
- raise XmlError('Group "{}" is not known: Cannot find project!'.format(node.attrib["group"]))
+ raise XmlError(f'Group "{node.attrib["group"]}" is not known: Cannot find project!')
else:
if project_context.project_name is None:
raise XmlError("Project shortcode has not been set in ProjectContext")
@@ -39,7 +39,7 @@ def __init__(self, node: etree.Element, project_context: ProjectContext) -> None
if tmp[0] in sysgroups:
self._group = "knora-admin:" + node.attrib["group"]
else:
- raise XmlError('Group "{}" is not known: '.format(node.attrib["group"]))
+ raise XmlError(f'Group "{node.attrib["group"]}" is not known: ')
self._permission = node.text
@property
diff --git a/src/dsp_tools/models/xmlpermission.py b/src/dsp_tools/models/xmlpermission.py
index e6ec5c8da..b5623933f 100644
--- a/src/dsp_tools/models/xmlpermission.py
+++ b/src/dsp_tools/models/xmlpermission.py
@@ -44,7 +44,7 @@ def get_permission_instance(self) -> Permissions:
def __str__(self) -> str:
allow_str: list[str] = []
for allow in self._allows:
- allow_str.append("{} {}".format(allow.permission, allow.group))
+ allow_str.append(f"{allow.permission} {allow.group}")
return "|".join(allow_str)
def print(self) -> None:
diff --git a/src/dsp_tools/models/xmlproperty.py b/src/dsp_tools/models/xmlproperty.py
index d1e850641..db3b55aa3 100644
--- a/src/dsp_tools/models/xmlproperty.py
+++ b/src/dsp_tools/models/xmlproperty.py
@@ -60,6 +60,6 @@ def values(self) -> list[XMLValue]:
def print(self) -> None:
"""Prints the property."""
- print(" Property: {} Type: {}".format(self._name, self._valtype))
+ print(f" Property: {self._name} Type: {self._valtype}")
for value in self._values:
value.print()
diff --git a/src/dsp_tools/utils/project_create.py b/src/dsp_tools/utils/project_create.py
index b4081052a..15026fe49 100644
--- a/src/dsp_tools/utils/project_create.py
+++ b/src/dsp_tools/utils/project_create.py
@@ -153,7 +153,7 @@ def _create_groups(
current_project_groups: dict[str, Group] = {}
try:
remote_groups: list[Group] = try_network_action(
- lambda: Group.getAllGroupsForProject(con=con, proj_iri=project.id) # type: ignore
+ lambda: Group.getAllGroupsForProject(con=con, proj_iri=project.iri) # type: ignore
)
except BaseError:
err_msg = (
@@ -266,7 +266,7 @@ def _get_group_iris_for_user(
logger.warning(err_msg, exc_info=True)
success = False
continue
- existing_group = [g for g in remote_groups if g.project == current_project.id and g.name == group_name]
+ existing_group = [g for g in remote_groups if g.project == current_project.iri and g.name == group_name]
if not existing_group:
print(f"\tWARNING: {inexisting_group_msg}")
success = False
@@ -338,7 +338,7 @@ def _get_projects_where_user_is_admin(
continue
in_project = in_project_list[0]
- project_info[in_project.id] = bool(project_role == "admin") # type: ignore
+ project_info[in_project.iri] = bool(project_role == "admin") # type: ignore
if verbose:
print(f"\tAdded user '{username}' as {project_role} to project '{in_project.shortname}'.")
@@ -536,7 +536,7 @@ def _create_ontologies(
print("Create ontologies...")
try:
project_ontologies: list[Ontology] = try_network_action(
- lambda: Ontology.getProjectOntologies(con=con, project_id=project_remote.id) # type: ignore
+ lambda: Ontology.getProjectOntologies(con=con, project_id=project_remote.iri) # type: ignore
)
except BaseError:
err_msg = "Unable to retrieve remote ontologies. Cannot check if your ontology already exists."
@@ -666,7 +666,7 @@ def _add_resource_classes_to_remote_ontology(
res_class_local.create, last_modification_date
)
res_class_remote = cast(ResourceClass, res_class_remote)
- new_res_classes[str(res_class_remote.id)] = res_class_remote
+ new_res_classes[str(res_class_remote.iri)] = res_class_remote
ontology_remote.lastModificationDate = last_modification_date
if verbose:
print(f"\tCreated resource class '{res_class['name']}'")
@@ -748,8 +748,8 @@ def _add_property_classes_to_remote_ontology(
name=prop_class["name"],
ontology_id=ontology_remote.iri,
superproperties=super_props,
- object=prop_object,
- subject=prop_class.get("subject"),
+ rdf_object=prop_object,
+ rdf_subject=prop_class.get("subject"),
gui_element="salsah-gui:" + prop_class["gui_element"],
gui_attributes=gui_attributes,
comment=LangString(prop_class["comments"]) if prop_class.get("comments") else None,
diff --git a/src/dsp_tools/utils/project_create_lists.py b/src/dsp_tools/utils/project_create_lists.py
index 5c2735e89..c754152a0 100644
--- a/src/dsp_tools/utils/project_create_lists.py
+++ b/src/dsp_tools/utils/project_create_lists.py
@@ -93,7 +93,7 @@ def create_lists_on_server(
# retrieve existing lists
try:
existing_lists: list[ListNode] = try_network_action(
- lambda: ListNode.getAllLists(con=con, project_iri=project_remote.id)
+ lambda: ListNode.getAllLists(con=con, project_iri=project_remote.iri)
)
except BaseError:
err_msg = "Unable to retrieve existing lists on DSP server. Cannot check if your lists are already existing."
@@ -105,7 +105,7 @@ def create_lists_on_server(
current_project_lists: dict[str, Any] = {}
for new_list in lists_to_create:
# if list exists already, add it to "current_project_lists" (for later usage), then skip it
- existing_list = [x for x in existing_lists if x.project == project_remote.id and x.name == new_list["name"]]
+ existing_list = [x for x in existing_lists if x.project == project_remote.iri and x.name == new_list["name"]]
if existing_list:
existing_list_name = existing_list[0].name
if not existing_list_name:
diff --git a/src/dsp_tools/utils/project_get.py b/src/dsp_tools/utils/project_get.py
index bb1b70d86..9527e7c9c 100644
--- a/src/dsp_tools/utils/project_get.py
+++ b/src/dsp_tools/utils/project_get.py
@@ -59,7 +59,7 @@ def get_project(
if verbose:
print("Getting groups...")
groups_obj: list[dict[str, Any]] = []
- groups = Group.getAllGroupsForProject(con=con, proj_iri=str(project.id))
+ groups = Group.getAllGroupsForProject(con=con, proj_iri=str(project.iri))
if groups:
for group in groups:
groups_obj.append(group.createDefinitionFileObj())
@@ -78,7 +78,7 @@ def get_project(
usr.createDefinitionFileObj(
con=con,
proj_shortname=str(project.shortname),
- proj_iri=str(project.id),
+ proj_iri=str(project.iri),
)
)
if verbose:
@@ -89,7 +89,7 @@ def get_project(
if verbose:
print("Getting lists...")
list_obj: list[dict[str, Any]] = []
- list_roots = ListNode.getAllLists(con=con, project_iri=project.id)
+ list_roots = ListNode.getAllLists(con=con, project_iri=project.iri)
if list_roots:
for list_root in list_roots:
complete_list = list_root.getAllNodes()
@@ -103,7 +103,7 @@ def get_project(
print("Getting ontologies...")
project_obj["ontologies"] = []
prefixes: dict[str, str] = dict()
- ontologies = Ontology.getProjectOntologies(con, str(project.id))
+ ontologies = Ontology.getProjectOntologies(con, str(project.iri))
ontology_ids = [onto.iri for onto in ontologies]
for ontology_id in ontology_ids:
onto_url_parts = ontology_id.split("/") # an id has the form http://0.0.0.0:3333/ontology/4123/testonto/v2
diff --git a/test/e2e/test_project.py b/test/e2e/test_project.py
index fc0f432aa..3c318cea1 100644
--- a/test/e2e/test_project.py
+++ b/test/e2e/test_project.py
@@ -24,7 +24,7 @@ def setUp(self) -> None:
def test_Project(self) -> None:
project = Project(
con=self.con,
- id="http://rdfh.ch/test",
+ iri="http://rdfh.ch/test",
shortcode="0FF0",
shortname="test_project",
longname="Test Project",
@@ -36,7 +36,7 @@ def test_Project(self) -> None:
)
self.assertIsNotNone(project)
- self.assertEqual(project.id, "http://rdfh.ch/test")
+ self.assertEqual(project.iri, "http://rdfh.ch/test")
self.assertEqual(project.shortcode, "0FF0")
self.assertEqual(project.shortname, "test_project")
self.assertEqual(project.longname, "Test Project")
@@ -47,9 +47,9 @@ def test_Project(self) -> None:
self.assertEqual(project.keywords, {"test", "project"})
def test_project_read(self) -> None:
- project = Project(con=self.con, id="http://rdfh.ch/projects/0001").read()
+ project = Project(con=self.con, iri="http://rdfh.ch/projects/0001").read()
- self.assertEqual(project.id, "http://rdfh.ch/projects/0001")
+ self.assertEqual(project.iri, "http://rdfh.ch/projects/0001")
self.assertEqual(project.shortcode, "0001")
self.assertEqual(project.shortname, "anything")
self.assertEqual(project.longname, "Anything Project")
diff --git a/test/e2e/test_propertyclass.py b/test/e2e/test_propertyclass.py
index 903592e95..1cd8cb4a1 100644
--- a/test/e2e/test_propertyclass.py
+++ b/test/e2e/test_propertyclass.py
@@ -61,14 +61,14 @@ def test_PropertyClass_create(self) -> None:
context=self.onto.context,
name=self.name,
ontology_id=self.onto.iri,
- object=self.object,
+ rdf_object=self.object,
label=self.label,
comment=self.comment,
).create(self.last_modification_date)
self.onto.lastModificationDate = self.last_modification_date
- self.assertIsNotNone(property_class.id)
+ self.assertIsNotNone(property_class.iri)
self.assertEqual(property_class.name, self.name)
self.assertEqual(property_class.label["de"], self.label["de"])
self.assertEqual(property_class.comment["de"], self.comment["de"])
@@ -90,12 +90,12 @@ def test_PropertyClass_update(self) -> None:
context=self.onto.context,
name=self.name,
ontology_id=self.onto.iri,
- object=self.object,
+ rdf_object=self.object,
label=self.label,
comment=self.comment,
).create(self.last_modification_date)
self.onto.lastModificationDate = self.last_modification_date
- self.assertIsNotNone(property_class.id)
+ self.assertIsNotNone(property_class.iri)
# modify the property class
property_class.addLabel("en", "This is english comment")
diff --git a/test/e2e/test_resourceclass.py b/test/e2e/test_resourceclass.py
index f5d5ec5ef..fb4291c5a 100644
--- a/test/e2e/test_resourceclass.py
+++ b/test/e2e/test_resourceclass.py
@@ -46,7 +46,7 @@ def test_ResourceClass_create(self) -> None:
comment=self.res_comment,
).create(last_modification_date_onto)
- self.assertIsNotNone(res_class.id)
+ self.assertIsNotNone(res_class.iri)
self.assertEqual(res_class.name, self.res_name)
self.assertEqual(res_class.label["en"], self.res_label["en"])
self.assertEqual(res_class.comment["en"], self.res_comment["en"])
@@ -73,7 +73,7 @@ def test_ResourceClass_update(self) -> None:
onto.lastModificationDate = last_modification_date
- self.assertIsNotNone(res_class.id)
+ self.assertIsNotNone(res_class.iri)
# modify the resource class
res_class.addLabel("de", "Dies ist ein Kommentar")
diff --git a/test/e2e/test_user.py b/test/e2e/test_user.py
index e28a5d33b..33072469a 100644
--- a/test/e2e/test_user.py
+++ b/test/e2e/test_user.py
@@ -50,8 +50,8 @@ def test_user_create(self) -> None:
self.assertEqual(user.in_groups, {iri_group_thing_searcher})
def test_user_read_by_iri(self) -> None:
- user = User(con=self.con, id="http://rdfh.ch/users/normaluser").read()
- self.assertEqual(user.id, "http://rdfh.ch/users/normaluser")
+ user = User(con=self.con, iri="http://rdfh.ch/users/normaluser").read()
+ self.assertEqual(user.iri, "http://rdfh.ch/users/normaluser")
self.assertEqual(user.username, "normaluser")
self.assertEqual(user.familyName, "User")
self.assertEqual(user.givenName, "Normal")
@@ -286,7 +286,7 @@ def test_user_add_as_project_admin(self) -> None:
def test_user_get_all_users(self) -> None:
all_users = User.getAllUsers(self.con)
for user in all_users:
- self.assertIsNotNone(user.id)
+ self.assertIsNotNone(user.iri)
def tearDown(self) -> None:
"""