diff --git a/rerun_py/rerun_sdk/rerun/__init__.py b/rerun_py/rerun_sdk/rerun/__init__.py index efcccb40766c..f58664c7f72a 100644 --- a/rerun_py/rerun_sdk/rerun/__init__.py +++ b/rerun_py/rerun_sdk/rerun/__init__.py @@ -306,10 +306,15 @@ def spawn(port: int = 9876, connect: bool = True) -> None: print("Rerun is disabled - spawn() call ignored") return + import os import subprocess import sys from time import sleep + # Let the spawned rerun process know it's just an app + new_env = os.environ.copy() + new_env["RERUN_APP_ONLY"] = "true" + # sys.executable: the absolute path of the executable binary for the Python interpreter python_executable = sys.executable if python_executable is None: @@ -317,7 +322,7 @@ def spawn(port: int = 9876, connect: bool = True) -> None: # start_new_session=True ensures the spawned process does NOT die when # we hit ctrl-c in the terminal running the parent Python process. - subprocess.Popen([python_executable, "-m", "rerun", "--port", str(port)], start_new_session=True) + subprocess.Popen([python_executable, "-m", "rerun", "--port", str(port)], env=new_env, start_new_session=True) # TODO(emilk): figure out a way to postpone connecting until the rerun viewer is listening. # For example, wait until it prints "Hosting a SDK server over TCP at …" diff --git a/rerun_py/src/python_bridge.rs b/rerun_py/src/python_bridge.rs index 0437757f6b3f..d42f3ef61a1a 100644 --- a/rerun_py/src/python_bridge.rs +++ b/rerun_py/src/python_bridge.rs @@ -107,6 +107,21 @@ fn rerun_bindings(py: Python<'_>, m: &PyModule) -> PyResult<()> { // called more than once. re_log::setup_native_logging(); + // We always want main to be available + m.add_function(wrap_pyfunction!(main, m)?)?; + + // These two components are necessary for imports to work + // TODO(jleibs): Refactor import logic so all we need is main + m.add_function(wrap_pyfunction!(get_registered_component_names, m)?)?; + m.add_class::()?; + + // If this is a special RERUN_APP_ONLY context (launched via .spawn), we + // can bypass everything else, which keeps us from preparing an SDK session + // that never gets used. + if matches!(std::env::var("RERUN_APP_ONLY").as_deref(), Ok("true")) { + return Ok(()); + } + python_session().set_python_version(python_version(py)); // NOTE: We do this here because we want child processes to share the same recording-id, @@ -114,10 +129,6 @@ fn rerun_bindings(py: Python<'_>, m: &PyModule) -> PyResult<()> { // See `default_recording_id` for extra information. python_session().set_recording_id(default_recording_id(py)); - m.add_function(wrap_pyfunction!(main, m)?)?; - - m.add_function(wrap_pyfunction!(get_registered_component_names, m)?)?; - m.add_function(wrap_pyfunction!(get_recording_id, m)?)?; m.add_function(wrap_pyfunction!(set_recording_id, m)?)?; @@ -150,8 +161,6 @@ fn rerun_bindings(py: Python<'_>, m: &PyModule) -> PyResult<()> { m.add_function(wrap_pyfunction!(log_cleared, m)?)?; m.add_function(wrap_pyfunction!(log_arrow_msg, m)?)?; - m.add_class::()?; - Ok(()) }