Skip to main content

simready.validate

Standalone Python library for validating USD assets against SimReady profiles. Reports which features passed or failed, with per-requirement detail on failures.


Installation

pip install simready-validate simready-foundation-tier-core

Quick start

import simready.validate as sv

# Load the installed tier wheels (omit when running inside Kit)
sv.initialize(rules_and_requirements_paths=[], features_paths=[], profiles_paths=[])

result = sv.validate_asset(sv.AssetValidationConfig(
    asset_path="/assets/props/crate_01/crate_01.usd",
    profile_id="Robotics-Prop",  # add profile_version=... to pin; see sv.get_available_profiles()
))

if result is None:
    # Profile not registered (see sv.get_available_profiles()), or the asset is
    # missing/unopenable. The log names the cause.
    print("Could not validate — see the validation diagnostics.")
else:
    passed = all(f["passed"] for f in result.features_summary.values())
    print(f"{result.profile_id} v{result.profile_version}: {'PASSED' if passed else 'FAILED'}")
    for feat_id, data in result.features_summary.items():
        if not data["passed"]:
            print(f"  {feat_id}: failing {data.get('failing requirements')}")

sv.destroy()

Key concepts

Profiles

A profile is a named, versioned set of features (e.g. Robotics-Prop, Robot-Body). Each feature groups a set of validation requirements. Passing a profile means every requirement of every feature in that profile passed.

Profile data (rules, features, profile TOMLs) is loaded via initialize(), either from installed tier wheels or from a tier's source directories. When running inside a Kit environment, profiles are already registered and initialize() can be omitted. sv.get_available_profiles() returns what is currently registered.

Profile inference

If profile_id is omitted from AssetValidationConfig, the library first reads SimReady_Metadata.validation.profile from the asset's .simready/validation.json receipt, then falls back to the same metadata embedded in USD customLayerData. This allows previously-stamped assets to be re-validated without specifying the profile.

Stamping results into USD

Setting write_metadata=True writes the validation outcome to the wrapped .simready/validation.json receipt while preserving unknown receipt keys. For writable .usd, .usda, and .usdc assets, the same metadata is embedded in customLayerData["SimReady_Metadata"]["validation"]. USDZ archives are read-only for this operation: their bytes are preserved and only the receipt is written. Writes use atomic same-directory replacements. Stamping applies to both passing and failing results.

Runtime variant validation

Physics runtime features (PhysX, Newton, MuJoCo) declare a runtime field in their feature JSON manifest naming the USD physics variant set to enable. When validating, the library groups the profile's requirements by that tag, then validates the neutral base with all physics variants disabled and each runtime group with only its variant enabled — so runtime-specific schemas (which compose only when the variant is on) are visible to their rules. Requirements shared with the neutral base are checked once. Variant selection is applied on the stage's session layer, so the asset's authored composition is never modified. Adding a new physics engine is a data-only change (a new runtime value); no code change is required. See docs/api.md for details.


Python API

Initialization

sv.initialize(
    rules_and_requirements_paths: list[Path],
    features_paths:               list[Path],
    profiles_paths:               list[Path],
) -> None

sv.destroy() -> None

Pass three empty lists to load installed tier wheels. Otherwise only the given paths are loaded: profiles_paths entries may be directories of profile TOMLs or single .toml / .json files. initialize() raises FileNotFoundError if any given path does not exist.

from pathlib import Path

tier = Path("nv_core/tiers/simready_foundation_tier_core/simready/foundation/tier_core")
sv.initialize(
    rules_and_requirements_paths=[tier / "capabilities"],
    features_paths=[tier / "features"],
    profiles_paths=[tier / "profiles"],
)

From a project config file

# Reads [validate] section from project_config.toml and calls initialize()
sv.initialize_from_config("/workspace/project_config.toml")

project_config.toml format:

[project_root]
setting = ".."   # optional offset from config file's directory

[validate]
requirements_paths = ["nv_core/tiers/simready_foundation_tier_core/simready/foundation/tier_core/capabilities"]
features_paths     = ["nv_core/tiers/simready_foundation_tier_core/simready/foundation/tier_core/features"]
profiles_paths     = ["nv_core/tiers/simready_foundation_tier_core/simready/foundation/tier_core/profiles"]

[docs]
url = "https://nvidia.github.io/simready-foundation/latest/"

Omit [validate] entirely to load installed tier wheels instead (see Initialization). When the paths are given, they may point either at a tier's package tree, as above, or at a plain spec folder with no owning Python package.

