def test_service_to_rdf_without_identifier_should_raise_error( minimal_spec: str, ) -> None: """It raises a RequiredFieldMissingError.""" with pytest.raises(RequiredFieldMissingError): catalog = Catalog() catalog.identifier = "http://example.com/catalogs/1" url = "http://example.com/specifications/1" oas = yaml.safe_load(minimal_spec) oas_spec = OASDataService(url, oas, "") for dataservice in oas_spec.dataservices: catalog.services.append(dataservice) catalog.to_rdf()
def test_to_graph_should_return_blank_skolemization( mocker: MockFixture) -> None: """It returns a catalog graph as blank node isomorphic to spec.""" catalog = Catalog() src = """ @prefix dct: <http://purl.org/dc/terms/> . @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . @prefix dcat: <http://www.w3.org/ns/dcat#> . <http://wwww.digdir.no/.well-known/skolem/284db4d2-80c2-11eb-82c3-83e80baa2f94> a dcat:Catalog . """ mocker.patch( "skolemizer.Skolemizer.add_skolemization", return_value=skolemization, ) g1 = Graph().parse(data=catalog.to_rdf(), format="turtle") g2 = Graph().parse(data=src, format="turtle") assert_isomorphic(g1, g2)
def test_to_graph_should_return_has_part() -> None: """It returns a has part graph isomorphic to spec.""" catalog = Catalog() catalog.identifier = "http://example.com/catalogs/1" part = Catalog() part.identifier = "http://example.com/catalogs/2" catalog.has_parts.append(part) src = """ @prefix dct: <http://purl.org/dc/terms/> . @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . @prefix dcat: <http://www.w3.org/ns/dcat#> . <http://example.com/catalogs/1> a dcat:Catalog ; dct:hasPart <http://example.com/catalogs/2> . """ g1 = Graph().parse(data=catalog.to_rdf(), format="turtle") g2 = Graph().parse(data=src, format="turtle") _isomorphic = isomorphic(g1, g2) if not _isomorphic: _dump_diff(g1, g2) pass assert _isomorphic
def create_catalog(): catalog = Catalog() _add_dataservices(catalog) _add_mandatory_catalog_props(catalog) _add_optional_catalog_props(catalog) return catalog.to_rdf().decode()
def test_to_graph_should_return_homepage() -> None: """It returns a homepage graph isomorphic to spec.""" catalog = Catalog() catalog.identifier = "http://example.com/catalogs/1" catalog.homepage = "http://example.org/catalog" src = """ @prefix dct: <http://purl.org/dc/terms/> . @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . @prefix dcat: <http://www.w3.org/ns/dcat#> . @prefix foaf: <http://xmlns.com/foaf/0.1/> . <http://example.com/catalogs/1> a dcat:Catalog ; foaf:homepage <http://example.org/catalog> ; . """ g1 = Graph().parse(data=catalog.to_rdf(), format="turtle") g2 = Graph().parse(data=src, format="turtle") _isomorphic = isomorphic(g1, g2) if not _isomorphic: _dump_diff(g1, g2) pass assert _isomorphic
def test_to_graph_should_return_catalog_record() -> None: """It returns a catalog record graph isomorphic to spec.""" catalog = Catalog() catalog.identifier = "http://example.com/catalogs/1" a_catalogrecord = CatalogRecord() a_catalogrecord.identifier = "http://example.com/catalogrecords/1" catalog.catalogrecords.append(a_catalogrecord) src = """ @prefix dct: <http://purl.org/dc/terms/> . @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . @prefix dcat: <http://www.w3.org/ns/dcat#> . <http://example.com/catalogs/1> a dcat:Catalog ; dcat:record <http://example.com/catalogrecords/1> ; . """ g1 = Graph().parse(data=catalog.to_rdf(), format="turtle") g2 = Graph().parse(data=src, format="turtle") _isomorphic = isomorphic(g1, g2) if not _isomorphic: _dump_diff(g1, g2) pass assert _isomorphic
def test_to_graph_should_return_catalog_without_services_as_graph() -> None: """It returns a catalog graph isomorphic to spec.""" catalog = Catalog() catalog.identifier = "http://example.com/catalogs/1" service1 = DataService() service1.identifier = "http://example.com/services/1" service1.title = {"nb": "Datatjeneste 1", "en": "Dataservice 1"} catalog.services.append(service1) service2 = DataService() service2.identifier = "http://example.com/services/2" service2.title = {"nb": "Datatjeneste 2", "en": "Dataservice 2"} catalog.services.append(service2) src = """ @prefix dct: <http://purl.org/dc/terms/> . @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . @prefix dcat: <http://www.w3.org/ns/dcat#> . <http://example.com/catalogs/1> a dcat:Catalog ; dcat:service <http://example.com/services/1>, <http://example.com/services/2> . """ g1 = Graph().parse(data=catalog.to_rdf(include_services=False), format="turtle") g2 = Graph().parse(data=src, format="turtle") _isomorphic = isomorphic(g1, g2) if not _isomorphic: _dump_diff(g1, g2) pass assert _isomorphic
def test_parse_minimal_spec(minimal_spec: str, mocker: MockFixture) -> None: """It returns a valid dataservice in a catalog.""" catalog = Catalog() catalog.identifier = "http://example.com/catalogs/1" url = "http://example.com/specifications/1" oas = yaml.safe_load(minimal_spec) identifier = "http://example.com/dataservices/1" oas_spec = OASDataService(url, oas, identifier) for dataservice in oas_spec.dataservices: catalog.services.append(dataservice) src = """ @prefix dct: <http://purl.org/dc/terms/> . @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . @prefix dcat: <http://www.w3.org/ns/dcat#> . <http://example.com/catalogs/1> a dcat:Catalog ; dcat:service <http://example.com/dataservices/1> . <http://example.com/dataservices/1> a dcat:DataService ; dct:title "Swagger Petstore"@en ; dcat:endpointDescription <http://example.com/specifications/1> ; . """ g1 = Graph().parse(data=catalog.to_rdf(), format="turtle") g2 = Graph().parse(data=src, format="turtle") _isomorphic = isomorphic(g1, g2) if not _isomorphic: _dump_diff(g1, g2) pass assert _isomorphic
def test_to_graph_should_return_catalog_record_skolemization( mocker: MockFixture, ) -> None: """It returns a catalog record graph isomorphic to spec.""" catalog = Catalog() catalog.identifier = "http://example.com/catalogs/1" a_catalogrecord = CatalogRecord() catalog.catalogrecords.append(a_catalogrecord) src = """ @prefix dct: <http://purl.org/dc/terms/> . @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . @prefix dcat: <http://www.w3.org/ns/dcat#> . <http://example.com/catalogs/1> a dcat:Catalog ; dcat:record <http://wwww.digdir.no/.well-known/skolem/284db4d2-80c2-11eb-82c3-83e80baa2f94> . """ mocker.patch( "skolemizer.Skolemizer.add_skolemization", return_value=skolemization, ) g1 = Graph().parse(data=catalog.to_rdf(), format="turtle") g2 = Graph().parse(data=src, format="turtle") _isomorphic = isomorphic(g1, g2) if not _isomorphic: _dump_diff(g1, g2) pass assert _isomorphic
def create_catalog() -> str: catalog = Catalog() _add_mandatory_catalog_props(catalog) _add_optional_catalog_props(catalog) _add_datasets(catalog) cat_rdf = catalog.to_rdf() for ds in catalog.datasets: for dist in ds.distributions: cat_rdf += utils.remove_prefix(dist.to_rdf()) return _clean_rdf(cat_rdf)
def test_to_graph_should_return_model_as_graph() -> None: """It returns a model graph isomorphic to spec.""" catalog = Catalog() catalog.identifier = "http://example.com/catalogs/1" # Creating a class as a placeholder for real InformationModel class InformationModel = type( "InformationModel", (object, ), { "title": "", "identifier": "", "_to_graph": lambda self: model_to_graph(self), }, ) model_1 = InformationModel() model_1.identifier = "http://example.com/models/1" # type: ignore model_1.title = {"en": "My first model"} # type: ignore catalog.models.append(model_1) model_2 = InformationModel() model_2.identifier = "http://example.com/models/2" # type: ignore model_2.title = {"en": "My second model"} # type: ignore catalog.models.append(model_2) src = """ @prefix dct: <http://purl.org/dc/terms/> . @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . @prefix dcat: <http://www.w3.org/ns/dcat#> . @prefix modelldcatno: <https://data.norge.no/vocabulary/modelldcatno#> . <http://example.com/catalogs/1> a dcat:Catalog ; modelldcatno:model <http://example.com/models/1> , <http://example.com/models/2> ; . <http://example.com/models/1> a modelldcatno:InformationModel ; dct:title "My first model"@en ; . <http://example.com/models/2> a modelldcatno:InformationModel ; dct:title "My second model"@en ; . """ g1 = Graph().parse(data=catalog.to_rdf(), format="turtle") g2 = Graph().parse(data=src, format="turtle") _isomorphic = isomorphic(g1, g2) if not _isomorphic: _dump_diff(g1, g2) pass assert _isomorphic
def test_to_graph_should_return_dataservice_skolemization( mocker: MockFixture) -> None: """It returns a dataservice graph isomorphic to spec.""" catalog = Catalog() catalog.identifier = "http://example.com/catalogs/1" dataservice1 = DataService() dataservice1.title = {"nb": "Dataservice 1", "en": "Dataservice 1"} catalog.services.append(dataservice1) dataservice2 = DataService() dataservice2.title = {"nb": "Dataservice 2", "en": "Dataservice 2"} catalog.services.append(dataservice2) src = """ @prefix dct: <http://purl.org/dc/terms/> . @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . @prefix dcat: <http://www.w3.org/ns/dcat#> . <http://example.com/catalogs/1> a dcat:Catalog ; dcat:service <http://wwww.digdir.no/.well-known/skolem/21043186-80ce-11eb-9829-cf7c8fc855ce> , <http://wwww.digdir.no/.well-known/skolem/284db4d2-80c2-11eb-82c3-83e80baa2f94> ; . <http://wwww.digdir.no/.well-known/skolem/284db4d2-80c2-11eb-82c3-83e80baa2f94> a dcat:DataService ; dct:title "Dataservice 1"@en, "Dataservice 1"@nb ; . <http://wwww.digdir.no/.well-known/skolem/21043186-80ce-11eb-9829-cf7c8fc855ce> a dcat:DataService ; dct:title "Dataservice 2"@en, "Dataservice 2"@nb ; . """ skolemutils = SkolemUtils() mocker.patch( "skolemizer.Skolemizer.add_skolemization", side_effect=skolemutils.get_skolemization, ) g1 = Graph().parse(data=catalog.to_rdf(), format="turtle") g2 = Graph().parse(data=src, format="turtle") _isomorphic = isomorphic(g1, g2) if not _isomorphic: _dump_diff(g1, g2) pass assert _isomorphic
def create_catalog() -> str: catalog = Catalog() _add_mandatory_catalog_props(catalog) _add_optional_catalog_props(catalog) _add_datasets(catalog) cat_rdf = catalog.to_rdf() for ds in catalog.datasets: for dist in ds.distributions: cat_rdf += utils.remove_prefix(dist.to_rdf()) return cat_rdf.decode().replace("[ a dct:Location ]", "<http://sws.geonames.org/3144096/>") \ .replace("<text/csv>", '"text/csv"') \ .replace("<text/csv>", '"text/csv"')
def test_parse_spec_with_contact(minimal_spec: str) -> None: """It returns a valid dataservice with contactPoint.""" catalog = Catalog() catalog.identifier = "http://example.com/catalogs/1" oas = yaml.safe_load(minimal_spec) oas["info"]["contact"] = {} oas["info"]["contact"]["name"] = "Example Inc" oas["info"]["contact"]["email"] = "*****@*****.**" oas["info"]["contact"]["url"] = "http://example.com" url = "http://example.com/specifications/1" identifier = "http://example.com/dataservices/1" oas_spec = OASDataService(url, oas, identifier) for dataservice in oas_spec.dataservices: catalog.services.append(dataservice) src = """ @prefix dct: <http://purl.org/dc/terms/> . @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . @prefix dcat: <http://www.w3.org/ns/dcat#> . @prefix vcard: <http://www.w3.org/2006/vcard/ns#> . <http://example.com/catalogs/1> a dcat:Catalog ; dcat:service <http://example.com/dataservices/1> . <http://example.com/dataservices/1> a dcat:DataService ; dct:title "Swagger Petstore"@en ; dcat:contactPoint [ a vcard:Organization ; vcard:hasEmail <mailto:[email protected]> ; vcard:hasOrganizationName "Example Inc"@en ; vcard:hasURL <http://example.com> ; ] ; dcat:endpointDescription <http://example.com/specifications/1> ; . """ g1 = Graph().parse(data=catalog.to_rdf(), format="turtle") g2 = Graph().parse(data=src, format="turtle") _isomorphic = isomorphic(g1, g2) if not _isomorphic: _dump_diff(g1, g2) pass assert _isomorphic
def test_parse_spec_with_multiple_servers_url(spec_with_multiple_servers: str, mocker: MockFixture) -> None: """It returns multiple valid dataservices with one endpoint URL.""" catalog = Catalog() catalog.identifier = "http://example.com/catalogs/1" ids = [1, 2] mocker.patch("oastodcat.oas_dataservice.create_id", side_effect=ids) url = "http://example.com/specifications/1" oas = yaml.safe_load(spec_with_multiple_servers) identifier = "http://example.com/dataservices/{id}" oas_spec = OASDataService(url, oas, identifier) for dataservice in oas_spec.dataservices: catalog.services.append(dataservice) src = """ @prefix dct: <http://purl.org/dc/terms/> . @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . @prefix dcat: <http://www.w3.org/ns/dcat#> . <http://example.com/catalogs/1> a dcat:Catalog ; dcat:service <http://example.com/dataservices/1> , <http://example.com/dataservices/2> . <http://example.com/dataservices/1> a dcat:DataService ; dct:title "Swagger Petstore"@en ; dcat:endpointURL <http://test.petstore.swagger.io/v1> ; dcat:endpointDescription <http://example.com/specifications/1> ; . <http://example.com/dataservices/2> a dcat:DataService ; dct:title "Swagger Petstore"@en ; dcat:endpointURL <http://petstore.swagger.io/v1> ; dcat:endpointDescription <http://example.com/specifications/1> ; . """ g1 = Graph().parse(data=catalog.to_rdf(), format="turtle") g2 = Graph().parse(data=src, format="turtle") _isomorphic = isomorphic(g1, g2) if not _isomorphic: _dump_diff(g1, g2) pass assert _isomorphic
def test_parse_spec_with_license(minimal_spec: str) -> None: """It returns a valid dataservice with license.""" catalog = Catalog() catalog.identifier = "http://example.com/catalogs/1" oas = yaml.safe_load(minimal_spec) oas["info"]["license"] = {} oas["info"]["license"]["name"] = "Apache 2.0" oas["info"]["license"][ "url"] = "https://www.apache.org/licenses/LICENSE-2.0.html" url = "http://example.com/specifications/1" identifier = "http://example.com/dataservices/1" oas_spec = OASDataService(url, oas, identifier) for dataservice in oas_spec.dataservices: catalog.services.append(dataservice) src = """ @prefix dct: <http://purl.org/dc/terms/> . @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . @prefix dcat: <http://www.w3.org/ns/dcat#> . <http://example.com/catalogs/1> a dcat:Catalog ; dcat:service <http://example.com/dataservices/1> . <http://example.com/dataservices/1> a dcat:DataService ; dct:title "Swagger Petstore"@en ; dct:license <https://www.apache.org/licenses/LICENSE-2.0.html> ; dcat:endpointDescription <http://example.com/specifications/1> ; . """ g1 = Graph().parse(data=catalog.to_rdf(), format="turtle") g2 = Graph().parse(data=src, format="turtle") _isomorphic = isomorphic(g1, g2) if not _isomorphic: _dump_diff(g1, g2) pass assert _isomorphic
def test_to_graph_should_return_dataset_as_graph() -> None: """It returns a dataset graph isomorphic to spec.""" catalog = Catalog() catalog.identifier = "http://example.com/catalogs/1" dataset1 = Dataset() dataset1.identifier = "http://example.com/datasets/1" dataset1.title = {"nb": "Datasett 1", "en": "Dataset 1"} catalog.datasets.append(dataset1) dataset2 = Dataset() dataset2.identifier = "http://example.com/datasets/2" dataset2.title = {"nb": "Datasett 2", "en": "Dataset 2"} catalog.datasets.append(dataset2) src = """ @prefix dct: <http://purl.org/dc/terms/> . @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . @prefix dcat: <http://www.w3.org/ns/dcat#> . <http://example.com/catalogs/1> a dcat:Catalog ; dcat:dataset <http://example.com/datasets/1> , <http://example.com/datasets/2> ; . <http://example.com/datasets/1> a dcat:Dataset ; dct:title "Dataset 1"@en, "Datasett 1"@nb ; . <http://example.com/datasets/2> a dcat:Dataset ; dct:title "Dataset 2"@en, "Datasett 2"@nb ; . """ g1 = Graph().parse(data=catalog.to_rdf(), format="turtle") g2 = Graph().parse(data=src, format="turtle") _isomorphic = isomorphic(g1, g2) if not _isomorphic: _dump_diff(g1, g2) pass assert _isomorphic
def test_parse_spec_with_media_types(spec_with_media_types: str) -> None: """It returns a valid dataservice with media types.""" catalog = Catalog() catalog.identifier = "http://example.com/catalogs/1" oas = yaml.safe_load(spec_with_media_types) url = "http://example.com/specifications/1" identifier = "http://example.com/dataservices/1" oas_spec = OASDataService(url, oas, identifier) for dataservice in oas_spec.dataservices: catalog.services.append(dataservice) src = """ @prefix dct: <http://purl.org/dc/terms/> . @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . @prefix dcat: <http://www.w3.org/ns/dcat#> . <http://example.com/catalogs/1> a dcat:Catalog ; dcat:service <http://example.com/dataservices/1> . <http://example.com/dataservices/1> a dcat:DataService ; dct:title "Swagger Petstore"@en ; dcat:mediaType \ <https://www.iana.org/assignments/media-types/application/json> , <https://www.iana.org/assignments/media-types/application/xml> ; dcat:endpointDescription <http://example.com/specifications/1> ; . """ g1 = Graph().parse(data=catalog.to_rdf(), format="turtle") g2 = Graph().parse(data=src, format="turtle") _isomorphic = isomorphic(g1, g2) if not _isomorphic: _dump_diff(g1, g2) pass assert _isomorphic
def test_to_graph_should_return_dct_identifier_as_graph() -> None: """It returns a dct_identifier graph isomorphic to spec.""" catalog = Catalog() catalog.identifier = "http://example.com/catalogs/1" catalog.dct_identifier = "Catalog_123456789" src = """ @prefix dct: <http://purl.org/dc/terms/> . @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . @prefix dcat: <http://www.w3.org/ns/dcat#> . <http://example.com/catalogs/1> a dcat:Catalog ; dct:identifier "Catalog_123456789"; . """ g1 = Graph().parse(data=catalog.to_rdf(), format="turtle") g2 = Graph().parse(data=src, format="turtle") _isomorphic = isomorphic(g1, g2) if not _isomorphic: _dump_diff(g1, g2) pass assert _isomorphic
def main(req: func.HttpRequest, msg: func.Out[str]) -> func.HttpResponse: logging.info('Python HTTP trigger function processed a request.') search = req.params.get('search') if not search: try: req_body = req.get_json() except ValueError: pass else: search = req_body.get('search') assetType = req.params.get('assetType') if not assetType: try: req_body = req.get_json() except ValueError: pass else: search = req_body.get('assetType') entityType = req.params.get('entityType') if not entityType: try: req_body = req.get_json() except ValueError: pass else: search = req_body.get('entityType') if search: logging.info(search) logging.info(assetType) logging.info(entityType) # search purview value = entitySearch(search) if int(json.loads(value)['@search.count']) > 0: logging.info(json.loads(value)['@search.count']) else: logging.info("Nothing was returned from the search") return func.HttpResponse( "This HTTP triggered function executed successfully, but no search criteria was returned from the Purview catalog. Pass a search in the query string or in the request body for a response.", status_code=200 ) #parse the response objToexport = [] score = 0 #loop through all of the results and filter on the assetType and entityType jsonObj = json.loads(value) for obj in jsonObj['value'] : if (obj['assetType'][0] == assetType) and (obj['entityType'] == entityType): #if there are multiple objects returned, select the one with the highest score if (obj['@search.score'] > score): objToexport = obj score = obj['@search.score'] # return function if not match has been found in the data returned from Purview if(len(objToexport) == 0): logging.info("No match was found in the Purview catalog for the search, assetType and entityType combination entityType: {0} {1} {2} ".format(search, assetType, entityType)) return func.HttpResponse( f"No match was found in the Purview catalog for search : {search} assetType: {assetType} entityType: {entityType} ", status_code=200 ) publisher = os.environ.get('publisher') logging.info(objToexport['assetType']) logging.info(objToexport['entityType']) logging.info(objToexport['@search.score']) logging.info(objToexport['qualifiedName']) logging.info(objToexport['name']) logging.info(publisher) logging.info(score) # Create catalog object catalog = Catalog() catalog.identifier = objToexport['qualifiedName'] catalog.title = {"en": objToexport['name']} catalog.publisher = publisher # Create a dataset: dataset = Dataset() dataset.identifier = objToexport['qualifiedName'] dataset.title = {"nb": objToexport['name'], "en": objToexport['name']} # # Add dataset to catalog: catalog.datasets.append(dataset) # get rdf representation in turtle (default) rdf = catalog.to_rdf() logging.info(rdf.decode()) # write the rdf to Azure storage msg.set(rdf.decode()) # return the function return func.HttpResponse(f"The HTTP triggered function for {search} executed successfully. The assetType provided was: {assetType} and the entityType was: {entityType }") else: return func.HttpResponse( "This HTTP triggered function executed successfully, but no search criteria was supplied. Pass a search in the query string or in the request body for a response.", status_code=200 )
from datacatalogtordf import Catalog, Dataset # Create catalog object catalog = Catalog() catalog.identifier = "http://example.com/catalogs/1" catalog.title = {"en": "A dataset catalog"} catalog.publisher = "https://example.com/publishers/1" # Create a dataset: dataset = Dataset() dataset.identifier = "http://example.com/datasets/1" dataset.title = {"nb": "inntektsAPI", "en": "incomeAPI"} # # Add concept to catalog: catalog.datasets.append(dataset) # get rdf representation in turtle (default) rdf = catalog.to_rdf() print(rdf.decode())