Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/docs/core/data_types.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ This is the list of all basic types supported by CocoIndex:
| float32 | `cocoindex.typing.Float32` |`float` |
| float64 | `cocoindex.typing.Float64` |`float` |
| range | `cocoindex.typing.Range` | `tuple[int, int]` |
| uuid | `uuid.UUId` | `uuid.UUID` |
| vector[*type*, *N*?] |`Annotated[list[type], cocoindex.typing.Vector(dim=N)]` | `list[type]` |
| json | `cocoindex.typing.Json` | Any type convertible to JSON by `json` package |

Expand Down Expand Up @@ -73,6 +74,7 @@ Currently, the following types are supported as types for key fields:
- `bool`
- `int64`
- `range`
- `uuid`
- Struct with all fields being key types

### Vector Type
Expand Down
6 changes: 6 additions & 0 deletions python/cocoindex/convert.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"""
import dataclasses
import inspect
import uuid

from typing import Any, Callable
from .typing import analyze_type_info, COLLECTION_TYPES
Expand All @@ -13,6 +14,8 @@ def to_engine_value(value: Any) -> Any:
return [to_engine_value(getattr(value, f.name)) for f in dataclasses.fields(value)]
if isinstance(value, (list, tuple)):
return [to_engine_value(v) for v in value]
if isinstance(value, uuid.UUID):
return value.bytes
return value

def make_engine_value_converter(
Expand Down Expand Up @@ -62,6 +65,9 @@ def make_engine_value_converter(
field_path.pop()
return lambda value: [elem_converter(v) for v in value] if value is not None else None

if src_type_kind == 'Uuid':
return lambda value: uuid.UUID(bytes=value)

return lambda value: value

def _make_engine_struct_value_converter(
Expand Down
3 changes: 3 additions & 0 deletions python/cocoindex/typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import dataclasses
import types
import inspect
import uuid
from typing import Annotated, NamedTuple, Any, TypeVar, TYPE_CHECKING, overload

class Vector(NamedTuple):
Expand Down Expand Up @@ -130,6 +131,8 @@ def analyze_type_info(t) -> AnalyzedTypeInfo:
kind = 'Int64'
elif t is float:
kind = 'Float64'
elif t is uuid.UUID:
kind = 'Uuid'
else:
raise ValueError(f"type unsupported yet: {t}")

Expand Down
22 changes: 10 additions & 12 deletions src/py/convert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,17 +63,14 @@ fn basic_value_to_py_object<'py>(
value::BasicValue::Int64(v) => v.into_bound_py_any(py)?,
value::BasicValue::Float32(v) => v.into_bound_py_any(py)?,
value::BasicValue::Float64(v) => v.into_bound_py_any(py)?,
value::BasicValue::Range(v) => pythonize(py, v).into_py_result()?,
value::BasicValue::Uuid(v) => v.as_bytes().into_bound_py_any(py)?,
value::BasicValue::Json(v) => pythonize(py, v).into_py_result()?,
value::BasicValue::Vector(v) => v
.iter()
.map(|v| basic_value_to_py_object(py, v))
.collect::<PyResult<Vec<_>>>()?
.into_bound_py_any(py)?,
_ => {
return Err(PyException::new_err(format!(
"unsupported value type: {}",
v.kind()
)))
}
};
Ok(result)
}
Expand Down Expand Up @@ -129,18 +126,19 @@ fn basic_value_from_py_object<'py>(
schema::BasicValueType::Int64 => value::BasicValue::Int64(v.extract::<i64>()?),
schema::BasicValueType::Float32 => value::BasicValue::Float32(v.extract::<f32>()?),
schema::BasicValueType::Float64 => value::BasicValue::Float64(v.extract::<f64>()?),
schema::BasicValueType::Range => value::BasicValue::Range(depythonize(v)?),
schema::BasicValueType::Uuid => {
value::BasicValue::Uuid(uuid::Uuid::from_bytes(v.extract::<uuid::Bytes>()?))
}
schema::BasicValueType::Json => {
value::BasicValue::Json(Arc::from(depythonize::<serde_json::Value>(v)?))
}
schema::BasicValueType::Vector(elem) => value::BasicValue::Vector(Arc::from(
v.extract::<Vec<Bound<'py, PyAny>>>()?
.into_iter()
.map(|v| basic_value_from_py_object(&elem.element_type, &v))
.collect::<PyResult<Vec<_>>>()?,
)),
_ => {
return Err(PyException::new_err(format!(
"unsupported value type: {}",
typ
)))
}
};
Ok(result)
}
Expand Down