Validate a single asset

sv.validate_asset(config: AssetValidationConfig) -> AssetValidationResult | None

Accepts .usd, .usda, .usdc, and .usdz. Returns None (with a distinct log diagnostic) if the profile is not registered, or the file is missing, unsupported, cannot be opened, or has no usable profile.

Validate multiple assets

sv.validate_asset_list(
    configs:          list[AssetValidationConfig],
    report_file_path: str | None = None,          # merged JSON report
) -> list[AssetValidationResult | None]

Configuration and result types

@dataclass
class AssetValidationConfig:
    asset_path:      str       # path to .usd / .usda / .usdc / .usdz file
    profile_id:      str | None = None   # None → receipt first, then USD metadata
    profile_version: str | None = None   # None → any registered version
    write_metadata:  bool = False         # stamp results into USD (pass or fail)

@dataclass
class AssetValidationResult:
    asset_path:       str
    profile_id:       str
    profile_version:  str
    features_summary: dict[str, dict]   # feature_id → {version, passed, failing requirements}
    issues:           list              # raw failing issues from the engine

Batch validation with JSON report

configs = [
    sv.AssetValidationConfig(asset_path=str(p), profile_id="Robotics-Prop")
    for p in Path("/assets").rglob("*.usd")
]

results = sv.validate_asset_list(configs, report_file_path="/reports/validation.json")

n_passed = sum(
    1 for r in results
    if r and all(f["passed"] for f in r.features_summary.values())
)
print(f"{n_passed}/{len(configs)} passed")

The JSON report is merged — new results for the same asset path override existing entries; other entries are preserved. The parent directory must exist before calling.


CLI

The simready-validate command is included with the package.

# Validate a single asset against the installed tiers
simready-validate --profile Robotics-Prop /assets/crate_01.usd

# Load a tier from source instead (directories)
simready-validate \
  --rules-path /tier_core/capabilities \
  --features-path /tier_core/features \
  --profiles-path /tier_core/profiles \
  --profile Robotics-Prop \
  /assets/crate_01.usd

# Validate a list of assets and save a JSON report
simready-validate \
  --profile Robotics-Prop \
  --output /reports/results.json \
  --asset_list assets.txt

# Stamp results into the USD (pass or fail)
simready-validate ... --stamp-asset-validation /assets/crate_01.usd

# Load paths from a project config file
simready-validate \
  --project-config /workspace/project_config.toml \
  --profile Robotics-Prop \
  /assets/crate_01.usd
Flag Description
ASSET_PATH Single .usd / .usda / .usdc / .usdz file to validate
--asset_list FILE Text file, one asset path per line
--profile ID Profile to validate against (omit for receipt-first inference)
--version VER Profile version (requires --profile)
--stamp-asset-validation Write the receipt and, except for USDZ, USD customLayerData
--output JSON Append results to a JSON report file
--project-config TOML Load spec paths from project_config.toml [validate] section
--rules-path DIR / --features-path DIR Rules/features directories (repeatable; must be directories)
--profiles-path DIR_OR_FILE Profiles directory or a single .toml file (repeatable)
-v / --verbose Per-issue detail on failure + DEBUG logging

Exit code: 0 = all passed, 1 = any failed or not found.


Metadata ownership

simready.validate owns only the validation sub-key of SimReady_Metadata in USD customLayerData and in the wrapped receipt. It preserves runtime_testing, asset_id, and all other unknown receipt or metadata keys.

customLayerData["SimReady_Metadata"]
├── asset_id        <- simready.create
├── validation      <- simready.validate
└── runtime_testing.tested_features   <- simready.test

License

Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0

Metadata

Release files for simready-validate 2026.8.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Built distribution (wheel)

Table of built distributions (wheels) for simready-validate 2026.8.0
File Interpreter ABI Platform
simready_validate-2026.8.0-py3-none-any.whl Python 3 none any Details

Release files / simready_validate-2026.8.0-py3-none-any.whl

Download URL simready_validate-2026.8.0-py3-none-any.whl
Size 65.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
6313d463e537246ddccbd05d8568cc0d1df71df9cd91b29b80d7d4b3026808c2
BLAKE2b-256 checksum
How to use checksums
ab87286fafac0a21aaa1efbd35761adf0b2093470cf2860f2b5bea5bb6b91db4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.7

Release history Release notifications | RSS feed

This release

2026.8.0 This release

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page