def login(server: str, user: str, password: str) -> Connection: """ Logs in and returns the active connection Args: server: URL of the DSP server to connect to user: Username (e-mail) password: Password of the user Return: Connection instance """ con = Connection(server) con.login(user, password) return con
def setUp(self) -> None: """ is executed before all tests; sets up a connection and logs in as user root; creates a new ontology """ self.con = Connection('http://0.0.0.0:3333') self.con.login('*****@*****.**', 'test') # Create a test ontology self.onto = Ontology( con=self.con, project=self.project, name=self.onto_name, label=self.onto_label, ).create() self.assertIsNotNone(self.onto.id) self.last_modification_date = self.onto.lastModificationDate
def test_log_in_and_out(self) -> None: con = Connection('http://0.0.0.0:3333') con.login('*****@*****.**', 'test') self.assertIsNotNone(con.token) con.logout() self.assertIsNone(con.token) self.assertRaisesRegex(BaseError, 'KNORA-ERROR: status code=400*', con.login, 'invalid', 'invalid')
class TestOntology(unittest.TestCase): test_project = "http://rdfh.ch/projects/0001" test_onto = "http://0.0.0.0:3333/ontology/0001/anything/v2" def setUp(self) -> None: """ is executed before all tests; sets up a connection and logs in as user root """ self.con = Connection('http://0.0.0.0:3333') self.con.login('*****@*****.**', 'test') def test_Ontology(self) -> None: last_mod_date_str = "2017-12-19T15:23:42.166Z" onto = Ontology( con=self.con, project=self.test_project, name="test_onto_name", label="Test ontology label", lastModificationDate=last_mod_date_str ) self.assertEqual(onto.project, self.test_project) self.assertEqual(onto.name, "test_onto_name") self.assertEqual(onto.label, "Test ontology label") self.assertEqual(onto.lastModificationDate, LastModificationDate(last_mod_date_str)) def test_ontology_read(self) -> None: onto = Ontology( con=self.con, id=self.test_onto ).read() self.assertEqual(onto.id, self.test_onto) self.assertEqual(onto.project, self.test_project) self.assertEqual(onto.name, "anything") self.assertEqual(onto.label, "The anything ontology") self.assertIsNotNone(onto.lastModificationDate) def test_ontology_create(self) -> None: onto = Ontology( con=self.con, project=self.test_project, name="test_onto_create", label="Test ontology create label", ).create() self.assertIsNotNone(onto.id) self.assertEqual(onto.id, "http://0.0.0.0:3333/ontology/0001/" + "test_onto_create" + "/v2") self.assertEqual(onto.project, self.test_project) self.assertEqual(onto.name, "test_onto_create") self.assertEqual(onto.label, "Test ontology create label") self.assertIsNotNone(onto.lastModificationDate) def test_ontology_update_label(self) -> None: onto = Ontology( con=self.con, project=self.test_project, name="test_onto_update", label="Test ontology update label", ).create() onto.label = 'Test ontology update label - modified' onto = onto.update() self.assertEqual(onto.label, 'Test ontology update label - modified') def test_ontology_delete(self) -> None: onto = Ontology( con=self.con, project=self.test_project, name="test_onto_delete", label="Test ontology delete label", ).create() res = onto.delete() self.assertEqual(res, "Ontology http://0.0.0.0:3333/ontology/0001/test_onto_delete/v2 has been deleted") def test_ontology_getProjectOntologies(self) -> None: onto_list = Ontology.getProjectOntologies(self.con, self.test_project) onto_list_ids = [l.id for l in onto_list] self.assertIn('http://0.0.0.0:3333/ontology/0001/anything/v2', onto_list_ids) self.assertIn('http://0.0.0.0:3333/ontology/0001/minimal/v2', onto_list_ids) self.assertIn('http://0.0.0.0:3333/ontology/0001/something/v2', onto_list_ids) def tearDown(self) -> None: """ is executed after all tests are run through; performs a log out """ self.con.logout()
def setUp(self) -> None: """ is executed before all tests; sets up a connection and logs in as user root """ self.con = Connection('http://0.0.0.0:3333') self.con.login('*****@*****.**', 'test')
class TestPropertyClass(unittest.TestCase): project = "http://rdfh.ch/projects/0001" onto_name = 'propclass-test-a' onto_label = 'propclass_test_ontology' onto: Ontology last_modification_date: LastModificationDate con: Connection name = 'MyPropClassName' object = 'TextValue' label = LangString({Languages.DE: 'MyPropClassLabel'}) comment = LangString( {Languages.DE: 'This is a property class for testing'}) def setUp(self) -> None: """ is executed before all tests; sets up a connection and logs in as user root; creates a new ontology """ self.con = Connection('http://0.0.0.0:3333') self.con.login('*****@*****.**', 'test') # Create a test ontology self.onto = Ontology( con=self.con, project=self.project, name=self.onto_name, label=self.onto_label, ).create() self.assertIsNotNone(self.onto.id) self.last_modification_date = self.onto.lastModificationDate def tearDown(self) -> None: """ is executed after all tests are run through; removes test ontology """ result = self.onto.delete() self.assertIsNotNone(result) def test_PropertyClass_create(self) -> None: """ create new property class """ self.last_modification_date, property_class = PropertyClass( con=self.con, context=self.onto.context, name=self.name, ontology_id=self.onto.id, 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.assertEqual(property_class.name, self.name) self.assertEqual(property_class.label['de'], self.label['de']) self.assertEqual(property_class.comment['de'], self.comment['de']) # get ontology data self.onto = self.onto.read() self.last_modification_date = self.onto.lastModificationDate self.last_modification_date = property_class.delete( self.last_modification_date) # get ontology data self.onto = self.onto.read() def test_PropertyClass_update(self) -> None: self.onto = self.onto.read() # create test resource class self.last_modification_date, property_class = PropertyClass( con=self.con, context=self.onto.context, name=self.name, ontology_id=self.onto.id, 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) # modify the property class property_class.addLabel('en', "This is english comment") property_class.rmLabel('de') property_class.addComment('it', "Commentario italiano") self.last_modification_date, property_class_updated = property_class.update( self.last_modification_date) self.onto.lastModificationDate = self.last_modification_date self.assertEqual(property_class_updated.label['en'], "This is english comment") self.assertEqual(property_class_updated.comment['it'], "Commentario italiano") # delete the resource class to clean up self.last_modification_date = property_class_updated.delete( self.last_modification_date) self.onto.lastModificationDate = self.last_modification_date
class TestListNode(unittest.TestCase): project = "http://rdfh.ch/projects/0001" otherTreeList = "http://rdfh.ch/lists/0001/otherTreeList" def setUp(self) -> None: """ is executed before all tests; sets up a connection and logs in as user root """ self.con = Connection('http://0.0.0.0:3333') self.con.login('*****@*****.**', 'test') def test_ListNode_read(self) -> None: """ Read an existing node :return: None """ node = ListNode(con=self.con, id=self.otherTreeList).read() self.assertEqual(node.id, self.otherTreeList) self.assertEqual(node.project, self.project) self.assertEqual(node.label['en'], 'Tree list root') self.assertTrue(node.isRootNode) self.assertIsNone(node.children) def test_ListNode_create(self) -> None: """ Create a list node :return: None """ node = ListNode(con=self.con, project=self.project, label=LangString({Languages.DE: "root node 1"}), comments=LangString({Languages.DE: "first root node"}), name="test_node_1").create() self.assertIsNotNone(node.id) self.assertEqual(node.project, self.project) self.assertEqual(node.label['de'], "root node 1") self.assertEqual(node.comments['de'], "first root node") self.assertEqual(node.name, "test_node_1") self.assertTrue(node.isRootNode) def test_ListNode_hierarchy(self) -> None: """ Create a node and a sub-node :return: None """ node = ListNode(con=self.con, project=self.project, label=LangString({Languages.EN: "root node"}), comments=LangString( {Languages.EN: "This is a root node"}), name="root_node").create() subnode = ListNode( con=self.con, project=self.project, label=LangString({Languages.DE: 'Ein Knoten der Liste'}), comments=LangString({Languages.DE: "Ein Kommentar"}), name="sub_node", parent=node).create() self.assertTrue(node.isRootNode) self.assertFalse(subnode.isRootNode) def test_ListNode_update(self) -> None: """ Update the data of a node :return: None """ node = ListNode(con=self.con, project=self.project, label=LangString({Languages.EN: "root node 3"}), comments=LangString({Languages.EN: "Third root node"}), name="test_node").create() node.addLabel('de', "Neues Label") node.rmLabel('en') node.addComment('fr', 'un commentaire en français') node.rmComment('en') node.name = 'test_node_update' node.update() self.assertEqual(node.label['de'], "Neues Label") self.assertEqual(node.comments['fr'], 'un commentaire en français') self.assertEqual(node.name, 'test_node_update') def test_ListNode_getAllLists(self) -> None: """ Get all lists :return: None """ lists = ListNode.getAllLists(self.con, self.project) list_ids = list(map(lambda l: l.id, lists)) self.assertIn(self.otherTreeList, list_ids) self.assertIn('http://rdfh.ch/lists/0001/treeList', list_ids) def test_ListNode_getAllNodes(self) -> None: """ Get all nodes of a list :return: None """ root_node = ListNode(con=self.con, id=self.otherTreeList).getAllNodes() self.assertTrue(root_node.isRootNode) self.assertEqual(root_node.project, self.project) self.assertEqual(root_node.label['en'], 'Tree list root') self.assertIsNotNone(root_node.children) self.assertEqual(root_node.children[0].id, 'http://rdfh.ch/lists/0001/otherTreeList01') self.assertEqual(root_node.children[0].name, 'Other Tree list node 01') self.assertEqual(root_node.children[0].label['en'], 'Other Tree list node 01') self.assertEqual(root_node.children[1].id, 'http://rdfh.ch/lists/0001/otherTreeList02') self.assertEqual(root_node.children[1].name, 'Other Tree list node 02') self.assertEqual(root_node.children[1].label['en'], 'Other Tree list node 02') self.assertEqual(root_node.children[2].id, "http://rdfh.ch/lists/0001/otherTreeList03") self.assertEqual(root_node.children[2].name, 'Other Tree list node 03') self.assertEqual(root_node.children[2].label['en'], 'Other Tree list node 03') self.assertIsNotNone(root_node.children[2].children) self.assertEqual(root_node.children[2].children[0].id, 'http://rdfh.ch/lists/0001/otherTreeList10') self.assertEqual(root_node.children[2].children[0].name, 'Other Tree list node 10') self.assertEqual(root_node.children[2].children[0].label['en'], 'Other Tree list node 10') self.assertEqual(root_node.children[2].children[1].id, 'http://rdfh.ch/lists/0001/otherTreeList11') self.assertEqual(root_node.children[2].children[1].name, 'Other Tree list node 11') self.assertEqual(root_node.children[2].children[1].label['en'], 'Other Tree list node 11') def tearDown(self) -> None: """ is executed after all tests are run through; performs a log out """ self.con.logout()
class TestProject(unittest.TestCase): logo_file = "logo.gif" def setUp(self) -> None: """ is executed before all tests; sets up a connection and logs in as user root """ self.con = Connection('http://0.0.0.0:3333') self.con.login('*****@*****.**', 'test') def test_Project(self) -> None: project = Project(con=self.con, id='http://rdfh.ch/test', shortcode='0FF0', shortname="test_project", longname="Test Project", description=LangString({ Languages.EN: 'This is a test project', Languages.DE: 'Das ist ein Testprojekt' }), keywords={'test', 'project'}, selfjoin=False, status=True, logo=self.logo_file) self.assertIsNotNone(project) self.assertEqual(project.id, 'http://rdfh.ch/test') self.assertEqual(project.shortcode, '0FF0') self.assertEqual(project.shortname, 'test_project') self.assertEqual(project.longname, 'Test Project') self.assertEqual(project.description['en'], 'This is a test project') self.assertEqual(project.description['de'], 'Das ist ein Testprojekt') self.assertEqual(project.selfjoin, False) self.assertEqual(project.status, True) self.assertEqual(project.keywords, {'test', 'project'}) def test_project_read(self) -> None: project = Project(con=self.con, id='http://rdfh.ch/projects/0001').read() self.assertEqual(project.id, 'http://rdfh.ch/projects/0001') self.assertEqual(project.shortcode, '0001') self.assertEqual(project.shortname, 'anything') self.assertEqual(project.longname, 'Anything Project') self.assertEqual(project.description[None], 'Anything Project') self.assertEqual(project.selfjoin, False) self.assertEqual(project.status, True) def test_project_create(self) -> None: project = Project(con=self.con, shortcode='0FF0', shortname="new_project", longname="New test project", description=LangString({ Languages.EN: 'New project', Languages.DE: 'Neues Projekt' }), keywords={'test', 'project', 'new'}, selfjoin=False, status=True, logo=self.logo_file) new_project = project.create() self.assertIsNotNone(new_project) self.assertEqual(new_project.shortcode, '0FF0') self.assertEqual(new_project.shortname, 'new_project') self.assertEqual(new_project.longname, 'New test project') self.assertEqual(new_project.description['en'], 'New project') self.assertEqual(new_project.description['de'], 'Neues Projekt') self.assertEqual(new_project.keywords, {'test', 'project', 'new'}) self.assertEqual(new_project.selfjoin, False) self.assertEqual(new_project.status, True) self.assertEqual(new_project.keywords, {'test', 'project', 'new'}) def test_project_update(self) -> None: project = Project(con=self.con, shortcode='0FF1', shortname="update_project", longname="Update Project", description=LangString({ Languages.EN: 'Project to be updated', Languages.DE: 'Update-Projekt' }), keywords={'test', 'project'}, selfjoin=False, status=True, logo=self.logo_file).create() project.shortname = "update_project" project.longname = "Update Project" project.addDescription('fr', 'Projet modifié') project.rmDescription('de') project.selfjoin = True project.status = False project.rmKeyword('project') project.addKeyword('updated') updated_project = project.update() self.assertEqual(updated_project.shortcode, '0FF1') self.assertEqual(updated_project.shortname, 'update_project') self.assertEqual(updated_project.longname, 'Update Project') self.assertEqual(updated_project.description['en'], 'Project to be updated') self.assertEqual(updated_project.description['fr'], 'Projet modifié') self.assertEqual(updated_project.selfjoin, True) self.assertEqual(updated_project.status, False) self.assertEqual(updated_project.keywords, {'test', 'updated'}) def test_project_delete(self) -> None: project = Project(con=self.con, shortcode='0FF2', shortname="delete_project", longname="Delete Project", description=LangString({ Languages.EN: 'Project to be deleted', Languages.DE: 'Lösch-Projekt' }), keywords={'test', 'project', 'delete'}, selfjoin=False, status=True, logo=self.logo_file).create() deleted_project = project.delete() self.assertEqual(deleted_project.shortcode, '0FF2') self.assertEqual(deleted_project.shortname, 'delete_project') self.assertEqual(deleted_project.longname, 'Delete Project') self.assertEqual(deleted_project.description['en'], 'Project to be deleted') self.assertEqual(deleted_project.description['de'], 'Lösch-Projekt') self.assertEqual(deleted_project.selfjoin, False) self.assertEqual(deleted_project.status, False) self.assertEqual(deleted_project.keywords, {'test', 'project', 'delete'}) def tearDown(self) -> None: """ is executed after all tests are run through; performs a log out """ self.con.logout()
class TestResource(unittest.TestCase): def setUp(self) -> None: """ is executed before all tests; sets up a connection and logs in as user root """ self.con = Connection('http://0.0.0.0:3333') self.con.login('*****@*****.**', 'test') def test_Resource_create(self) -> None: # make class factory for project anything. The factory creates classes that implement the CRUD methods # for the given resource classes factory = ResourceInstanceFactory(self.con, 'anything') # get a blue_thing resource class blue_thing = factory.get_resclass('anything:BlueThing') a_blue_thing = blue_thing(con=self.con, label='BlueThing', values={ 'anything:hasBoolean': True, 'anything:hasColor': ['#ff0033', '#0077FF'], 'anything:hasDate': make_value(value='1833', comment='not verified!'), 'anything:hasDecimal': 3.14159, 'anything:hasInteger': "42", 'anything:hasTimeStamp': "2004-04-12T13:20:00Z", 'anything:hasInterval': [make_value(value="0.0:3.0", comment="first interval"), make_value(value="3.5:3.7", comment="second interval")], 'anything:hasRichtext': KnoraStandoffXml("This is <em>bold</em> text."), 'anything:hasText': "Dies ist ein einfacher Text", 'anything:hasUri': 'http://test.com:65500/res' }).create() new_blue_thing = a_blue_thing.read() self.assertEqual(new_blue_thing.label, "BlueThing") self.assertEqual(new_blue_thing.value("anything:hasColor"), ['#ff0033', '#0077FF']) self.assertEqual(new_blue_thing.value("anything:hasInteger"), 42) self.assertEqual(new_blue_thing.value("anything:hasBoolean"), True) self.assertEqual(new_blue_thing.value("anything:hasDecimal"), 3.14159) self.assertEqual(new_blue_thing.value("anything:hasText"), "Dies ist ein einfacher Text") thing_picture = factory.get_resclass('anything:ThingPicture') sipi = Sipi('http://0.0.0.0:1024', self.con.get_token()) img = sipi.upload_bitstream('testdata/bitstreams/TEMP11.TIF') file_ref = img['uploadedFiles'][0]['internalFilename'] res_perm = Permissions({PermissionValue.M: ["knora-admin:UnknownUser", "knora-admin:KnownUser"], PermissionValue.CR: ["knora-admin:Creator", "knora-admin:ProjectAdmin"]}) resource_bitstream = { 'value': 'testdata/bitstreams/TEMP11.TIF', 'internal_file_name': file_ref, 'permissions': res_perm } thing_picture( con=self.con, label='ThingPicture', bitstream=resource_bitstream, permissions=res_perm, values={ 'anything:hasPictureTitle': make_value(value="A Thing Picture named Lena", permissions=res_perm) } ).create() def tearDown(self) -> None: """ is executed after all tests are run through; performs a log out """ self.con.logout()
class TestGroup(unittest.TestCase): test_project = "http://rdfh.ch/projects/0001" def setUp(self) -> None: """ is executed before all tests; sets up a connection and logs in as user root """ self.con = Connection('http://0.0.0.0:3333') self.con.login('*****@*****.**', 'test') def test_group_getAllGroups(self) -> None: """ Retrieve all groups :return: None """ groups = Group.getAllGroups(self.con) group_ids = [] for group in groups: group_ids.append(group.id) group_ids_expected = [ "http://rdfh.ch/groups/00FF/images-reviewer", "http://rdfh.ch/groups/0001/thing-searcher" ] self.assertTrue(set(group_ids).issuperset(set(group_ids_expected))) def test_group_create(self) -> None: """ Create a group :return: None """ group = Group(con=self.con, name="Group create", descriptions=LangString( {Languages.EN: 'This is group create'}), project=self.test_project, status=True, selfjoin=False) self.assertEqual(group.name, 'Group create') self.assertCountEqual(group.descriptions.toJsonObj(), [{ 'language': 'en', 'value': 'This is group create' }]) self.assertEqual(group.project, self.test_project) self.assertTrue(group.status) self.assertFalse(group.selfjoin) def test_group_read(self) -> None: """ Read an existing group :return: None """ group = Group(con=self.con, id='http://rdfh.ch/groups/0001/thing-searcher').read() self.assertEqual(group.name, 'Thing searcher') self.assertEqual(group.project, self.test_project) self.assertTrue(group.status) self.assertTrue(group.selfjoin) def test_Group_update(self) -> None: """ Update an existing group :return: None """ group = Group(con=self.con, name="Group update", descriptions=LangString( {Languages.EN: 'This is group update'}), project=self.test_project, status=True, selfjoin=False).create() group.name = "Group update - modified" group.descriptions = {"en": "This is group update - modified"} group.selfjoin = True group.status = False updated_group = group.update() self.assertEqual(updated_group.name, 'Group update - modified') self.assertCountEqual(updated_group.descriptions.toJsonObj(), [{ 'language': 'en', 'value': 'This is group ' 'update - ' 'modified' }]) self.assertEqual(updated_group.project, self.test_project) self.assertFalse(updated_group.status) self.assertTrue(updated_group.selfjoin) def test_Group_delete(self) -> None: """ Mark an existing group as deleted (it will not be deleted completely from the triplestore, but status set to False) :return: None """ group = Group(con=self.con, name="Group delete", descriptions=LangString( {Languages.EN: 'This is group delete'}), project=self.test_project, status=True, selfjoin=False).create() deleted_group = group.delete() self.assertEqual(deleted_group.name, 'Group delete') self.assertCountEqual(deleted_group.descriptions.toJsonObj(), [{ 'language': 'en', 'value': 'This is group delete' }]) self.assertEqual(deleted_group.project, self.test_project) self.assertFalse(deleted_group.status) self.assertFalse(deleted_group.selfjoin) def tearDown(self) -> None: """ is executed after all tests are run through; performs a log out """ self.con.logout()
class TestConnection(unittest.TestCase): def setUp(self) -> None: """ is executed before all tests; sets up a connection and logs in as user root """ self.con = Connection('http://0.0.0.0:3333') self.con.login('*****@*****.**', 'test') def test_Connection(self) -> None: self.assertIsInstance(self.con, Connection) def test_log_in_and_out(self) -> None: con = Connection('http://0.0.0.0:3333') con.login('*****@*****.**', 'test') self.assertIsNotNone(con.token) con.logout() self.assertIsNone(con.token) self.assertRaisesRegex(BaseError, 'KNORA-ERROR: status code=400*', con.login, 'invalid', 'invalid') def test_get(self) -> None: res = self.con.get("/ontology/0001/anything/simple/v2") self.assertIsNotNone(res['@graph']) self.assertRaises(BaseError, self.con.get, "/doesNotExist") self.con.logout() self.assertIsNotNone(res['@graph']) self.assertRaises(BaseError, self.con.get, "/doesNotExist") def test_put(self) -> None: # TODO add test pass def test_post(self) -> None: res_info = """{ "@type" : "anything:Thing", "knora-api:attachedToProject" : { "@id" : "http://rdfh.ch/projects/0001" }, "anything:hasBoolean" : { "@type" : "knora-api:BooleanValue", "knora-api:booleanValueAsBoolean" : true }, "rdfs:label" : "knora-py thing", "knora-api:hasPermissions" : "CR knora-admin:Creator|V http://rdfh.ch/groups/0001/thing-searcher", "@context" : { "rdf" : "http://www.w3.org/1999/02/22-rdf-syntax-ns#", "knora-api" : "http://api.knora.org/ontology/knora-api/v2#", "rdfs" : "http://www.w3.org/2000/01/rdf-schema#", "xsd" : "http://www.w3.org/2001/XMLSchema#", "anything" : "http://0.0.0.0:3333/ontology/0001/anything/v2#" } } """ res = self.con.post('/v2/resources', res_info) self.assertIsNotNone(res['@id']) self.assertEqual(res['@type'], 'anything:Thing') self.assertEqual(res['rdfs:label'], 'knora-py thing') res_id = res['@id'] erase_info = f"""{{ "@id" : "{res_id}", "@type" : "anything:Thing", "@context" : {{ "rdf" : "http://www.w3.org/1999/02/22-rdf-syntax-ns#", "knora-api" : "http://api.knora.org/ontology/knora-api/v2#", "rdfs" : "http://www.w3.org/2000/01/rdf-schema#", "xsd" : "http://www.w3.org/2001/XMLSchema#", "anything" : "http://0.0.0.0:3333/ontology/0001/anything/v2#" }} }} """ res = self.con.post('/v2/resources/erase', erase_info) self.assertIsNotNone(res['knora-api:result']) self.assertEqual(res['knora-api:result'], 'Resource erased') def test_delete(self) -> None: # TODO add test pass def tearDown(self) -> None: """ is executed after all tests are run through; performs a log out """ self.con.logout()
class TestResourceClass(unittest.TestCase): test_project = "http://rdfh.ch/projects/0001" res_name = 'res_class_name' res_label = LangString({Languages.EN: 'Resource Class Label'}) res_comment = LangString( {Languages.EN: 'This is a resource class for testing'}) def setUp(self) -> None: """ is executed before all tests; sets up a connection and logs in as user root """ self.con = Connection('http://0.0.0.0:3333') self.con.login('*****@*****.**', 'test') def test_ResourceClass_create(self) -> None: onto = Ontology( con=self.con, project=self.test_project, name='test_onto', label='Test Ontology', ).create() last_modification_date_onto = onto.lastModificationDate # create test resource class last_modification_date_res, res_class = ResourceClass( con=self.con, context=onto.context, name=self.res_name, ontology_id=onto.id, label=self.res_label, comment=self.res_comment).create(last_modification_date_onto) self.assertIsNotNone(res_class.id) 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']) def test_ResourceClass_update(self) -> None: onto = Ontology( con=self.con, project=self.test_project, name='test_onto_2', label='Test Ontology 2', ).create() last_modification_date = onto.lastModificationDate # create test resource class last_modification_date, res_class = ResourceClass( con=self.con, context=onto.context, name=self.res_name, ontology_id=onto.id, label=self.res_label, comment=self.res_comment).create(last_modification_date) onto.lastModificationDate = last_modification_date self.assertIsNotNone(res_class.id) # modify the resource class res_class.addLabel('de', "Dies ist ein Kommentar") res_class.rmLabel('en') res_class.addComment('it', "Commentario italiano") last_modification_date, res_class = res_class.update( last_modification_date) self.assertEqual(res_class.label['de'], "Dies ist ein Kommentar") self.assertEqual(res_class.comment['it'], "Commentario italiano") def tearDown(self) -> None: """ is executed after all tests are run through; performs a log out """ self.con.logout()
def xml_upload(input_file: str, server: str, user: str, password: str, imgdir: str, sipi: str, verbose: bool, validate_only: bool, incremental: bool) -> None: """ This function reads an XML file and imports the data described in it onto the DSP server. Args: input_file : the XML with the data to be imported onto the DSP server server : the DSP server where the data should be imported user : the user (e-mail) with which the data should be imported password : the password of the user with which the data should be imported imgdir : the image directory sipi : the sipi instance to be used verbose : verbose option for the command, if used more output is given to the user validate_only : validation option to validate the XML data without the actual import of the data incremental: if set, IRIs instead of internal IDs are expected as resource pointers Returns: None """ # Validate the input XML file current_dir = os.path.dirname(os.path.realpath(__file__)) schema_file = os.path.join(current_dir, '../schemas/data.xsd') if validate_xml_against_schema(input_file, schema_file): print( "The input data file is syntactically correct and passed validation." ) if validate_only: exit(0) else: print("ERROR The input data file did not pass validation.") exit(1) # Connect to the DaSCH Service Platform API and get the project context con = Connection(server) con.login(user, password) proj_context = ProjectContext(con=con) resources: list[XMLResource] = [] permissions: dict[str, XmlPermission] = {} # parse the XML file containing the data tree = etree.parse(input_file) # Iterate through all XML elements for elem in tree.getiterator(): # Skip comments and processing instructions, # because they do not have names if not (isinstance(elem, etree._Comment) or isinstance(elem, etree._ProcessingInstruction)): # Remove a namespace URI in the element's name elem.tag = etree.QName(elem).localname # Remove unused namespace declarations etree.cleanup_namespaces(tree) knora = tree.getroot() default_ontology = knora.attrib['default-ontology'] shortcode = knora.attrib['shortcode'] for child in knora: # get all permissions if child.tag == "permissions": permission = XmlPermission(child, proj_context) permissions[permission.id] = permission # get all resources elif child.tag == "resource": resources.append(XMLResource(child, default_ontology)) # sort the resources (resources which do not link to others come first) but only if not an incremental upload if not incremental: resources = do_sort_order(resources, verbose) sipi = Sipi(sipi, con.get_token()) # get the project information and project ontology from the server project = ResourceInstanceFactory(con, shortcode) # create a dictionary to look up permissions permissions_lookup: dict[str, Permissions] = {} for key, perm in permissions.items(): permissions_lookup[key] = perm.get_permission_instance() # create a dictionary to look up resource classes res_classes: dict[str, type] = {} for res_class_name in project.get_resclass_names(): res_classes[res_class_name] = project.get_resclass(res_class_name) res_iri_lookup: dict[str, str] = {} failed_uploads = [] for resource in resources: if verbose: resource.print() resource_bitstream = None if resource.bitstream: img = sipi.upload_bitstream( os.path.join(imgdir, resource.bitstream.value)) internal_file_name_bitstream = img['uploadedFiles'][0][ 'internalFilename'] resource_bitstream = resource.get_bitstream( internal_file_name_bitstream, permissions_lookup) permissions_tmp = permissions_lookup.get(resource.permissions) try: # create a resource instance (ResourceInstance) from the given resource in the XML (XMLResource) instance: ResourceInstance = res_classes[resource.restype]( con=con, label=resource.label, permissions=permissions_tmp, bitstream=resource_bitstream, values=resource.get_propvals(res_iri_lookup, permissions_lookup)).create() except BaseError as err: print( f"ERROR while trying to create resource '{resource.label}' ({resource.id}). The error message was: {err.message}" ) failed_uploads.append(resource.id) continue except Exception as exception: print( f"ERROR while trying to create resource '{resource.label}' ({resource.id}). The error message was: {exception}" ) failed_uploads.append(resource.id) continue res_iri_lookup[resource.id] = instance.iri print( f"Created resource '{instance.label}' ({resource.id}) with IRI '{instance.iri}'" ) # write mapping of internal IDs to IRIs to file with timestamp timestamp_now = datetime.now() timestamp_str = timestamp_now.strftime("%Y%m%d-%H%M%S") xml_file_name = Path(input_file).stem res_iri_lookup_file = "id2iri_" + xml_file_name + "_mapping_" + timestamp_str + ".json" with open(res_iri_lookup_file, "w") as outfile: print( f"============\nThe mapping of internal IDs to IRIs was written to {res_iri_lookup_file}" ) outfile.write(json.dumps(res_iri_lookup)) if failed_uploads: print(f"Could not upload the following resources: {failed_uploads}")