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 <noreply@anthropic.com>
This commit is contained in:
yujonglee 2026-11-10 07:31:36 +09:00 • committed by GitHub
parent b09061b640
commit 3876802160
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 17 additions and 4 deletions

View file

@ -4423,6 +4423,7 @@ dependencies = [
"pyo3-async-runtimes",
"reqwest",
"rstest",
"rustls 0.23.42",
"serde",
"serde_json",
"serde_with",

View file

@ -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

View file

@ -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())
);
}
}

View file

@ -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

View file

@ -42,9 +42,6 @@ pub fn connect(
host: HostServices,
breaker: Option<Breaker>,
) -> Result<RedisClient, Error> {
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;