From 6785f5430be93ad3837a198273a0b1f3f40a7b94 Mon Sep 17 00:00:00 2001 From: Sheikh Dawood <7774242+sheikh-nv@users.noreply.github.com> Date: Thu, 3 Sep 2026 21:44:14 +0000 Subject: [PATCH 1/5] Align Isaac Lab with Asset Region Profiles --- .../installation/asset_caching_details.inc | 51 ------------ docs/source/setup/installation/index.rst | 71 ++++++++++++++++ skills/user/install-isaac-lab/SKILL.md | 10 +-- skills/user/install-isaac-lab/evaluations.md | 6 +- skills/user/install-isaac-lab/examples.md | 4 +- skills/user/install-isaac-lab/reference.md | 12 +-- .../changelog.d/asset-region-profiles.rst | 6 ++ source/isaaclab/isaaclab/utils/assets.py | 80 ++++++++++++------- source/isaaclab/test/utils/test_assets.py | 57 ++++++++++--- 9 files changed, 186 insertions(+), 111 deletions(-) create mode 100644 source/isaaclab/changelog.d/asset-region-profiles.rst diff --git a/docs/source/setup/installation/asset_caching_details.inc b/docs/source/setup/installation/asset_caching_details.inc index b698b9cfb9ab..ed7895e6025f 100644 --- a/docs/source/setup/installation/asset_caching_details.inc +++ b/docs/source/setup/installation/asset_caching_details.inc @@ -81,57 +81,6 @@ resolves them once, when :mod:`isaaclab.utils.assets` is imported, so setting even though Isaac Sim itself honors those forms. Editing ``persistent.isaac.asset_root.default`` in the experience file does work, because that is the value Isaac Lab reads when the variable is unset. -.. rubric:: Using the China Storage Profile - -To use the public China asset mirror, clear any explicit asset-root override, then select the same named storage -profile used by Isaac Sim before launch: - -.. tab-set:: - :sync-group: os - - .. tab-item:: :icon:`fa-brands fa-linux` Linux - :sync: linux - - .. code:: bash - - unset ISAACSIM_ASSET_ROOT - export ISAACSIM_STORAGE_PROFILE=china - - .. tab-item:: :icon:`fa-brands fa-windows` Windows - :sync: windows - - .. code:: batch - - set ISAACSIM_ASSET_ROOT= - set ISAACSIM_STORAGE_PROFILE=china - -Isaac Lab uses the same versioned public bucket paths shown by Isaac Sim and routes reads through the profile's CDN. -This also works in kitless mode without Isaac Sim installed. ``ISAACSIM_ASSET_ROOT`` still takes precedence when -both variables are set. - -Isaac Lab launchers and asset helpers apply the profile automatically. A standalone kitless script that calls -``omni.client`` before launching an Isaac Lab runtime must initialize the profile first: - -.. code:: python - - from isaaclab.utils.assets import configure_storage_profile - - configure_storage_profile() - -.. note:: - The China service mirrors a subset of the global asset set, and that subset can change between releases. - Check the `Isaac 6.1 asset availability manifest - `__ before choosing an asset. The manifest lists - service path records relative to the versioned ``Isaac`` folder. A path with no row is not mirrored, and a listed - path must have an ``available`` status to load from the service. Use an available asset or a local asset pack when - needed. - - Build paths from profile-resolved constants such as :attr:`~isaaclab.utils.assets.ISAAC_NUCLEUS_DIR` or - :attr:`~isaaclab.utils.assets.ISAACLAB_NUCLEUS_DIR` instead of hard-coding bucket or CDN URLs. This keeps the - selected storage profile and asset release applicable when routing changes. Access the resolved paths through - Isaac Lab or ``omni.client``; opening the object-storage URL directly in a browser or with ``curl`` can return - HTTP 403 because it bypasses the profile's CDN routing. - .. note:: If you previously redirected Isaac Lab assets by editing ``persistent.isaac.asset_root.cloud`` in an experience file, that edit no longer has any effect. Isaac Lab now reads diff --git a/docs/source/setup/installation/index.rst b/docs/source/setup/installation/index.rst index b5ffeb380677..3e17e6b0e050 100644 --- a/docs/source/setup/installation/index.rst +++ b/docs/source/setup/installation/index.rst @@ -1084,6 +1084,77 @@ still downloads each asset; later runs use the local cache. Omniverse Nucleus and Omniverse Launcher are deprecated starting with Isaac Sim 4.5. Existing local Nucleus installations continue to work. +.. _installation-asset-region-profiles: + +Asset Region Profiles +--------------------- + +An Asset Region Profile selects a compatible asset root and configures any storage settings required +for that service. Isaac Lab provides these profiles: + +.. list-table:: + :header-rows: 1 + :widths: 20 80 + + * - Profile + - Use + * - ``us`` + - Primary public asset service and explicit switchback profile. + * - ``china`` + - Regional asset service for users in mainland China. + +Set the profile before launching Isaac Lab. Clear ``ISAACSIM_ASSET_ROOT`` first because an explicit +asset-root override takes precedence over the selected profile. + +.. tab-set:: + :sync-group: os + + .. tab-item:: :icon:`fa-brands fa-linux` Linux + :sync: linux + + .. code-block:: bash + + unset ISAACSIM_ASSET_ROOT + export ISAACSIM_ASSET_REGION_PROFILE=china + + .. tab-item:: :icon:`fa-brands fa-windows` Windows + :sync: windows + + .. code-block:: batch + + set ISAACSIM_ASSET_ROOT= + set ISAACSIM_ASSET_REGION_PROFILE=china + +Isaac Lab launchers and asset helpers apply the profile automatically. The same variable also selects +the profile when Isaac Lab launches Isaac Sim. In kitless mode, Isaac Lab configures the required +``omni.client`` routing without requiring Isaac Sim. + +A standalone kitless script that calls ``omni.client`` before launching an Isaac Lab runtime must +initialize the profile first: + +.. code-block:: python + + from isaaclab.utils.assets import configure_asset_region_profile + + configure_asset_region_profile() + +To return to the primary service, clear ``ISAACSIM_ASSET_ROOT`` and select the ``us`` profile for the +next process. You can leave the profile unset for later processes. + +The ``china`` profile publishes an +`asset availability manifest `__. +The ``isaac_version`` field identifies the asset release. Each ``asset_path`` is the full path to a +file relative to the versioned asset root's ``Isaac`` directory. A ``status`` value of ``available`` +reports that the file is mirrored, ``reason_code`` explains other statuses when provided, and +``checked_at`` records when the status last changed. A path with no row is not mirrored. The manifest +does not confirm the availability of paths outside the root's ``Isaac`` directory. + +Build paths from profile-resolved constants such as +:attr:`~isaaclab.utils.assets.ISAAC_NUCLEUS_DIR` and +:attr:`~isaaclab.utils.assets.ISAACLAB_NUCLEUS_DIR`. Do not hardcode the profile's storage endpoint or +derive direct object URLs from the manifest. Opening an object-storage URL directly in a browser or +with ``curl`` can return HTTP 403 because it bypasses the profile's CDN routing. + Troubleshooting --------------- diff --git a/skills/user/install-isaac-lab/SKILL.md b/skills/user/install-isaac-lab/SKILL.md index ec1f71d93281..74d305a3b2f9 100644 --- a/skills/user/install-isaac-lab/SKILL.md +++ b/skills/user/install-isaac-lab/SKILL.md @@ -1,6 +1,6 @@ --- name: isaaclab-installing-isaac-lab -description: Installs Isaac Lab end-to-end with minimal user interaction. Auto-detects the system with read-only checks, picks the right install method (automatic uv, downloaded Isaac Sim, source build, Isaac Lab wheel, legacy isaaclab.sh, managed Python env, or Docker) from the install docs, applies the documented China storage profile when requested, shows one consolidated plan, and after a single confirmation executes the docs-prescribed commands unattended through verification. Use when installing Isaac Lab for the first time, picking between install combinations, configuring China asset access during installation, or asking for install commands for a specific platform. +description: Installs Isaac Lab end-to-end with minimal user interaction. Auto-detects the system with read-only checks, picks the right install method (automatic uv, downloaded Isaac Sim, source build, Isaac Lab wheel, legacy isaaclab.sh, managed Python env, or Docker) from the install docs, applies the documented China Asset Region Profile when requested, shows one consolidated plan, and after a single confirmation executes the docs-prescribed commands unattended through verification. Use when installing Isaac Lab for the first time, picking between install combinations, configuring China asset access during installation, or asking for install commands for a specific platform. audience: user status: experimental owners: @@ -27,11 +27,11 @@ The express flow asks the user at most one question: the final go/no-go. Do not 2. Read the "System requirements" section and the install-method comparison from `docs/source/setup/installation/index.rst` in the checkout — never from memory — compare against the detected facts, and route to the correct section anchor in `index.rst` using the mapping in [reference.md](reference.md). 3. If a hard blocker exists (no NVIDIA GPU or driver, driver below the documented minimum, insufficient disk), stop before any state-changing command. Report each blocker with its fix and the documented alternative (the legacy Newton-only installer at `installation-legacy-installer` for no-Isaac-Sim machines). Do not attempt driver installs unattended. If existing install artifacts were found, hand off to `isaaclab-setup-troubleshooting` instead of reinstalling over them. 4. Auto-pick the remaining choices, honoring stated preferences. A preference the user already stated (conda, Docker, source build, Newton-only, a specific env name or directory, or China storage) always wins and must not be re-asked. Otherwise pick without asking: the docs-Recommended method (automatic uv from the checkout); uv if present, else conda if present, else the docs' uv install step; install into the current checkout with the docs-default env name. -5. Read the routed section of `index.rst` (and any `.inc` fragments it includes) from the checkout and extract its commands verbatim for this platform. When the user requests China storage, also read `asset_caching_details.inc` and follow the China Storage Profile rules in [reference.md](reference.md). Do not paraphrase, reorder, or substitute steps. -6. Show one consolidated confirmation: detected system in two or three lines, chosen method and why, selected storage profile when applicable, the exact commands in order, which steps need sudo, and rough download size. Ask one go/no-go question. This is the only question in the flow. +5. Read the routed section of `index.rst` (and any `.inc` fragments it includes) from the checkout and extract its commands verbatim for this platform. When the user requests China storage, also read the `installation-asset-region-profiles` section and follow the Asset Region Profile rules in [reference.md](reference.md). Do not paraphrase, reorder, or substitute steps. +6. Show one consolidated confirmation: detected system in two or three lines, chosen method and why, selected Asset Region Profile when applicable, the exact commands in order, which steps need sudo, and rough download size. Ask one go/no-go question. This is the only question in the flow. 7. On yes, execute every step in order without further prompts, streaming output and appending everything to `~/.isaaclab/logs/install-.log`. Announce sudo steps as they run; the password prompt is expected, not a question. On the "Downloaded Isaac Sim package" route only, pause at the manual Isaac Sim download step with the URL from the docs section and resume when the user confirms — the one unavoidable manual step. 8. On a step failure, check the failure routing table in [reference.md](reference.md), apply at most one documented fix, and retry the step once. If it still fails, stop and hand off to `isaaclab-setup-troubleshooting` with the log path. -9. Run the docs-defined minimal verification command for the chosen method, with the selected storage-profile environment when applicable, then hand over: how to activate the env, how to select the profile for future commands, how to run a first demo from the docs quickstart, and the log file path. Save a short summary of facts, route, storage profile, and commands run to `~/.isaaclab/install_profile.yaml` for reproducibility. +9. Run the docs-defined minimal verification command for the chosen method, with the selected Asset Region Profile environment when applicable, then hand over: how to activate the env, how to select the profile for future commands, how to run a first demo from the docs quickstart, and the log file path. Save a short summary of facts, route, Asset Region Profile, and commands run to `~/.isaaclab/install_profile.yaml` for reproducibility. ## Validation @@ -62,7 +62,7 @@ Keep this skill synchronized with the following install docs. If commands or ver - `docs/source/setup/installation/index.rst` — `installation-method-python-env` steps (managed venv/conda + pip Isaac Sim). - `docs/source/setup/installation/index.rst` — `installation-method-wheel` steps (Isaac Lab Python package for external projects). - `docs/source/setup/installation/index.rst` — `installation-method-binary` steps (downloaded Isaac Sim package). -- `docs/source/setup/installation/index.rst` — `installation-method-source` steps (Isaac Sim source build). +- `docs/source/setup/installation/index.rst` — `installation-method-source` steps (Isaac Sim source build) and the `installation-asset-region-profiles` workflow. - `docs/source/setup/installation/asset_caching_details.inc` — asset caching notes. - `docs/source/features/docker_cloud.rst` — Docker and cloud-workstation deep dive; complements `installation-method-container` and `installation-method-cloud` in `index.rst`. - `docs/source/refs/troubleshooting.rst` — hand-off target for post-install diagnostics. diff --git a/skills/user/install-isaac-lab/evaluations.md b/skills/user/install-isaac-lab/evaluations.md index 917400b492b1..386aff0657d2 100644 --- a/skills/user/install-isaac-lab/evaluations.md +++ b/skills/user/install-isaac-lab/evaluations.md @@ -7,7 +7,7 @@ - [Scenario 3: Stated Preferences Override Auto-Pick](#scenario-3-stated-preferences-override-auto-pick) - [Scenario 4: Preflight Blocker Stops The Flow](#scenario-4-preflight-blocker-stops-the-flow) - [Scenario 5: Windows 11 Guided Fallback](#scenario-5-windows-11-guided-fallback) -- [Scenario 6: China Storage Profile During Installation](#scenario-6-china-storage-profile-during-installation) +- [Scenario 6: China Asset Region Profile During Installation](#scenario-6-china-asset-region-profile-during-installation) ## Scenario 1: Express Install On Ubuntu 22.04 @@ -93,7 +93,7 @@ Known failure modes: - Skips the long-path support step documented for Windows. - Applies the Linux express unattended flow where the docs require Windows-specific handling. -## Scenario 6: China Storage Profile During Installation +## Scenario 6: China Asset Region Profile During Installation Query: "Install Isaac Lab for a workstation in mainland China." @@ -101,7 +101,7 @@ Expected behavior: - Runs the normal preflight and chooses the install method from current system requirements rather than changing the package source solely because of location. -- Reads `asset_caching_details.inc`, includes the documented China profile setting in the single consolidated plan, +- Reads the Asset Region Profiles section in `index.rst`, includes the documented China profile setting in the single consolidated plan, and handles an existing `ISAACSIM_ASSET_ROOT` according to its documented precedence. - Runs the normal verification with the profile selected, while stating that this does not prove every mirrored asset is available. diff --git a/skills/user/install-isaac-lab/examples.md b/skills/user/install-isaac-lab/examples.md index 0e5c9ebd6988..f668d8b1a589 100644 --- a/skills/user/install-isaac-lab/examples.md +++ b/skills/user/install-isaac-lab/examples.md @@ -60,9 +60,9 @@ User: "Install Isaac Lab for a workstation in mainland China." Suggested agent response: -1. Run the normal preflight, including the existing asset-root and storage-profile environment variables. Route to the +1. Run the normal preflight, including the existing asset-root and Asset Region Profile environment variables. Route to the install method from the current installation docs; location does not change the package-install method. -2. Read the China Storage Profile section from `asset_caching_details.inc`. Add its profile setting to the consolidated +2. Read the Asset Region Profiles section from `index.rst`. Add its China profile setting to the consolidated plan and explain that an existing `ISAACSIM_ASSET_ROOT` must be unset in the session for the profile to take effect. 3. After the single confirmation, install normally and run the docs-defined verification with the profile selected. 4. Before recommending an asset-bearing demo, find all of its full relative asset paths in the current availability diff --git a/skills/user/install-isaac-lab/reference.md b/skills/user/install-isaac-lab/reference.md index 5c4d2ae01c15..7d235fc209f8 100644 --- a/skills/user/install-isaac-lab/reference.md +++ b/skills/user/install-isaac-lab/reference.md @@ -5,7 +5,7 @@ - [Preflight Detection](#preflight-detection) - [Express Route Mapping](#express-route-mapping) - [Express Flow Rules](#express-flow-rules) -- [China Storage Profile](#china-storage-profile) +- [Asset Region Profiles](#asset-region-profiles) - [Prerequisite Minimums](#prerequisite-minimums) - [Minimal Verification](#minimal-verification) - [Install-Time Failure Routing](#install-time-failure-routing) @@ -19,7 +19,7 @@ Read-only commands to gather routing facts on Linux; nothing changes system stat grep PRETTY_NAME /etc/os-release && uname -m && ldd --version | head -1 nvidia-smi --query-gpu=name,memory.total,driver_version --format=csv,noheader command -v python3.12 uv conda; free -g | head -2; df -h . -env | grep -E '^(ISAACSIM_STORAGE_PROFILE|ISAACSIM_ASSET_ROOT)=' || true +env | grep -E '^(ISAACSIM_ASSET_REGION_PROFILE|ISAACSIM_ASSET_ROOT)=' || true ``` Also note existing install artifacts: `.venv/` or an env directory in the checkout, and `~/.isaaclab/install_profile.yaml`. On Windows, collect the equivalents (driver via `nvidia-smi`, Python version, free disk). @@ -56,14 +56,14 @@ User-stated preferences override the routing and map directly: - Log every executed command and its output to `~/.isaaclab/logs/install-.log`. - After success, write facts, route, and commands run to `~/.isaaclab/install_profile.yaml`. -## China Storage Profile +## Asset Region Profiles Use the China profile only when the user requests it or states that Isaac Lab will run in mainland China. Do not infer the profile from an IP address or other geolocation lookup. -Read `docs/source/setup/installation/asset_caching_details.inc` from the checkout every time. Use its current profile -setting and asset-availability manifest instead of copying release numbers, service endpoints, bucket names, or CDN -URLs into the skill. +Read the `installation-asset-region-profiles` section in `docs/source/setup/installation/index.rst` from the checkout +every time. Use its current profile setting and asset-availability manifest instead of copying release numbers, +service endpoints, bucket names, or CDN URLs into the skill. - Add the documented profile environment variable to the install verification and subsequent example commands. Do not edit shell startup files unless the user explicitly requests persistence. diff --git a/source/isaaclab/changelog.d/asset-region-profiles.rst b/source/isaaclab/changelog.d/asset-region-profiles.rst new file mode 100644 index 000000000000..0d5009eb8c3f --- /dev/null +++ b/source/isaaclab/changelog.d/asset-region-profiles.rst @@ -0,0 +1,6 @@ +Changed +^^^^^^^ + +* Renamed the China profile selector from ``ISAACSIM_STORAGE_PROFILE`` to + ``ISAACSIM_ASSET_REGION_PROFILE`` and added the ``us`` profile for explicit switchback. Added + ``configure_asset_region_profile()`` while retaining ``configure_storage_profile()`` for compatibility. diff --git a/source/isaaclab/isaaclab/utils/assets.py b/source/isaaclab/isaaclab/utils/assets.py index 2ee7344c5a4b..5f1c3d307909 100644 --- a/source/isaaclab/isaaclab/utils/assets.py +++ b/source/isaaclab/isaaclab/utils/assets.py @@ -24,7 +24,7 @@ import tempfile import uuid from types import ModuleType -from typing import Literal, TypedDict +from typing import Literal, NotRequired, TypedDict from urllib.parse import urlparse from filelock import FileLock @@ -50,45 +50,51 @@ # legacy ``cloud`` setting is only consulted for experience files that predate it. _KIT_ASSET_ROOT_SETTINGS = ("default", "cloud") -_STORAGE_PROFILE_ENV_VAR = "ISAACSIM_STORAGE_PROFILE" +_STORAGE_PROFILE_ENV_VAR = "ISAACSIM_ASSET_REGION_PROFILE" # Update this value when the China mirror moves to a new Isaac Sim asset release. _ISAAC_SIM_ASSET_RELEASE = "6.1" -_CHINA_STORAGE_ENDPOINT = "simready-cn.s3.oss-cn-shanghai.aliyuncs.com" +_CHINA_ASSET_ENDPOINT = "simready-cn.s3.oss-cn-shanghai.aliyuncs.com" +_US_ASSET_ROOT = ( + f"https://omniverse-content-production.s3-us-west-2.amazonaws.com/Assets/Isaac/{_ISAAC_SIM_ASSET_RELEASE}" +) class _StorageProfile(TypedDict): - """OmniClient routing and asset-root values for a named storage profile.""" + """OmniClient routing and asset-root values for a named asset region profile.""" - endpoint: str - bucket: str - region: str - cdn_url: str - cdn_for_list: bool asset_root: str + endpoint: NotRequired[str] + bucket: NotRequired[str] + region: NotRequired[str] + cdn_url: NotRequired[str] + cdn_for_list: NotRequired[bool] _STORAGE_PROFILES: dict[str, _StorageProfile] = { + "us": { + "asset_root": _US_ASSET_ROOT, + }, "china": { - "endpoint": _CHINA_STORAGE_ENDPOINT, + "endpoint": _CHINA_ASSET_ENDPOINT, "bucket": "simready-cn", "region": "oss-cn-shanghai", "cdn_url": "https://assets.simready.cn/", "cdn_for_list": False, - "asset_root": f"https://{_CHINA_STORAGE_ENDPOINT}/Assets/Isaac/{_ISAAC_SIM_ASSET_RELEASE}", + "asset_root": f"https://{_CHINA_ASSET_ENDPOINT}/Assets/Isaac/{_ISAAC_SIM_ASSET_RELEASE}", }, } _CONFIGURED_STORAGE_PROFILES: set[str] = set() def _selected_storage_profile() -> tuple[str, _StorageProfile] | None: - """Return the storage profile selected by the environment, if it is known.""" + """Return the asset region profile selected by the environment, if it is known.""" profile_name = os.getenv(_STORAGE_PROFILE_ENV_VAR) if not profile_name: return None profile = _STORAGE_PROFILES.get(profile_name) if profile is None: - logger.warning("Ignoring %s: no storage profile named '%s'", _STORAGE_PROFILE_ENV_VAR, profile_name) + logger.warning("Ignoring %s: no asset region profile named '%s'", _STORAGE_PROFILE_ENV_VAR, profile_name) return None return profile_name, profile @@ -103,32 +109,35 @@ def _configure_storage_profile(omni_client: ModuleType) -> None: if profile_name in _CONFIGURED_STORAGE_PROFILES: return - result = omni_client.set_s3_configuration( - url=profile["endpoint"], - bucket=profile["bucket"], - region=profile["region"], - cloudfrontUrl=profile["cdn_url"], - cloudfrontForList=profile["cdn_for_list"], - writeConfig=False, - ) - if result != omni_client.Result.OK: - raise RuntimeError(f"Storage profile '{profile_name}' failed to configure {profile['endpoint']}: {result}") + endpoint = profile.get("endpoint") + if endpoint: + result = omni_client.set_s3_configuration( + url=endpoint, + bucket=profile.get("bucket"), + region=profile.get("region"), + cloudfrontUrl=profile.get("cdn_url"), + cloudfrontForList=profile.get("cdn_for_list", False), + writeConfig=False, + ) + if result != omni_client.Result.OK: + raise RuntimeError(f"Asset region profile '{profile_name}' failed to configure {endpoint}: {result}") _CONFIGURED_STORAGE_PROFILES.add(profile_name) - logger.info("Applied storage profile '%s'", profile_name) + logger.info("Applied asset region profile '%s'", profile_name) def configure_storage_profile() -> None: - """Configure OmniClient routing for the selected storage profile. + """Configure OmniClient routing for the selected asset region profile. The configuration is applied in memory and at most once per profile. Isaac Lab launchers and asset helpers call this automatically. Standalone kitless scripts should call it before using ``omni.client`` directly. Raises: - RuntimeError: When OmniClient rejects the selected storage profile. + RuntimeError: When OmniClient rejects the selected asset region profile. """ - if _selected_storage_profile() is None: + selected_profile = _selected_storage_profile() + if selected_profile is None or not selected_profile[1].get("endpoint"): return import omni.client # noqa: PLC0415 @@ -136,8 +145,17 @@ def configure_storage_profile() -> None: _configure_storage_profile(omni.client) +def configure_asset_region_profile() -> None: + """Configure the selected asset region profile. + + This name matches the public Asset Region Profile terminology. The existing + :func:`configure_storage_profile` initializer remains supported. + """ + configure_storage_profile() + + def _get_omni_client() -> ModuleType: - """Import OmniClient lazily and apply the selected storage profile.""" + """Import OmniClient lazily and apply the selected asset region profile.""" import omni.client # noqa: PLC0415 _configure_storage_profile(omni.client) @@ -166,13 +184,13 @@ def _resolve_asset_root() -> str: """Resolve the configured Isaac asset root. The ``ISAACSIM_ASSET_ROOT`` environment variable follows the public Isaac Sim - asset-root precedence. When it is unset, the asset root from the storage profile - named by ``ISAACSIM_STORAGE_PROFILE`` is used. The kit file remains the fallback + asset-root precedence. When it is unset, the asset root from the asset region profile + named by ``ISAACSIM_ASSET_REGION_PROFILE`` is used. The kit file remains the fallback for kitless use. Returns: Value of ``ISAACSIM_ASSET_ROOT`` without its trailing separator, or the value - selected by ``ISAACSIM_STORAGE_PROFILE``, or the value configured in + selected by ``ISAACSIM_ASSET_REGION_PROFILE``, or the value configured in ``isaaclab.python.kit``. """ # the value is used exactly as ``isaacsim.storage.native`` uses it, so both sides resolve diff --git a/source/isaaclab/test/utils/test_assets.py b/source/isaaclab/test/utils/test_assets.py index c3f37e677b40..d4a153dcb9ba 100644 --- a/source/isaaclab/test/utils/test_assets.py +++ b/source/isaaclab/test/utils/test_assets.py @@ -27,7 +27,7 @@ def test_asset_root_environment_override_takes_precedence(monkeypatch): """Test the documented Isaac Sim asset-root environment override.""" monkeypatch.setenv("ISAACSIM_ASSET_ROOT", "/tmp/isaacsim_assets/Assets/Isaac/X.Y/") - monkeypatch.setenv("ISAACSIM_STORAGE_PROFILE", "china") + monkeypatch.setenv("ISAACSIM_ASSET_REGION_PROFILE", "china") monkeypatch.setattr(assets_utils, "_parse_kit_asset_root", lambda: "https://example.com/kit-assets") assert assets_utils._resolve_asset_root() == "/tmp/isaacsim_assets/Assets/Isaac/X.Y" @@ -36,16 +36,16 @@ def test_asset_root_environment_override_takes_precedence(monkeypatch): def test_asset_root_falls_back_to_kit_file(monkeypatch): """Test kitless asset-root resolution when the environment override is absent.""" monkeypatch.delenv("ISAACSIM_ASSET_ROOT", raising=False) - monkeypatch.delenv("ISAACSIM_STORAGE_PROFILE", raising=False) + monkeypatch.delenv("ISAACSIM_ASSET_REGION_PROFILE", raising=False) monkeypatch.setattr(assets_utils, "_parse_kit_asset_root", lambda: "https://example.com/kit-assets") assert assets_utils._resolve_asset_root() == "https://example.com/kit-assets" def test_asset_root_uses_china_storage_profile(monkeypatch): - """Test the China storage profile uses the same public bucket root as Isaac Sim.""" + """Test the China asset region profile uses the same public bucket root as Isaac Sim.""" monkeypatch.delenv("ISAACSIM_ASSET_ROOT", raising=False) - monkeypatch.setenv("ISAACSIM_STORAGE_PROFILE", "china") + monkeypatch.setenv("ISAACSIM_ASSET_REGION_PROFILE", "china") monkeypatch.setattr(assets_utils, "_parse_kit_asset_root", lambda: "https://example.com/kit-assets") expected_root = ( @@ -54,16 +54,25 @@ def test_asset_root_uses_china_storage_profile(monkeypatch): assert assets_utils._resolve_asset_root() == expected_root +def test_asset_root_uses_us_asset_region_profile(monkeypatch): + """Test the US asset region profile uses the same public bucket root as Isaac Sim.""" + monkeypatch.delenv("ISAACSIM_ASSET_ROOT", raising=False) + monkeypatch.setenv("ISAACSIM_ASSET_REGION_PROFILE", "us") + monkeypatch.setattr(assets_utils, "_parse_kit_asset_root", lambda: "https://example.com/kit-assets") + + assert assets_utils._resolve_asset_root() == assets_utils._US_ASSET_ROOT + + def test_asset_root_ignores_unknown_storage_profile(monkeypatch, caplog): """Test an unknown profile warns and falls back to the experience file.""" monkeypatch.delenv("ISAACSIM_ASSET_ROOT", raising=False) - monkeypatch.setenv("ISAACSIM_STORAGE_PROFILE", "unknown") + monkeypatch.setenv("ISAACSIM_ASSET_REGION_PROFILE", "unknown") monkeypatch.setattr(assets_utils, "_parse_kit_asset_root", lambda: "https://example.com/kit-assets") with caplog.at_level(logging.WARNING, logger=assets_utils.logger.name): assert assets_utils._resolve_asset_root() == "https://example.com/kit-assets" - assert "no storage profile named 'unknown'" in caplog.text + assert "no asset region profile named 'unknown'" in caplog.text def test_configure_china_storage_profile_once(monkeypatch): @@ -71,7 +80,7 @@ def test_configure_china_storage_profile_once(monkeypatch): import omni.client calls = [] - monkeypatch.setenv("ISAACSIM_STORAGE_PROFILE", "china") + monkeypatch.setenv("ISAACSIM_ASSET_REGION_PROFILE", "china") monkeypatch.setattr(assets_utils, "_CONFIGURED_STORAGE_PROFILES", set()) def configure(**kwargs): @@ -95,21 +104,33 @@ def configure(**kwargs): ] +def test_configure_us_storage_profile_is_lazy(monkeypatch): + """Test the primary profile selects its root without importing OmniClient.""" + monkeypatch.setenv("ISAACSIM_ASSET_REGION_PROFILE", "us") + original_omni_client = sys.modules.pop("omni.client", None) + try: + assets_utils.configure_storage_profile() + assert "omni.client" not in sys.modules + finally: + if original_omni_client is not None: + sys.modules["omni.client"] = original_omni_client + + def test_configure_storage_profile_reports_client_failure(monkeypatch): """Test a rejected OmniClient profile fails before an inaccessible asset is used.""" import omni.client - monkeypatch.setenv("ISAACSIM_STORAGE_PROFILE", "china") + monkeypatch.setenv("ISAACSIM_ASSET_REGION_PROFILE", "china") monkeypatch.setattr(assets_utils, "_CONFIGURED_STORAGE_PROFILES", set()) monkeypatch.setattr(omni.client, "set_s3_configuration", lambda **_kwargs: "rejected") - with pytest.raises(RuntimeError, match="Storage profile 'china' failed to configure"): + with pytest.raises(RuntimeError, match="Asset region profile 'china' failed to configure"): assets_utils.configure_storage_profile() def test_configure_storage_profile_is_lazy_without_selection(monkeypatch): """Test the initializer does not import OmniClient when no profile is selected.""" - monkeypatch.delenv("ISAACSIM_STORAGE_PROFILE", raising=False) + monkeypatch.delenv("ISAACSIM_ASSET_REGION_PROFILE", raising=False) original_omni_client = sys.modules.pop("omni.client", None) try: assets_utils.configure_storage_profile() @@ -119,6 +140,16 @@ def test_configure_storage_profile_is_lazy_without_selection(monkeypatch): sys.modules["omni.client"] = original_omni_client +def test_configure_asset_region_profile_alias(monkeypatch): + """Test the public Asset Region Profile initializer forwards to the existing initializer.""" + calls = [] + monkeypatch.setattr(assets_utils, "configure_storage_profile", lambda: calls.append(True)) + + assets_utils.configure_asset_region_profile() + + assert calls == [True] + + def test_asset_client_applies_storage_profile(monkeypatch): """Test remote asset helpers configure routing whenever they import OmniClient.""" import omni.client @@ -141,7 +172,7 @@ def test_asset_root_environment_override_strips_windows_separator(monkeypatch): def test_asset_root_ignores_empty_environment_override(monkeypatch): """Test an empty override falls back, matching when ``isaacsim.storage.native`` skips it.""" monkeypatch.setenv("ISAACSIM_ASSET_ROOT", "") - monkeypatch.delenv("ISAACSIM_STORAGE_PROFILE", raising=False) + monkeypatch.delenv("ISAACSIM_ASSET_REGION_PROFILE", raising=False) monkeypatch.setattr(assets_utils, "_parse_kit_asset_root", lambda: "https://example.com/kit-assets") assert assets_utils._resolve_asset_root() == "https://example.com/kit-assets" @@ -197,11 +228,11 @@ def test_exported_asset_root_constants_follow_environment_override(monkeypatch): def test_exported_asset_root_constants_follow_china_storage_profile(monkeypatch): - """Test kitless asset constants follow the selected China storage profile.""" + """Test kitless asset constants follow the selected China asset region profile.""" try: with monkeypatch.context() as patched_env: patched_env.delenv("ISAACSIM_ASSET_ROOT", raising=False) - patched_env.setenv("ISAACSIM_STORAGE_PROFILE", "china") + patched_env.setenv("ISAACSIM_ASSET_REGION_PROFILE", "china") module = importlib.reload(assets_utils) root = f"https://simready-cn.s3.oss-cn-shanghai.aliyuncs.com/Assets/Isaac/{module._ISAAC_SIM_ASSET_RELEASE}" From e2985de0e202243d512bb925efd8302ed80f0564 Mon Sep 17 00:00:00 2001 From: Sheikh Dawood <7774242+sheikh-nv@users.noreply.github.com> Date: Thu, 3 Sep 2026 21:53:58 +0000 Subject: [PATCH 2/5] Preserve legacy asset profile selection --- docs/source/setup/installation/index.rst | 3 +++ .../asset-region-profiles.minor.rst | 10 ++++++++ .../changelog.d/asset-region-profiles.rst | 6 ----- source/isaaclab/isaaclab/utils/assets.py | 15 +++++++++--- source/isaaclab/test/utils/test_assets.py | 24 +++++++++++++++++++ 5 files changed, 49 insertions(+), 9 deletions(-) create mode 100644 source/isaaclab/changelog.d/asset-region-profiles.minor.rst delete mode 100644 source/isaaclab/changelog.d/asset-region-profiles.rst diff --git a/docs/source/setup/installation/index.rst b/docs/source/setup/installation/index.rst index 3e17e6b0e050..56dea7aead9c 100644 --- a/docs/source/setup/installation/index.rst +++ b/docs/source/setup/installation/index.rst @@ -1138,6 +1138,9 @@ initialize the profile first: configure_asset_region_profile() +The previous ``ISAACSIM_STORAGE_PROFILE`` variable remains supported as a deprecated fallback. Use +``ISAACSIM_ASSET_REGION_PROFILE`` for new configurations. + To return to the primary service, clear ``ISAACSIM_ASSET_ROOT`` and select the ``us`` profile for the next process. You can leave the profile unset for later processes. diff --git a/source/isaaclab/changelog.d/asset-region-profiles.minor.rst b/source/isaaclab/changelog.d/asset-region-profiles.minor.rst new file mode 100644 index 000000000000..44239377f635 --- /dev/null +++ b/source/isaaclab/changelog.d/asset-region-profiles.minor.rst @@ -0,0 +1,10 @@ +Added +^^^^^ + +* Added the ``us`` asset region profile and ``configure_asset_region_profile()`` initializer. + +Changed +^^^^^^^ + +* Renamed the preferred China profile selector from ``ISAACSIM_STORAGE_PROFILE`` to + ``ISAACSIM_ASSET_REGION_PROFILE`` while retaining the previous name as a deprecated fallback. diff --git a/source/isaaclab/changelog.d/asset-region-profiles.rst b/source/isaaclab/changelog.d/asset-region-profiles.rst deleted file mode 100644 index 0d5009eb8c3f..000000000000 --- a/source/isaaclab/changelog.d/asset-region-profiles.rst +++ /dev/null @@ -1,6 +0,0 @@ -Changed -^^^^^^^ - -* Renamed the China profile selector from ``ISAACSIM_STORAGE_PROFILE`` to - ``ISAACSIM_ASSET_REGION_PROFILE`` and added the ``us`` profile for explicit switchback. Added - ``configure_asset_region_profile()`` while retaining ``configure_storage_profile()`` for compatibility. diff --git a/source/isaaclab/isaaclab/utils/assets.py b/source/isaaclab/isaaclab/utils/assets.py index 5f1c3d307909..1109d79b5759 100644 --- a/source/isaaclab/isaaclab/utils/assets.py +++ b/source/isaaclab/isaaclab/utils/assets.py @@ -50,7 +50,8 @@ # legacy ``cloud`` setting is only consulted for experience files that predate it. _KIT_ASSET_ROOT_SETTINGS = ("default", "cloud") -_STORAGE_PROFILE_ENV_VAR = "ISAACSIM_ASSET_REGION_PROFILE" +_ASSET_REGION_PROFILE_ENV_VAR = "ISAACSIM_ASSET_REGION_PROFILE" +_LEGACY_STORAGE_PROFILE_ENV_VAR = "ISAACSIM_STORAGE_PROFILE" # Update this value when the China mirror moves to a new Isaac Sim asset release. _ISAAC_SIM_ASSET_RELEASE = "6.1" _CHINA_ASSET_ENDPOINT = "simready-cn.s3.oss-cn-shanghai.aliyuncs.com" @@ -88,13 +89,21 @@ class _StorageProfile(TypedDict): def _selected_storage_profile() -> tuple[str, _StorageProfile] | None: """Return the asset region profile selected by the environment, if it is known.""" - profile_name = os.getenv(_STORAGE_PROFILE_ENV_VAR) + profile_env_var = _ASSET_REGION_PROFILE_ENV_VAR + profile_name = os.getenv(profile_env_var) + if not profile_name: + profile_env_var = _LEGACY_STORAGE_PROFILE_ENV_VAR + profile_name = os.getenv(profile_env_var) + if profile_name: + logger.warning( + "%s is deprecated; use %s instead", _LEGACY_STORAGE_PROFILE_ENV_VAR, _ASSET_REGION_PROFILE_ENV_VAR + ) if not profile_name: return None profile = _STORAGE_PROFILES.get(profile_name) if profile is None: - logger.warning("Ignoring %s: no asset region profile named '%s'", _STORAGE_PROFILE_ENV_VAR, profile_name) + logger.warning("Ignoring %s: no asset region profile named '%s'", profile_env_var, profile_name) return None return profile_name, profile diff --git a/source/isaaclab/test/utils/test_assets.py b/source/isaaclab/test/utils/test_assets.py index d4a153dcb9ba..fbcd85c5f13d 100644 --- a/source/isaaclab/test/utils/test_assets.py +++ b/source/isaaclab/test/utils/test_assets.py @@ -37,6 +37,7 @@ def test_asset_root_falls_back_to_kit_file(monkeypatch): """Test kitless asset-root resolution when the environment override is absent.""" monkeypatch.delenv("ISAACSIM_ASSET_ROOT", raising=False) monkeypatch.delenv("ISAACSIM_ASSET_REGION_PROFILE", raising=False) + monkeypatch.delenv("ISAACSIM_STORAGE_PROFILE", raising=False) monkeypatch.setattr(assets_utils, "_parse_kit_asset_root", lambda: "https://example.com/kit-assets") assert assets_utils._resolve_asset_root() == "https://example.com/kit-assets" @@ -63,6 +64,27 @@ def test_asset_root_uses_us_asset_region_profile(monkeypatch): assert assets_utils._resolve_asset_root() == assets_utils._US_ASSET_ROOT +def test_asset_root_supports_legacy_storage_profile(monkeypatch, caplog): + """Test the released storage-profile variable remains a deprecated fallback.""" + monkeypatch.delenv("ISAACSIM_ASSET_ROOT", raising=False) + monkeypatch.delenv("ISAACSIM_ASSET_REGION_PROFILE", raising=False) + monkeypatch.setenv("ISAACSIM_STORAGE_PROFILE", "china") + + with caplog.at_level(logging.WARNING, logger=assets_utils.logger.name): + assert assets_utils._resolve_asset_root() == assets_utils._STORAGE_PROFILES["china"]["asset_root"] + + assert "ISAACSIM_STORAGE_PROFILE is deprecated; use ISAACSIM_ASSET_REGION_PROFILE instead" in caplog.text + + +def test_asset_region_profile_takes_precedence_over_legacy_variable(monkeypatch): + """Test the documented selector wins when both profile variables are set.""" + monkeypatch.delenv("ISAACSIM_ASSET_ROOT", raising=False) + monkeypatch.setenv("ISAACSIM_ASSET_REGION_PROFILE", "us") + monkeypatch.setenv("ISAACSIM_STORAGE_PROFILE", "china") + + assert assets_utils._resolve_asset_root() == assets_utils._US_ASSET_ROOT + + def test_asset_root_ignores_unknown_storage_profile(monkeypatch, caplog): """Test an unknown profile warns and falls back to the experience file.""" monkeypatch.delenv("ISAACSIM_ASSET_ROOT", raising=False) @@ -131,6 +153,7 @@ def test_configure_storage_profile_reports_client_failure(monkeypatch): def test_configure_storage_profile_is_lazy_without_selection(monkeypatch): """Test the initializer does not import OmniClient when no profile is selected.""" monkeypatch.delenv("ISAACSIM_ASSET_REGION_PROFILE", raising=False) + monkeypatch.delenv("ISAACSIM_STORAGE_PROFILE", raising=False) original_omni_client = sys.modules.pop("omni.client", None) try: assets_utils.configure_storage_profile() @@ -173,6 +196,7 @@ def test_asset_root_ignores_empty_environment_override(monkeypatch): """Test an empty override falls back, matching when ``isaacsim.storage.native`` skips it.""" monkeypatch.setenv("ISAACSIM_ASSET_ROOT", "") monkeypatch.delenv("ISAACSIM_ASSET_REGION_PROFILE", raising=False) + monkeypatch.delenv("ISAACSIM_STORAGE_PROFILE", raising=False) monkeypatch.setattr(assets_utils, "_parse_kit_asset_root", lambda: "https://example.com/kit-assets") assert assets_utils._resolve_asset_root() == "https://example.com/kit-assets" From 39844eedbea43a9decc69e1cf4a405c91f9f2aaa Mon Sep 17 00:00:00 2001 From: Sheikh Dawood <7774242+sheikh-nv@users.noreply.github.com> Date: Thu, 3 Sep 2026 22:04:59 +0000 Subject: [PATCH 3/5] Remove legacy storage profile fallback --- docs/source/setup/installation/index.rst | 3 --- .../asset-region-profiles.minor.rst | 4 ++-- source/isaaclab/isaaclab/utils/assets.py | 13 ++-------- source/isaaclab/test/utils/test_assets.py | 24 ------------------- 4 files changed, 4 insertions(+), 40 deletions(-) diff --git a/docs/source/setup/installation/index.rst b/docs/source/setup/installation/index.rst index 56dea7aead9c..3e17e6b0e050 100644 --- a/docs/source/setup/installation/index.rst +++ b/docs/source/setup/installation/index.rst @@ -1138,9 +1138,6 @@ initialize the profile first: configure_asset_region_profile() -The previous ``ISAACSIM_STORAGE_PROFILE`` variable remains supported as a deprecated fallback. Use -``ISAACSIM_ASSET_REGION_PROFILE`` for new configurations. - To return to the primary service, clear ``ISAACSIM_ASSET_ROOT`` and select the ``us`` profile for the next process. You can leave the profile unset for later processes. diff --git a/source/isaaclab/changelog.d/asset-region-profiles.minor.rst b/source/isaaclab/changelog.d/asset-region-profiles.minor.rst index 44239377f635..6d39999b992a 100644 --- a/source/isaaclab/changelog.d/asset-region-profiles.minor.rst +++ b/source/isaaclab/changelog.d/asset-region-profiles.minor.rst @@ -6,5 +6,5 @@ Added Changed ^^^^^^^ -* Renamed the preferred China profile selector from ``ISAACSIM_STORAGE_PROFILE`` to - ``ISAACSIM_ASSET_REGION_PROFILE`` while retaining the previous name as a deprecated fallback. +* Renamed the China profile selector from ``ISAACSIM_STORAGE_PROFILE`` to + ``ISAACSIM_ASSET_REGION_PROFILE``. diff --git a/source/isaaclab/isaaclab/utils/assets.py b/source/isaaclab/isaaclab/utils/assets.py index 1109d79b5759..38e99a40476a 100644 --- a/source/isaaclab/isaaclab/utils/assets.py +++ b/source/isaaclab/isaaclab/utils/assets.py @@ -51,7 +51,6 @@ _KIT_ASSET_ROOT_SETTINGS = ("default", "cloud") _ASSET_REGION_PROFILE_ENV_VAR = "ISAACSIM_ASSET_REGION_PROFILE" -_LEGACY_STORAGE_PROFILE_ENV_VAR = "ISAACSIM_STORAGE_PROFILE" # Update this value when the China mirror moves to a new Isaac Sim asset release. _ISAAC_SIM_ASSET_RELEASE = "6.1" _CHINA_ASSET_ENDPOINT = "simready-cn.s3.oss-cn-shanghai.aliyuncs.com" @@ -89,21 +88,13 @@ class _StorageProfile(TypedDict): def _selected_storage_profile() -> tuple[str, _StorageProfile] | None: """Return the asset region profile selected by the environment, if it is known.""" - profile_env_var = _ASSET_REGION_PROFILE_ENV_VAR - profile_name = os.getenv(profile_env_var) - if not profile_name: - profile_env_var = _LEGACY_STORAGE_PROFILE_ENV_VAR - profile_name = os.getenv(profile_env_var) - if profile_name: - logger.warning( - "%s is deprecated; use %s instead", _LEGACY_STORAGE_PROFILE_ENV_VAR, _ASSET_REGION_PROFILE_ENV_VAR - ) + profile_name = os.getenv(_ASSET_REGION_PROFILE_ENV_VAR) if not profile_name: return None profile = _STORAGE_PROFILES.get(profile_name) if profile is None: - logger.warning("Ignoring %s: no asset region profile named '%s'", profile_env_var, profile_name) + logger.warning("Ignoring %s: no asset region profile named '%s'", _ASSET_REGION_PROFILE_ENV_VAR, profile_name) return None return profile_name, profile diff --git a/source/isaaclab/test/utils/test_assets.py b/source/isaaclab/test/utils/test_assets.py index fbcd85c5f13d..d4a153dcb9ba 100644 --- a/source/isaaclab/test/utils/test_assets.py +++ b/source/isaaclab/test/utils/test_assets.py @@ -37,7 +37,6 @@ def test_asset_root_falls_back_to_kit_file(monkeypatch): """Test kitless asset-root resolution when the environment override is absent.""" monkeypatch.delenv("ISAACSIM_ASSET_ROOT", raising=False) monkeypatch.delenv("ISAACSIM_ASSET_REGION_PROFILE", raising=False) - monkeypatch.delenv("ISAACSIM_STORAGE_PROFILE", raising=False) monkeypatch.setattr(assets_utils, "_parse_kit_asset_root", lambda: "https://example.com/kit-assets") assert assets_utils._resolve_asset_root() == "https://example.com/kit-assets" @@ -64,27 +63,6 @@ def test_asset_root_uses_us_asset_region_profile(monkeypatch): assert assets_utils._resolve_asset_root() == assets_utils._US_ASSET_ROOT -def test_asset_root_supports_legacy_storage_profile(monkeypatch, caplog): - """Test the released storage-profile variable remains a deprecated fallback.""" - monkeypatch.delenv("ISAACSIM_ASSET_ROOT", raising=False) - monkeypatch.delenv("ISAACSIM_ASSET_REGION_PROFILE", raising=False) - monkeypatch.setenv("ISAACSIM_STORAGE_PROFILE", "china") - - with caplog.at_level(logging.WARNING, logger=assets_utils.logger.name): - assert assets_utils._resolve_asset_root() == assets_utils._STORAGE_PROFILES["china"]["asset_root"] - - assert "ISAACSIM_STORAGE_PROFILE is deprecated; use ISAACSIM_ASSET_REGION_PROFILE instead" in caplog.text - - -def test_asset_region_profile_takes_precedence_over_legacy_variable(monkeypatch): - """Test the documented selector wins when both profile variables are set.""" - monkeypatch.delenv("ISAACSIM_ASSET_ROOT", raising=False) - monkeypatch.setenv("ISAACSIM_ASSET_REGION_PROFILE", "us") - monkeypatch.setenv("ISAACSIM_STORAGE_PROFILE", "china") - - assert assets_utils._resolve_asset_root() == assets_utils._US_ASSET_ROOT - - def test_asset_root_ignores_unknown_storage_profile(monkeypatch, caplog): """Test an unknown profile warns and falls back to the experience file.""" monkeypatch.delenv("ISAACSIM_ASSET_ROOT", raising=False) @@ -153,7 +131,6 @@ def test_configure_storage_profile_reports_client_failure(monkeypatch): def test_configure_storage_profile_is_lazy_without_selection(monkeypatch): """Test the initializer does not import OmniClient when no profile is selected.""" monkeypatch.delenv("ISAACSIM_ASSET_REGION_PROFILE", raising=False) - monkeypatch.delenv("ISAACSIM_STORAGE_PROFILE", raising=False) original_omni_client = sys.modules.pop("omni.client", None) try: assets_utils.configure_storage_profile() @@ -196,7 +173,6 @@ def test_asset_root_ignores_empty_environment_override(monkeypatch): """Test an empty override falls back, matching when ``isaacsim.storage.native`` skips it.""" monkeypatch.setenv("ISAACSIM_ASSET_ROOT", "") monkeypatch.delenv("ISAACSIM_ASSET_REGION_PROFILE", raising=False) - monkeypatch.delenv("ISAACSIM_STORAGE_PROFILE", raising=False) monkeypatch.setattr(assets_utils, "_parse_kit_asset_root", lambda: "https://example.com/kit-assets") assert assets_utils._resolve_asset_root() == "https://example.com/kit-assets" From 55ce7a3da9e854a9761a68005279a4bffc8da57c Mon Sep 17 00:00:00 2001 From: Sheikh Dawood <7774242+sheikh-nv@users.noreply.github.com> Date: Fri, 4 Sep 2026 16:10:21 +0000 Subject: [PATCH 4/5] Clarify asset region profile switchback --- docs/source/setup/installation/index.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/source/setup/installation/index.rst b/docs/source/setup/installation/index.rst index 3e17e6b0e050..9d859a41d86e 100644 --- a/docs/source/setup/installation/index.rst +++ b/docs/source/setup/installation/index.rst @@ -1138,8 +1138,7 @@ initialize the profile first: configure_asset_region_profile() -To return to the primary service, clear ``ISAACSIM_ASSET_ROOT`` and select the ``us`` profile for the -next process. You can leave the profile unset for later processes. +To return to the primary service, clear ``ISAACSIM_ASSET_ROOT`` and select the ``us`` profile. The ``china`` profile publishes an `asset availability manifest `__. From f4522ba5911f58b657cc2db186ebd42128d74a57 Mon Sep 17 00:00:00 2001 From: Sheikh Dawood <7774242+sheikh-nv@users.noreply.github.com> Date: Fri, 4 Sep 2026 16:20:39 +0000 Subject: [PATCH 5/5] Document asset region profile runtime selection --- docs/source/setup/installation/asset_caching_details.inc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/source/setup/installation/asset_caching_details.inc b/docs/source/setup/installation/asset_caching_details.inc index ed7895e6025f..a01109486093 100644 --- a/docs/source/setup/installation/asset_caching_details.inc +++ b/docs/source/setup/installation/asset_caching_details.inc @@ -75,8 +75,8 @@ root resolves to the same value when you use one of the provided Isaac Lab exper load ``isaacsim.storage.native``. A custom experience that does not build on one of them may leave the Isaac Sim asset root pointing at the cloud. -The environment variable is the only supported runtime override for the Isaac Lab asset paths. Isaac Lab -resolves them once, when :mod:`isaaclab.utils.assets` is imported, so setting +Isaac Lab supports the ``ISAACSIM_ASSET_ROOT`` and ``ISAACSIM_ASSET_REGION_PROFILE`` environment variables +for runtime asset selection. It resolves asset paths once, when :mod:`isaaclab.utils.assets` is imported, so setting ``persistent.isaac.asset_root.default`` on the command line or changing it at runtime does not move them, even though Isaac Sim itself honors those forms. Editing ``persistent.isaac.asset_root.default`` in the experience file does work, because that is the value Isaac Lab reads when the variable is unset.