Assets in Nominal with Python

To use this guide, install the Nominal Python library with pip3 install nominal.

See Quickstart for more details.

Please contact us if you’re not sure whether your organization has access to Nominal.

Assets organize test data around physical systems, rather than around individual test events. For example, an Asset might be an airplane or a satellite. Each Asset can connect to runs, workbooks, and checklists.

Connect to Nominal

To add an Asset, first connect to your Nominal platform tenant.

When using the Nominal client library, there are two primary ways of authenticating:

First, run the following in your terminal and follow on-screen prompts to insert the base_url and API key:

$$ python -m nominal auth set-token
>
># Alternatively, use the globally installed CLI
>$ nom auth set-token

This will store your API key in a config file ~/.nominal.yml. The API key will automatically be used when using the client again.

1import nominal
2
3# Simply grab the "default" client using your stored credentials
4client = nominal.get_default_client()
5
6# Get details about the currently logged-in user to validate authentication
7# Will display an object like: `User(display_name='your_email@your_company.com', ...)`
8print(client.get_user())
1import nominal
2
3# Set login details for the user
4nominal.set_token("<insert api key>")
5
6# Get an instance of the client using provided credentials
7client = nominal.get_default_client()
8
9# Get details about the currently logged-in user to validate authentication
10# Will display an object like: `User(display_name='your_email@your_company.com', ...)`
11print(client.get_user())

NOTE: you should never share your Nominal API key with anyone. We therefore recommend that you not save it in your code and/or scripts.

  • If you trust the computer you are on, use nom to store the credential to disk.
  • Otherwise, use a password manager such as 1password or bitwarden to keep your token safe.
If you’re not sure whether your company has a Nominal tenant, please reach out to us.

Create an Asset

To create an Asset, use create_asset(). You can, optionally, add a description, properties, and labels:

1import nominal as nm
2
3uav_drone_asset = nm.create_asset(
4 name = 'Quadcopter-456',
5 description = 'Airborne observation platform',
6 properties = {'rotors': '4'},
7 labels = ('camera', 'airborne')
8)
9
10print("Created asset:", uav_drone_asset.rid)

Add data to an asset

To add a Dataset to an Asset, use Asset.add_dataset():

1import polars as pl
2import nominal as nm
3
4df = pl.read_csv('hf://datasets/nominal-io/frosty-flight/frosty_flight_1k_rows.csv')
5df.write_csv('frosty_flight_1k_rows.csv')
6
7csv_dataset = nm.upload_csv(
8 'frosty_flight_1k_rows.csv',
9 name = 'Frosty Flight',
10 timestamp_column = 'source_time',
11 timestamp_type = 'iso_8601',
12)
13
14uav_drone_asset.add_dataset(
15 dataset = csv_dataset,
16 data_scope_name = 'high-precipitation-flight'
17)

Datasets are the file representation of Nominal’s Data Source primitive. Most often, Datasets are tabular files with at least one time dimension. Datasets can also be video files.

Head over to the Datasets page to see your organization’s most recently uploaded Datasets.

Asset data with data scope names

To add a Dataset with a data scope name to an Asset, set the data_scope_name parameter in Asset.add_dataset().

1uav_drone_asset.add_dataset(
2 dataset = csv_dataset,
3 data_scope_name = 'high-precipitation-flight'
4)

Data scope names are a namespace for data sources that share common channels, but do not necessarily belong to the same Asset. They allow data sources with similar schema to be referenced as a group. For example, data sources with the same data scope name can share Workbook templates and Checklists.

Check if an Asset exists

You can check for a Asset’s existence with nm.search_assets().

1import nominal as nm
2
3found_assets = nm.search_assets(search_text = '000-123')
4
5if len(found_assets) == 0:
6 uav_drone_asset = nm.create_asset(
7 name = 'Quadcopter-000-123',
8)

Update an Asset

Asset metadata can be updated with Asset.update():

For example, to set an Asset’s title:

1uav_drone_asset.update(title = 'Quadcopter-001-456')

Please see Asset.update() for all updatable metadata.

Asset attachments

File attachments such as PDF reports or PowerPoints can be added to Assets:

1filepath = '/path/to/my_report.pdf'
2attachment = nm.upload_attachment(file = filepath, name = 'KittyHawk.pdf')
3nominal_asset.add_attachments(attachments = [attachment])

Retrieve an Asset

Like Datasets, Assets can be retrieved by their resource ID (“RID”):

1asset = nm.get_asset('ri.scout.cerulean-staging.asset.22697726-5454-4fad-a3ea-fe45e9fa9f09')
2asset.update(labels = ['NEW-MOTOR-VENDOR'])

To retrieve an Asset’s RID, visit its detail page and click on the clipboard icon next to “ID” in the right-hand drawer:

run-metadata

All Nominal primitives (eg Datasets, Runs, Workbooks, and Checks) have a unique identifier called a “Resource ID”. Resource IDs may be referred to as “RID” or simply “ID” throughout the platform. They can be obtained from a primitive’s detail page (or URL) and have a format that looks like ri.catalog.cerulean-staging.dataset.e5ede17b-05f9-404d-aaf5-ba85c99761a2.

Query Assets

Assets can be queried with nm.search_assets().

For example, to retrieve all assets with the label “NEW-MOTOR-VENDOR”:

1quadcopter_assets = nm.search_assets(label = 'NEW-MOTOR-VENDOR')

See nm.search_assets() for all Assets search parameters.

Remove Asset Data Sources

The list data_sources can contain Connection, Dataset, Video instances, or rids as string.

1import nominal as nm
2
3asset = nm.get_asset('ri.scout.cerulean-staging.asset.6c41d7fd-a48f-4d60-baa7-f34492264156')
4
5asset.remove_data_sources(data_sources = ['ri.catalog.cerulean-staging.dataset.d4f413c4-4787-4259-a142-1286587b50af'])

Archive an Asset

Once an Asset is no longer needed, it can be archived. This does not delete the Asset, but makes it invisible on the web. If you save the rid of the Asset, you can retrieve and unarchive it at a later date.

1uav_drone_asset.archive()