-
Notifications
You must be signed in to change notification settings - Fork 83
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Rust implementation for Python client's update_run()
method.
#1314
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -46,43 +46,43 @@ impl FromPyObject<'_> for RunCreateExtended { | |
} | ||
} | ||
|
||
fn extract_attachments(value: &Bound<'_, PyAny>) -> PyResult<Option<Vec<Attachment>>> { | ||
if value.is_none() { | ||
return Ok(None); | ||
} | ||
|
||
let mapping = value.downcast::<PyMapping>()?; | ||
#[derive(Debug)] | ||
pub struct RunUpdateExtended(langsmith_tracing_client::client::RunUpdateExtended); | ||
|
||
let size = mapping.len()?; | ||
if size == 0 { | ||
return Ok(None); | ||
impl RunUpdateExtended { | ||
#[inline] | ||
pub(crate) fn into_inner(self) -> langsmith_tracing_client::client::RunUpdateExtended { | ||
self.0 | ||
} | ||
} | ||
|
||
let mut attachments = Vec::with_capacity(size); | ||
|
||
for result in mapping.items()?.iter()? { | ||
let key_value_pair = result?; | ||
|
||
let key_item = key_value_pair.get_item(0)?; | ||
let key = key_item.extract::<&str>()?; | ||
impl FromPyObject<'_> for RunUpdateExtended { | ||
fn extract_bound(value: &Bound<'_, PyAny>) -> PyResult<Self> { | ||
let run_update = value.extract::<RunUpdate>()?.into_inner(); | ||
|
||
// TODO: attachments are WIP at the moment, ignore them here for now. | ||
// | ||
// let attachments = { | ||
// if let Ok(attachments_value) = value.get_item(pyo3::intern!(value.py(), "attachments")) | ||
// { | ||
// extract_attachments(&attachments_value)? | ||
// } else { | ||
// None | ||
// } | ||
// }; | ||
let attachments = None; | ||
|
||
// Each value in the attachments dict is a (mime_type, bytes) tuple. | ||
let value = key_value_pair.get_item(1)?; | ||
let value_tuple = value.downcast_exact::<PyTuple>()?; | ||
let mime_type_value = value_tuple.get_item(0)?; | ||
let bytes_value = value_tuple.get_item(1)?; | ||
let io = RunIO { | ||
inputs: serialize_optional_dict_value(value, pyo3::intern!(value.py(), "inputs"))?, | ||
outputs: serialize_optional_dict_value(value, pyo3::intern!(value.py(), "outputs"))?, | ||
}; | ||
|
||
attachments.push(Attachment { | ||
// TODO: It's unclear whether the key in the attachments dict is | ||
// the `filename`` or the `ref_name`, and where the other one is coming from. | ||
ref_name: key.to_string(), | ||
filename: key.to_string(), | ||
data: bytes_value.extract()?, | ||
content_type: mime_type_value.extract()?, | ||
}); | ||
Ok(Self(langsmith_tracing_client::client::RunUpdateExtended { | ||
run_update, | ||
io, | ||
attachments, | ||
})) | ||
} | ||
|
||
Ok(Some(attachments)) | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I just moved this function down, to keep all the type definitions next to each other in the file. Otherwise it remained unchanged. |
||
|
||
#[derive(Debug)] | ||
|
@@ -137,6 +137,26 @@ impl FromPyObject<'_> for RunCreate { | |
} | ||
} | ||
|
||
#[derive(Debug)] | ||
pub(crate) struct RunUpdate(langsmith_tracing_client::client::RunUpdate); | ||
|
||
impl FromPyObject<'_> for RunUpdate { | ||
fn extract_bound(value: &Bound<'_, PyAny>) -> PyResult<Self> { | ||
let common = RunCommon::extract_bound(value)?.into_inner(); | ||
|
||
let end_time = extract_time_value(&value.get_item(pyo3::intern!(value.py(), "end_time"))?)?; | ||
|
||
Ok(Self(langsmith_tracing_client::client::RunUpdate { common, end_time })) | ||
} | ||
} | ||
|
||
impl RunUpdate { | ||
#[inline] | ||
pub(crate) fn into_inner(self) -> langsmith_tracing_client::client::RunUpdate { | ||
self.0 | ||
} | ||
} | ||
|
||
#[derive(Debug)] | ||
pub(crate) struct RunCommon(langsmith_tracing_client::client::RunCommon); | ||
|
||
|
@@ -196,6 +216,45 @@ impl FromPyObject<'_> for RunCommon { | |
} | ||
} | ||
|
||
fn extract_attachments(value: &Bound<'_, PyAny>) -> PyResult<Option<Vec<Attachment>>> { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This function is unchanged, just moved farther down in the same file. |
||
if value.is_none() { | ||
return Ok(None); | ||
} | ||
|
||
let mapping = value.downcast::<PyMapping>()?; | ||
|
||
let size = mapping.len()?; | ||
if size == 0 { | ||
return Ok(None); | ||
} | ||
|
||
let mut attachments = Vec::with_capacity(size); | ||
|
||
for result in mapping.items()?.iter()? { | ||
let key_value_pair = result?; | ||
|
||
let key_item = key_value_pair.get_item(0)?; | ||
let key = key_item.extract::<&str>()?; | ||
|
||
// Each value in the attachments dict is a (mime_type, bytes) tuple. | ||
let value = key_value_pair.get_item(1)?; | ||
let value_tuple = value.downcast_exact::<PyTuple>()?; | ||
let mime_type_value = value_tuple.get_item(0)?; | ||
let bytes_value = value_tuple.get_item(1)?; | ||
|
||
attachments.push(Attachment { | ||
// TODO: It's unclear whether the key in the attachments dict is | ||
// the `filename`` or the `ref_name`, and where the other one is coming from. | ||
ref_name: key.to_string(), | ||
filename: key.to_string(), | ||
Comment on lines
+248
to
+249
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it's the ref_name There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The attachments dict is |
||
data: bytes_value.extract()?, | ||
content_type: mime_type_value.extract()?, | ||
}); | ||
} | ||
|
||
Ok(Some(attachments)) | ||
} | ||
|
||
/// Get an optional string from a Python `None`, string, or string-like object such as a UUID value. | ||
fn extract_string_like_or_none(value: Option<&Bound<'_, PyAny>>) -> PyResult<Option<String>> { | ||
match value { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The GIL info here was outdated, so I removed it. The current implementation drops the GIL explicitly by calling
allow_threads()
.