NCP-OUSD study materials
NCP-OUSD study resources

Auto-apply API schema that never applies

NCP-OUSD · Put your knowledge to work in context.

All case studies

Auto-apply API schema that never applies

A pipeline team defines StudioAssetAPI as a multiple-apply API schema with studio:assetId (string) and studio:department (token). They set autoApply = true in schema.usda, run usdGenSchema, and install generatedSchema.usda plus plugInfo.json under plugins/studioAssetAPI/resources/, with PXR_PLUGINPATH_NAME pointing there. Their importer creates UsdGeomMesh prims and expects prim.HasAPI("StudioAssetAPI") to be true. It is false, and prim.GetAttribute("studio:assetId") is invalid. If they call StudioAssetAPI.Apply(prim, "asset") manually, it works. A second team wants a codeless schema for a Python-only pipeline and asks whether they can skip C++ generation entirely. The team also needs to know how to verify that the schema is actually registered and discoverable in a fresh process.

1. Explain why auto-apply did not apply the schema and what the team must change. Include the role of multiple-apply instance names, `apiSchemas` metadata, and `CanApply`/`Apply`.

Read the worked answer

The decisive issue is that StudioAssetAPI is a multiple-apply schema. Auto-apply is defined for single-apply API schemas: the schema registry can add a single schema type name to a prim's apiSchemas metadata automatically when a prim of the gated type is created. A multiple-apply schema needs an instance name, which the registry cannot invent, so it is not auto-applied. Setting autoApply = true on a multiple-apply schema does not produce the intended behavior.

Applying an API schema is not the same as creating the prim. Apply(prim, "asset") authors an entry such as apiSchemas = ["StudioAssetAPI:asset"] on the prim in the current edit target. HasAPI("StudioAssetAPI") then becomes true, and the schema's properties are available through the schema definition. CanApply is the pre-check; it verifies that the prim's type is allowed by the schema's gating metadata and, for multiple-apply, that the instance name is valid and not already applied.

The team has two consistent options:

  1. If only one StudioAssetAPI instance is ever needed per prim, convert it to a single-apply API schema and keep auto-apply.
  2. If multiple instances per prim are required, keep it multiple-apply and apply it explicitly in the importer, for example StudioAssetAPI.Apply(prim, "asset") during import, or author apiSchemas = ["StudioAssetAPI:asset"] in the layer that creates the prim. The importer must run before downstream code expects HasAPI to be true.

Auto-apply also does not retroactively apply to prims that already exist in a saved layer; it affects prim creation. The importer should apply the schema at creation time or in a post-import pass.

2. How should the team verify schema registration and plugin discovery in a clean process? Name the concrete checks and what each failure would indicate.

Read the worked answer

A clean-process verification should separate plugin discovery from schema registration.

  • Set PXR_PLUGINPATH_NAME to the directory that contains plugInfo.json, not to the parent of resources/ unless that is how the plugin is packaged. In a fresh Python process, inspect Plug.Registry().GetPluginWithName(...) for the plugin. If the plugin is absent, the path or plugInfo.json metadata is wrong, or the process environment did not inherit the variable.
  • Query Usd.SchemaRegistry.GetAutoApplyAPISchemas() and check whether StudioAssetAPI appears. It should not appear for a multiple-apply schema, which confirms the diagnosis rather than a registration failure.
  • Create a test prim of the gated type, call prim.CanApply("StudioAssetAPI", "asset"), then Apply and print prim.GetAppliedSchemas(). The applied-schemas list is the authoritative check that the apiSchemas metadata was authored.
  • Inspect the generated schema asset and confirm the type name, apiSchemaType, and gating metadata match what the code queries. A common mistake is a mismatch between the registered type name and the string passed to HasAPI/Apply.

If Apply works manually but auto-apply does not, registration is probably fine and the problem is the auto-apply contract. If Apply fails or warns that the schema is unknown, focus on plugInfo.json and PXR_PLUGINPATH_NAME. Checking both paths separately prevents "fixing" registration when the real issue is schema kind.

3. The second team can use either a compiled schema or a codeless schema. What should they choose, and what are the limits of a codeless schema in a Python-only pipeline?

Read the worked answer

A codeless schema is a reasonable choice when the pipeline only needs the schema's identity, metadata, and property definitions to be registered so that HasAPI, Apply, apiSchemas validation, and generic property access by name work. Codeless schemas still ship a generatedSchema.usda and a plugInfo.json; they simply omit compiled C++ classes. They do not provide generated C++ accessors or a compiled class that C++ code can cast to.

For a Python-only pipeline, the important limit is that a codeless schema does not give you a generated Python class with typed properties. Python code still works through the generic Usd API: prim.HasAPI("StudioAssetAPI"), prim.ApplyAPI(...), and prim.GetAttribute("studio:assetId"). If the team wants a Python class with properties or methods, they should generate and bind the schema, or provide a thin Python wrapper around the generic API rather than assuming codeless generation creates one.

A codeless schema is also not a workaround for the auto-apply issue. If the schema remains multiple-apply, it still requires explicit instance names. If it is single-apply and auto-apply is desired, the codeless registration must include the same auto-apply metadata as a compiled schema. The decision should be based on whether the pipeline needs compiled accessors and ABI stability, not on whether the language is Python.