Pull Request 6949
本次pr包括代码逻辑、测试逻辑和文档撰写三部分。
打掉第一只野怪!金币+1,经验+3。
edit time: 2026-03-14 20:19:59
感悟:对ai工作流的优化
- codex用于处理环境配置等耗时的问题,并且负责整理整体代码结构(慢),
- deepseek用于快速问答、给我讲解我要做什么(快)。
代码逻辑
crates/tensorzero-core/src/config/mod.rs
这里从原来的 config 必须字面写出 endpoint 来源,修改为了可以支持传入 env::SOME_ENV ,在这里parse出 endpoint 来源。
具体而言,有三处:
- 把config的本地引用改为
mut,这样的话我们可以直接parse改成新值。 - 在进入后续逻辑之前,首先调用
resolve_object_storage_endpoint,执行我们添加的parse helper函数。 - 编写
resolve_object_storage_endpoint函数逻辑。
impl ObjectStoreInfo {
pub fn new(config: Option<StorageKind>) -> Result<Option<Self>, Error> {
let Some(mut config) = config else {
return Ok(None);
};
if let StorageKind::S3Compatible { endpoint, .. } = &mut config
&& let Some(endpoint_value) = endpoint.take()
{
*endpoint = Some(resolve_object_storage_endpoint(&endpoint_value)?);
}
let object_store: Option<Arc<dyn ObjectStore>> = match &config {
StorageKind::Filesystem { path } => {
Some(Arc::new(match LocalFileSystem::new_with_prefix(path) {
format!("{e:?}").contains("BadScheme")
}
fn resolve_object_storage_endpoint(endpoint: &str) -> Result<String, Error> {
if let Some(env_var) = endpoint.strip_prefix("env::") {
return std::env::var(env_var).map_err(|_| {
Error::new(ErrorDetails::Config {
message: format!(
"Environment variable `{env_var}` not found. Your configuration for `[object_storage]` requires this variable for `endpoint`."
),
})
});
}
if endpoint.starts_with("dynamic::")
|| endpoint.starts_with("path::")
|| endpoint.starts_with("path_from_env::")
|| matches!(endpoint, "sdk" | "none")
{
return Err(Error::new(ErrorDetails::Config {
message: format!(
"Invalid `[object_storage].endpoint`: `{endpoint}`. Use `env::ENVIRONMENT_VARIABLE` or a literal endpoint value."
),
}));
}
Ok(endpoint.to_string())
}
测试逻辑
crates/tensorzero-core/src/config/tests.rs
添加了三个单元测试。
use tempfile::NamedTempFile;
use toml::de::DeTable;
use crate::{
embeddings::EmbeddingProviderConfig,
inference::types::{Role, storage::StorageKind},
variant::JsonMode,
};
/// Ensure that the sample valid config can be parsed without panicking
#[tokio::test]
"Unexpected error message: {err}"
);
}
#[tokio::test]
async fn test_config_object_storage_endpoint_env_var_resolves() {
tensorzero_unsafe_helpers::set_env_var_tests_only(
"TENSORZERO_TEST_S3_ENDPOINT",
"https://storage.example.com",
);
let config_str = r#"
[object_storage]
type = "s3_compatible"
bucket_name = "tensorzero-fake-bucket"
region = "us-east-1"
endpoint = "env::TENSORZERO_TEST_S3_ENDPOINT"
[functions]"#;
let config = toml::from_str(config_str).expect("Failed to parse sample config");
let config = Box::pin(Config::load_from_toml(ConfigInput::Fresh(config)))
.await
.expect("Env-backed object storage endpoint should be valid config");
let object_store_info = config
.object_store_info
.as_ref()
.expect("Object store info should be initialized");
let StorageKind::S3Compatible { endpoint, .. } = &object_store_info.kind else {
panic!("Expected an S3-compatible object store");
};
assert_eq!(
endpoint.as_deref(),
Some("https://storage.example.com"),
"The resolved endpoint should be stored in the object store kind"
);
}
#[tokio::test]
async fn test_config_object_storage_endpoint_env_var_missing_errors() {
let config_str = r#"
[object_storage]
type = "s3_compatible"
bucket_name = "tensorzero-fake-bucket"
region = "us-east-1"
endpoint = "env::TENSORZERO_TEST_NONEXISTENT_S3_ENDPOINT_VAR"
[functions]"#;
let config = toml::from_str(config_str).expect("Failed to parse sample config");
let err = Box::pin(Config::load_from_toml(ConfigInput::Fresh(config)))
.await
.expect_err("Should error when the object storage endpoint env var is missing");
let err_msg = err.to_string();
assert!(
err_msg.contains("TENSORZERO_TEST_NONEXISTENT_S3_ENDPOINT_VAR"),
"Error should mention the missing env var: {err_msg}"
);
}
#[tokio::test]
async fn test_config_object_storage_endpoint_dynamic_rejected() {
let config_str = r#"
[object_storage]
type = "s3_compatible"
bucket_name = "tensorzero-fake-bucket"
region = "us-east-1"
endpoint = "dynamic::s3_endpoint"
[functions]"#;
let config = toml::from_str(config_str).expect("Failed to parse sample config");
let err = Box::pin(Config::load_from_toml(ConfigInput::Fresh(config)))
.await
.expect_err("Dynamic object storage endpoints should be rejected");
let err_msg = err.to_string();
assert!(
err_msg.contains("Invalid `[object_storage].endpoint`"),
"Error should point to the invalid object storage endpoint: {err_msg}"
);
assert!(
err_msg.contains("Use `env::ENVIRONMENT_VARIABLE` or a literal endpoint value"),
"Error should explain the supported endpoint forms: {err_msg}"
);
}
#[tokio::test]
async fn test_config_blocked_s3_http_endpoint_default() {
let logs_contain = crate::utils::testing::capture_logs();
文档撰写
docs/gateway/configuration-reference.mdx
添加了一行文档。
You can also set it to `env::YOUR_ENVIRONMENT_VARIABLE` to read from the environment variable `YOUR_ENVIRONMENT_VARIABLE` on startup.