Assets#

An asset represents a system you test, such as a vehicle, satellite or test stand. It collects that system’s datasets, runs, events and attachments across every test.

Connect the client#

This guide assumes you have installed the client and setup your API keys.

from nominal.core import NominalClient

client = NominalClient.from_profile("default")

Create or find an asset#

Properties identify the physical system, such as a serial number. get_or_create_asset_by_properties() returns the asset with those properties, creating it if none exists, so a script can run more than once:

asset = client.get_or_create_asset_by_properties(
    {"serial": "QC-456"},
    name="Quadcopter 456",
    description="Airborne observation platform",
    labels=["camera", "airborne"],
)

It raises ValueError if more than one asset has those properties. To always create a new asset, use create_asset().

Add data with data scopes#

An asset holds each dataset under a data scope name, such as "telemetry". Use the same data scope name for the same kind of data on every asset, so workbook templates and checklists work across them.

get_or_create_dataset() returns the dataset under a data scope name, creating it if needed.

The examples upload flight.csv. To run them as written, save this sample under that name:

time,altitude,temperature,tail_number
2026-09-10T14:38:19Z,100.0,20.0,N456QC
2026-09-10T14:38:20Z,101.5,20.2,N456QC
2026-09-10T14:38:21Z,103.0,20.4,N456QC
dataset = asset.get_or_create_dataset("telemetry", name="Quadcopter 456 telemetry")
dataset.add_tabular_data("flight.csv", timestamp_column="time", timestamp_type="iso_8601")

Running the upload again adds another file to the same dataset. See Datasets for file formats and waiting for ingestion.

To attach a dataset that already exists, use add_dataset():

asset.add_dataset("ground-station", client.get_dataset("<DATASET_RID>"))

remove_data_scopes() detaches data by data scope name or by dataset. It doesn’t delete the dataset.

asset.remove_data_scopes(names=["ground-station"])

Find assets#

search_assets() combines its filters with AND:

assets = client.search_assets(labels=["airborne"], properties={"serial": "QC-456"})

search_text is a fuzzy match, so results may not contain the text verbatim. Use exact_substring when they must.

To retrieve one asset, use its RID from the asset’s page in Nominal:

asset = client.get_asset("<ASSET_RID>")

Update metadata and attachments#

update() replaces each field you pass and leaves the others unchanged. To add a label, merge it with the existing ones:

asset.update(labels=[*asset.labels, "new-motor-vendor"])

Attach files that describe the system across tests, such as a specification:

asset.add_attachments([client.create_attachment("spec.pdf")])

Attach files about a single test to its run instead.

Archive an asset#

archive() hides the asset from views and searches without deleting its data. unarchive() restores it.

asset.archive()