Core: 6. Context serialization#

This tutorial shows context serialization. First of all, let’s do all the necessary imports from DFF.

[1]:
# installing dependencies
%pip install -q dff
Note: you may need to restart the kernel to use updated packages.
[2]:
import logging

from dff.script import TRANSITIONS, RESPONSE, Context, Message
import dff.script.conditions as cnd

from dff.pipeline import Pipeline
from dff.utils.testing.common import (
    check_happy_path,
    is_interactive_mode,
    run_interactive_mode,
)

This function returns the user request number.

[3]:
def response_handler(ctx: Context, _: Pipeline) -> Message:
    return Message(f"answer {len(ctx.requests)}")
[4]:
# a dialog script
toy_script = {
    "flow_start": {
        "node_start": {
            RESPONSE: response_handler,
            TRANSITIONS: {("flow_start", "node_start"): cnd.true()},
        }
    }
}

# testing
happy_path = (
    (Message("hi"), Message("answer 1")),
    (Message("how are you?"), Message("answer 2")),
    (Message("ok"), Message("answer 3")),
    (Message("good"), Message("answer 4")),
)

Draft function that performs serialization.

[5]:
def process_response(ctx: Context):
    ctx_json = ctx.model_dump_json()
    if isinstance(ctx_json, str):
        logging.info("context serialized to json str")
    else:
        raise Exception(f"ctx={ctx_json} has to be serialized to json string")

    ctx_dict = ctx.model_dump()
    if isinstance(ctx_dict, dict):
        logging.info("context serialized to dict")
    else:
        raise Exception(f"ctx={ctx_dict} has to be serialized to dict")

    if not isinstance(ctx, Context):
        raise Exception(f"ctx={ctx} has to have Context type")
[6]:
pipeline = Pipeline.from_script(
    toy_script,
    start_label=("flow_start", "node_start"),
    post_services=[process_response],
)

if __name__ == "__main__":
    check_happy_path(pipeline, happy_path)
    if is_interactive_mode():
        run_interactive_mode(pipeline)
Service 'process_response_0' execution failed!
Traceback (most recent call last):
  File "/home/runner/work/dialog_flow_framework/dialog_flow_framework/dff/pipeline/service/service.py", line 151, in _run_as_service
    await self._run_handler(ctx, pipeline)
  File "/home/runner/work/dialog_flow_framework/dialog_flow_framework/dff/pipeline/service/service.py", line 118, in _run_handler
    await wrap_sync_function_in_async(self.handler, ctx)
  File "/home/runner/work/dialog_flow_framework/dialog_flow_framework/dff/pipeline/service/utils.py", line 25, in wrap_sync_function_in_async
    return func(*args, **kwargs)
  File "/tmp/ipykernel_16880/4050068440.py", line 2, in process_response
    ctx_json = ctx.model_dump_json()
  File "/home/runner/.cache/pypoetry/virtualenvs/dff-7eKxroBE-py3.9/lib/python3.9/site-packages/pydantic/main.py", line 358, in model_dump_json
    return self.__pydantic_serializer__.to_json(
pydantic_core._pydantic_core.PydanticSerializationError: Unable to serialize unknown type: <class 'function'>
Service 'process_response_0' execution failed!
Traceback (most recent call last):
  File "/home/runner/work/dialog_flow_framework/dialog_flow_framework/dff/pipeline/service/service.py", line 151, in _run_as_service
    await self._run_handler(ctx, pipeline)
  File "/home/runner/work/dialog_flow_framework/dialog_flow_framework/dff/pipeline/service/service.py", line 118, in _run_handler
    await wrap_sync_function_in_async(self.handler, ctx)
  File "/home/runner/work/dialog_flow_framework/dialog_flow_framework/dff/pipeline/service/utils.py", line 25, in wrap_sync_function_in_async
    return func(*args, **kwargs)
  File "/tmp/ipykernel_16880/4050068440.py", line 2, in process_response
    ctx_json = ctx.model_dump_json()
  File "/home/runner/.cache/pypoetry/virtualenvs/dff-7eKxroBE-py3.9/lib/python3.9/site-packages/pydantic/main.py", line 358, in model_dump_json
    return self.__pydantic_serializer__.to_json(
pydantic_core._pydantic_core.PydanticSerializationError: Unable to serialize unknown type: <class 'function'>
Service 'process_response_0' execution failed!
Traceback (most recent call last):
  File "/home/runner/work/dialog_flow_framework/dialog_flow_framework/dff/pipeline/service/service.py", line 151, in _run_as_service
    await self._run_handler(ctx, pipeline)
  File "/home/runner/work/dialog_flow_framework/dialog_flow_framework/dff/pipeline/service/service.py", line 118, in _run_handler
    await wrap_sync_function_in_async(self.handler, ctx)
  File "/home/runner/work/dialog_flow_framework/dialog_flow_framework/dff/pipeline/service/utils.py", line 25, in wrap_sync_function_in_async
    return func(*args, **kwargs)
  File "/tmp/ipykernel_16880/4050068440.py", line 2, in process_response
    ctx_json = ctx.model_dump_json()
  File "/home/runner/.cache/pypoetry/virtualenvs/dff-7eKxroBE-py3.9/lib/python3.9/site-packages/pydantic/main.py", line 358, in model_dump_json
    return self.__pydantic_serializer__.to_json(
pydantic_core._pydantic_core.PydanticSerializationError: Unable to serialize unknown type: <class 'function'>
Service 'process_response_0' execution failed!
Traceback (most recent call last):
  File "/home/runner/work/dialog_flow_framework/dialog_flow_framework/dff/pipeline/service/service.py", line 151, in _run_as_service
    await self._run_handler(ctx, pipeline)
  File "/home/runner/work/dialog_flow_framework/dialog_flow_framework/dff/pipeline/service/service.py", line 118, in _run_handler
    await wrap_sync_function_in_async(self.handler, ctx)
  File "/home/runner/work/dialog_flow_framework/dialog_flow_framework/dff/pipeline/service/utils.py", line 25, in wrap_sync_function_in_async
    return func(*args, **kwargs)
  File "/tmp/ipykernel_16880/4050068440.py", line 2, in process_response
    ctx_json = ctx.model_dump_json()
  File "/home/runner/.cache/pypoetry/virtualenvs/dff-7eKxroBE-py3.9/lib/python3.9/site-packages/pydantic/main.py", line 358, in model_dump_json
    return self.__pydantic_serializer__.to_json(
pydantic_core._pydantic_core.PydanticSerializationError: Unable to serialize unknown type: <class 'function'>
(user) >>> text='hi'
 (bot) <<< text='answer 1'
(user) >>> text='how are you?'
 (bot) <<< text='answer 2'
(user) >>> text='ok'
 (bot) <<< text='answer 3'
(user) >>> text='good'
 (bot) <<< text='answer 4'