Asset Info#

What Is Asset Info?#

Asset info is a metadata dictionary that records where a piece of scene description came from. When a prim is published from an asset management system, assetInfo is where you stamp the identity of that asset: what it is called, which revision it is, and how to find it again.

The most important thing to understand about assetInfo is that it is descriptive, not functional. Authoring it does not make referencing work and does not cause OpenUSD to load anything. It is a standardized place to record provenance so that every pipeline does not have to invent its own convention for the same information.

This matters once assets start moving between teams and organizations. A composed stage tells you what the data is, but not which published revision of which asset it came from. Asset info carries that answer along with the data.

How Does It Work?#

assetInfo is defined on UsdObject, which means it can be authored on prims and on properties. It behaves like any other dictionary-valued metadata: you can put arbitrary keys in it, and it is composed along with the prim it lives on.

The Conventional Fields#

Any key is legal, but four have an agreed-upon meaning and direct API access through UsdModelAPI:

Field

Type

Purpose

identifier

asset

The asset path this content came from

name

string

The asset’s name in your asset database

version

string

The revision the data was published at

payloadAssetDependencies

asset[]

Pre-computed dependencies, so tools can inspect them without loading the payload

Because identifier is a genuine asset-typed value, it participates in asset resolution the same way a reference path does: relative paths are anchored to the layer that authored them.

payloadAssetDependencies is worth calling out because it exists to solve a specific performance problem. Walking an asset’s dependencies normally means loading its payloads. Publishing the dependency list up onto the interface prim lets tooling answer “what does this asset need?” without paying that cost, which is the same lofting idea covered in Reference/Payload Pattern.

How Asset Info Composes#

Dictionary metadata composes per key, not as a single value. If a downstream layer authors assetInfo with only a version key, it overrides version and leaves the other keys from the referenced asset intact.

This is what makes the field usable in practice. A shot layer can stamp a version bump without having to restate an asset’s identity, and without accidentally erasing the fields it did not set.

Note

That per-key composition is convenient, but it is not free. As noted in Custom Properties, composable dictionary metadata costs more to compose than a plain attribute. Use assetInfo for the asset identity it was designed for, and reach for custom properties when you need general-purpose user data.

Working With Python#

There are two ways to reach the same data. UsdModelAPI gives you typed accessors for the four conventional fields:

1from pxr import Usd, Sdf
2
3model = Usd.ModelAPI(prim)
4model.SetAssetIdentifier(Sdf.AssetPath("asset://chairs/chair_a.usd"))
5model.SetAssetName("chair_a")
6model.SetAssetVersion("v003")

UsdObject gives you raw dictionary access, which is how you author your own keys:

1prim.SetAssetInfoByKey("department", "set_dress")
2prim.GetAssetInfo()          # the whole dictionary
3prim.HasAuthoredAssetInfo()  # was any of it authored here?
4prim.ClearAssetInfoByKey("department")

Note that SetAssetInfoByKey sets a single key without disturbing the others, while SetAssetInfo replaces the entire dictionary.

Examples#

Tip

You can run these examples locally as Jupyter notebooks. See How to Run Notebooks Locally for setup instructions.

Note

Examples on this page use create_new_stage(), a notebook helper imported in a hidden setup cell. In your own scripts, use Usd.Stage.CreateNew() in its place. If you’re running the lessons from a clone of this repository, you can import the helper instead: from lousd.utils.helperfunctions import create_new_stage. See How to Run Notebooks Locally for why.

Example 1: Stamping Asset Info on a Published Asset#

Here we build a small component asset and record its identity on the entry point prim. In a real pipeline these values would come from your asset management system at publish time rather than being typed in by hand.

 1from pxr import Usd, UsdGeom, Sdf
 2
 3file_path = "_assets/chair_a.usda"
 4stage: Usd.Stage = create_new_stage(file_path)
 5
 6# Build the asset's entry point prim and make it the default prim
 7chair: UsdGeom.Xform = UsdGeom.Xform.Define(stage, "/chair_a")
 8stage.SetDefaultPrim(chair.GetPrim())
 9UsdGeom.Cube.Define(stage, chair.GetPath().AppendPath("Geometry"))
