chainlit icon indicating copy to clipboard operation
chainlit copied to clipboard

TypeError on float when using DynamoDBDataLayer

Open jc-magnan opened this issue 1 year ago • 2 comments
trafficstars

Describe the bug Context: Chatbot using Anthropic's Claude Sonnet via AWS Bedrock. DynamoDBDataLayer (with S3 storage) is added to keep track of conversations.

What happens: During the call to DynamoDBDataLayer._update_item to upload bot answer (after answer has been displayed in chat), a TypeError is raised in boto3 dynamodb module. Here is the stack trace

future: <Task finished name='Task-476' coro=<DynamoDBDataLayer.update_step() done, defined at /home/jmagnan/workspace/puy-du-fou/poc-bot-lgr/bot/modules/front/app/.venv/lib/python3.11/site-packages/chainlit/data/__init__.py:44> exception=TypeError('Float types are not supported. Use Decimal types instead.')>
Traceback (most recent call last):
  File "/usr/lib/python3.11/asyncio/tasks.py", line 277, in __step
    result = coro.send(None)
             ^^^^^^^^^^^^^^^
  File "/home/jmagnan/workspace/puy-du-fou/poc-bot-lgr/bot/modules/front/app/.venv/lib/python3.11/site-packages/chainlit/data/__init__.py", line 59, in wrapper
    return await method(self, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/jmagnan/workspace/puy-du-fou/poc-bot-lgr/bot/modules/front/app/.venv/lib/python3.11/site-packages/chainlit/data/dynamodb.py", line 345, in update_step
    self._update_item(
  File "/home/jmagnan/workspace/puy-du-fou/poc-bot-lgr/bot/modules/front/app/.venv/lib/python3.11/site-packages/chainlit/data/dynamodb.py", line 97, in _update_item
    ExpressionAttributeValues=self._serialize_item(expression_attribute_values),
                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/jmagnan/workspace/puy-du-fou/poc-bot-lgr/bot/modules/front/app/.venv/lib/python3.11/site-packages/chainlit/data/dynamodb.py", line 68, in _serialize_item
    return {
           ^
  File "/home/jmagnan/workspace/puy-du-fou/poc-bot-lgr/bot/modules/front/app/.venv/lib/python3.11/site-packages/chainlit/data/dynamodb.py", line 69, in <dictcomp>
    key: self._type_serializer.serialize(value) for key, value in item.items()
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/jmagnan/workspace/puy-du-fou/poc-bot-lgr/bot/modules/front/app/.venv/lib/python3.11/site-packages/boto3/dynamodb/types.py", line 116, in serialize
    return {dynamodb_type: serializer(value)}
                           ^^^^^^^^^^^^^^^^^
  File "/home/jmagnan/workspace/puy-du-fou/poc-bot-lgr/bot/modules/front/app/.venv/lib/python3.11/site-packages/boto3/dynamodb/types.py", line 240, in _serialize_m
    return {k: self.serialize(v) for k, v in value.items()}
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/jmagnan/workspace/puy-du-fou/poc-bot-lgr/bot/modules/front/app/.venv/lib/python3.11/site-packages/boto3/dynamodb/types.py", line 240, in <dictcomp>
    return {k: self.serialize(v) for k, v in value.items()}
               ^^^^^^^^^^^^^^^^^
  File "/home/jmagnan/workspace/puy-du-fou/poc-bot-lgr/bot/modules/front/app/.venv/lib/python3.11/site-packages/boto3/dynamodb/types.py", line 114, in serialize
    dynamodb_type = self._get_dynamodb_type(value)
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/jmagnan/workspace/puy-du-fou/poc-bot-lgr/bot/modules/front/app/.venv/lib/python3.11/site-packages/boto3/dynamodb/types.py", line 127, in _get_dynamodb_type
    elif self._is_number(value):
         ^^^^^^^^^^^^^^^^^^^^^^
  File "/home/jmagnan/workspace/puy-du-fou/poc-bot-lgr/bot/modules/front/app/.venv/lib/python3.11/site-packages/boto3/dynamodb/types.py", line 171, in _is_number
    raise TypeError(
TypeError: Float types are not supported. Use Decimal types instead.

After further investigations, trouble comes from following dictionary being passed as value on line 69 of DynamoDBDataLayer.py

{
  "promptId": None,
  "provider": "amazon_bedrock_chat",
  "model": None,
  "error": None,
  "settings": {
    "region_name": "us-east-1",
    "stop": None,
    "model_id": "anthropic.claude-3-sonnet-20240229-v1: 0",
    "model_kwargs": {
      "temperature": 0
    },
    "streaming": True,
    "provider_stop_sequence_key_name_map": {
      "anthropic": "stop_sequences",
      "amazon": "stopSequences",
      "ai21": "stop_sequences",
      "cohere": "stop_sequences",
      "mistral": "stop"
    },
    "guardrails": {
      "id": None,
      "version": None,
      "trace": False
    }
  },
  "variables": {
    "input": ""
  },
  "tags": [],
  "tools": None,
  "tokenCount": None,
  "inputTokenCount": None,
  "outputTokenCount": None,
  "ttFirstToken": 1388.7031078338623,
  "tokenThroughputInSeconds": 14.863459771077393,
  "duration": 2.3547680377960205,
  "messages": [
    {
      "role": "system",
      "content": "some content"
    },
    {
      "role": "user",
      "content": "hi there"
    }
  ],
  "messageCompletion": {
    "role": "assistant",
    "content": "bot answer"
  },
  "type": "CHAT"
}

It indeed holds several float values which are not supported by boto3 dynamodb serializer. Following code helps circumvent the issue for now:

def convert_floats_to_decimal(obj):
    if isinstance(obj, dict):
        for key, value in obj.items():
            if isinstance(value, float):
                obj[key] = Decimal(str(value))
            elif isinstance(value, dict):
                convert_floats_to_decimal(value)
            elif isinstance(value, list):
                obj[key] = [convert_floats_to_decimal(i) for i in value]
    elif isinstance(obj, list):
        return [convert_floats_to_decimal(i) for i in obj]
    return obj

To Reproduce Use dictionary provided above on DynamoDBDataLayer._type_serializer.serialize() method with following librairies version : chainlit==1.1.306 ; python_version >= "3.11" and python_version < "4.0" boto3==1.34.139 ; python_version >= "3.11" and python_version < "4.0"

and eventually for further investigation langchain-aws==0.1.6 ; python_version >= "3.11" and python_version < "4.0" langchain-community==0.0.38 ; python_version >= "3.11" and python_version < "4.0" langchain-core==0.1.52 ; python_version >= "3.11" and python_version < "4.0" langchain-text-splitters==0.0.2 ; python_version >= "3.11" and python_version < "4.0" langchain==0.1.20 ; python_version >= "3.11" and python_version < "4.0"

Expected behavior No TypeError exception

Screenshots Cf stack trace above

Desktop (please complete the following information):

  • OS: Ubuntu WSL
  • Browser Firefox
  • Version 127.0.2 (64-bit)

Additional context None

jc-magnan avatar Jul 04 '24 15:07 jc-magnan