From 3876802160f4298f59f52d91df1da0aef2bf3ddf Mon Sep 17 00:00:00 2001 From: yujonglee Date: Tue, 10 Nov 2026 07:31:36 +0900 Subject: [PATCH] fix(rust): install the rustls crypto provider at the Python host boundary (#50502) python-bridge now installs ring in its pymodule_init, matching the gateway's startup install. redis-connect no longer sets the process default as a side effect of connecting, so a dependency that calls ClientConfig::builder() without a provider cannot panic on the Python host depending on whether Redis has connected yet Co-authored-by: Claude Opus 5.5 --- litellm-rust/Cargo.lock | 1 + litellm-rust/crates/python-bridge/Cargo.toml | 1 + litellm-rust/crates/python-bridge/src/lib.rs | 15 +++++++++++++++ litellm-rust/crates/redis-connect/Cargo.toml | 1 - litellm-rust/crates/redis-connect/src/connect.rs | 3 --- 5 files changed, 17 insertions(+), 4 deletions(-) diff --git a/litellm-rust/Cargo.lock b/litellm-rust/Cargo.lock index 48b6730b0c6..c20454c7058 100644 --- a/litellm-rust/Cargo.lock +++ b/litellm-rust/Cargo.lock @@ -4423,6 +4423,7 @@ dependencies = [ "pyo3-async-runtimes", "reqwest", "rstest", + "rustls 0.23.42", "serde", "serde_json", "serde_with", diff --git a/litellm-rust/crates/python-bridge/Cargo.toml b/litellm-rust/crates/python-bridge/Cargo.toml index 6ecfebf0096..79773ca5559 100644 --- a/litellm-rust/crates/python-bridge/Cargo.toml +++ b/litellm-rust/crates/python-bridge/Cargo.toml @@ -19,6 +19,7 @@ huggingface = ["litellm-token-counter/huggingface"] tiktoken = ["litellm-token-counter/tiktoken"] [dependencies] +rustls.workspace = true litellm-secret-value.workspace = true fancy-regex.workspace = true litellm-tracing.workspace = true diff --git a/litellm-rust/crates/python-bridge/src/lib.rs b/litellm-rust/crates/python-bridge/src/lib.rs index 0883dfa7d31..7513ff6b87b 100644 --- a/litellm-rust/crates/python-bridge/src/lib.rs +++ b/litellm-rust/crates/python-bridge/src/lib.rs @@ -92,6 +92,7 @@ mod _native { #[pymodule_init] fn init(module: &Bound<'_, PyModule>) -> PyResult<()> { + let _ = rustls::crypto::ring::default_provider().install_default(); let py = module.py(); let dict = module.dict(); dict.set_item( @@ -189,4 +190,18 @@ mod tests { assert_eq!(public_names, expected); }); } + #[rstest::rstest] + fn module_import_installs_ring_as_the_process_crypto_provider() { + Python::initialize(); + Python::attach(|py| { + native_module(py); + }); + + let installed = rustls::crypto::CryptoProvider::get_default() + .expect("importing _native should install a process crypto provider"); + assert_eq!( + format!("{installed:?}"), + format!("{:?}", rustls::crypto::ring::default_provider()) + ); + } } diff --git a/litellm-rust/crates/redis-connect/Cargo.toml b/litellm-rust/crates/redis-connect/Cargo.toml index 72a453d36de..29b3293b856 100644 --- a/litellm-rust/crates/redis-connect/Cargo.toml +++ b/litellm-rust/crates/redis-connect/Cargo.toml @@ -17,7 +17,6 @@ litellm-circuit-breaker.workspace = true litellm-redis-types.workspace = true litellm-core-utils.workspace = true litellm-http.workspace = true -rustls.workspace = true litellm-redis-client.workspace = true futures-util.workspace = true serde.workspace = true diff --git a/litellm-rust/crates/redis-connect/src/connect.rs b/litellm-rust/crates/redis-connect/src/connect.rs index cf7fe2334d5..d11f6ba47ff 100644 --- a/litellm-rust/crates/redis-connect/src/connect.rs +++ b/litellm-rust/crates/redis-connect/src/connect.rs @@ -42,9 +42,6 @@ pub fn connect( host: HostServices, breaker: Option, ) -> Result { - if rustls::crypto::CryptoProvider::get_default().is_none() { - let _ = rustls::crypto::ring::default_provider().install_default(); - } tracing::info!(target = ?resolved.target, namespace = ?resolved.namespace, "redis client configured"); let credentials = credentials(resolved.auth, &host)?; let events = host.events;