10
11# Use UsdModelAPI for the four conventional fields
12model = Usd.ModelAPI(chair.GetPrim())
13model.SetAssetIdentifier(Sdf.AssetPath("asset://chairs/chair_a.usd"))
14model.SetAssetName("chair_a")
15model.SetAssetVersion("v003")
16
17# Any additional key you need can go in the same dictionary
18chair.GetPrim().SetAssetInfoByKey("department", "set_dress")
19
20stage.Save()
21print(chair.GetPrim().GetAssetInfo())
{'department': 'set_dress', 'identifier': Sdf.AssetPath(authoredPath='asset://chairs/chair_a.usd'), 'name': 'chair_a', 'version': 'v003'}
        
    

Notice how assetInfo is serialized as a dictionary on the prim, with identifier written using OpenUSD’s @...@ asset path syntax.

Example 2: Asset Info Travels Through a Reference#

Now we reference that asset into a scene. The asset info composes through the reference, so the consuming stage can see exactly which asset and revision it picked up.

 1from pxr import Usd
 2
 3scene_path = "_assets/asset_info_scene.usda"
 4scene: Usd.Stage = create_new_stage(scene_path)
 5
 6world = scene.DefinePrim("/World", "Xform")
 7scene.SetDefaultPrim(world)
 8
 9chair_1 = scene.DefinePrim("/World/Chair_1", "Xform")
10chair_1.GetReferences().AddReference("./chair_a.usda")
11
12# The asset info came along with the reference, even though
13# nothing was authored for it in this layer
14print("Composed asset info:", chair_1.GetAssetInfo())
15print("Authored in this layer?", chair_1.HasAuthoredAssetInfo())
16
17scene.Save()
Composed asset info: {'department': 'set_dress', 'identifier': Sdf.AssetPath(authoredPath='asset://chairs/chair_a.usd'), 'name': 'chair_a', 'version': 'v003'}
Authored in this layer? True

HasAuthoredAssetInfo reports True here because the referenced layer authored it. Use it to check whether asset info exists at all, not to test whether this particular layer is the one that set it.

Example 3: Overriding a Single Field#

Finally, we bump the version on the referencing prim. Because dictionary metadata composes per key, the fields we do not touch survive.

 1from pxr import Usd
 2
 3scene_path = "_assets/asset_info_scene.usda"
 4scene: Usd.Stage = Usd.Stage.Open(scene_path)
 5chair_1 = scene.GetPrimAtPath("/World/Chair_1")
 6
 7print("Before:", chair_1.GetAssetInfo())
 8
 9# Override only the version key
10chair_1.SetAssetInfoByKey("version", "v004")
11
12composed = chair_1.GetAssetInfo()
13print("After: ", composed)
14print()
15print("version was overridden:", composed["version"])
16print("name survived from the referenced asset:", composed["name"])
17print("department survived too:", composed["department"])
18
19scene.Save()
Before: {'department': 'set_dress', 'identifier': Sdf.AssetPath(authoredPath='asset://chairs/chair_a.usd'), 'name': 'chair_a', 'version': 'v003'}
After:  {'department': 'set_dress', 'identifier': Sdf.AssetPath(authoredPath='asset://chairs/chair_a.usd'), 'name': 'chair_a', 'version': 'v004'}

version was overridden: v004
name survived from the referenced asset: chair_a
department survived too: set_dress
        
    

Only version appears in this layer’s scene description, but the composed value still carries all four keys. If we had used SetAssetInfo with a dictionary containing just version, we would have replaced the whole dictionary in this layer instead and lost the ability to see the rest of the identity downstream.

Key Takeaways#

Asset info is OpenUSD’s standard place to record asset provenance: which asset a prim came from, what it is called, and which revision was published. It is a dictionary on UsdObject, so it works on prims and properties alike, and it composes per key so downstream layers can update one field without restating the others.

It is worth being clear about what asset info does not do. It records a version, but it does not manage one; nothing validates that the stamped value matches what actually composed, so it is only as trustworthy as the process that wrote it. Outside of payloadAssetDependencies, which exists as a hint for dependency-analysis tooling, OpenUSD itself does not act on these fields. They are a convention that your pipeline is responsible for writing and honoring.