From e1b2da1ff0510248359059e4337b662ca9ab8e3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleix=20Conchillo=20Flaqu=C3=A9?= Date: Wed, 12 Jun 2024 12:09:22 -0700 Subject: [PATCH] serializer: allow deserialize() to return None --- CHANGELOG.md | 3 +++ src/pipecat/serializers/base_serializer.py | 2 +- src/pipecat/serializers/protobuf.py | 8 +++++--- src/pipecat/transports/network/websocket_server.py | 4 ++++ 4 files changed, 13 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ca4c9885b..2c6e974eb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- `FrameSerializer.deserialize()` can now return `None` in case it is not + possible to desearialize the given data. + - `daily_rest.DailyRoomProperties` now allows extra unknown parameters. - Added `DeepgramSTTService`. This service has an ongoing websocket diff --git a/src/pipecat/serializers/base_serializer.py b/src/pipecat/serializers/base_serializer.py index c137f873d..71d274cff 100644 --- a/src/pipecat/serializers/base_serializer.py +++ b/src/pipecat/serializers/base_serializer.py @@ -16,5 +16,5 @@ class FrameSerializer(ABC): pass @abstractmethod - def deserialize(self, data: bytes) -> Frame: + def deserialize(self, data: bytes) -> Frame | None: pass diff --git a/src/pipecat/serializers/protobuf.py b/src/pipecat/serializers/protobuf.py index 50692a51b..c51fe8869 100644 --- a/src/pipecat/serializers/protobuf.py +++ b/src/pipecat/serializers/protobuf.py @@ -11,6 +11,8 @@ import pipecat.frames.protobufs.frames_pb2 as frame_protos from pipecat.frames.frames import AudioRawFrame, Frame, TextFrame, TranscriptionFrame from pipecat.serializers.base_serializer import FrameSerializer +from loguru import logger + class ProtobufFrameSerializer(FrameSerializer): SERIALIZABLE_TYPES = { @@ -39,7 +41,7 @@ class ProtobufFrameSerializer(FrameSerializer): result = proto_frame.SerializeToString() return result - def deserialize(self, data: bytes) -> Frame: + def deserialize(self, data: bytes) -> Frame | None: """Returns a Frame object from a Frame protobuf. Used to convert frames passed over the wire as protobufs to Frame objects used in pipelines and frame processors. @@ -61,8 +63,8 @@ class ProtobufFrameSerializer(FrameSerializer): proto = frame_protos.Frame.FromString(data) which = proto.WhichOneof("frame") if which not in self.SERIALIZABLE_FIELDS: - raise ValueError( - "Proto does not contain a valid frame. You may need to add a new case to ProtobufFrameSerializer.deserialize.") + logger.error("Unable to deserialize a valid frame") + return None class_name = self.SERIALIZABLE_FIELDS[which] args = getattr(proto, which) diff --git a/src/pipecat/transports/network/websocket_server.py b/src/pipecat/transports/network/websocket_server.py index bf51732e1..43d4d0505 100644 --- a/src/pipecat/transports/network/websocket_server.py +++ b/src/pipecat/transports/network/websocket_server.py @@ -82,6 +82,10 @@ class WebsocketServerInputTransport(BaseInputTransport): # Handle incoming messages async for message in websocket: frame = self._params.serializer.deserialize(message) + + if not frame: + continue + if isinstance(frame, AudioRawFrame): self.push_audio_frame(frame) else: