From b866142587d2eaccde77f9fe327e4251f3168baf Mon Sep 17 00:00:00 2001 From: Mattias Lundell Date: Mon, 26 May 2025 16:10:23 +0200 Subject: [PATCH] fix: allow for using datetime in list, dict and pydantic model --- pyproject.toml | 2 +- src/opperai/core/utils/__init__.py | 4 +- tests/test_utils.py | 78 ++++++++++++++++++++++++++++++ 3 files changed, 82 insertions(+), 2 deletions(-) create mode 100644 tests/test_utils.py diff --git a/pyproject.toml b/pyproject.toml index 78d267b..2ccc8ed 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "opperai" -version = "0.31.3" +version = "0.31.4" description = "Opper Python client" authors = [{ name = "Opper", email = "support@opper.ai" }] requires-python = "~=3.9" diff --git a/src/opperai/core/utils/__init__.py b/src/opperai/core/utils/__init__.py index a8abe7b..c3bb2b9 100644 --- a/src/opperai/core/utils/__init__.py +++ b/src/opperai/core/utils/__init__.py @@ -19,8 +19,10 @@ def convert_function_call_to_json(func, *args, **kwargs): def prepare_input(input: Any) -> Any: if isinstance(input, str): return input + elif isinstance(input, datetime): + return input.isoformat() elif isinstance(input, BaseModel): - return input.model_dump(exclude_none=True) + return input.model_dump(exclude_none=True, mode="json") elif isinstance(input, list): _input = [prepare_input(item) for item in input] return _input diff --git a/tests/test_utils.py b/tests/test_utils.py new file mode 100644 index 0000000..b4a78a0 --- /dev/null +++ b/tests/test_utils.py @@ -0,0 +1,78 @@ +from datetime import datetime +from typing import Optional + +from pydantic import BaseModel + +from opperai.core.utils import prepare_input + + +class TestUtils: + class TestPrepareInput: + def test_prepare_input(self): + # test basic functionality with various types + assert prepare_input("hello") == "hello" + assert prepare_input(42) == 42 + assert prepare_input(True) is True + + def test_prepare_input_with_datetime(self): + dt = datetime(2023, 1, 1, 12, 0, 0) + result = prepare_input(dt) + assert result == "2023-01-01T12:00:00" + + def test_prepare_input_with_pydantic_model(self): + class TestModel(BaseModel): + name: str + age: int + email: Optional[str] = None + date: datetime + + dt = datetime(2023, 1, 1, 12, 0, 0) + model = TestModel(name="john", age=30, date=dt) + result = prepare_input(model) + expected = { + "name": "john", + "age": 30, + "date": "2023-01-01T12:00:00", + } + assert result == expected + + def test_prepare_input_with_list(self): + dt = datetime(2023, 1, 1, 12, 0, 0) + input_list = ["hello", 42, dt, True] + result = prepare_input(input_list) + expected = ["hello", 42, "2023-01-01T12:00:00", True] + assert result == expected + + def test_prepare_input_with_dict(self): + dt = datetime(2023, 1, 1, 12, 0, 0) + input_dict = {"text": "hello", "number": 42, "date": dt, "flag": True} + result = prepare_input(input_dict) + expected = { + "text": "hello", + "number": 42, + "date": "2023-01-01T12:00:00", + "flag": True, + } + assert result == expected + + def test_prepare_input_with_none(self): + result = prepare_input(None) + assert result is None + + def test_prepare_input_with_int(self): + result = prepare_input(42) + assert result == 42 + + def test_prepare_input_with_float(self): + result = prepare_input(3.14) + assert result == 3.14 + + def test_prepare_input_with_bool(self): + result = prepare_input(True) + assert result is True + result = prepare_input(False) + assert result is False + + def test_prepare_input_with_str(self): + result = prepare_input("hello world") + assert result == "hello world"