6. DSMS Apps and Pipelines#
In this tutorial we see how to create apps and run them manually
6.1: Setting up#
Before you run this tutorial: make sure to have access to a DSMS-instance of your interest, alongwith with installation of this package and have establised access to the DSMS through DSMS-SDK (refer to Connecting to DSMS)
Now let us import the needed classes and functions for this tutorial.
[1]:
from dsms import DSMS, KItem, AppConfig
import time
Now source the environmental variables from an .env file and start the DSMS-session.
[2]:
dsms = DSMS(env=".env")
6.1. Investigating Available Apps#
We can investigate which apps are available:
[3]:
dsms.app_configs
[3]:
[app:
name: ckan-fetch,
app:
name: csv_tensile_test,
app:
name: csv_tensile_test_f2,
app:
name: csv_tensile_test_three_directions,
app:
name: dsms-materialcard,
app:
name: dsms-tensile-test-analysis,
app:
name: excel_notch_tensile_test,
app:
name: excel_notched_tensile_test,
app:
name: excel_shear_tensile_test,
app:
name: excel_shear_test,
app:
name: excel_tensile_test,
app:
name: ternary-plot]
6.2 Create a new app config and apply it to a KItem#
6.2.1 Arbitrary python code#
To be defined.
6.2.2 - Data2RDF#
6.2.2.1 Prepare app and its config#
In the following example, we would like to upload some csv with some arbitrary data and describe it through an RDF. This will give us the opportunity to harmonize the entities of the data file through ontological concepts and allow us to convert values of the data frame columns in to any compatible unit we would like to have.
Fist of all, let us define the data:
[4]:
data = """A,B,C
1.2,1.3,1.5
1.7,1.8,1.9
2.0,2.1,2.3
2.5,2.6,2.8
3.0,3.2,3.4
3.6,3.7,3.9
4.1,4.3,4.4
4.7,4.8,5.0
5.2,5.3,5.5
5.8,6.0,6.1
"""
We will also give the config a defined name:
[5]:
configname = "testapp2"
As a next step, we want to create a new app specification. The specification is following the definition of an Argo Workflow. The workflow shall trigger a pipeline from a docker image with the Data2RDF package.
The image has already been deployed on the k8s cluster of the DSMS and the workflow template with the name dsms-data2rdf has been implemented previously. Hence we only need to configure our pipeline for our data shown above, which we would like to upload and describe through an RDF.
For more details about the data2rdf package, please refer to the documentation of Data2RDF mentioned above.
The parameters of the app config are defining the inputs for our Data2RDF pipeline. This e.g. are:
the parser kind (
csvhere)the time series header length (
1here)the metadata length (
0here)the time series separator (
,here)the log level (
DEBUGhere)the mapping
Ais the test time and has a unit in secondsBis the standard force in kilonewtonsCis the absolut cross head travel in millimeters
[6]:
parameters = [
{"name": "parser", "value": "csv"},
{"name": "time_series_header_length", "value": 1},
{"name": "metadata_length", "value": 0},
{"name": "time_series_sep", "value": ","},
{
"name": "mapping",
"value": """
[
{
"key": "A",
"iri": "https://w3id.org/steel/ProcessOntology/TestTime",
"unit": "s"
},
{
"key": "B",
"iri": "https://w3id.org/steel/ProcessOntology/StandardForce",
"unit": "kN"
},
{
"key": "C",
"iri": "https://w3id.org/steel/ProcessOntology/AbsoluteCrossheadTravel",
"unit": "mm"
}
]
""",
},
]
Now we add the parameters to our app specification. We assign a prefix datardf- which shall generate a new name with some random characters as suffix. The workflow template with the Docker image we want to run is called dsms-data2rdf and its entrypoint is execute_pipeline.
[ ]:
# Define app specification
specification = {
"apiVersion": "argoproj.io/v1alpha1",
"kind": "Workflow",
"metadata": {"generateName": "data2rdf-"},
"spec": {
"entrypoint": "execute-pipeline",
"workflowTemplateRef": {"name": "dsms-data2rdf-1.2.3"},
"arguments": {"parameters": parameters},
},
}
Now we instanciate the new app config:
[8]:
appspec = AppConfig(
name=configname,
specification=specification, # this can also be a file path to a yaml file instead of a dict
expose_sdk_config=True,
)
Please note that the expose_sdk_config is important here, since the pipeline needs to be aware of the settings of our platform and our current SDK-session.
We commit the new app config:
[9]:
dsms.commit()
And show the app specification:
[30]:
appspec.specification
[30]:
{'apiVersion': 'argoproj.io/v1alpha1',
'kind': 'Workflow',
'metadata': {'generateName': 'data2rdf-'},
'spec': {'entrypoint': 'execute_pipeline',
'workflowTemplateRef': {'name': 'dsms-data2rdf-1.2.1'},
'arguments': {'parameters': [{'name': 'parser', 'value': 'csv'},
{'name': 'time_series_header_length', 'value': 1},
{'name': 'metadata_length', 'value': 0},
{'name': 'time_series_sep', 'value': ','},
{'name': 'mapping',
'value': '\n [\n {\n "key": "A",\n "iri": "https://w3id.org/steel/ProcessOntology/TestTime",\n "unit": "s"\n },\n {\n "key": "B",\n "iri": "https://w3id.org/steel/ProcessOntology/StandardForce",\n "unit": "kN"\n },\n {\n "key": "C",\n "iri": "https://w3id.org/steel/ProcessOntology/AbsoluteCrossheadTravel",\n "unit": "mm"\n }\n ]\n '},
{'name': 'request_timeout', 'value': 120},
{'name': 'ping', 'value': True},
{'name': 'host_url', 'value': 'https://bue.materials-data.space/'},
{'name': 'ssl_verify', 'value': True},
{'name': 'kitem_repo', 'value': 'knowledge-items'},
{'name': 'encoding', 'value': 'utf-8'}]}}}
Now we would like to apply the app config to a KItem. The set the triggerUponUpload must be set to True so that the app is triggered automatically when we upload an attachment.
Additionally, we must tell the file extension for which the upload shall be triggered. Here it is .csv.
We also want to generate a qr code as avatar for the KItem with avatar={"include_qr": True}.
[11]:
item = KItem(
name="my tensile test experiment",
ktype_id=dsms.ktypes.Dataset,
kitem_apps=[
{
"executable": appspec.name,
"title": "data2rdf",
"additional_properties": {
"triggerUponUpload": True,
"triggerUponUploadFileExtensions": [".csv"],
},
}
],
avatar={"include_qr": True},
)
We commit the KItem:
[12]:
dsms.commit()
Now we add our data with our attachment:
[13]:
item.attachments = [{"name": "dummy_data.csv", "content": data}]
And we commit again:
[14]:
dsms.commit()
6.2.2.2 Get results#
Now we can verify that the data extraction was successful:
[15]:
print(item)
kitem:
name: my tensile test experiment
id: 12f0939b-8125-4a4a-9159-84f731e54d5d
ktype_id: dataset
in_backend: true
slug: mytensiletestexperiment-12f0939b
annotations: []
attachments:
- name: dummy_data.csv
content: null
- name: subgraph.ttl
content: null
linked_kitems: []
affiliations: []
authors:
- user_id: 7f0e5a37-353b-4bbc-b1f1-b6ad575f562d
avatar_exists: true
contacts: []
created_at: 2025-01-17 12:05:18.315322
updated_at: 2025-01-17 12:05:18.315322
external_links: []
kitem_apps:
- executable: testapp2
title: data2rdf
description: null
tags: null
additional_properties:
triggerUponUpload: true
triggerUponUploadFileExtensions:
- .csv
user_groups: []
dataframe:
- column_id: 0
name: TestTime
- column_id: 1
name: StandardForce
- column_id: 2
name: AbsoluteCrossheadTravel
rdf_exists: true
And also that the RDF generation was successful:
[16]:
print(item.subgraph.serialize())
@prefix csvw: <http://www.w3.org/ns/csvw#> .
@prefix dcat: <http://www.w3.org/ns/dcat#> .
@prefix dcterms: <http://purl.org/dc/terms/> .
@prefix ns1: <http://xmlns.com/foaf/spec/> .
@prefix ns2: <http://qudt.org/schema/qudt/> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
<https://bue.materials-data.space/12f0939b-8125-4a4a-9159-84f731e54d5d/dataset> a dcat:Dataset ;
dcterms:hasPart <https://bue.materials-data.space/12f0939b-8125-4a4a-9159-84f731e54d5d/tableGroup> ;
dcat:distribution [ a dcat:Distribution ;
dcat:accessURL "https://bue.materials-data.space/api/knowledge/data_api/12f0939b-8125-4a4a-9159-84f731e54d5d"^^xsd:anyURI ;
dcat:mediaType "http://www.iana.org/assignments/media-types/text/csv"^^xsd:anyURI ] .
<https://bue.materials-data.space/12f0939b-8125-4a4a-9159-84f731e54d5d/AbsoluteCrossheadTravel> a <https://w3id.org/steel/ProcessOntology/AbsoluteCrossheadTravel> ;
ns2:hasUnit "http://qudt.org/vocab/unit/MilliM"^^xsd:anyURI .
<https://bue.materials-data.space/12f0939b-8125-4a4a-9159-84f731e54d5d/StandardForce> a <https://w3id.org/steel/ProcessOntology/StandardForce> ;
ns2:hasUnit "http://qudt.org/vocab/unit/KiloN"^^xsd:anyURI .
<https://bue.materials-data.space/12f0939b-8125-4a4a-9159-84f731e54d5d/TestTime> a <https://w3id.org/steel/ProcessOntology/TestTime> ;
ns2:hasUnit "http://qudt.org/vocab/unit/SEC"^^xsd:anyURI .
<https://bue.materials-data.space/12f0939b-8125-4a4a-9159-84f731e54d5d/tableGroup> a csvw:TableGroup ;
csvw:table [ a csvw:Table ;
rdfs:label "Time series data" ;
csvw:tableSchema [ a csvw:Schema ;
csvw:column [ a csvw:Column ;
ns2:quantity <https://bue.materials-data.space/12f0939b-8125-4a4a-9159-84f731e54d5d/TestTime> ;
csvw:titles "A"^^xsd:string ;
ns1:page [ a ns1:Document ;
dcterms:format "https://www.iana.org/assignments/media-types/application/json"^^xsd:anyURI ;
dcterms:identifier "https://bue.materials-data.space/api/knowledge/data_api/column-0"^^xsd:anyURI ;
dcterms:type "http://purl.org/dc/terms/Dataset"^^xsd:anyURI ] ],
[ a csvw:Column ;
ns2:quantity <https://bue.materials-data.space/12f0939b-8125-4a4a-9159-84f731e54d5d/StandardForce> ;
csvw:titles "B"^^xsd:string ;
ns1:page [ a ns1:Document ;
dcterms:format "https://www.iana.org/assignments/media-types/application/json"^^xsd:anyURI ;
dcterms:identifier "https://bue.materials-data.space/api/knowledge/data_api/column-1"^^xsd:anyURI ;
dcterms:type "http://purl.org/dc/terms/Dataset"^^xsd:anyURI ] ],
[ a csvw:Column ;
ns2:quantity <https://bue.materials-data.space/12f0939b-8125-4a4a-9159-84f731e54d5d/AbsoluteCrossheadTravel> ;
csvw:titles "C"^^xsd:string ;
ns1:page [ a ns1:Document ;
dcterms:format "https://www.iana.org/assignments/media-types/application/json"^^xsd:anyURI ;
dcterms:identifier "https://bue.materials-data.space/api/knowledge/data_api/column-2"^^xsd:anyURI ;
dcterms:type "http://purl.org/dc/terms/Dataset"^^xsd:anyURI ] ] ] ] .
And now we are able to convert our data into any compatiable unit we want. For the StandardForce, it was previously kN, but we want to have it in N now:
[17]:
item.dataframe.StandardForce.convert_to("N")
[17]:
[1300.0,
1800.0,
2100.0,
2600.0,
3200.0,
3700.0,
4300.0,
4800.0,
5300.0,
6000.0]
6.2.2.3 Manipulate dataframe#
We are able to retrieve the dataframe as pd.DataFrame:
[18]:
item.dataframe.to_df()
[18]:
| TestTime | StandardForce | AbsoluteCrossheadTravel | |
|---|---|---|---|
| 0 | 1.2 | 1.3 | 1.5 |
| 1 | 1.7 | 1.8 | 1.9 |
| 2 | 2.0 | 2.1 | 2.3 |
| 3 | 2.5 | 2.6 | 2.8 |
| 4 | 3.0 | 3.2 | 3.4 |
| 5 | 3.6 | 3.7 | 3.9 |
| 6 | 4.1 | 4.3 | 4.4 |
| 7 | 4.7 | 4.8 | 5.0 |
| 8 | 5.2 | 5.3 | 5.5 |
| 9 | 5.8 | 6.0 | 6.1 |
We are able to overwrite the dataframe with new data:
[19]:
item.dataframe = {
"TestTime": list(range(100)),
"StandardForce": list(range(1,101)),
"AbsoluteCrossheadTravel": list(range(2,102))
}
dsms.commit()
We are able to retrieve the data colum-wise:
[20]:
for column in item.dataframe:
print("column:", column.name, ",\n", "data:", column.get())
column: TestTime ,
data: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99]
column: StandardForce ,
data: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100]
column: AbsoluteCrossheadTravel ,
data: [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101]
… and also to modify the dataframe directly as we need:
[21]:
new_df = item.dataframe.to_df().drop(['TestTime'], axis=1)
item.dataframe = new_df
6.2.2.4 Run app on demand#
We are able to run the app on demand, not being triggered automatically during the upload of an attachment every time. For this purpose, we just need to refer to the name of the app we assigned during the KItem creation ( here it is simply data2rdf).
Additionally, we need to tell the attachment_name and hand over the access token and host url to the app by explicitly setting expose_sdk_config to True. This is basically telling the SDK that the app is using the SDK also internally and that the app should receive its parameters from the current SDK session.
The app is running synchronously, hence the job is created when the pipeline run finished.
[22]:
job = item.kitem_apps.by_title["data2rdf"].run(
attachment_name="dummy_data.csv",
expose_sdk_config=True
)
We are able to retrieve the job status:
[23]:
job.status
[23]:
JobStatus(phase='Succeeded', estimated_duration=None, finished_at='01/17/2025, 12:06:14', started_at='01/17/2025, 12:05:54', message=None, progress='1/1')
… and the job logs:
[31]:
job.logs
[31]:
'"[2025-01-17 12:06:24,552 - dsms_data2rdf.main - INFO]: Fetch KItem: \\n kitem:\\n name: my tensile test experiment\\n id: 12f0939b-8125-4a4a-9159-84f731e54d5d\\n ktype_id: dataset\\n slug: mytensiletestexperiment-12f0939b\\n annotations: []\\n attachments:\\n - name: dummy_data.csv\\n content: null\\n - name: subgraph.ttl\\n content: null\\n linked_kitems: []\\n affiliations: []\\n authors:\\n - user_id: 7f0e5a37-353b-4bbc-b1f1-b6ad575f562d\\n avatar_exists: true\\n contacts: []\\n created_at: 2025-01-17 12:05:18.315322\\n updated_at: 2025-01-17 12:05:18.315322\\n external_links: []\\n kitem_apps:\\n - executable: testapp2\\n title: data2rdf\\n description: null\\n tags: null\\n additional_properties:\\n triggerUponUpload: true\\n triggerUponUploadFileExtensions:\\n - .csv\\n user_groups: []\\n rdf_exists: true\\n\\n[2025-01-17 12:06:24,569 - dsms_data2rdf.main - INFO]: Run pipeline with the following parser arguments: {\'metadata_sep\': \',\', \'metadata_length\': 0, \'time_series_sep\': \',\', \'time_series_header_length\': 1, \'drop_na\': False, \'fillna\': None}\\n[2025-01-17 12:06:24,569 - dsms_data2rdf.main - INFO]: Run pipeline with the following parser: Parser.csv\\n[2025-01-17 12:06:24,569 - dsms_data2rdf.main - INFO]: Run pipeline with the following config: {\'base_iri\': \'https://bue.materials-data.space/12f0939b-8125-4a4a-9159-84f731e54d5d\', \'data_download_uri\': \'https://bue.materials-data.space/api/knowledge/data_api/12f0939b-8125-4a4a-9159-84f731e54d5d\', \'graph_identifier\': \'https://bue.materials-data.space/12f0939b-8125-4a4a-9159-84f731e54d5d\', \'separator\': \'/\', \'encoding\': \'utf-8\'}\\n[2025-01-17 12:06:29,292 - dsms_data2rdf.main - INFO]: Pipeline finished.\\n[2025-01-17 12:06:29,292 - dsms_data2rdf.main - INFO]: Pipeline did detect any metadata. Will not make annotations for KItem\\n[2025-01-17 12:06:29,292 - dsms_data2rdf.main - INFO]: Extracted Time Series: Index([\'TestTime\', \'StandardForce\', \'AbsoluteCrossheadTravel\'], dtype=\'object\')\\n[2025-01-17 12:06:29,788 - dsms_data2rdf.main - INFO]: Checking that dataframe is up to date.\\n[2025-01-17 12:06:29,788 - dsms_data2rdf.main - INFO]: Dataframe upload was successful after 0 retries.\\n[2025-01-17 12:06:29,788 - dsms_data2rdf.main - INFO]: Done!\\n"'
In case we would like to run the job in the background, we simply add a wait=False:
[25]:
job = item.kitem_apps.by_title["data2rdf"].run(
attachment_name="dummy_data.csv",
expose_sdk_config=True,
wait=False,
)
We are able to monitor the job status and logs asynchronously:
[26]:
while True:
time.sleep(1)
print("\n Current status:")
print(job.status)
print("\n Current logs:")
print(job.logs)
if job.status.phase != "Running":
break
Current status:
phase='Running' estimated_duration=None finished_at=None started_at='01/17/2025, 12:06:15' message=None progress='0/1'
Current logs:
""
Current status:
phase='Running' estimated_duration=None finished_at=None started_at='01/17/2025, 12:06:15' message=None progress='0/1'
Current logs:
""
Current status:
phase='Running' estimated_duration=None finished_at=None started_at='01/17/2025, 12:06:15' message=None progress='0/1'
Current logs:
""
Current status:
phase='Running' estimated_duration=None finished_at=None started_at='01/17/2025, 12:06:15' message=None progress='0/1'
Current logs:
""
Current status:
phase='Running' estimated_duration=None finished_at=None started_at='01/17/2025, 12:06:15' message=None progress='0/1'
Current logs:
""
Current status:
phase='Running' estimated_duration=None finished_at=None started_at='01/17/2025, 12:06:15' message=None progress='0/1'
Current logs:
""
Current status:
phase='Running' estimated_duration=None finished_at=None started_at='01/17/2025, 12:06:15' message=None progress='0/1'
Current logs:
""
Current status:
phase='Running' estimated_duration=None finished_at=None started_at='01/17/2025, 12:06:15' message=None progress='0/1'
Current logs:
""
Current status:
phase='Running' estimated_duration=None finished_at=None started_at='01/17/2025, 12:06:15' message=None progress='0/1'
Current logs:
""
Current status:
phase='Running' estimated_duration=None finished_at=None started_at='01/17/2025, 12:06:15' message=None progress='0/1'
Current logs:
""
Current status:
phase='Running' estimated_duration=None finished_at=None started_at='01/17/2025, 12:06:15' message=None progress='0/1'
Current logs:
""
Current status:
phase='Running' estimated_duration=None finished_at=None started_at='01/17/2025, 12:06:15' message=None progress='0/1'
Current logs:
""
Current status:
phase='Running' estimated_duration=None finished_at=None started_at='01/17/2025, 12:06:15' message=None progress='0/1'
Current logs:
""
Current status:
phase='Running' estimated_duration=None finished_at=None started_at='01/17/2025, 12:06:15' message=None progress='0/1'
Current logs:
""
Current status:
phase='Running' estimated_duration=None finished_at=None started_at='01/17/2025, 12:06:15' message=None progress='0/1'
Current logs:
""
Current status:
phase='Running' estimated_duration=None finished_at=None started_at='01/17/2025, 12:06:15' message=None progress='0/1'
Current logs:
""
Current status:
phase='Running' estimated_duration=None finished_at=None started_at='01/17/2025, 12:06:15' message=None progress='0/1'
Current logs:
""
Current status:
phase='Running' estimated_duration=None finished_at=None started_at='01/17/2025, 12:06:15' message=None progress='0/1'
Current logs:
""
Current status:
phase='Running' estimated_duration=None finished_at=None started_at='01/17/2025, 12:06:15' message=None progress='0/1'
Current logs:
""
Current status:
phase='Succeeded' estimated_duration=None finished_at='01/17/2025, 12:06:41' started_at='01/17/2025, 12:06:15' message=None progress='1/1'
Current logs:
"[2025-01-17 12:06:24,552 - dsms_data2rdf.main - INFO]: Fetch KItem: \n kitem:\n name: my tensile test experiment\n id: 12f0939b-8125-4a4a-9159-84f731e54d5d\n ktype_id: dataset\n slug: mytensiletestexperiment-12f0939b\n annotations: []\n attachments:\n - name: dummy_data.csv\n content: null\n - name: subgraph.ttl\n content: null\n linked_kitems: []\n affiliations: []\n authors:\n - user_id: 7f0e5a37-353b-4bbc-b1f1-b6ad575f562d\n avatar_exists: true\n contacts: []\n created_at: 2025-01-17 12:05:18.315322\n updated_at: 2025-01-17 12:05:18.315322\n external_links: []\n kitem_apps:\n - executable: testapp2\n title: data2rdf\n description: null\n tags: null\n additional_properties:\n triggerUponUpload: true\n triggerUponUploadFileExtensions:\n - .csv\n user_groups: []\n rdf_exists: true\n\n[2025-01-17 12:06:24,569 - dsms_data2rdf.main - INFO]: Run pipeline with the following parser arguments: {'metadata_sep': ',', 'metadata_length': 0, 'time_series_sep': ',', 'time_series_header_length': 1, 'drop_na': False, 'fillna': None}\n[2025-01-17 12:06:24,569 - dsms_data2rdf.main - INFO]: Run pipeline with the following parser: Parser.csv\n[2025-01-17 12:06:24,569 - dsms_data2rdf.main - INFO]: Run pipeline with the following config: {'base_iri': 'https://bue.materials-data.space/12f0939b-8125-4a4a-9159-84f731e54d5d', 'data_download_uri': 'https://bue.materials-data.space/api/knowledge/data_api/12f0939b-8125-4a4a-9159-84f731e54d5d', 'graph_identifier': 'https://bue.materials-data.space/12f0939b-8125-4a4a-9159-84f731e54d5d', 'separator': '/', 'encoding': 'utf-8'}\n[2025-01-17 12:06:29,292 - dsms_data2rdf.main - INFO]: Pipeline finished.\n[2025-01-17 12:06:29,292 - dsms_data2rdf.main - INFO]: Pipeline did detect any metadata. Will not make annotations for KItem\n[2025-01-17 12:06:29,292 - dsms_data2rdf.main - INFO]: Extracted Time Series: Index(['TestTime', 'StandardForce', 'AbsoluteCrossheadTravel'], dtype='object')\n[2025-01-17 12:06:29,788 - dsms_data2rdf.main - INFO]: Checking that dataframe is up to date.\n[2025-01-17 12:06:29,788 - dsms_data2rdf.main - INFO]: Dataframe upload was successful after 0 retries.\n[2025-01-17 12:06:29,788 - dsms_data2rdf.main - INFO]: Done!\n"
IMPORTANT: When job has run asychronously (in the background), we need to manually refresh the KItem afterwards:
[27]:
item.refresh()
Clean up the DSMS from the tutorial
[28]:
del dsms[item]
del dsms[appspec]
dsms.commit()