MCAP Video ingest in Python

This guide will walk you through the process of downloading a sample MCAP file, inspecting it to find video topics, and ingesting the video into Nominal.

Prerequisites

Make sure you have the following Python packages installed:

  • huggingface_hub
  • mcap
  • nominal

You can install them all using:

1pip3 install huggingface_hub mcap nominal

Step 1: Download the Sample MCAP File

First, download a sample MCAP file using the huggingface_hub library.

1from huggingface_hub import hf_hub_download
2
3video_path = hf_hub_download(
4 repo_id="nominal-io/xplane",
5 filename="xplane.mcap",
6 repo_type='dataset'
7)
8
9print(f"File saved to: {video_path}")

Step 2: Inspect the MCAP File to Find Video Topics

Next, use the mcap library to inspect the MCAP file and identify available video topics.

1from mcap.reader import make_reader
2
3with open(video_path, "rb") as f:
4 reader = make_reader(f)
5
6 schemas = reader.get_summary().schemas
7 channels = reader.get_summary().channels
8
9 def schema_name(channel):
10 schema = schemas.get(channel.schema_id)
11 if not schema:
12 return None
13 return schema.name
14
15 video_topics = [
16 channel.topic for channel in channels.values()
17 if schema_name(channel) == "foxglove.CompressedVideo"
18 ]
19
20 print("Video topics: ", video_topics)

This script will output the video topics available in the MCAP file, which you’ll use in the next step.

Step 3: Connect to Nominal

Before ingesting the video, ensure you’re connected to Nominal.

Concepts
  • Base URL: The URL through which the Nominal API is accessed (typically https://api.gov.nominal.io/api; shown under Settings → API keys).
  • Workspace: A mechanism by which to isolate datasets; each user has one or more workspace, and data in one cannot be seen from another. Note that a token / API key is attached to a user, and may access multiple workspaces.
  • Profile: A combination of base URL, API key, and workspace.

There are two primary ways of authenticating the Nominal Client. The first is to use a profile stored on disk, and the second is to use a token directly.

Run the following in a terminal and follow on-screen prompts to set up a connection profile:

$$ nom config profile add default
>
># Alternatively, if `nom` is missing from the path:
>$ python -m nominal config profile add default

Here, “default” can be any name chosen to represent this profile (reminder: a profile represents a base URL, API key, and workspace).

The profile will be stored in ~/.config/nominal/config.yml, and can then be used to create a client:

1from nominal.core import NominalClient
2
3client = NominalClient.from_profile("default")
4
5# Get details about the currently logged-in user to validate authentication
6# Will display an object like: `User(display_name='your_email@your_company.com', ...)`
7print(client.get_user())

If you have previously used nom to store credentials, prior to the availability of profiles, you will need to migrate your old configuration file (~/.nominal.yml) to the new format (~/.config/nominal/config.yml).

You can do this with the following command:

$nom config migrate
>
># Or, if `nom` is missing from your path:
>python -m nominal config migrate
1from nominal.core import NominalClient
2
3# Get an instance of the client using provided credentials
4client = NominalClient.from_token("<insert api key>")
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())

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.

Step 4: Ingest the Video

Finally, upload the video to Nominal using a topic from the list.

1from nominal.core import NominalClient
2
3client = NominalClient.from_profile("default")
4
5video = client.create_empty_video(name="X-Plane Simulation")
6video = video.add_mcap_to_video(
7 video_path, "video"
8)
9print(video)