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?? 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.prefixFromIri( "http://www.w3.org/1999/02/22-rdf-syntax-ns#") rdfs = context.prefixFromIri("http://www.w3.org/2000/01/rdf-schema#") owl = context.prefixFromIri("http://www.w3.org/2002/07/owl#") xsd = context.prefixFromIri("http://www.w3.org/2001/XMLSchema#") knora_api = context.prefixFromIri( "http://api.knora.org/ontology/knora-api/v2#") salsah_gui = context.prefixFromIri( "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!") if json_obj.get('@id') is None: raise BaseError('Resource class has no "@id"!') tmp_id = json_obj.get('@id').split(':') id = context.iriFromPrefix(tmp_id[0]) + '#' + tmp_id[1] ontology_id = tmp_id[0] name = tmp_id[1] superclasses_obj = json_obj.get(rdfs + ':subClassOf') if superclasses_obj is not None: supercls: List[Any] = list( filter(lambda a: a.get('@id') is not None, superclasses_obj)) superclasses: List[str] = list(map(lambda a: a['@id'], supercls)) has_props: List[Any] = list( filter(lambda a: a.get('@type') == (owl + ':Restriction'), superclasses_obj)) has_properties: Dict[HasProperty] = dict( map(lambda a: HasProperty.fromJsonObj(con, context, a), has_props)) else: superclasses = None has_properties = None label = LangString.fromJsonLdObj(json_obj.get(rdfs + ':label')) comment = LangString.fromJsonLdObj(json_obj.get(rdfs + ':comment')) return cls(con=con, context=context, name=name, id=id, ontology_id=ontology_id, superclasses=superclasses, label=label, comment=comment, has_properties=has_properties)
def label(self, value: Optional[Union[LangString, str]]) -> None: if value is None: self._label.empty() # clear all labels else: if isinstance(value, LangString): self._label = value elif isinstance(value, str): self._label = LangString(value) else: raise BaseError('Not a valid LangString') self._changed.add('label')
def comment(self, value: Optional[LangString]) -> None: if value is None: self._comment.empty() # clear all comments! else: if isinstance(value, LangString): self._comment = value elif isinstance(value, str): self._comment = LangString(value) else: raise BaseError('Not a valid LangString') self._changed.add('comment')
def __init__(self, con: Connection, context: Context, id: Optional[str] = None, name: Optional[str] = None, ontology_id: Optional[str] = None, superclasses: Optional[List[Union['ResourceClass', str]]] = None, label: Optional[Union[LangString, str]] = None, comment: Optional[Union[LangString, str]] = None, permissions: Optional[str] = None, has_properties: Optional[Dict[str, HasProperty]] = None): 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') self.con = con self._context = context self._id = id self._name = name self._ontology_id = ontology_id if isinstance(superclasses, ResourceClass): self._superclasses = list(map(lambda a: a.id, superclasses)) else: self._superclasses = superclasses # # process label # if label is not None: if isinstance(label, str): self._label = LangString(label) elif isinstance(label, LangString): self._label = label else: raise BaseError('Invalid LangString for label!') else: self._label = None # # process comment # if comment is not None: if isinstance(comment, str): self._comment = LangString(comment) elif isinstance(comment, LangString): self._comment = comment else: raise BaseError('Invalid LangString for comment!') else: self._comment = None self._permissions = permissions self._has_properties = has_properties self._changed = set()
def __init__(self, con: Connection, id: Optional[str] = None, shortcode: Optional[str] = None, shortname: Optional[str] = None, longname: Optional[str] = None, description: LangStringParam = None, keywords: Optional[Set[str]] = None, ontologies: Optional[Set[str]] = None, selfjoin: Optional[bool] = None, status: Optional[bool] = None, logo: Optional[str] = None): """ 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 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] :param keywords: Set of keywords [required for CREATE] :param ontologies: Set of ontologies that belong to this project [optional] :param selfjoin: Allow selfjoin [required for CREATE] :param status: Status of project (active if True) [required for CREATE] :param logo: Path to logo image file [optional] NOT YET USED """ if not isinstance(con, Connection): raise BaseError( '"con"-parameter must be an instance of Connection') self.con = con self._id = id self._shortcode = shortcode self._shortname = shortname self._longname = longname self._description = LangString(description) self._keywords = keywords if not isinstance(ontologies, set) and ontologies is not None: raise BaseError('Ontologies must be a set of strings or None!') self._ontologies = ontologies self._selfjoin = selfjoin self._status = status self._logo = logo self.changed = set()
def fromJsonObj(cls, con: Connection, json_obj: Any) -> Any: """ Internal method! Should not be used directly! This method is used to create a ListNode instance from the JSON data returned by Knora :param con: Connection instance :param json_obj: JSON data returned by Knora as python3 object :return: ListNode instance """ id = json_obj.get('id') project = json_obj.get('projectIri') if id is None: raise BaseError('ListNode id is missing') label = LangString.fromJsonObj(json_obj.get('labels')) comment = LangString.fromJsonObj(json_obj.get('comments')) name = json_obj.get('name') parent = json_obj.get('parentNodeIri') isRootNode = json_obj.get('isRootNode') child_info = json_obj.get('children') children = None if child_info is not None: children = ListNode._getChildren(con, child_info) rootNodeIri = json_obj.get('hasRootNode') return cls(con=con, id=id, project=project, label=label, comment=comment, name=name, parent=parent, isRootNode=isRootNode, children=children, rootNodeIri=rootNodeIri)
def fromJsonObj(cls, con: Connection, json_obj: Any) -> Any: """ Internal method! Should not be used directly! This method is used to create a Project instance from the JSON data returned by Knora :param con: Connection instance :param json_obj: JSON data returned by Knora as python3 object :return: Project instance """ id = json_obj.get('id') if id is None: raise BaseError('Project id is missing') shortcode = json_obj.get('shortcode') if shortcode is None: raise BaseError("Shortcode is missing") shortname = json_obj.get('shortname') if shortname is None: raise BaseError("Shortname is missing") longname = json_obj.get('longname') if longname is None: raise BaseError("Longname is missing") description = LangString.fromJsonObj(json_obj.get('description')) keywords = set(json_obj.get('keywords')) if keywords is None: raise BaseError("Keywords are missing") ontologies = set(json_obj.get('ontologies')) if ontologies is None: raise BaseError("Keywords are missing") selfjoin = json_obj.get('selfjoin') if selfjoin is None: raise BaseError("Selfjoin is missing") status = json_obj.get('status') if status is None: raise BaseError("Status is missing") logo = json_obj.get('logo') return cls(con=con, id=id, shortcode=shortcode, shortname=shortname, longname=longname, description=description, keywords=keywords, ontologies=ontologies, selfjoin=selfjoin, status=status, logo=logo)
def toJsonObj(self, lastModificationDate: LastModificationDate, action: Actions, what: Optional[str] = None) -> Any: def resolve_resref(resref: str): tmp = resref.split(':') if len(tmp) > 1: if tmp[0]: return { "@id": resref } # fully qualified name in the form "prefix:name" else: return { "@id": self._context.prefixFromIri(self._ontology_id) + ':' + tmp[1] } # ":name" in current ontology else: return { "@id": "knora-api:" + resref } # no ":", must be from knora-api! tmp = {} exp = re.compile('^http.*') # It is already a fully IRI if exp.match(self._ontology_id): resid = self._context.prefixFromIri( self._ontology_id) + ":" + self._name ontid = self._ontology_id else: resid = self._ontology_id + ":" + self._name ontid = self._context.iriFromPrefix(self._ontology_id) if action == Actions.Create: if self._name is None: raise BaseError("There must be a valid resource class name!") if self._ontology_id is None: raise BaseError("There must be a valid ontology_id given!") if self._superclasses is None: superclasses = [{"@id": "knora-api:Resource"}] else: superclasses = list(map(resolve_resref, self._superclasses)) if self._comment is None or self._comment.isEmpty(): self._comment = LangString("no comment vailable") tmp = { "@id": ontid, # self._ontology_id, "@type": "owl:Ontology", "knora-api:lastModificationDate": lastModificationDate.toJsonObj(), "@graph": [{ "@id": resid, "@type": "owl:Class", "rdfs:label": self._label.toJsonLdObj(), "rdfs:comment": self._comment.toJsonLdObj(), "rdfs:subClassOf": superclasses }], "@context": self._context.toJsonObj(), } elif action == Actions.Update: tmp = { "@id": ontid, # self._ontology_id, "@type": "owl:Ontology", "knora-api:lastModificationDate": lastModificationDate.toJsonObj(), "@graph": [{ "@id": resid, "@type": "owl:Class", }], "@context": self._context.toJsonObj(), } if what == 'label': if not self._label.isEmpty() and 'label' in self._changed: tmp['@graph'][0]['rdfs:label'] = self._label.toJsonLdObj() if what == 'comment': if not self._comment.isEmpty() and 'comment' in self._changed: tmp['@graph'][0][ 'rdfs:comment'] = self._comment.toJsonLdObj() return tmp
class ResourceClass: con: Connection _context: Context _id: str _name: str _ontology_id: str _superclasses: List[str] _label: LangString _comment: LangString _permissions: str _has_properties: Dict[str, HasProperty] _changed: Set[str] def __init__(self, con: Connection, context: Context, id: Optional[str] = None, name: Optional[str] = None, ontology_id: Optional[str] = None, superclasses: Optional[List[Union['ResourceClass', str]]] = None, label: Optional[Union[LangString, str]] = None, comment: Optional[Union[LangString, str]] = None, permissions: Optional[str] = None, has_properties: Optional[Dict[str, HasProperty]] = None): 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') self.con = con self._context = context self._id = id self._name = name self._ontology_id = ontology_id if isinstance(superclasses, ResourceClass): self._superclasses = list(map(lambda a: a.id, superclasses)) else: self._superclasses = superclasses # # process label # if label is not None: if isinstance(label, str): self._label = LangString(label) elif isinstance(label, LangString): self._label = label else: raise BaseError('Invalid LangString for label!') else: self._label = None # # process comment # if comment is not None: if isinstance(comment, str): self._comment = LangString(comment) elif isinstance(comment, LangString): self._comment = comment else: raise BaseError('Invalid LangString for comment!') else: self._comment = None self._permissions = permissions self._has_properties = has_properties self._changed = set() # # Here follows a list of getters/setters # @property def name(self) -> Optional[str]: return self._name @name.setter def name(self, value: str) -> None: raise BaseError('"name" cannot be modified!') @property def id(self) -> Optional[str]: return self._id @id.setter def id(self, value: str) -> None: raise BaseError('"id" cannot be modified!') @property def ontology_id(self) -> Optional[str]: return self._ontology_id @ontology_id.setter def ontology_id(self, value: str) -> None: raise BaseError('"ontology_id" cannot be modified!') @property def superclasses(self) -> Optional[List[str]]: return self._superclasses @superclasses.setter def superclasses(self, value: List[str]) -> None: raise BaseError('"superclasses" cannot be modified!') @property def label(self) -> Optional[LangString]: return self._label @label.setter def label(self, value: Optional[Union[LangString, str]]) -> None: if value is None: self._label.empty() # clear all labels else: if isinstance(value, LangString): self._label = value elif isinstance(value, str): self._label = LangString(value) else: raise BaseError('Not a valid LangString') self._changed.add('label') def addLabel(self, lang: Union[Languages, str], value: str) -> None: self._label[lang] = value self._changed.add('label') def rmLabel(self, lang: Union[Languages, str]) -> None: del self._label[lang] self._changed.add('label') @property def comment(self) -> Optional[LangString]: return self._comment @comment.setter def comment(self, value: Optional[LangString]) -> None: if value is None: self._comment.empty() # clear all comments! else: if isinstance(value, LangString): self._comment = value elif isinstance(value, str): self._comment = LangString(value) else: raise BaseError('Not a valid LangString') self._changed.add('comment') def addComment(self, lang: Union[Languages, str], value: str) -> None: self._comment[lang] = value self._changed.add('comment') def rmComment(self, lang: Union[Languages, str]) -> None: del self._comment[lang] self._changed.add('comment') @property def permissions(self) -> Optional[str]: return self._permissions @permissions.setter def permissions(self, value: str) -> None: raise BaseError('"permissions" cannot be modified!') @property def has_property(self) -> Dict[str, HasProperty]: return self._has_properties @has_property.setter def has_property(self, value: str) -> None: raise BaseError('"has_property" cannot be modified!') def getProperty(self, property_id) -> Optional[HasProperty]: if self._has_properties is None: return None else: return self._has_properties.get( self._context.getPrefixIri(property_id)) def addProperty( self, property_id: str, cardinality: Cardinality, last_modification_date: LastModificationDate ) -> Optional[LastModificationDate]: if self._has_properties.get(property_id) is None: latest_modification_date, resclass = HasProperty( con=self.con, context=self._context, ontology_id=self._ontology_id, property_id=property_id, resclass_id=self.id, cardinality=cardinality).create(last_modification_date) hp = resclass.getProperty(property_id) hp.ontology_id = self._context.iriFromPrefix(self._ontology_id) hp.resclass_id = self.id self._has_properties[hp.property_id] = hp return latest_modification_date else: raise BaseError("Property already has cardinality in this class!") def updateProperty( self, property_id: str, cardinality: Cardinality, last_modification_date: LastModificationDate ) -> Optional[LastModificationDate]: property_id = self._context.getPrefixIri(property_id) if self._has_properties.get(property_id) is not None: has_properties = self._has_properties[property_id] onto_id = has_properties.ontology_id # save for later user rescl_id = has_properties.resclass_id # save for later user has_properties.cardinality = cardinality latest_modification_date, resclass = has_properties.update( last_modification_date) hp = resclass.getProperty(property_id) hp.ontology_id = self._context.iriFromPrefix( onto_id) # restore value hp.resclass_id = rescl_id # restore value self._has_properties[hp.property_id] = hp return latest_modification_date else: return last_modification_date @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?? 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.prefixFromIri( "http://www.w3.org/1999/02/22-rdf-syntax-ns#") rdfs = context.prefixFromIri("http://www.w3.org/2000/01/rdf-schema#") owl = context.prefixFromIri("http://www.w3.org/2002/07/owl#") xsd = context.prefixFromIri("http://www.w3.org/2001/XMLSchema#") knora_api = context.prefixFromIri( "http://api.knora.org/ontology/knora-api/v2#") salsah_gui = context.prefixFromIri( "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!") if json_obj.get('@id') is None: raise BaseError('Resource class has no "@id"!') tmp_id = json_obj.get('@id').split(':') id = context.iriFromPrefix(tmp_id[0]) + '#' + tmp_id[1] ontology_id = tmp_id[0] name = tmp_id[1] superclasses_obj = json_obj.get(rdfs + ':subClassOf') if superclasses_obj is not None: supercls: List[Any] = list( filter(lambda a: a.get('@id') is not None, superclasses_obj)) superclasses: List[str] = list(map(lambda a: a['@id'], supercls)) has_props: List[Any] = list( filter(lambda a: a.get('@type') == (owl + ':Restriction'), superclasses_obj)) has_properties: Dict[HasProperty] = dict( map(lambda a: HasProperty.fromJsonObj(con, context, a), has_props)) else: superclasses = None has_properties = None label = LangString.fromJsonLdObj(json_obj.get(rdfs + ':label')) comment = LangString.fromJsonLdObj(json_obj.get(rdfs + ':comment')) return cls(con=con, context=context, name=name, id=id, ontology_id=ontology_id, superclasses=superclasses, label=label, comment=comment, has_properties=has_properties) def toJsonObj(self, lastModificationDate: LastModificationDate, action: Actions, what: Optional[str] = None) -> Any: def resolve_resref(resref: str): tmp = resref.split(':') if len(tmp) > 1: if tmp[0]: return { "@id": resref } # fully qualified name in the form "prefix:name" else: return { "@id": self._context.prefixFromIri(self._ontology_id) + ':' + tmp[1] } # ":name" in current ontology else: return { "@id": "knora-api:" + resref } # no ":", must be from knora-api! tmp = {} exp = re.compile('^http.*') # It is already a fully IRI if exp.match(self._ontology_id): resid = self._context.prefixFromIri( self._ontology_id) + ":" + self._name ontid = self._ontology_id else: resid = self._ontology_id + ":" + self._name ontid = self._context.iriFromPrefix(self._ontology_id) if action == Actions.Create: if self._name is None: raise BaseError("There must be a valid resource class name!") if self._ontology_id is None: raise BaseError("There must be a valid ontology_id given!") if self._superclasses is None: superclasses = [{"@id": "knora-api:Resource"}] else: superclasses = list(map(resolve_resref, self._superclasses)) if self._comment is None or self._comment.isEmpty(): self._comment = LangString("no comment vailable") tmp = { "@id": ontid, # self._ontology_id, "@type": "owl:Ontology", "knora-api:lastModificationDate": lastModificationDate.toJsonObj(), "@graph": [{ "@id": resid, "@type": "owl:Class", "rdfs:label": self._label.toJsonLdObj(), "rdfs:comment": self._comment.toJsonLdObj(), "rdfs:subClassOf": superclasses }], "@context": self._context.toJsonObj(), } elif action == Actions.Update: tmp = { "@id": ontid, # self._ontology_id, "@type": "owl:Ontology", "knora-api:lastModificationDate": lastModificationDate.toJsonObj(), "@graph": [{ "@id": resid, "@type": "owl:Class", }], "@context": self._context.toJsonObj(), } if what == 'label': if not self._label.isEmpty() and 'label' in self._changed: tmp['@graph'][0]['rdfs:label'] = self._label.toJsonLdObj() if what == 'comment': if not self._comment.isEmpty() and 'comment' in self._changed: tmp['@graph'][0][ 'rdfs:comment'] = self._comment.toJsonLdObj() return tmp def create( self, last_modification_date: LastModificationDate ) -> Tuple[LastModificationDate, 'ResourceClass']: jsonobj = self.toJsonObj(last_modification_date, Actions.Create) jsondata = json.dumps(jsonobj) result = self.con.post('/v2/ontologies/classes', jsondata) last_modification_date = LastModificationDate( result['knora-api:lastModificationDate']) return last_modification_date, ResourceClass.fromJsonObj( self.con, self._context, result['@graph']) def update( self, last_modification_date: LastModificationDate ) -> Tuple[LastModificationDate, 'ResourceClass']: # # Note: Knora is able to change only one thing per call, either label or comment! # result = None something_changed = False if 'label' in self._changed: jsonobj = self.toJsonObj(last_modification_date, Actions.Update, 'label') jsondata = json.dumps(jsonobj, cls=SetEncoder, indent=4) result = self.con.put('v2/ontologies/classes', jsondata) last_modification_date = LastModificationDate( result['knora-api:lastModificationDate']) something_changed = True if 'comment' in self._changed: jsonobj = self.toJsonObj(last_modification_date, Actions.Update, 'comment') jsondata = json.dumps(jsonobj, cls=SetEncoder, indent=4) result = self.con.put('v2/ontologies/classes', jsondata) last_modification_date = LastModificationDate( result['knora-api:lastModificationDate']) something_changed = True if something_changed: return last_modification_date, ResourceClass.fromJsonObj( self.con, self._context, result['@graph']) else: return last_modification_date, self def delete( self, last_modification_date: LastModificationDate ) -> LastModificationDate: result = self.con.delete('v2/ontologies/classes/' + quote_plus(self._id) + '?lastModificationDate=' + str(last_modification_date)) return LastModificationDate(result['knora-api:lastModificationDate']) def print(self, offset: int = 0): blank = ' ' print(f'{blank:>{offset}}Resource Class Info') print(f'{blank:>{offset+2}}Name: {self._name}') print(f'{blank:>{offset+2}}Ontology prefix: {self._ontology_id}') print(f'{blank:>{offset+2}}Superclasses:') if self._superclasses is not None: for sc in self._superclasses: print(f'{blank:>{offset + 4}}{sc}') if self._label is not None: print(f'{blank:>{offset + 2}}Labels:') self._label.print(offset + 4) if self._comment is not None: print(f'{blank:>{offset + 2}}Comments:') self._comment.print(offset + 4) 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(): hp.print(offset + 4)
def label(self, value: Optional[Union[LangString, str]]) -> None: self._label = LangString(value) self.changed.add('label')
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?? 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.prefixFromIri( "http://www.w3.org/1999/02/22-rdf-syntax-ns#") rdfs = context.prefixFromIri("http://www.w3.org/2000/01/rdf-schema#") owl = context.prefixFromIri("http://www.w3.org/2002/07/owl#") xsd = context.prefixFromIri("http://www.w3.org/2001/XMLSchema#") knora_api = context.prefixFromIri( "http://api.knora.org/ontology/knora-api/v2#") salsah_gui = context.prefixFromIri( "http://api.knora.org/ontology/salsah-gui/v2#") 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.iriFromPrefix(tmp_id[0]) + '#' + tmp_id[1] ontology_id = tmp_id[0] name = tmp_id[1] superproperties_obj = json_obj.get(rdfs + ':subPropertyOf') superproperties: List[Union[None, str]] if not isinstance(superproperties_obj, list): superproperties_obj = [superproperties_obj ] # make a list out of it if superproperties_obj is not None: superprops: List[Any] = list( filter(lambda a: a.get('@id') is not None, superproperties_obj)) superproperties = list(map(lambda a: a['@id'], superprops)) else: superproperties = None object = WithId(json_obj.get(knora_api + ':objectType')).str() 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 if json_obj.get(salsah_gui + ':guiElement') is not None: gui_element = WithId(json_obj.get(salsah_gui + ':guiElement')).str() gui_attributes_list = json_obj.get(salsah_gui + ':guiAttribute') gui_attributes: Union[None, Dict[str, str]] = None if gui_attributes_list is not None: gui_attributes = {} if not isinstance(gui_attributes_list, list): gui_attributes_list = [gui_attributes_list] for ga in gui_attributes_list: tmp = ga.split('=') if len(tmp) == 1: gui_attributes[tmp[0]] = '' else: gui_attributes[tmp[0]] = tmp[1] editable = json_obj.get(knora_api + ':isEditable') linkvalue = json_obj.get(knora_api + ':isLinkProperty') return cls(con=con, context=context, id=id, name=name, ontology_id=ontology_id, superproperties=superproperties, object=object, subject=subject, gui_element=gui_element, gui_attributes=gui_attributes, label=label, comment=comment, editable=editable, linkvalue=linkvalue)
def description(self, value: Optional[LangString]) -> None: self._description = LangString(value) self.changed.add('description')
if __name__ == '__main__': con = Connection('http://0.0.0.0:3333') con.login('*****@*****.**', 'test') projects = Project.getAllProjects(con) for project in projects: project.print() print('==============================================================') new_project = Project(con=con, shortcode='F11F', shortname='mytest3', longname='A Test beloning to me', description=LangString( {Languages.EN: 'My Tests description'}), keywords={'AAA', 'BBB'}, selfjoin=False, status=True).create() new_project.print() new_project.longname = 'A long name fore a short project' new_project.status = False new_project.description = LangString( {Languages.DE: 'Beschreibung meines Tests'}) new_project.add_keyword('CCC') new_project = new_project.update() new_project.print() new_project = new_project.delete()
def program(args): # # parse the arguments of the command line # parser = argparse.ArgumentParser() parser.add_argument("datamodelfile", help="path to data model file") parser.add_argument("-s", "--server", type=str, default="http://0.0.0.0:3333", help="URL of the Knora server") parser.add_argument("-u", "--user", default="*****@*****.**", help="Username for Knora") parser.add_argument("-p", "--password", default="test", help="The password for login") parser.add_argument( "-V", "--validate", action='store_true', help="Do only validation of JSON, no upload of the ontology") parser.add_argument("-l", "--lists", action='store_true', help="Only create the lists") parser.add_argument("-v", "--verbose", action="store_true", help="Verbose feedback") args = parser.parse_args(args) current_dir = os.path.dirname(os.path.realpath(__file__)) # let's read the schema for the data model definition if args.lists: with open(os.path.join(current_dir, 'knora-schema-lists.json')) as s: schema = json.load(s) else: with open(os.path.join(current_dir, 'knora-schema.json')) as s: schema = json.load(s) # read the data model definition with open(args.datamodelfile) as f: datamodel = json.load(f) # validate the data model definition in order to be sure that it is correct validate(datamodel, schema) print("data model is syntactically correct and passed validation!") if args.validate: exit(0) # # Connect to the DaSCH Service Platform API # con = Connection(args.server) con.login(args.user, args.password) # -------------------------------------------------------------------------- # let's read the prefixes of external ontologies that may be used # context = Context(datamodel["prefixes"]) # -------------------------------------------------------------------------- # Let's create the project... # project = None if not args.lists: # # Deal with the project info # try: # we try to read the project to see if it's existing.... project = Project( con=con, shortcode=datamodel["project"]["shortcode"], ).read() # # we got it, update the project data if necessary... # if project.shortname != datamodel["project"]["shortname"]: project.shortname = datamodel["project"]["shortname"] if project.longname != datamodel["project"]["longname"]: project.longname == datamodel["project"]["longname"] project.description = datamodel["project"].get("descriptions") project.keywords = set(datamodel["project"].get("keywords")) nproject = project.update() if nproject is not None: project = nproject if args.verbose: print("Modified project:") project.print() except: # # The project doesn't exist yet – let's create it # try: project = Project( con=con, shortcode=datamodel["project"]["shortcode"], shortname=datamodel["project"]["shortname"], longname=datamodel["project"]["longname"], description=LangString( datamodel["project"].get("descriptions")), keywords=set(datamodel["project"].get("keywords")), selfjoin=False, status=True).create() except BaseError as err: print("Creating project failed: " + err.message) exit(100) if args.verbose: print("Created project:") project.print() else: project = Project( con=con, shortcode=datamodel["project"]["shortcode"], ).read() assert project is not None # -------------------------------------------------------------------------- # now let's create the lists # if args.verbose is not None: print("Creating lists...") lists = datamodel["project"].get('lists') listrootnodes = {} if lists is not None: for rootnode in lists: if args.verbose is not None: print(" Creating list:" + rootnode['name']) root_list_node = ListNode(con=con, project=project, label=rootnode['labels'], comment=rootnode.get('comments'), name=rootnode['name']).create() listnodes = list_creator(con, project, root_list_node, rootnode['nodes']) listrootnodes[rootnode['name']] = { "id": root_list_node.id, "nodes": listnodes } with open('lists.json', 'w', encoding="utf-8") as fp: json.dump(listrootnodes, fp, indent=3, sort_keys=True) print( "The definitions of the node-id's can be found in \"lists.json\"!") if args.lists: exit(0) # -------------------------------------------------------------------------- # now let's add the groups (if there are groups defined...) # if args.verbose is not None: print("Adding groups...") new_groups = {} groups = datamodel["project"].get('groups') if groups is not None: for group in groups: new_group = None try: new_group = Group( con=con, name=group["name"], description=group["description"], project=project, status=group["status"] if group.get("status") is not None else True, selfjoin=group["selfjoin"] if group.get("selfjoin") is not None else False).create() except BaseError as err: print("Creating group failed: " + err.message) exit(101) new_groups[new_group.name] = new_group if args.verbose is not None: new_group.print() # -------------------------------------------------------------------------- # now let's add the users (if there are users defined...) # if args.verbose is not None: print("Adding users...") all_groups: List[Group] = [] all_projects: List[Project] = [] users = datamodel["project"].get('users') if users is not None: for user in users: sysadmin = False group_ids: Set[str] = set() for groupname in user["groups"]: # # First we determine the groups the user is in because we can do this in one call # groupname has the form [proj_shortname]:groupname|"SystemAdmin" (projectname omitted = current project) # tmp = groupname.split(':') if len(tmp) > 1: group = None if tmp[0] and tmp[0] != '': # we have 'proj_shortname:groupname if not all_groups: all_groups = Group.getAllGroups(con) tmp_group = list( filter( lambda g: g.project.shortname == tmp[0] and g. name == tmp[1], all_groups)) assert len(tmp_group) == 1 group = tmp_group[0] else: # we have ':groupname' and add to current project group = new_groups.get(tmp[1]) assert group is not None group_ids.add(group.id) else: if tmp[0] == "SystemAdmin": sysadmin = True project_infos: Dict[str, bool] = {} for projectname in user["projects"]: # # now we determine the project memberships of the user # projectname has the form [projectname]:"member"|"admin" (projectname omitted = current project) # tmp = projectname.split(':') assert len(tmp) == 2 if tmp[0]: # we have 'proj_shortname:"member"|"admin"' if not all_projects: all_projects = project.getAllProjects(con) tmp_project = list( filter(lambda g: g.shortname == tmp[0], all_projects)) assert len(tmp_project) == 1 in_project = tmp_project[0] else: # we have ':"member"|"admin"' in_project = project if tmp[1] == "admin": project_infos[in_project.id] = True else: project_infos[in_project.id] = False user_existing = False tmp_user = None try: tmp_user = User(con, username=user["username"]).read() except Error as err: pass if tmp_user is None: try: tmp_user = User(con, email=user["email"]).read() except Error as err: pass if tmp_user: # # The user is already in the database – let's update its settings # if tmp_user.username != user["username"]: tmp_user.username = user["username"] if tmp_user.email != user["email"]: tmp_user.email = user["email"] if tmp_user.givenName != user["givenName"]: tmp_user.givenName = user["givenName"] if tmp_user.familyName != user["familyName"]: tmp_user.familyName = user["familyName"] if tmp_user.password != user["password"]: tmp_user.password = user["password"] if user.get("status") and tmp_user.status != user["status"]: tmp_user.status = user["status"] if user.get("lang") and tmp_user.lang != user["lang"]: tmp_user.lang = user["lang"] if tmp_user.sysadmin != sysadmin: tmp_user.sysadmin = sysadmin try: tmp_user.update() except Error as err: pprint(tmp_user) print("Updating user failed: " + err.message) exit(103) # # now we update group and project membership # Note: we do NOT remove any mambership here, we just add! # tmp_in_groups = tmp_user.in_groups add_groups = group_ids - tmp_in_groups for g in add_groups: User.addToGroup(g) rm_groups = tmp_in_groups - group_ids # we do no remove a user from a group here! tmp_in_projects = tmp_user.in_projects for p in project_infos.items(): if tmp_in_projects.get( p[0]) and tmp_in_projects[p[0]] == p[1]: continue User.addToProject(p[0], p[1]) else: # # The user does not exist yet, let's create a new one # try: new_user = User(con=con, username=user["username"], email=user["email"], givenName=user["givenName"], familyName=user["familyName"], password=user["password"], status=user["status"] if user.get("status") is not None else True, lang=user["lang"] if user.get("lang") is not None else "en", sysadmin=sysadmin, in_projects=project_infos, in_groups=group_ids).create() except Error as err: print("Creating user failed: " + err.message) exit(104) if args.verbose is not None: new_user.print() # -------------------------------------------------------------------------- # now let's create the ontologies # ontologies = datamodel["project"]["ontologies"] for ontology in ontologies: last_modification_date, newontology = Ontology( con=con, project=project, label=ontology["label"], name=ontology["name"]).create() if args.verbose is not None: newontology.print() # # First we create the empty resource classes # resclasses = ontology["resources"] newresclasses: Dict[str, ResourceClass] = {} for resclass in resclasses: resname = resclass.get("name") super_classes = resclass.get("super") if isinstance(super_classes, str): super_classes = [super_classes] reslabel = LangString(resclass.get("labels")) rescomment = resclass.get("comment") if rescomment is not None: rescomment = LangString(rescomment) try: last_modification_date, newresclass = ResourceClass( con=con, context=newontology.context, ontology_id=newontology.id, name=resname, superclasses=super_classes, label=reslabel, comment=rescomment).create(last_modification_date) except Error as err: print("Creating resource class failed: " + err.message) exit(105) newresclasses[newresclass.id] = newresclass if args.verbose is not None: newresclass.print() # # Then we create the property classes # propclasses = ontology["properties"] newpropclasses: Dict[str, ResourceClass] = {} for propclass in propclasses: propname = propclass.get("name") proplabel = LangString(propclass.get("labels")) # # get the super-property/ies if defined. Valid forms are: # - "prefix:superproperty" : fully qualified name of property in another ontology. The prefix has to # be defined in the prefixes part. # - "superproperty" : Use of super-property defined in the knora-api ontology # if omitted, automatically "knora-api:hasValue" is assumed # if propclass.get("super") is not None: super_props = list( map(lambda a: a if ':' in a else "knora-api:" + a, propclass["super"])) else: super_props = ["knora-api:hasValue"] # # now we get the "object" if defined. Valid forms are: # - "prefix:object_name" : fully qualified object. The prefix has to be defined in the prefixes part. # - ":object_name" : The object is defined in the current ontology. # - "object_name" : The object is defined in "knora-api" # if propclass.get("object") is not None: tmp = propclass["object"].split(':') if len(tmp) > 1: if tmp[0]: object = propclass["object"] # fully qualified name else: object = newontology.name + ':' + tmp[1] else: object = "knora-api:" + propclass["object"] else: object = None if propclass.get("subject") is not None: subject = propclass["subject"] else: subject = None gui_element = propclass.get("gui_element") gui_attributes = propclass.get("gui_attributes") if gui_attributes is not None and gui_attributes.get( "hlist") is not None: gui_attributes['hlist'] = "<" + listrootnodes[ gui_attributes['hlist']]["id"] + ">" propcomment = propclass.get("comment") if propcomment is not None: propcomment = LangString(propcomment) else: propcomment = "no comment given" try: last_modification_date, newpropclass = PropertyClass( con=con, context=newontology.context, label=proplabel, name=propname, ontology_id=newontology.id, superproperties=super_props, object=object, subject=subject, gui_element="salsah-gui:" + gui_element, gui_attributes=gui_attributes, comment=propcomment).create(last_modification_date) except Error as err: print("Creating property class failed: " + err.message) exit(105) newpropclasses[newpropclass.id] = newpropclass if args.verbose is not None: newpropclass.print() # # Add cardinalities # switcher = { "1": Cardinality.C_1, "0-1": Cardinality.C_0_1, "0-n": Cardinality.C_0_n, "1-n": Cardinality.C_1_n } for resclass in resclasses: for cardinfo in resclass["cardinalities"]: rc = newresclasses.get(newontology.id + '#' + resclass["name"]) cardinality = switcher[cardinfo["cardinality"]] tmp = cardinfo["propname"].split(':') if len(tmp) > 1: if tmp[0]: propid = cardinfo["propname"] # fully qualified name else: propid = newontology.name + ':' + tmp[1] else: propid = "knora-api:" + cardinfo["propname"] last_modification_date = rc.addProperty( propid, cardinality, last_modification_date)
class ListNode: """ This class represents a list node or a while list from Knora Attributes ---------- con : Connection A Connection instance to a Knora server (for some operation a login has to be performedwith valid credentials) id : str IRI of the project [readonly, cannot be modified after creation of instance] project : str IRI of project. Only used for the creation of a new list (root node) [write]. label : LangString A LangString instance with language depenedent labels. Setting this attributes overwites all entries with the new ones. In order to add/remove a specific entry, use "addLabel" or "rmLabel". At least one label is required [read/write]. comment : LangString A LangString instance with language depenedent comments. Setting this attributes overwites all entries with the new ones.In order to add/remove a specific entry, use "addComment" or "rmComment". name : str A unique name for the ListNode (unique regarding the whole list) [read/write]. parent : IRI | ListNode Is required and allowed only for the CREATE operation. Otherwise use the "children" attribute [write]. isRootNode : bool Is True if the ListNode is a root node of a list Cannot be set [read]. children : List[ListNode] Contains a list of children nodes. This attribute is only avaliable for nodes that have been read by the method "getAllNodes()"! [read] rootNodeIri : str IRI of the root node. This attribute is only avaliable for nodes that have been read by the method "getAllNodes()"! [read] Methods ------- create : Knora ListNode information object Creates a new project and returns the information from the project as it is in Knora. Used to create new lists or append new ListNodes to an existing list. If appending, the attribute "parent" must not be None! read : Knora ListNode information object Read single list node update : Knora ListNode information object Updates the changed attributes and returns the updated information from the ListNode as it is in Knora delete : Knora result code Deletes a ListNode and returns the result code [NOT YET IMPLEMENTED!] getAllNodes : ListNode Get all nodes of a list. The IRI of the root node must be supplied. getAllLists [static]: returns all lists of a given project. print : None Prints the ListNode information to stdout (no recursion for children!) """ _id: str _project: str _label: LangString _comment: LangString _name: str _parent: str _isRootNode: bool _children: List['ListNode'] _rootNodeIri: str changed: Set[str] def __init__(self, con: Connection, id: Optional[str] = None, project: Optional[Union[Project, str]] = None, label: LangStringParam = None, comment: LangStringParam = None, name: Optional[str] = None, parent: Optional[Union['ListNode', str]] = None, isRootNode: Optional[bool] = None, children: Optional[List['ListNode']] = None, rootNodeIri: Optional[str] = None): """ This is the constructor for the ListNode object. For CREATE: * The "con" and at least one "label" are required READ: * The "con" and "id" attributes are required UPDATE: * Only "label", "comment" and "name" may be changed DELETE: * Not yet implemented in the Knora-backend :param con: A valid Connection instance with a user logged in that has the appropriate permissions :param id: IRI of the project [readonly, cannot be modified after creation of instance] :param project: IRI of project. Only used for the creation of a new list (root node) [write]. :param label: A LangString instance with language depenedent labels. Setting this attributes overwites all entries with the new ones. In order to add/remove a specific entry, use "addLabel" or "rmLabel". At least one label is required [read/write]. :param comment: A LangString instance with language depenedent comments. Setting this attributes overwites all entries with the new ones.In order to add/remove a specific entry, use "addComment" or "rmComment". :param name: A unique name for the ListNode (unique regarding the whole list) [read/write]. :param parent: Is required and allowed only for the CREATE operation. Otherwise use the "children" attribute [write]. :param isRootNode: Is True if the ListNode is a root node of a list Cannot be set [read]. :param children: Contains a list of children nodes. This attribute is only avaliable for nodes that have been read by the method "getAllNodes()"! [read] :param rootNodeIri: IRI of the root node. This attribute is only avaliable for nodes that have been read by the method "getAllNodes()"! [read] """ if not isinstance(con, Connection): raise BaseError ('"con"-parameter must be an instance of Connection') self.con = con self._project = project.id if isinstance(project, Project) else str(project) if project is not None else None self._id = str(id) if id is not None else None self._label = LangString(label) self._comment = LangString(comment) self._name = str(name) if name is not None else None if not isinstance(parent, ListNode) and parent is not None: raise BaseError('Parent must be ListNode instance or None!') if isinstance(parent, ListNode): self._parent = parent.id else: self._parent = parent self._isRootNode = isRootNode if children is not None: if isinstance(children, List) and len(children) > 0 and isinstance(children[0], ListNode): self._children = children else: raise BaseError('Children must be list of ListNodes!') else: self._children = None if not isinstance(rootNodeIri, str) and rootNodeIri is not None: raise BaseError('rootNodeIri must be a str!') self._rootNodeIri = rootNodeIri self.changed = set() # # Here follows a list of getters/setters # @property def id(self) -> Optional[str]: return self._id @id.setter def id(self, value: str) -> None: raise BaseError('ListNode id cannot be modified!') @property def project(self) -> Optional[str]: return self._project @project.setter def project(self, value: str) -> None: raise BaseError('Project id cannot be modified!') @property def label(self) -> Optional[LangString]: return self._label @label.setter def label(self, value: Optional[Union[LangString, str]]) -> None: self._label = LangString(value) self.changed.add('label') def addLabel(self, lang: Union[Languages, str], value: str) -> None: """ Add/replace a node label with the given language (executed at next update) :param lang: The language the label, either a string "EN", "DE", "FR", "IT" or a Language instance :param value: The text of the label :return: None """ self._label[lang] = value self.changed.add('label') def rmLabel(self, lang: Union[Languages, str]) -> None: """ Remove a label from a list node (executed at next update) :param lang: The language the label to be removed is in, either a string "EN", "DE", "FR", "IT" or a Language instance :return: None """ del self._label[lang] self.changed.add('label') @property def comment(self) -> Optional[LangString]: return self._comment @comment.setter def comment(self, value: Optional[Union[LangString, str]]) -> None: self._comment = LangString(value) self.changed.add('comment') def addComment(self, lang: Union[Languages, str], value: str) -> None: """ Add/replace a node comment with the given language (executed at next update) :param lang: The language the comment, either a string "EN", "DE", "FR", "IT" or a Language instance :param value: The text of the comment :return: None """ self._comment[lang] = value self.changed.add('comment') def rmComment(self, lang: Union[Languages, str]) -> None: """ Remove a comment from a list node (executed at next update) :param lang: The language the comment to be removed is in, either a string "EN", "DE", "FR", "IT" or a Language instance :return: None """ del self._comment[lang] self.changed.add('comment') @property def name(self) -> Optional[str]: return self._name @name.setter def name(self, value: str) -> None: self._name = str(value) self.changed.add('name') @property def parent(self) -> Optional[str]: raise BaseError('Property parent cannot be read!') @parent.setter def parent(self, value: any): raise BaseError('Property parent cannot be set!') @property def isRootNode(self) -> Optional[bool]: return self._isRootNode @isRootNode.setter def isRootNode(self, value: bool) -> None: raise BaseError('Property isRootNode cannot be set!') @property def children(self) -> Optional[List['ListNode']]: return self._children @staticmethod def _getChildren(con: Connection, children: List[Any]) -> Optional[List['ListNode']]: """ Internal method! Should not be used directly! Static method gets a recursive List of children nodes :param con: Valid Connection instance :param children: json object of children :return: List of ListNode instances """ if len(children) == 0: return None child_nodes = [] for child in children: child_nodes.append(ListNode.fromJsonObj(con, child)) return child_nodes @property def rootNodeIri(self) -> Optional[str]: return self._rootNodeIri @rootNodeIri.setter def rootNodeIri(self, value: str): raise BaseError('rootNodeIri cannot be set!') @classmethod def fromJsonObj(cls, con: Connection, json_obj: Any) -> Any: """ Internal method! Should not be used directly! This method is used to create a ListNode instance from the JSON data returned by Knora :param con: Connection instance :param json_obj: JSON data returned by Knora as python3 object :return: ListNode instance """ id = json_obj.get('id') project = json_obj.get('projectIri') if id is None: raise BaseError('ListNode id is missing') label = LangString.fromJsonObj(json_obj.get('labels')) comment = LangString.fromJsonObj(json_obj.get('comments')) name = json_obj.get('name') parent = json_obj.get('parentNodeIri') isRootNode = json_obj.get('isRootNode') child_info = json_obj.get('children') children = None if child_info is not None: children = ListNode._getChildren(con, child_info) rootNodeIri = json_obj.get('hasRootNode') return cls(con=con, id=id, project=project, label=label, comment=comment, name=name, parent=parent, isRootNode=isRootNode, children=children, rootNodeIri=rootNodeIri) def toJsonObj(self, action: Actions, listIri: str = None) -> Any: """ Internal method! Should not be used directly! Creates a JSON-object from the ListNode instance that can be used to call Knora :param action: Action the object is used for (Action.CREATE or Action.UPDATE) :return: JSON-object """ tmp = {} if action == Actions.Create: if self._project is None: raise BaseError("There must be a project id given!") tmp['projectIri'] = self._project if self._label.isEmpty(): raise BaseError("There must be a valid ListNode label!") tmp['labels'] = self._label.toJsonObj() if not self._comment.isEmpty(): tmp['comments'] = self._comment.toJsonObj() else: tmp['comments'] = [] if self._name is not None: tmp['name'] = self._name if self._parent is not None: tmp['parentNodeIri'] = self._parent elif action == Actions.Update: if self.id is None: raise BaseError("There must be a node id given!") tmp['listIri'] = listIri if self._project is None: raise BaseError("There must be a project id given!") tmp['projectIri'] = self._project if not self._label.isEmpty() and 'label' in self.changed: tmp['labels'] = self._label.toJsonObj() if not self._comment.isEmpty() and 'comment' in self.changed: tmp['comments'] = self._comment.toJsonObj() if self._name is not None and 'name' in self.changed: tmp['name'] = self._name return tmp def create(self) -> 'ListNode': """ Create a new List in Knora :return: JSON-object from Knora """ jsonobj = self.toJsonObj(Actions.Create) jsondata = json.dumps(jsonobj, cls=SetEncoder) if self._parent is not None: result = self.con.post('/admin/lists/'+ quote_plus(self._parent), jsondata) return ListNode.fromJsonObj(self.con, result['nodeinfo']) else: result = self.con.post('/admin/lists', jsondata) return ListNode.fromJsonObj(self.con, result['list']['listinfo']) def read(self) -> Any: """ Read a project from Knora :return: JSON-object from Knora """ result = self.con.get('/admin/lists/nodes/' + quote_plus(self._id)) return self.fromJsonObj(self.con, result['nodeinfo']) def update(self) -> Union[Any, None]: """ Udate the ListNode info in Knora with the modified data in this ListNode instance :return: JSON-object from Knora refecting the update """ jsonobj = self.toJsonObj(Actions.Update, self.id) if jsonobj: jsondata = json.dumps(jsonobj, cls=SetEncoder) result = self.con.put('/admin/lists/infos/' + quote_plus(self.id), jsondata) return ListNode.fromJsonObj(self.con, result['listinfo']) else: return None def delete(self) -> None: """ Delete the given ListNode :return: Knora response """ raise BaseError("NOT YET IMPLEMENTED BY KNORA BACKEND!") result = self.con.delete('/admin/lists/' + quote_plus(self._id)) return result #return Project.fromJsonObj(self.con, result['project']) def getAllNodes(self): """ Get all nodes of the list. Mus be called from a ListNode instance that has at least set the list iri! :return: Root node of list with recursive ListNodes ("children"-attributes) """ result = self.con.get('/admin/lists/' + quote_plus(self._id)) if 'list' not in result: raise BaseError("Request got no list!") if 'listinfo' not in result['list']: raise BaseError("Request got no proper list information!") root = ListNode.fromJsonObj(self.con, result['list']['listinfo']) if 'children' in result['list']: root._children = ListNode._getChildren(self.con, result['list']['children']) return root @staticmethod def getAllLists(con: Connection, project_iri: str) -> List['ListNode']: """ Get all lists of the specified project :param con: Connection instance :param project_iri: Iri/id of project :return: list of ListNodes """ result = con.get('/admin/lists?projectIri=' + quote_plus(project_iri)) if 'lists' not in result: raise BaseError("Request got no lists!") return list(map(lambda a: ListNode.fromJsonObj(con, a), result['lists'])) def print(self): """ print info to stdout :return: None """ print('Node Info:') print(' Id: {}'.format(self._id)) print(' Project: {}'.format(self._project)) print(' Name: {}'.format(self._name)) print(' Label: ') if self._label is not None: for lbl in self._label.items(): print(' {}: {}'.format(lbl[0], lbl[1])) else: print(' None') print(' Comment: ') if self._comment is not None: for lbl in self._comment.items(): print(' {}: {}'.format(lbl[0], lbl[1])) else: print(' None') print(' Parent', self._parent) print(' IsRootNode: {}'.format(self._isRootNode))
def comment(self, value: Optional[Union[LangString, str]]) -> None: self._comment = LangString(value) self.changed.add('comment')
class PropertyClass: _context: Context _id: str _name: str _ontology_id: str _superproperties: List[str] _object: str _subject: str _gui_element: str _gui_attributes: Dict[str, str] _label: LangString _comment: LangString _editable: bool _linkvalue: bool _changed: Set[str] def __init__(self, con: Connection, context: Context, id: Optional[str] = None, name: Optional[str] = None, ontology_id: Optional[str] = None, superproperties: Optional[List[Union['PropertyClass', str]]] = None, object: Optional[str] = None, subject: Optional[str] = None, gui_element: Optional[str] = None, gui_attributes: Optional[Dict[str, str]] = None, label: Optional[Union[LangString, str]] = None, comment: Optional[Union[LangString, str]] = None, editable: Optional[bool] = None, linkvalue: Optional[bool] = None): 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') self.con = con self._context = context self._id = id self._name = name self._ontology_id = ontology_id if isinstance(superproperties, PropertyClass): self._superproperties = list(map(lambda a: a.id, superproperties)) else: self._superproperties = superproperties self._object = object self._subject = subject self._gui_element = gui_element self._gui_attributes = gui_attributes # # process label # if label is not None: if isinstance(label, str): self._label = LangString(label) elif isinstance(label, LangString): self._label = label else: raise BaseError('Invalid LangString for label!') else: self._label = None # # process comment # if comment is not None: if isinstance(comment, str): self._comment = LangString(comment) elif isinstance(comment, LangString): self._comment = comment else: raise BaseError('Invalid LangString for comment!') else: self._comment = None self._editable = editable self._linkvalue = linkvalue self._changed = set() # # Here follows a list of getters/setters # @property def name(self) -> Optional[str]: return self._name @name.setter def name(self, value: str) -> None: raise BaseError('"name" cannot be modified!') @property def id(self) -> Optional[str]: return self._id @id.setter def id(self, value: str) -> None: raise BaseError('"id" cannot be modified!') @property def ontology_id(self) -> Optional[str]: return self._ontology_id @ontology_id.setter def ontology_id(self, value: str) -> None: raise BaseError('"ontology_id" cannot be modified!') @property def superproperties(self) -> Optional[str]: return self._superproperties @superproperties.setter def superproperties(self, value: str) -> None: raise BaseError('"superproperties" cannot be modified!') @property def object(self) -> Optional[str]: return self._object @object.setter def object(self, value: Any): raise BaseError('"object" cannot be modified!') @property def subject(self) -> Optional[str]: return self._subject @subject.setter def subject(self, value: Any): raise BaseError('"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) -> Optional[LangString]: return self._label @label.setter def label(self, value: Optional[Union[LangString, str]]) -> None: if value is None: self._label.empty() # clear all labels else: if isinstance(value, LangString): self._label = value elif isinstance(value, str): self._label = LangString(value) else: raise BaseError('Not a valid LangString') self._changed.add('label') def addLabel(self, lang: Union[Languages, str], value: str) -> None: self._label[lang] = value self._changed.add('label') def rmLabel(self, lang: Union[Languages, str]) -> None: del self._label[lang] self._changed.add('label') @property def comment(self) -> Optional[LangString]: return self._comment @comment.setter def comment(self, value: Optional[LangString]) -> None: if value is None: self._comment.empty() # clear all comments! else: if isinstance(value, LangString): self._comment = value elif isinstance(value, str): self._comment = LangString(value) else: raise BaseError('Not a valid LangString') self._changed.add('comment') def addComment(self, lang: Union[Languages, str], value: str) -> None: self._comment[lang] = value self._changed.add('comment') def rmComment(self, lang: Union[Languages, str]) -> None: del self._comment[lang] self._changed.add('comment') @property def editable(self) -> bool: return self._editable @editable.setter def editable(self, value: bool) -> None: raise BaseError('"editable" cannot be modified!') @property def linkvalue(self) -> bool: return self._linkvalue @linkvalue.setter def linkvalue(self) -> None: raise BaseError('"linkvalue" cannot be modified!') @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?? 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.prefixFromIri( "http://www.w3.org/1999/02/22-rdf-syntax-ns#") rdfs = context.prefixFromIri("http://www.w3.org/2000/01/rdf-schema#") owl = context.prefixFromIri("http://www.w3.org/2002/07/owl#") xsd = context.prefixFromIri("http://www.w3.org/2001/XMLSchema#") knora_api = context.prefixFromIri( "http://api.knora.org/ontology/knora-api/v2#") salsah_gui = context.prefixFromIri( "http://api.knora.org/ontology/salsah-gui/v2#") 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.iriFromPrefix(tmp_id[0]) + '#' + tmp_id[1] ontology_id = tmp_id[0] name = tmp_id[1] superproperties_obj = json_obj.get(rdfs + ':subPropertyOf') superproperties: List[Union[None, str]] if not isinstance(superproperties_obj, list): superproperties_obj = [superproperties_obj ] # make a list out of it if superproperties_obj is not None: superprops: List[Any] = list( filter(lambda a: a.get('@id') is not None, superproperties_obj)) superproperties = list(map(lambda a: a['@id'], superprops)) else: superproperties = None object = WithId(json_obj.get(knora_api + ':objectType')).str() 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 if json_obj.get(salsah_gui + ':guiElement') is not None: gui_element = WithId(json_obj.get(salsah_gui + ':guiElement')).str() gui_attributes_list = json_obj.get(salsah_gui + ':guiAttribute') gui_attributes: Union[None, Dict[str, str]] = None if gui_attributes_list is not None: gui_attributes = {} if not isinstance(gui_attributes_list, list): gui_attributes_list = [gui_attributes_list] for ga in gui_attributes_list: tmp = ga.split('=') if len(tmp) == 1: gui_attributes[tmp[0]] = '' else: gui_attributes[tmp[0]] = tmp[1] editable = json_obj.get(knora_api + ':isEditable') linkvalue = json_obj.get(knora_api + ':isLinkProperty') return cls(con=con, context=context, id=id, name=name, ontology_id=ontology_id, superproperties=superproperties, object=object, subject=subject, gui_element=gui_element, gui_attributes=gui_attributes, label=label, comment=comment, editable=editable, linkvalue=linkvalue) def toJsonObj(self, lastModificationDate: LastModificationDate, action: Actions, what: Optional[str] = None) -> Any: def resolve_propref(resref: str): tmp = resref.split(':') if len(tmp) > 1: if tmp[0]: return { "@id": resref } # fully qualified name in the form "prefix:name" else: return { "@id": self._context.prefixFromIri(self._ontology_id) + ':' + tmp[1] } # ":name" in current ontology else: return { "@id": "knora-api:" + resref } # no ":", must be from knora-api! tmp = {} exp = re.compile('^http.*') # It is already a fully IRI if exp.match(self._ontology_id): propid = self._context.prefixFromIri( self._ontology_id) + ":" + self._name ontid = self._ontology_id else: propid = self._ontology_id + ":" + self._name ontid = self._context.iriFromPrefix(self._ontology_id) if action == Actions.Create: if self._name is None: raise BaseError("There must be a valid property class name!") if self._ontology_id is None: raise BaseError("There must be a valid ontology_id given!") if self._superproperties is None: superproperties = [{"@id": "knora-api:hasValue"}] else: superproperties = list( map(resolve_propref, self._superproperties)) tmp = { "@id": ontid, # self._ontology_id, "@type": "owl:Ontology", "knora-api:lastModificationDate": lastModificationDate.toJsonObj(), "@graph": [{ "@id": propid, "@type": "owl:ObjectProperty", "rdfs:label": self._label.toJsonLdObj(), "rdfs:subPropertyOf": superproperties }], "@context": self._context.toJsonObj() } if self._comment is not None: if not self._comment.isEmpty(): tmp['@graph'][0][ "rdfs:comment"] = self._comment.toJsonLdObj() if self._subject is not None: tmp['@graph'][0]["knora-api:subjectType"] = resolve_propref( self._subject) if self._object is not None: tmp['@graph'][0]["knora-api:objectType"] = resolve_propref( self._object) if self._gui_element is not None: tmp['@graph'][0]["salsah-gui:guiElement"] = { "@id": self._gui_element } if self._gui_attributes: ga = list( map(lambda x: x[0] + '=' + str(x[1]), self._gui_attributes.items())) tmp['@graph'][0]["salsah-gui:guiAttribute"] = ga elif action == Actions.Update: tmp = { "@id": ontid, # self._ontology_id, "@type": "owl:Ontology", "knora-api:lastModificationDate": lastModificationDate.toJsonObj(), "@graph": [{ "@id": propid, "@type": "owl:ObjectProperty", }], "@context": self._context.toJsonObj(), } if what == 'label': if not self._label.isEmpty() and 'label' in self._changed: tmp['@graph'][0]['rdfs:label'] = self._label.toJsonLdObj() if what == 'comment': if not self._comment.isEmpty() and 'comment' in self._changed: tmp['@graph'][0][ 'rdfs:comment'] = self._comment.toJsonLdObj() return tmp def create( self, last_modification_date: LastModificationDate ) -> Tuple[LastModificationDate, 'PropertyClass']: jsonobj = self.toJsonObj(last_modification_date, Actions.Create) jsondata = json.dumps(jsonobj, cls=SetEncoder, indent=2) result = self.con.post('/v2/ontologies/properties', jsondata) last_modification_date = LastModificationDate( result['knora-api:lastModificationDate']) return last_modification_date, PropertyClass.fromJsonObj( self.con, self._context, result['@graph']) def update( self, last_modification_date: LastModificationDate ) -> Tuple[LastModificationDate, 'ResourceClass']: # # Note: Knora is able to change only one thing per call, either label or comment! # result = None something_changed = False if 'label' in self._changed: jsonobj = self.toJsonObj(last_modification_date, Actions.Update, 'label') jsondata = json.dumps(jsonobj, cls=SetEncoder, indent=4) result = self.con.put('/v2/ontologies/properties', jsondata) last_modification_date = LastModificationDate( result['knora-api:lastModificationDate']) something_changed = True if 'comment' in self._changed: jsonobj = self.toJsonObj(last_modification_date, Actions.Update, 'comment') jsondata = json.dumps(jsonobj, cls=SetEncoder, indent=4) result = self.con.put('/v2/ontologies/properties', jsondata) last_modification_date = LastModificationDate( result['knora-api:lastModificationDate']) something_changed = True if something_changed: return last_modification_date, PropertyClass.fromJsonObj( self.con, self._context, result['@graph']) else: return last_modification_date, self def delete( self, last_modification_date: LastModificationDate ) -> LastModificationDate: result = self.con.delete('/v2/ontologies/properties/' + quote_plus(self._id) + '?lastModificationDate=' + str(last_modification_date)) return LastModificationDate(result['knora-api:lastModificationDate']) def print(self, offset: int = 0): blank = ' ' print(f'{blank:>{offset}}Property Class Info') print(f'{blank:>{offset+2}}Name: {self._name}') print(f'{blank:>{offset+2}}Ontology prefix: {self._ontology_id}') print(f'{blank:>{offset+2}}Superproperties:') if self._superproperties is not None: for sc in self._superproperties: print(f'{blank:>{offset + 4}}{sc}') 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._gui_element is not None: print(f'{blank:>{offset + 4}}Guielement: {self._gui_element}') if self._gui_attributes is not None: print(f'{blank:>{offset + 4}}Gui Attributes:') if self._gui_attributes is not None: pprint(self._gui_attributes) for (attname, attvalue) in self._gui_attributes.items(): print( f'{blank:>{offset + 6}}Attribute: {attname} Value: {attvalue}' ) if self._comment is not None: print(f'{blank:>{offset + 2}}Comments:') self._comment.print(offset + 4) if self._editable is not None: print(f'{blank:>{offset + 4}}Editable: {self._editable}') if self._linkvalue is not None: print(f'{blank:>{offset + 4}}Editable: {self._linkvalue}')
class Project: """ This class represents a project in Knora. Attributes ---------- con : Connection A Connection instance to a Knora server id : str IRI of the project [readonly, cannot be modified after creation of instance] shortcode : str Knora project shortcode [readonly, cannot be modified after creation of instance] shortname : str Knora project shortname [read/write] longname : str Knora project longname [read/write] description : LangString Knora project description in a given language (Languages.EN, Languages.DE, Languages.FR, Languages.IT). A desciption can be add/replaced or removed with the methods ``addDescription``and ``rmDescription``. keywords : Set[str] Set of keywords describing the project. Keywords can be added/removed by the methods ``addKeyword`` and ``rmKeyword`` ontologies : Set[str] Set if IRI's of te ontologies attached to the project [readonly] selfjoin : bool Boolean if the project allows selfjoin Methods ------- create : Knora project information object Creates a new project and returns the information from the project as it is in Knora read : Knora project information object Read project data from an existing project update : Knora project information object Updates the changed attributes and returns the updated information from the project as it is in Knora delete : Knora result code Deletes a project and returns the result code getAllprojects [static]: List of all projects Returns a list of all projects available print : None Prints the project information to stdout """ _id: str _shortcode: str _shortname: str _longname: str _description: LangString _keywords: Set[str] _ontologies: Set[str] _selfjoin: bool _status: bool _logo: Optional[str] changed: Set[str] SYSTEM_PROJECT: str = "http://www.knora.org/ontology/knora-admin#SystemProject" def __init__(self, con: Connection, id: Optional[str] = None, shortcode: Optional[str] = None, shortname: Optional[str] = None, longname: Optional[str] = None, description: LangStringParam = None, keywords: Optional[Set[str]] = None, ontologies: Optional[Set[str]] = None, selfjoin: Optional[bool] = None, status: Optional[bool] = None, logo: Optional[str] = None): """ 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 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] :param keywords: Set of keywords [required for CREATE] :param ontologies: Set of ontologies that belong to this project [optional] :param selfjoin: Allow selfjoin [required for CREATE] :param status: Status of project (active if True) [required for CREATE] :param logo: Path to logo image file [optional] NOT YET USED """ if not isinstance(con, Connection): raise BaseError( '"con"-parameter must be an instance of Connection') self.con = con self._id = id self._shortcode = shortcode self._shortname = shortname self._longname = longname self._description = LangString(description) self._keywords = keywords if not isinstance(ontologies, set) and ontologies is not None: raise BaseError('Ontologies must be a set of strings or None!') self._ontologies = ontologies self._selfjoin = selfjoin self._status = status self._logo = logo self.changed = set() def __str__(self): tmpstr = self._id + "\n " + self._shortcode + "\n " + self._shortname return tmpstr # # Here follows a list of getters/setters # @property def id(self) -> Optional[str]: return self._id @id.setter def id(self, value: str) -> None: raise BaseError('Project id cannot be modified!') @property def shortcode(self) -> Optional[str]: return self._shortcode @shortcode.setter def shortcode(self, value: str) -> None: raise BaseError('Shortcode id cannot be modified!') @property def shortname(self) -> Optional[str]: return self._shortname @shortname.setter def shortname(self, value: str) -> None: self._shortname = str(value) self.changed.add('shortname') @property def longname(self) -> Optional[str]: return self._longname @longname.setter def longname(self, value: str) -> None: self._longname = str(value) self.changed.add('longname') @property def description(self) -> Optional[LangString]: return self._description @description.setter def description(self, value: Optional[LangString]) -> None: self._description = LangString(value) self.changed.add('description') def addDescription(self, lang: Union[Languages, str], value: str) -> None: """ Add/replace a project description with the given language (executed at next update) :param lang: The language the description is in, either a string "EN", "DE", "FR", "IT" or a Language instance :param value: The text of the description :return: None """ self._description[lang] = value self.changed.add('description') 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 :return: None """ del self._description[lang] self.changed.add('description') @property def keywords(self) -> Set[str]: return self._keywords @keywords.setter def keywords(self, value: Union[List[str], Set[str]]): if isinstance(value, set): self._keywords = value self.changed.add('keywords') elif isinstance(value, list): self._keywords = set(value) self.changed.add('keywords') else: raise BaseError('Must be a set of strings!') def addKeyword(self, value: str): """ Add a new keyword to the set of keywords. (executed at next update) May raise a BaseError :param value: keyword :return: None """ self._keywords.add(value) self.changed.add('keywords') def rmKeyword(self, value: str): """ Remove a keyword from the list of keywords (executed at next update) May raise a BaseError :param value: keyword :return: None """ try: self._keywords.remove(value) except KeyError as ke: raise BaseError('Keyword "' + value + '" is not in keyword set') self.changed.add('keywords') @property def ontologies(self) -> Set[str]: return self._ontologies @ontologies.setter def ontologies(self, value: Set[str]) -> None: raise BaseError('Cannot add a ontology!') @property def selfjoin(self) -> Optional[bool]: return self._selfjoin @selfjoin.setter def selfjoin(self, value: bool) -> None: if self._selfjoin != value: self.changed.add('selfjoin') self._selfjoin = value @property def status(self) -> bool: return self._status @status.setter def status(self, value: bool) -> None: self._status = value self.changed.add('status') @property def logo(self) -> str: return self._logo @logo.setter def logo(self, value: str) -> None: self._logo = value self.changed.add('logo') @classmethod def fromJsonObj(cls, con: Connection, json_obj: Any) -> Any: """ Internal method! Should not be used directly! This method is used to create a Project instance from the JSON data returned by Knora :param con: Connection instance :param json_obj: JSON data returned by Knora as python3 object :return: Project instance """ id = json_obj.get('id') if id is None: raise BaseError('Project id is missing') shortcode = json_obj.get('shortcode') if shortcode is None: raise BaseError("Shortcode is missing") shortname = json_obj.get('shortname') if shortname is None: raise BaseError("Shortname is missing") longname = json_obj.get('longname') if longname is None: raise BaseError("Longname is missing") description = LangString.fromJsonObj(json_obj.get('description')) keywords = set(json_obj.get('keywords')) if keywords is None: raise BaseError("Keywords are missing") ontologies = set(json_obj.get('ontologies')) if ontologies is None: raise BaseError("Keywords are missing") selfjoin = json_obj.get('selfjoin') if selfjoin is None: raise BaseError("Selfjoin is missing") status = json_obj.get('status') if status is None: raise BaseError("Status is missing") logo = json_obj.get('logo') return cls(con=con, id=id, shortcode=shortcode, shortname=shortname, longname=longname, description=description, keywords=keywords, ontologies=ontologies, selfjoin=selfjoin, status=status, logo=logo) def toJsonObj(self, action: Actions) -> Any: """ Internal method! Should not be used directly! Creates a JSON-object from the Project instance that can be used to call Knora :param action: Action the object is used for (Action.CREATE or Action.UPDATE) :return: JSON-object """ tmp = {} if action == Actions.Create: if self._shortcode is None: raise BaseError("There must be a valid project shortcode!") tmp['shortcode'] = self._shortcode if self._shortname is None: raise BaseError("There must be a valid project shortname!") tmp['shortname'] = self._shortname if self._longname is None: raise BaseError("There must be a valid project longname!") tmp['longname'] = self._longname if self._description.isEmpty(): raise BaseError("There must be a valid project description!") tmp['description'] = self._description.toJsonObj() if len(self._keywords) > 0: tmp['keywords'] = self._keywords if self._selfjoin is None: raise BaseError("selfjoin must be defined (True or False!") tmp['selfjoin'] = self._selfjoin if self._status is None: raise BaseError("status must be defined (True or False!") tmp['status'] = self._status elif action == Actions.Update: if self._shortcode is not None and 'shortcode' in self.changed: tmp['shortcode'] = self._shortcode if self._shortname is not None and 'shortname' in self.changed: tmp['shortname'] = self._shortname if self._longname is not None and 'longname' in self.changed: tmp['longname'] = self._longname if not self._description.isEmpty( ) and 'description' in self.changed: tmp['description'] = self._description.toJsonObj() if len(self._keywords) > 0 and 'keywords' in self.changed: tmp['keywords'] = self._keywords if self._selfjoin is not None and 'selfjoin' in self.changed: tmp['selfjoin'] = self._selfjoin if self._status is not None and 'status' in self.changed: tmp['status'] = self._status return tmp def create(self) -> 'Project': """ Create a new project in Knora :return: JSON-object from Knora """ jsonobj = self.toJsonObj(Actions.Create) jsondata = json.dumps(jsonobj, cls=SetEncoder) result = self.con.post('/admin/projects', jsondata) return Project.fromJsonObj(self.con, result['project']) def read(self) -> 'Project': """ Read a project from Knora :return: JSON-object from Knora """ if self._id is not None: result = self.con.get('/admin/projects/iri/' + quote_plus(self._id)) elif self._shortcode is not None: result = self.con.get('/admin/projects/shortcode/' + quote_plus(self._shortcode)) return Project.fromJsonObj(self.con, result['project']) def update(self) -> Union['Project', None]: """ Udate the project info in Knora with the modified data in this project instance :return: JSON-object from Knora refecting the update """ jsonobj = self.toJsonObj(Actions.Update) if jsonobj: jsondata = json.dumps(jsonobj, cls=SetEncoder) result = self.con.put('/admin/projects/iri/' + quote_plus(self.id), jsondata) return Project.fromJsonObj(self.con, result['project']) else: return None def delete(self) -> 'Project': """ Delete the given Knora project :return: Knora response """ result = self.con.delete('/admin/projects/iri/' + quote_plus(self._id)) return Project.fromJsonObj(self.con, result['project']) @staticmethod def getAllProjects(con: Connection) -> List['Project']: """ Get all existing projects in Knora :param con: Connection instance :return: """ result = con.get('/admin/projects') if 'projects' not in result: raise BaseError("Request got no projects!") return list( map(lambda a: Project.fromJsonObj(con, a), result['projects'])) def print(self): """ print info to stdout :return: None """ print('Project Info:') print(' Id: {}'.format(self._id)) print(' Shortcode: {}'.format(self._shortcode)) print(' Shortname: {}'.format(self._shortname)) print(' Longname: {}'.format(self._longname)) if self._description is not None: print(' Description:') for descr in self._description.items(): print(' {}: {}'.format(descr[0], descr[1])) else: print(' Description: None') if self._keywords is not None: print(' Keywords: {}'.format(' '.join(self._keywords))) else: print(' Keywords: None') if self._ontologies is not None: print(' Ontologies: {}'.format(' '.join(self._ontologies))) else: print(' Ontologies: None') print(' Selfjoin: {}'.format(self._selfjoin)) print(' Status: {}'.format(self._status))
def __init__(self, con: Connection, context: Context, id: Optional[str] = None, name: Optional[str] = None, ontology_id: Optional[str] = None, superproperties: Optional[List[Union['PropertyClass', str]]] = None, object: Optional[str] = None, subject: Optional[str] = None, gui_element: Optional[str] = None, gui_attributes: Optional[Dict[str, str]] = None, label: Optional[Union[LangString, str]] = None, comment: Optional[Union[LangString, str]] = None, editable: Optional[bool] = None, linkvalue: Optional[bool] = None): 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') self.con = con self._context = context self._id = id self._name = name self._ontology_id = ontology_id if isinstance(superproperties, PropertyClass): self._superproperties = list(map(lambda a: a.id, superproperties)) else: self._superproperties = superproperties self._object = object self._subject = subject self._gui_element = gui_element self._gui_attributes = gui_attributes # # process label # if label is not None: if isinstance(label, str): self._label = LangString(label) elif isinstance(label, LangString): self._label = label else: raise BaseError('Invalid LangString for label!') else: self._label = None # # process comment # if comment is not None: if isinstance(comment, str): self._comment = LangString(comment) elif isinstance(comment, LangString): self._comment = comment else: raise BaseError('Invalid LangString for comment!') else: self._comment = None self._editable = editable self._linkvalue = linkvalue self._changed = set()
def __init__(self, con: Connection, id: Optional[str] = None, project: Optional[Union[Project, str]] = None, label: LangStringParam = None, comment: LangStringParam = None, name: Optional[str] = None, parent: Optional[Union['ListNode', str]] = None, isRootNode: Optional[bool] = None, children: Optional[List['ListNode']] = None, rootNodeIri: Optional[str] = None): """ This is the constructor for the ListNode object. For CREATE: * The "con" and at least one "label" are required READ: * The "con" and "id" attributes are required UPDATE: * Only "label", "comment" and "name" may be changed DELETE: * Not yet implemented in the Knora-backend :param con: A valid Connection instance with a user logged in that has the appropriate permissions :param id: IRI of the project [readonly, cannot be modified after creation of instance] :param project: IRI of project. Only used for the creation of a new list (root node) [write]. :param label: A LangString instance with language depenedent labels. Setting this attributes overwites all entries with the new ones. In order to add/remove a specific entry, use "addLabel" or "rmLabel". At least one label is required [read/write]. :param comment: A LangString instance with language depenedent comments. Setting this attributes overwites all entries with the new ones.In order to add/remove a specific entry, use "addComment" or "rmComment". :param name: A unique name for the ListNode (unique regarding the whole list) [read/write]. :param parent: Is required and allowed only for the CREATE operation. Otherwise use the "children" attribute [write]. :param isRootNode: Is True if the ListNode is a root node of a list Cannot be set [read]. :param children: Contains a list of children nodes. This attribute is only avaliable for nodes that have been read by the method "getAllNodes()"! [read] :param rootNodeIri: IRI of the root node. This attribute is only avaliable for nodes that have been read by the method "getAllNodes()"! [read] """ if not isinstance(con, Connection): raise BaseError ('"con"-parameter must be an instance of Connection') self.con = con self._project = project.id if isinstance(project, Project) else str(project) if project is not None else None self._id = str(id) if id is not None else None self._label = LangString(label) self._comment = LangString(comment) self._name = str(name) if name is not None else None if not isinstance(parent, ListNode) and parent is not None: raise BaseError('Parent must be ListNode instance or None!') if isinstance(parent, ListNode): self._parent = parent.id else: self._parent = parent self._isRootNode = isRootNode if children is not None: if isinstance(children, List) and len(children) > 0 and isinstance(children[0], ListNode): self._children = children else: raise BaseError('Children must be list of ListNodes!') else: self._children = None if not isinstance(rootNodeIri, str) and rootNodeIri is not None: raise BaseError('rootNodeIri must be a str!') self._rootNodeIri = rootNodeIri self.changed = set()