From 93e81ab40f85020d51415d1183cd6dd2fcaa2a3a Mon Sep 17 00:00:00 2001 From: Luke <58807644+munday-tech@users.noreply.github.com> Date: Thu, 25 Jul 2024 18:29:59 +1000 Subject: [PATCH 1/6] Fix langchain_aws Decimal errors Add functions to convert floats to decimal and decimals to float to fix TypeErrors causes when using ChatBedrock --- backend/chainlit/data/dynamodb.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/backend/chainlit/data/dynamodb.py b/backend/chainlit/data/dynamodb.py index 0b63614318..8b09208761 100644 --- a/backend/chainlit/data/dynamodb.py +++ b/backend/chainlit/data/dynamodb.py @@ -3,6 +3,7 @@ import logging import os import random +from decimal import Decimal from dataclasses import asdict from datetime import datetime from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union @@ -71,6 +72,32 @@ def _deserialize_item(self, item: Dict[str, Any]) -> Dict[str, Any]: for key, value in item.items() } + def _convert_floats_to_decimal(self, obj): + if isinstance(obj, dict): + for key, value in obj.items(): + if isinstance(value, float): + obj[key] = Decimal(str(value)) + elif isinstance(value, dict): + self._convert_floats_to_decimal(value) + elif isinstance(value, list): + obj[key] = [self._convert_floats_to_decimal(i) for i in value] + elif isinstance(obj, list): + return [self._convert_floats_to_decimal(i) for i in obj] + return obj + + def _convert_decimal_to_floats(self, obj): + if isinstance(obj, dict): + for key, value in obj.items(): + if isinstance(value, Decimal): + obj[key] = float(value) + elif isinstance(value, dict): + self._convert_decimal_to_floats(value) + elif isinstance(value, list): + obj[key] = [self._convert_decimal_to_floats(i) for i in value] + elif isinstance(obj, list): + return [self._convert_decimal_to_floats(i) for i in obj] + return obj + def _update_item(self, key: Dict[str, Any], updates: Dict[str, Any]): update_expr: List[str] = [] expression_attribute_names = {} @@ -83,6 +110,8 @@ def _update_item(self, key: Dict[str, Any], updates: Dict[str, Any]): k, v = f"#{index}", f":{index}" update_expr.append(f"{k} = {v}") expression_attribute_names[k] = attr + if isinstance(value, dict): + value = self._convert_floats_to_decimal(value) expression_attribute_values[v] = value self.client.update_item( @@ -510,6 +539,7 @@ async def get_thread(self, thread_id: str) -> "Optional[ThreadDict]": steps = [] elements = [] + thread_items = self._convert_decimal_to_floats(thread_items) for item in thread_items: if item["SK"] == "THREAD": thread_dict = item From 0f516158dc20ec53c767d836033625448144fdcb Mon Sep 17 00:00:00 2001 From: Luke <58807644+munday-tech@users.noreply.github.com> Date: Thu, 25 Jul 2024 18:40:00 +1000 Subject: [PATCH 2/6] fix: update type check --- backend/chainlit/data/dynamodb.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/chainlit/data/dynamodb.py b/backend/chainlit/data/dynamodb.py index 8b09208761..f79bfc68da 100644 --- a/backend/chainlit/data/dynamodb.py +++ b/backend/chainlit/data/dynamodb.py @@ -110,7 +110,7 @@ def _update_item(self, key: Dict[str, Any], updates: Dict[str, Any]): k, v = f"#{index}", f":{index}" update_expr.append(f"{k} = {v}") expression_attribute_names[k] = attr - if isinstance(value, dict): + if isinstance(value, (dict, list)): value = self._convert_floats_to_decimal(value) expression_attribute_values[v] = value From c1b313fc1b4ca938298f2368b729ab1162483cb6 Mon Sep 17 00:00:00 2001 From: Luke <58807644+munday-tech@users.noreply.github.com> Date: Sun, 28 Jul 2024 00:04:58 +1000 Subject: [PATCH 3/6] Update backend/chainlit/data/dynamodb.py Co-authored-by: Mayaank Vadlamani --- backend/chainlit/data/dynamodb.py | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/backend/chainlit/data/dynamodb.py b/backend/chainlit/data/dynamodb.py index f79bfc68da..088191803a 100644 --- a/backend/chainlit/data/dynamodb.py +++ b/backend/chainlit/data/dynamodb.py @@ -86,16 +86,20 @@ def _convert_floats_to_decimal(self, obj): return obj def _convert_decimal_to_floats(self, obj): - if isinstance(obj, dict): - for key, value in obj.items(): - if isinstance(value, Decimal): - obj[key] = float(value) - elif isinstance(value, dict): - self._convert_decimal_to_floats(value) - elif isinstance(value, list): - obj[key] = [self._convert_decimal_to_floats(i) for i in value] - elif isinstance(obj, list): + if isinstance(obj, list): return [self._convert_decimal_to_floats(i) for i in obj] + + if not isinstance(obj, dict): + return obj + + for key, value in obj.items(): + if isinstance(value, Decimal): + obj[key] = float(value) + elif isinstance(value, dict): + self._convert_decimal_to_floats(value) + elif isinstance(value, list): + obj[key] = [self._convert_decimal_to_floats(i) for i in value] + return obj def _update_item(self, key: Dict[str, Any], updates: Dict[str, Any]): From 67a57d034514f4d533e23bf0fca7711ab8da5e6e Mon Sep 17 00:00:00 2001 From: Luke <58807644+munday-tech@users.noreply.github.com> Date: Sun, 28 Jul 2024 00:05:03 +1000 Subject: [PATCH 4/6] Update backend/chainlit/data/dynamodb.py Co-authored-by: Mayaank Vadlamani --- backend/chainlit/data/dynamodb.py | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/backend/chainlit/data/dynamodb.py b/backend/chainlit/data/dynamodb.py index 088191803a..81f14d7895 100644 --- a/backend/chainlit/data/dynamodb.py +++ b/backend/chainlit/data/dynamodb.py @@ -73,16 +73,20 @@ def _deserialize_item(self, item: Dict[str, Any]) -> Dict[str, Any]: } def _convert_floats_to_decimal(self, obj): - if isinstance(obj, dict): - for key, value in obj.items(): - if isinstance(value, float): - obj[key] = Decimal(str(value)) - elif isinstance(value, dict): - self._convert_floats_to_decimal(value) - elif isinstance(value, list): - obj[key] = [self._convert_floats_to_decimal(i) for i in value] - elif isinstance(obj, list): + if isinstance(obj, list): return [self._convert_floats_to_decimal(i) for i in obj] + + if not isinstance(obj, dict): + return obj + + for key, value in obj.items(): + if isinstance(value, float): + obj[key] = Decimal(str(value)) + elif isinstance(value, dict): + self._convert_floats_to_decimal(value) + elif isinstance(value, list): + obj[key] = [self._convert_floats_to_decimal(i) for i in value] + return obj def _convert_decimal_to_floats(self, obj): From 64646d58a8cf6fb827d1fc32aab4a27d8187becc Mon Sep 17 00:00:00 2001 From: Luke <58807644+munday-tech@users.noreply.github.com> Date: Sun, 28 Jul 2024 00:22:55 +1000 Subject: [PATCH 5/6] Move function calls to sterilization calls --- backend/chainlit/data/dynamodb.py | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/backend/chainlit/data/dynamodb.py b/backend/chainlit/data/dynamodb.py index 81f14d7895..c65d9d6510 100644 --- a/backend/chainlit/data/dynamodb.py +++ b/backend/chainlit/data/dynamodb.py @@ -61,17 +61,6 @@ def __init__( def _get_current_timestamp(self) -> str: return datetime.now().isoformat() + "Z" - def _serialize_item(self, item: Dict[str, Any]) -> Dict[str, Any]: - return { - key: self._type_serializer.serialize(value) for key, value in item.items() - } - - def _deserialize_item(self, item: Dict[str, Any]) -> Dict[str, Any]: - return { - key: self._type_deserializer.deserialize(value) - for key, value in item.items() - } - def _convert_floats_to_decimal(self, obj): if isinstance(obj, list): return [self._convert_floats_to_decimal(i) for i in obj] @@ -104,6 +93,21 @@ def _convert_decimal_to_floats(self, obj): elif isinstance(value, list): obj[key] = [self._convert_decimal_to_floats(i) for i in value] + def _serialize_item(self, item: Dict[str, Any]) -> Dict[str, Any]: + item = self._convert_floats_to_decimal(item) + return { + key: self._type_serializer.serialize(value) + for key, value in item.items() + } + + def _deserialize_item(self, item: Dict[str, Any]) -> Dict[str, Any]: + item = self._convert_decimal_to_floats(item) + return { + key: self._type_deserializer.deserialize(value) + for key, value in item.items() + } + + return obj def _update_item(self, key: Dict[str, Any], updates: Dict[str, Any]): @@ -118,8 +122,6 @@ def _update_item(self, key: Dict[str, Any], updates: Dict[str, Any]): k, v = f"#{index}", f":{index}" update_expr.append(f"{k} = {v}") expression_attribute_names[k] = attr - if isinstance(value, (dict, list)): - value = self._convert_floats_to_decimal(value) expression_attribute_values[v] = value self.client.update_item( @@ -547,7 +549,6 @@ async def get_thread(self, thread_id: str) -> "Optional[ThreadDict]": steps = [] elements = [] - thread_items = self._convert_decimal_to_floats(thread_items) for item in thread_items: if item["SK"] == "THREAD": thread_dict = item From 6ecb06a1b63cee284d584e149c00f0dc06c4f0cd Mon Sep 17 00:00:00 2001 From: Luke <58807644+munday-tech@users.noreply.github.com> Date: Mon, 12 Aug 2024 20:46:35 +1000 Subject: [PATCH 6/6] fix mypy --- backend/chainlit/data/dynamodb.py | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/backend/chainlit/data/dynamodb.py b/backend/chainlit/data/dynamodb.py index c65d9d6510..1ed49daf61 100644 --- a/backend/chainlit/data/dynamodb.py +++ b/backend/chainlit/data/dynamodb.py @@ -65,9 +65,6 @@ def _convert_floats_to_decimal(self, obj): if isinstance(obj, list): return [self._convert_floats_to_decimal(i) for i in obj] - if not isinstance(obj, dict): - return obj - for key, value in obj.items(): if isinstance(value, float): obj[key] = Decimal(str(value)) @@ -82,9 +79,6 @@ def _convert_decimal_to_floats(self, obj): if isinstance(obj, list): return [self._convert_decimal_to_floats(i) for i in obj] - if not isinstance(obj, dict): - return obj - for key, value in obj.items(): if isinstance(value, Decimal): obj[key] = float(value) @@ -93,6 +87,8 @@ def _convert_decimal_to_floats(self, obj): elif isinstance(value, list): obj[key] = [self._convert_decimal_to_floats(i) for i in value] + return obj + def _serialize_item(self, item: Dict[str, Any]) -> Dict[str, Any]: item = self._convert_floats_to_decimal(item) return { @@ -108,8 +104,6 @@ def _deserialize_item(self, item: Dict[str, Any]) -> Dict[str, Any]: } - return obj - def _update_item(self, key: Dict[str, Any], updates: Dict[str, Any]): update_expr: List[str] = [] expression_attribute_names = {}