Delete Twins
When Digital Twins are no longer needed they can be deleted through the IOTICSpace user interface or the IOTICS API.
This page covers:
- Introduction to Delete Digital Twins
- Delete Digital Twins
- Delete a Digital Twin with the IOTICSpace user interface
- Delete a Digital Twin with the IOTICS API
- Delete Digital Twin Models
- Delete a Digital Twin Model with the IOTICSpace user interface
- Delete a Digital Twin Model with the IOTICS API
Introduction to Delete Digital Twins
You may wish to delete one or more Twins if you no longer need them and no other Twins are following their data feeds. You can delete Twins and Twin Models in the same way you have created them, either through the IOTICS user interface or the IOTICS API.
A Twin can be only updated and/or deleted with the credentials initially used to create the Twin
The IOTICS user interface and the IOTICS API use different credentials to create Twins. This means that, if you have created your Digital Twin through the user interface, you won't be able to delete it via the API, and vice-versa.
Delete Digital Twins
Delete a Twin with the IOTICS user interface
Navigate to the Twins section on your IOTICSpace user interface. Once you have found the Digital Twin to delete, click on the delete icon in the ACTIONS section.
Delete a Twin with the IOTICS API
Click here to see the prerequisites.
from requests import request
response = request(
method="DELETE",
url=f"{HOST}/qapi/hosts/{host_id}/twins/{twin_did}",
headers=headers,
)
response.raise_for_status()
Delete Digital Twin Models
Delete a Twin Model with the IOTICS user interface
Navigate to the Twin Models section on your IOTICSpace user interface. Once you have found the Model to delete, click on the delete icon in the ACTIONS section. Deleting a Model will automatically delete all the associated Twins.
Delete a Twin Model with the IOTICS API
When deleting a Twin Model, make sure you also delete all the Twins belonging to that Model. In fact, a Twin without its Model:
- by concept is meaningless: every Twin must belong to a specific existing Twin template (e.g. Twin Model);
- the Twin's property Twin from Model would point to a non-existing Twin DID.
Click to see the entire code on how to Delete a Twin Model along with all its Twins from Model
import json
from datetime import datetime, timedelta, timezone
from typing import List
from iotics.lib.identity.api.high_level_api import get_rest_high_level_identity_api
from requests import request
RESOLVER_URL = "resolver_url"
HOST = "host_url"
USER_KEY_NAME = "user_key_name"
AGENT_KEY_NAME = "agent_key_name"
USER_SEED = bytes.fromhex("user_seed")
AGENT_SEED = bytes.fromhex("agent_seed")
class IoticsRest:
def __init__(self):
self._high_level_api = get_rest_high_level_identity_api(
resolver_url=RESOLVER_URL
)
(
self._user_registered_id,
self._agent_registered_id,
) = self._high_level_api.create_user_and_agent_with_auth_delegation(
user_seed=USER_SEED,
user_key_name=USER_KEY_NAME,
agent_seed=AGENT_SEED,
agent_key_name=AGENT_KEY_NAME,
delegation_name="#AuthDeleg",
)
token = self._high_level_api.create_agent_auth_token(
agent_registered_identity=self._agent_registered_id,
user_did=self._user_registered_id.did,
duration=600,
)
self._headers = {
"accept": "application/json",
"Iotics-ClientAppId": "example_code",
"Authorization": f"Bearer {token}",
"Content-Type": "application/json",
}
def _make_api_call(self, method: str, url: str, json: dict = None):
response = request(method=method, url=url, headers=self._headers, json=json)
response.raise_for_status()
return response.json()
def get_host_id(self):
host_id = self._make_api_call(method="GET", url=f"{HOST}/qapi/host/id")
return host_id["hostId"]
def search_twins(
self,
text: str = None,
location: dict = None,
properties: List[dict] = None,
scope: str = "LOCAL",
response_type: str = "FULL",
):
twins_list = []
search_headers = self._headers.copy()
# Search headers require a new header "Iotics-RequestTimeout".
# The latter is used to stop the request once the timeout is reached
search_headers.update(
{
"Iotics-RequestTimeout": (
datetime.now(tz=timezone.utc) + timedelta(seconds=5)
).isoformat(),
}
)
payload = {"responseType": response_type, "filter": {}}
if text:
payload["filter"]["text"] = text
if properties:
payload["filter"]["properties"] = properties
if location:
payload["filter"]["location"] = location
with request(
method="POST",
url=f"{HOST}/qapi/searches",
headers=search_headers,
stream=True,
verify=True,
params={"scope": scope},
json=payload,
) as resp:
resp.raise_for_status()
# Iterates over the response data, one Host at a time
for chunk in resp.iter_lines():
response = json.loads(chunk)
twins_found = []
try:
twins_found = response["result"]["payload"]["twins"]
except KeyError:
continue
finally:
if twins_found:
# Append the twins found to the list of twins
twins_list.extend(twins_found)
print(f"Found {len(twins_list)} twin(s)")
return twins_list
def delete_twin(self, twin_did: str, host_id: str):
self._make_api_call(
method="DELETE", url=f"{HOST}/qapi/hosts/{host_id}/twins/{twin_did}"
)
def main():
iotics_rest = IoticsRest()
host_id = iotics_rest.get_host_id()
twin_model_list = iotics_rest.search_twins(
properties=[
{
"key": "http://www.w3.org/1999/02/22-rdf-syntax-ns#type",
"uriValue": {"value": "https://data.iotics.com/app#Model"},
}
]
)
twin_model_did = ""
for twin_model in twin_model_list:
print(twin_model)
twin_model_did = twin_model["twinId"]["id"]
answer = input(
f"\nDo you want to delete this Twin Model with all its Twins from Model (y/n) ? "
)
if answer == "y":
break
if twin_model_did:
try:
iotics_rest.delete_twin(twin_did=twin_model_did, host_id=host_id)
except Exception:
print(f"Can't delete Twin {twin_model_did}")
else:
print(f"Twin Model {twin_model_did} deleted")
print("Searching for Twins from Model...")
twin_from_model_list = iotics_rest.search_twins(
properties=[
{
"key": "https://data.iotics.com/app#model",
"uriValue": {"value": twin_model_did},
}
]
)
for twin in twin_from_model_list:
twin_did = twin["twinId"]["id"]
try:
iotics_rest.delete_twin(twin_did=twin_did, host_id=host_id)
except Exception:
print(f"Can't delete Twin {twin_did}")
else:
print(f"Twin {twin_did} deleted")
if __name__ == "__main__":
main()
Updated 9 months ago