5. Searching KItems with the SDK#

In this tutorial we see how to search existing Kitems

5.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

Now source the environmental variables from an .env file and start the DSMS-session.

[2]:
dsms = DSMS(env=".env")

5.2. Searching for KItems#

In this section, we would like to search for specfic KItems we created in the DSMS.

For this purpose, we will firstly create some KItems and apply the search-method on the DSMS-object later on in order to find them again in the DSMS.

We also want to demonstrate here, that we can link KItems to each other in order to find e.g. a related item of type DatasetCatalog. For this strategy, we are using the linked_kitems- attribute and the id of the item which we would like to link.

The procedure looks like this:

[3]:
item1 = KItem(
    name="Machine-1",
    ktype_id=dsms.ktypes.Testingmachine,
    annotations=["https://w3id.org/steel/ProcessOntology/TestingMachine"],
    custom_properties={"Producer": "TestingLab GmBH",
                       "Room Number": "A404",
                       "Description": "Bending Test Machine"
                       }
)

item2 = KItem(
    name="Machine-2",
    ktype_id=dsms.ktypes.Testingmachine,
    annotations=["https://w3id.org/steel/ProcessOntology/TestingMachine"],
    custom_properties={"Producer": "StressStrain GmBH",
                       "Room Number": "B500",
                       "Description": "Compression Test Machine"
                       }
)

item3 = KItem(
    name="Specimen-1",
    ktype_id=dsms.ktypes.Specimen,
    linked_kitems=[item1],
    annotations=["https://w3id.org/steel/ProcessOntology/TestPiece"],
    custom_properties = {
        "Width": 0.5,
        "Length": [0.1, 0.2],
    }

)
item4 = KItem(
    name="Specimen-2",
    ktype_id=dsms.ktypes.Specimen,
    linked_kitems=[item2],
    annotations=["https://w3id.org/steel/ProcessOntology/TestPiece"],
    custom_properties = {
        "Width": 0.8,
        "Length": [0.8, 0.9],
    }
)

item5 = KItem(
    name="Research Institute ABC",
    ktype_id=dsms.ktypes.Organization,
    linked_kitems=[item1,item2],
    annotations=["www.researchBACiri.org/foo"],
)

