-
Notifications
You must be signed in to change notification settings - Fork 133
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changing the serializer for Dapr actors #255
Comments
This issue has been automatically marked as stale because it has not had activity in the last 60 days. It will be closed in the next 7 days unless it is tagged (pinned, good first issue, help wanted or triaged/resolved) or other activity occurs. Thank you for your contributions. |
This issue has been automatically marked as stale because it has not had activity in the last 60 days. It will be closed in the next 7 days unless it is tagged (pinned, good first issue, help wanted or triaged/resolved) or other activity occurs. Thank you for your contributions. |
/ping bot |
You can specify the serializer when you register Actors. Please note that your custom serializers must extend https://github.com/dapr/python-sdk/blob/master/dapr/actor/runtime/runtime.py#L44 @classmethod
async def register_actor(
cls, actor: Type[Actor],
message_serializer: Serializer = DefaultJSONSerializer(),
state_serializer: Serializer = DefaultJSONSerializer(),
http_timeout_seconds: int = settings.DAPR_HTTP_TIMEOUT_SECONDS) -> None:
"""Registers an :class:`Actor` object with the runtime.
Args:
actor (:class:`Actor`): Actor implementation.
message_serializer (:class:`Serializer`): A serializer that serializes message
between actors.
state_serializer (:class:`Serializer`): Serializer that serializes state values.
http_timeout_seconds (:int:): a configurable timeout value
""" Example (https://github.com/dapr/python-sdk/blob/master/examples/demo_actor/demo_actor/demo_actor_service.py): Update the actor service code like so: from dapr.serializers.json import DefaultJSONSerializer
@app.on_event("startup")
async def startup_event():
# Register DemoActor
await actor.register_actor(
DemoActor,
message_serializer = DefaultJSONSerializer(),
state_serializer = DefaultJSONSerializer(),
) |
I'm not sure where a good place to document this is. I don't want to add clutter to existing examples as most people won't need to change the serializers. Hopefully for now this GitHub issue will be sufficient in search. |
@berndverst this looks good, do you think it's enough so someone can de/serialize from/to Protobuf or Avro? |
Just to add this with the latest dapr 1.12 version: You also need to define the ActorProxy, otherwise messages are not properly serialized. from typing import Any, Callable, Optional, Type
from dapr.serializers.base import Serializer
from dapr.serializers.json import DefaultJSONSerializer
from pydantic import BaseModel
class PydanticSerializer(Serializer):
_fallback: DefaultJSONSerializer = DefaultJSONSerializer()
def serialize(self, obj: object, custom_hook: Optional[Callable[[object], bytes]] = None) -> bytes:
# try with pydantic first, if that fails, try with the fallback
if isinstance(obj, BaseModel):
return obj.model_dump_json().encode("utf-8")
else:
return self._fallback.serialize(obj, custom_hook)
def deserialize(self, data: bytes, data_type: Optional[Type] = object, custom_hook: Optional[Callable[[bytes], object]] = None) -> Any:
# try with pydantic first, if that fails, try with the fallback
if issubclass(data_type, BaseModel):
return data_type.model_validate_json(data.decode("utf-8"))
else:
return self._fallback.deserialize(data, data_type, custom_hook) I register the actors with this: await ActorRuntime.register_actor(MyActor, message_serializer=PydanticSerializer(), state_serializer=PydanticSerializer()) And I talk to the actors like this: def get_my_actor(id: str) -> MyActorInterface:
"""
Creates a new MyActor interface from an id.
"""
return ActorProxy.create(actor_type="MyActor", actor_id=ActorId(id), actor_interface=MyActorInterface, actor_proxy_factory=ActorProxyFactory(message_serializer=PydanticSerializer())) |
Maybe we want this documented? @elena-kolevska @berndverst |
I think this might make sense in the actors docs page: https://docs.dapr.io/developing-applications/sdks/python/python-actor/. I'll send a PR. |
Is there anyway to change the sterilization protocol for Actors and state manager? Currently Dapr is using json.dumps underneath and it seems impossible to pass any special Encoders.
The text was updated successfully, but these errors were encountered: