Repository: tensorzero/tensorzero (language: rust)

Issue:
Log a warning when you call `build_embedded` but don't provide a config
Like we do with the gateway:

```
        tracing::warn!("No config file provided, so only default functions will be available. Use `--config-file path/to/tensorzero.toml` to specify a config file.");
```

So:

```
No config file provided, so only default functions will be available. Use `config_file="path/to/tensorzero.toml"` to specify a config file.
```


Discussion / hints:

Fix patch:
diff --git a/clients/python-pyo3/src/lib.rs b/clients/python-pyo3/src/lib.rs
index c331682f4..3f8f33369 100644
--- a/clients/python-pyo3/src/lib.rs
+++ b/clients/python-pyo3/src/lib.rs
@@ -13,6 +13,7 @@ use std::{collections::HashMap, future::Future, path::PathBuf, sync::Arc, time::
 use futures::StreamExt;
 use pyo3::{
     exceptions::{PyStopAsyncIteration, PyStopIteration, PyValueError},
+    ffi::c_str,
     marker::Ungil,
     prelude::*,
     sync::GILOnceCell,
@@ -413,6 +414,7 @@ impl TensorZeroGateway {
         config_path: Option<&str>,
         clickhouse_url: Option<String>,
     ) -> PyResult<Py<TensorZeroGateway>> {
+        warn_no_config(cls.py(), config_path)?;
         let client_fut = ClientBuilder::new(ClientBuilderMode::EmbeddedGateway {
             config_path: config_path.map(PathBuf::from),
             clickhouse_url,
@@ -662,6 +664,7 @@ impl AsyncTensorZeroGateway {
         config_path: Option<&str>,
         clickhouse_url: Option<String>,
     ) -> PyResult<Bound<'a, PyAny>> {
+        warn_no_config(cls.py(), config_path)?;
         let client_fut = ClientBuilder::new(ClientBuilderMode::EmbeddedGateway {
             config_path: config_path.map(PathBuf::from),
             clickhouse_url,
@@ -866,3 +869,15 @@ fn tensorzero_internal_error(py: Python<'_>, msg: &str) -> PyResult<PyErr> {
     })?;
     Ok(PyErr::from_value(err.bind(py).call1((msg,))?))
 }
+
+fn warn_no_config(py: Python<'_>, config: Option<&str>) -> PyResult<()> {
+    if config.is_none() {
+        let user_warning = py.get_type::<pyo3::exceptions::PyUserWarning>();
+        PyErr::warn(
+            py,
+            &user_warning,
+            c_str!("No config file provided, so only default functions will be available. Use `config_file=\"path/to/tensorzero.toml\"` to specify a config file."), 0
+        )?;
+    }
+    Ok(())
+}
diff --git a/clients/python-pyo3/uv.lock b/clients/python-pyo3/uv.lock
index 66e17641a..dde325977 100644
--- a/clients/python-pyo3/uv.lock
+++ b/clients/python-pyo3/uv.lock
@@ -91,7 +91,6 @@ wheels = [
 
 [[package]]
 name = "tensorzero"
-version = "0.1.0"
 source = { editable = "." }
 dependencies = [
     { name = "httpx" },


Test patch:
diff --git a/clients/python-pyo3/tests/test_client.py b/clients/python-pyo3/tests/test_client.py
index e5ca70bb5..b03f9e024 100644
--- a/clients/python-pyo3/tests/test_client.py
+++ b/clients/python-pyo3/tests/test_client.py
@@ -70,9 +70,10 @@ async def async_client(request):
 
 
 def test_sync_embedded_gateway_no_config():
+    with pytest.warns(UserWarning, match="No config file provided"):
+        client = TensorZeroGateway.build_embedded()
     with pytest.raises(TensorZeroError) as exc_info:
-        with TensorZeroGateway.build_embedded() as client:
-            client.inference(function_name="my_missing_func", input={})
+        client.inference(function_name="my_missing_func", input={})
 
     assert exc_info.value.status_code == 404
     assert exc_info.value.text == '{"error":"Unknown function: my_missing_func"}'
@@ -80,9 +81,10 @@ def test_sync_embedded_gateway_no_config():
 
 @pytest.mark.asyncio
 async def test_async_embedded_gateway_no_config():
+    with pytest.warns(UserWarning, match="No config file provided"):
+        client = await AsyncTensorZeroGateway.build_embedded()
     with pytest.raises(TensorZeroError) as exc_info:
-        async with await AsyncTensorZeroGateway.build_embedded() as client:
-            await client.inference(function_name="my_missing_func", input={})
+        await client.inference(function_name="my_missing_func", input={})
 
     assert exc_info.value.status_code == 404
     assert exc_info.value.text == '{"error":"Unknown function: my_missing_func"}'