# Copyright (c) 2022-2025, The Isaac Lab Project Developers.# All rights reserved.## SPDX-License-Identifier: BSD-3-Clause"""Sub-module that defines the host-server where assets and resources are stored.By default, we use the Isaac Sim Nucleus Server for hosting assets and resources. This makesdistribution of the assets easier and makes the repository smaller in size code-wise.For more information, please check information on `Omniverse Nucleus`_... _Omniverse Nucleus: https://docs.omniverse.nvidia.com/nucleus/latest/overview/overview.html"""importioimportosimporttempfilefromtypingimportLiteralimportcarbimportomni.clientNUCLEUS_ASSET_ROOT_DIR=carb.settings.get_settings().get("/persistent/isaac/asset_root/cloud")"""Path to the root directory on the Nucleus Server."""NVIDIA_NUCLEUS_DIR=f"{NUCLEUS_ASSET_ROOT_DIR}/NVIDIA""""Path to the root directory on the NVIDIA Nucleus Server."""ISAAC_NUCLEUS_DIR=f"{NUCLEUS_ASSET_ROOT_DIR}/Isaac""""Path to the ``Isaac`` directory on the NVIDIA Nucleus Server."""ISAACLAB_NUCLEUS_DIR=f"{ISAAC_NUCLEUS_DIR}/IsaacLab""""Path to the ``Isaac/IsaacLab`` directory on the NVIDIA Nucleus Server."""
[docs]defcheck_file_path(path:str)->Literal[0,1,2]:"""Checks if a file exists on the Nucleus Server or locally. Args: path: The path to the file. Returns: The status of the file. Possible values are listed below. * :obj:`0` if the file does not exist * :obj:`1` if the file exists locally * :obj:`2` if the file exists on the Nucleus Server """ifos.path.isfile(path):return1# we need to convert backslash to forward slash on Windows for omni.client APIelifomni.client.stat(path.replace(os.sep,"/"))[0]==omni.client.Result.OK:return2else:return0
[docs]defretrieve_file_path(path:str,download_dir:str|None=None,force_download:bool=True)->str:"""Retrieves the path to a file on the Nucleus Server or locally. If the file exists locally, then the absolute path to the file is returned. If the file exists on the Nucleus Server, then the file is downloaded to the local machine and the absolute path to the file is returned. Args: path: The path to the file. download_dir: The directory where the file should be downloaded. Defaults to None, in which case the file is downloaded to the system's temporary directory. force_download: Whether to force download the file from the Nucleus Server. This will overwrite the local file if it exists. Defaults to True. Returns: The path to the file on the local machine. Raises: FileNotFoundError: When the file not found locally or on Nucleus Server. RuntimeError: When the file cannot be copied from the Nucleus Server to the local machine. This can happen when the file already exists locally and :attr:`force_download` is set to False. """# check file statusfile_status=check_file_path(path)iffile_status==1:returnos.path.abspath(path)eliffile_status==2:# resolve download directoryifdownload_dirisNone:download_dir=tempfile.gettempdir()else:download_dir=os.path.abspath(download_dir)# create download directory if it does not existifnotos.path.exists(download_dir):os.makedirs(download_dir)# download file in temp directory using osfile_name=os.path.basename(omni.client.break_url(path.replace(os.sep,"/")).path)target_path=os.path.join(download_dir,file_name)# check if file already exists locallyifnotos.path.isfile(target_path)orforce_download:# copy file to local machineresult=omni.client.copy(path.replace(os.sep,"/"),target_path)ifresult!=omni.client.Result.OKandforce_download:raiseRuntimeError(f"Unable to copy file: '{path}'. Is the Nucleus Server running?")returnos.path.abspath(target_path)else:raiseFileNotFoundError(f"Unable to find the file: {path}")
[docs]defread_file(path:str)->io.BytesIO:"""Reads a file from the Nucleus Server or locally. Args: path: The path to the file. Raises: FileNotFoundError: When the file not found locally or on Nucleus Server. Returns: The content of the file. """# check file statusfile_status=check_file_path(path)iffile_status==1:withopen(path,"rb")asf:returnio.BytesIO(f.read())eliffile_status==2:file_content=omni.client.read_file(path.replace(os.sep,"/"))[2]returnio.BytesIO(memoryview(file_content).tobytes())else:raiseFileNotFoundError(f"Unable to find the file: {path}")