Python Environment#

Developer Reference

This document will cover:

  • Details about how running standalone Python scripts works.

  • A short list of interesting/useful standalone Python scripts to try.

  • Resources to develop Python scripts for NVIDIA Isaac Sim, such as VSCode and Jupyter Notebook support.

Details: How python.sh works#

Note

  • On Windows use python.bat instead of python.sh

  • The details of how python.sh works below are similar to how python.bat works

This script first defines the location of the apps folder so the contained .kit files can be located at runtime.

# Get path to the script
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
# The apps directory is relative to where the script lives
export EXP_PATH=$SCRIPT_DIR/apps

Then we source the NVIDIA Isaac Sim Python environment so all extension interfaces can be loaded correctly.

source ${SCRIPT_DIR}/setup_python_env.sh

The setup_python_env.sh script update/defined the following environment variables:

  • ISAAC_PATH: Path to the main isaac folder

  • PYTHONPATH: Paths to each extensions Python interfaces

  • LD_LIBRARY_PATH: Paths to binary interfaces required to find symbols at runtime

  • CARB_APP_PATH: path to the core Omniverse kit executable

ROS 2 environment setup#

The python.sh and python.bat launchers also configure the bundled ROS 2 libraries when ROS_DISTRO is not set. On Linux, python.sh selects ROS 2 Humble on Ubuntu 22.04 and ROS 2 Jazzy on Ubuntu 24.04. On Windows, python.bat selects ROS 2 Jazzy.

On Linux, the launcher sets RMW_IMPLEMENTATION to rmw_fastrtps_cpp when it is unset and adds the selected bundled libraries to LD_LIBRARY_PATH. On Windows, the launcher defaults to rmw_zenoh_cpp, adds the bundled ROS 2 prefix to AMENT_PREFIX_PATH, and prepends the bundled libraries to PATH. Explicit environment settings are preserved.

Pass --no-ros-env before the script path to disable automatic ROS configuration. The launcher consumes this option, so the Python script does not receive it:

./python.sh --no-ros-env <path/to/standalone/script.py>

For manual ROS environment configuration and supported distribution details, see Configuring Options and Enabling Internal ROS Libraries.

Finally, we execute the Python interpreter that is packaged with Omniverse:

python_exe=${PYTHONEXE:-"${SCRIPT_DIR}/kit/python/bin/python3"}
...
$python_exe $@

SimulationApp#

The SimulationApp Class provides convenience functions to manage the lifetime of a NVIDIA Isaac Sim application.

Usage Example:#

The following code provides a usage example for how SimulationApp can be used to create an app, step forward in time and then exit.

Note

Any Omniverse level imports must occur after the class is instantiated. Because APIs are provided by the extension/runtime plugin system, it must be loaded before they will be available to import.

Important

When running headless:

  • Set "headless": True in the config when initializing SimulationApp

  • Any calls that create/open a matplotlib window need to be commented out

from isaacsim import SimulationApp

# Simple example showing how to start and stop the helper
simulation_app = SimulationApp({"headless": True})

### Perform any omniverse imports here after the helper loads ###

simulation_app.update()  # Render a single frame
simulation_app.close()  # Cleanup application

Details: How SimulationApp works#

Although SimulationApp further configures the application and exposes APIs, there are some fundamental steps in any Omniverse Kit-based implementation that must be executed.

The first is to get the carbonite framework. Here the environment variables (e.g.: CARB_APP_PATH, ISAAC_PATH and EXP_PATH) were defined when running the python.sh script.

import carb
import omni.kit.app

framework = carb.get_framework()
framework.load_plugins(
    loaded_file_wildcards=["omni.kit.app.plugin"],
    search_paths=[os.path.abspath(f'{os.environ["CARB_APP_PATH"]}/kernel/plugins')],
)

After loading the framework, it is possible to configure the start arguments before loading the application. For example:

# Inject a experience config
sys.argv.insert(1, f'{os.environ["EXP_PATH"]}/isaacsim.exp.base.python.kit')

# Add paths to extensions
sys.argv.append(f"--ext-folder")
sys.argv.append(f'{os.path.abspath(os.environ["ISAAC_PATH"])}/exts')

# Run headless
sys.argv.append("--no-window")

And then start the application.

app = omni.kit.app.get_app()
app.startup("Isaac-Sim", os.environ["CARB_APP_PATH"], sys.argv)

Shutting down a running application is done by calling shutdown and then unloading the framework:

app.shutdown()
framework.unload_all_plugins()

Enabling additional extensions#

There are two methods for adding additional extensions:

  1. Under [dependencies] section in an experience file (e.g.: apps/isaacsim.exp.base.python.kit):

    # [dependencies]
    # # Enable the layers and stage windows in the UI
    # "omni.kit.window.stage" = {}
    # "omni.kit.widget.layers" = {}
    
  2. From Python code:

    from isaacsim import SimulationApp
    
    # Start the application
    simulation_app = SimulationApp({"headless": False})
    
    # Get the utility to enable extensions
    from isaacsim.core.utils.extensions import enable_extension
    
    # Enable the layers and stage windows in the UI
    enable_extension("omni.kit.widget.stage")
    enable_extension("omni.kit.widget.layers")
    
    simulation_app.update()
    

Standalone Example Scripts#

Time Stepping#

This sample shows how to start an Omniverse Kit Python app and then create callbacks which get called each rendering frame and each physics timestep. It also shows the different ways to step physics and rendering.

The sample can be executed by running the following:

./python.sh standalone_examples/deprecated/api/isaacsim.core.api/time_stepping.py

Livestream#

This sample demonstrates how to enable livestreaming when running in native Python.

See Isaac Sim WebRTC Streaming Client for more information on running the client.

./python.sh standalone_examples/api/isaacsim.simulation_app/livestream.py

Note