dsms.add([item1, item2, item3, item4, item5])
dsms.commit()
/app/dsms/knowledge/kitem.py:406: UserWarning: A flat dictionary was provided for custom properties.
                    Will be transformed into `KItemCustomPropertiesModel`.
  warnings.warn(
/app/dsms/knowledge/kitem.py:306: UserWarning: Found a <class 'dsms.knowledge.kitem.KItem'> to be linked instead of an <class 'dsms.knowledge.properties.linked_kitems.KItemRelationshipModel'>. Will link it with the default relationship 'dcterms:haspart'.
  warnings.warn(
/usr/local/lib/python3.11/site-packages/pydantic/main.py:463: UserWarning: Pydantic serializer warnings:
  PydanticSerializationUnexpectedValue(Expected `str` - serialized value may not be as expected [input_value=False, input_type=bool])
  return self.__pydantic_serializer__.to_python(
/app/dsms/knowledge/kitem.py:692: UserWarning: No webform was defined for entry `Producer`. Cannot check if value is of correct type.
  warnings.warn(
/app/dsms/knowledge/kitem.py:692: UserWarning: No webform was defined for entry `Room Number`. Cannot check if value is of correct type.
  warnings.warn(
/app/dsms/knowledge/kitem.py:692: UserWarning: No webform was defined for entry `Description`. Cannot check if value is of correct type.
  warnings.warn(

Note : Here in this tutorial, we use dsms.search with limit=1 to maintain readability but the user can adjust the variable limit as per requirement.

</b>

Now, we are apply to search for e.g. kitems of type TestingMachine:

[4]:
result = dsms.search(ktypes=[dsms.ktypes.Specimen], limit=2)
print(result)
print("Name of the first kitem:")
print(result.hits[0].kitem.name)
hits:
- kitem:
    id: 14e9a531-7f91-4dd5-a72d-f8753a84d1ab
    name: Specimen123
    ktype_id: specimen
    slug: specimen123-14e9a531
    annotations: []
    attachments:
    - name: subgraph.ttl
    linked_kitems: []
    affiliations: []
    authors:
    - user_id: 7f0e5a37-353b-4bbc-b1f1-b6ad575f562d
    avatar_exists: false
    contacts: []
    created_at: 2025-08-12 14:41:51.234220
    updated_at: 2025-08-12 14:41:51.234220
    external_links: []
    apps: []
    user_groups: []
    custom_properties:
      content:
        sections:
        - id: idb424123144cdd8
          name: Untitled Section
          entries:
          - id: id6c76bbffe7ca78
            type: Number
            label: Width
            value: 0.5
            measurementUnit:
              iri: http://qudt.org/vocab/unit/MilliM
              label: Millimetre
              symbol: null
              namespace: http://qudt.org/vocab/unit
            relationMapping: null
            required: false
          - id: id717d07130a7618
            type: Slider
            label: Length
            value:
            - 0.1
            - 0.2
            measurementUnit:
              iri: http://qudt.org/vocab/unit/MilliM
              label: Millimetre
              symbol: null
              namespace: http://qudt.org/vocab/unit
            relationMapping: null
            required: false
    rdf_exists: true
    contexts: []
  fuzzy: false
- kitem:
    id: 1f3694d3-4624-45b8-9182-3bf88c6511f9
    name: Specimen-123
    ktype_id: specimen
    slug: specimen123-1f3694d3
    annotations:
    - iri: https://w3id.org/pmd/co/Specimen
      label: Specimen
      namespace: https://w3id.org/pmd/co
    attachments:
    - name: subgraph.ttl
    - name: testfile.txt
    linked_kitems: []
    affiliations: []
    authors:
    - user_id: 7f0e5a37-353b-4bbc-b1f1-b6ad575f562d
    avatar_exists: false
    contacts:
    - name: Specimen preparation
      email: specimenpreparation@group.mail
    created_at: 2025-08-13 13:08:52.481587
    updated_at: 2025-08-13 14:23:47.730855
    external_links:
    - label: specimen-link
      url: http://specimens.org
    apps: []
    user_groups: []
    custom_properties:
      content:
        sections:
        - id: idb424123144cdd8
          name: Untitled Section
          entries:
          - id: id6c76bbffe7ca78
            type: Number
            label: Width
            value: 1
            measurementUnit:
              iri: http://qudt.org/vocab/unit/MilliM
              label: Millimetre
              symbol: null
              namespace: http://qudt.org/vocab/unit
            relationMapping: null
            required: false
          - id: id717d07130a7618
            type: Slider
            label: Length
            value:
            - 0.1
            - 0.2
            measurementUnit:
              iri: http://qudt.org/vocab/unit/MilliM
              label: Millimetre
              symbol: null
              namespace: http://qudt.org/vocab/unit
            relationMapping: null
            required: false
    rdf_exists: true
    contexts: []
  fuzzy: false
total_count: 5

Name of the first kitem:
Specimen123

… and for all of type Organization and Testingmachine:

[5]:
for result in dsms.search(ktypes=[dsms.ktypes.Organization, dsms.ktypes.Testingmachine], limit=2):
    print(result.kitem)
    print("fuzziness: ", result.fuzzy)
    print("\n")
kitem:
  id: 4d587532-4275-4f4f-9d19-e199d9452d13
  name: Research Institute ABC
  ktype_id: organization
  slug: researchinstituteabc-4d587532
  annotations:
  - iri: www.researchBACiri.org/foo
    label: foo
    namespace: www.researchBACiri.org
  attachments:
  - name: subgraph.ttl
  linked_kitems:
  - is_incoming: false
    label: Has Part
    kitem:
      id: 0f89d6ad-3446-4d8a-9f27-39a69bcffeee
      name: Machine-1
      ktype_id: testingmachine
      slug: machine-1-0f89d6ad
    iri: http://purl.org/dc/terms/hasPart
  - is_incoming: false
    label: Has Part
    kitem:
      id: 2cf0aea2-b4c2-40b0-a786-bcf00ddb1991
      name: Machine-2
      ktype_id: testingmachine
      slug: machine-2-2cf0aea2
    iri: http://purl.org/dc/terms/hasPart
  affiliations: []
  authors:
  - user_id: 7f0e5a37-353b-4bbc-b1f1-b6ad575f562d
  avatar_exists: false
  contacts: []
  created_at: 2025-08-13 14:33:33.681221
  updated_at: 2025-08-13 14:33:33.681221
  external_links: []
  apps: []
  user_groups: []
  rdf_exists: true
  contexts: []

fuzziness:  False


kitem:
  id: 0f89d6ad-3446-4d8a-9f27-39a69bcffeee
  name: Machine-1
  ktype_id: testingmachine
  slug: machine-1-0f89d6ad
  annotations:
  - iri: https://w3id.org/steel/ProcessOntology/TestingMachine
    label: TestingMachine
    namespace: https://w3id.org/steel/ProcessOntology
  attachments: []
  linked_kitems:
  - is_incoming: true
    label: Has Part
    kitem:
      id: 4d587532-4275-4f4f-9d19-e199d9452d13
      name: Research Institute ABC
      ktype_id: organization
      slug: researchinstituteabc-4d587532
    iri: http://purl.org/dc/terms/hasPart
  - is_incoming: true
    label: Has Part
    kitem:
      id: d1ce4f7e-223b-4086-b5e5-11017f47270d
      name: Specimen-1
      ktype_id: specimen
      slug: specimen-1-d1ce4f7e
    iri: http://purl.org/dc/terms/hasPart
  affiliations: []
  authors:
  - user_id: 7f0e5a37-353b-4bbc-b1f1-b6ad575f562d
  avatar_exists: false
  contacts: []
  created_at: 2025-08-13 14:33:29.742517
  updated_at: 2025-08-13 14:33:29.742517
  external_links: []
  apps: []
  user_groups: []
  custom_properties:
    content:
      sections:
      - id: id17550956094374867vv
        name: Misc
        entries:
        - id: id1755095609437i4mybj
          type: Text
          label: Producer
          value: TestingLab GmBH
          measurementUnit: null
          relationMapping: null
          required: false
        - id: id1755095609437hd07kh
          type: Text
          label: Room Number
          value: A404
          measurementUnit: null
          relationMapping: null
          required: false
        - id: id17550956094377bpur4
          type: Text
          label: Description
          value: Bending Test Machine
          measurementUnit: null
          relationMapping: null
          required: false
  rdf_exists: false
  contexts: []

fuzziness:  False


… or for all of type Specimen with Specimen-1 in the name (Please note that the allow_fuzzy is set the False in order to get only exact matches):

[6]:
for result in dsms.search(query="Specimen-1", ktypes=[dsms.ktypes.Specimen], allow_fuzzy=False, limit=1):
    print(result)
kitem:
  id: 1f3694d3-4624-45b8-9182-3bf88c6511f9
  name: Specimen-123
  ktype_id: specimen
  slug: specimen123-1f3694d3
  annotations:
  - iri: https://w3id.org/pmd/co/Specimen
    label: Specimen
    namespace: https://w3id.org/pmd/co
  attachments:
  - name: subgraph.ttl
  - name: testfile.txt
  linked_kitems: []
  affiliations: []
  authors:
  - user_id: 7f0e5a37-353b-4bbc-b1f1-b6ad575f562d
  avatar_exists: false
  contacts:
  - name: Specimen preparation
    email: specimenpreparation@group.mail
  created_at: 2025-08-13 13:08:52.481587
  updated_at: 2025-08-13 14:23:47.730855
  external_links:
  - label: specimen-link
    url: http://specimens.org
  apps: []
  user_groups: []
  custom_properties:
    content:
      sections:
      - id: idb424123144cdd8
        name: Untitled Section
        entries:
        - id: id6c76bbffe7ca78
          type: Number
          label: Width
          value: 1
          measurementUnit:
            iri: http://qudt.org/vocab/unit/MilliM
            label: Millimetre
            symbol: null
            namespace: http://qudt.org/vocab/unit
          relationMapping: null
          required: false
        - id: id717d07130a7618
          type: Slider
          label: Length
          value:
          - 0.1
          - 0.2
          measurementUnit:
            iri: http://qudt.org/vocab/unit/MilliM
            label: Millimetre
            symbol: null
            namespace: http://qudt.org/vocab/unit
          relationMapping: null
          required: false
  rdf_exists: true
  contexts: []
fuzzy: false

… and for all of type Organization with the annotation www.researchBACiri.org/foo:

[7]:
for result in dsms.search(
          ktypes=[dsms.ktypes.Organization], annotations=["www.researchBACiri.org/foo"], allow_fuzzy=False, limit=1
    ):
    print(result)

kitem:
  id: 4d587532-4275-4f4f-9d19-e199d9452d13
  name: Research Institute ABC
  ktype_id: organization
  slug: researchinstituteabc-4d587532
  annotations:
  - iri: www.researchBACiri.org/foo
    label: foo
    namespace: www.researchBACiri.org
  attachments:
  - name: subgraph.ttl
  linked_kitems:
  - is_incoming: false
    label: Has Part
    kitem:
      id: 2cf0aea2-b4c2-40b0-a786-bcf00ddb1991
      name: Machine-2
      ktype_id: testingmachine
      slug: machine-2-2cf0aea2
    iri: http://purl.org/dc/terms/hasPart
  - is_incoming: false
    label: Has Part
    kitem:
      id: 0f89d6ad-3446-4d8a-9f27-39a69bcffeee
      name: Machine-1
      ktype_id: testingmachine
      slug: machine-1-0f89d6ad
    iri: http://purl.org/dc/terms/hasPart
  affiliations: []
  authors:
  - user_id: 7f0e5a37-353b-4bbc-b1f1-b6ad575f562d
  avatar_exists: false
  contacts: []
  created_at: 2025-08-13 14:33:33.681221
  updated_at: 2025-08-13 14:33:33.681221
  external_links: []
  apps: []
  user_groups: []
  rdf_exists: true
  contexts: []
fuzzy: false

5.3. Fetching linked KItems from a KItem#

In the beginning under 5.1 we created some kitems and linked each other. Now we want to fetch the linked kitems and display them to the user. For this we use the linked_kitems attribute.

[8]:
item5.linked_kitems
[8]:
- is_incoming: false
  label: Has Part
  kitem:
    id: 2cf0aea2-b4c2-40b0-a786-bcf00ddb1991
    name: Machine-2
    ktype_id: testingmachine
    slug: machine-2-2cf0aea2
  iri: http://purl.org/dc/terms/hasPart
- is_incoming: false
  label: Has Part
  kitem:
    id: 0f89d6ad-3446-4d8a-9f27-39a69bcffeee
    name: Machine-1
    ktype_id: testingmachine
    slug: machine-1-0f89d6ad
  iri: http://purl.org/dc/terms/hasPart

However, this linked KItem is not a “real” KItem. Due to performance reasons, we only display a slim representation of the linked KItem. Imagine if the linked KItem also has a linked KItem… this might lead to an infinite recursion. We can fetch the “real” KItem by using the fetch method of the linked KItem:

[9]:
item5.linked_kitems[0].fetch()
[9]:
kitem:
  id: 2cf0aea2-b4c2-40b0-a786-bcf00ddb1991
  name: Machine-2
  ktype_id: testingmachine
  slug: machine-2-2cf0aea2
  annotations:
  - iri: https://w3id.org/steel/ProcessOntology/TestingMachine
    label: TestingMachine
    namespace: https://w3id.org/steel/ProcessOntology
  attachments: []
  linked_kitems: []
  affiliations: []
  authors:
  - user_id: 7f0e5a37-353b-4bbc-b1f1-b6ad575f562d
  avatar_exists: false
  contacts: []
  created_at: 2025-08-13 14:33:30.358137
  updated_at: 2025-08-13 14:33:30.358137
  external_links: []
  apps: []
  user_groups: []
  custom_properties:
    content:
      sections:
      - id: id1755095609461z4tdh1
        name: Misc
        entries:
        - id: id1755095609461bqgrqv
          type: Text
          label: Producer
          value: StressStrain GmBH
          measurementUnit: null
          relationMapping: null
          required: false
        - id: id17550956094616vktvr
          type: Text
          label: Room Number
          value: B500
          measurementUnit: null
          relationMapping: null
          required: false
        - id: id1755095609461dhszfo
          type: Text
          label: Description
          value: Compression Test Machine
          measurementUnit: null
          relationMapping: null
          required: false
  rdf_exists: false
  contexts: []

We can retrieve the linked KItem by the IRI of the relation:

[10]:
item5.linked_kitems.by_relation
[10]:
{'http://purl.org/dc/terms/hasPart': [kitem:
    id: 2cf0aea2-b4c2-40b0-a786-bcf00ddb1991
    name: Machine-2
    ktype_id: testingmachine
    slug: machine-2-2cf0aea2,
  kitem:
    id: 0f89d6ad-3446-4d8a-9f27-39a69bcffeee
    name: Machine-1
    ktype_id: testingmachine
    slug: machine-1-0f89d6ad]}
[11]:
item5.linked_kitems.by_relation["http://purl.org/dc/terms/hasPart"][0].fetch()

[11]:
kitem:
  id: 2cf0aea2-b4c2-40b0-a786-bcf00ddb1991
  name: Machine-2
  ktype_id: testingmachine
  slug: machine-2-2cf0aea2
  annotations:
  - iri: https://w3id.org/steel/ProcessOntology/TestingMachine
    label: TestingMachine
    namespace: https://w3id.org/steel/ProcessOntology
  attachments: []
  linked_kitems: []
  affiliations: []
  authors:
  - user_id: 7f0e5a37-353b-4bbc-b1f1-b6ad575f562d
  avatar_exists: false
  contacts: []
  created_at: 2025-08-13 14:33:30.358137
  updated_at: 2025-08-13 14:33:30.358137
  external_links: []
  apps: []
  user_groups: []
  custom_properties:
    content:
      sections:
      - id: id1755095609461z4tdh1
        name: Misc
        entries:
        - id: id1755095609461bqgrqv
          type: Text
          label: Producer
          value: StressStrain GmBH
          measurementUnit: null
          relationMapping: null
          required: false
        - id: id17550956094616vktvr
          type: Text
          label: Room Number
          value: B500
          measurementUnit: null
          relationMapping: null
          required: false
        - id: id1755095609461dhszfo
          type: Text
          label: Description
          value: Compression Test Machine
          measurementUnit: null
          relationMapping: null
          required: false
  rdf_exists: false
  contexts: []

Additionally, we can retrieve the linked KItems grouped by ktype:

[12]:
item5.linked_kitems.by_ktype
[12]:
{ktype:
   id: testingmachine
   name: TestingMachine
   created_at: '2025-07-22T12:41:50.505566'
   updated_at: '2025-07-22T12:41:50.505566': [kitem:
    id: 2cf0aea2-b4c2-40b0-a786-bcf00ddb1991
    name: Machine-2
    ktype_id: testingmachine
    slug: machine-2-2cf0aea2,
  kitem:
    id: 0f89d6ad-3446-4d8a-9f27-39a69bcffeee
    name: Machine-1
    ktype_id: testingmachine
    slug: machine-1-0f89d6ad]}

… and retrieve them by type:

[13]:
item5.linked_kitems.by_ktype[dsms.ktypes.Testingmachine][0].fetch()
[13]:
kitem:
  id: 2cf0aea2-b4c2-40b0-a786-bcf00ddb1991
  name: Machine-2
  ktype_id: testingmachine
  slug: machine-2-2cf0aea2
  annotations:
  - iri: https://w3id.org/steel/ProcessOntology/TestingMachine
    label: TestingMachine
    namespace: https://w3id.org/steel/ProcessOntology
  attachments: []
  linked_kitems: []
  affiliations: []
  authors:
  - user_id: 7f0e5a37-353b-4bbc-b1f1-b6ad575f562d
  avatar_exists: false
  contacts: []
  created_at: 2025-08-13 14:33:30.358137
  updated_at: 2025-08-13 14:33:30.358137
  external_links: []
  apps: []
  user_groups: []
  custom_properties:
    content:
      sections:
      - id: id1755095609461z4tdh1
        name: Misc
        entries:
        - id: id1755095609461bqgrqv
          type: Text
          label: Producer
          value: StressStrain GmBH
          measurementUnit: null
          relationMapping: null
          required: false
        - id: id17550956094616vktvr
          type: Text
          label: Room Number
          value: B500
          measurementUnit: null
          relationMapping: null
          required: false
        - id: id1755095609461dhszfo
          type: Text
          label: Description
          value: Compression Test Machine
          measurementUnit: null
          relationMapping: null
          required: false
  rdf_exists: false
  contexts: []

Clean up the DSMS from the tutortial:

[14]:
del dsms[item1]
del dsms[item2]
del dsms[item3]
del dsms[item4]
del dsms[item5]

dsms.commit()