11from datetime import datetime
2- from typing import Any , Optional
2+ from typing import Any , Optional , Type , TypeVar , Union , overload
33from durabletask .entities .entity_instance_id import EntityInstanceId
44
55import durabletask .internal .orchestrator_service_pb2 as pb
66
7+ TState = TypeVar ("TState" )
8+
79
810class EntityMetadata :
911 """Class representing the metadata of a durable entity.
@@ -28,7 +30,7 @@ def __init__(self,
2830 locked_by : str ,
2931 includes_state : bool ,
3032 state : Optional [Any ]):
31- """Initializes a new instance of the EntityState class.
33+ """Initializes a new instance of the EntityMetadata class.
3234
3335 Args:
3436 value: The initial state value of the entity.
@@ -38,7 +40,7 @@ def __init__(self,
3840 self .backlog_queue_size = backlog_queue_size
3941 self .locked_by = locked_by
4042 self .includes_state = includes_state
41- self .state = state
43+ self ._state = state
4244
4345 @staticmethod
4446 def from_entity_response (entity_response : pb .GetEntityResponse , includes_state : bool ):
@@ -47,12 +49,35 @@ def from_entity_response(entity_response: pb.GetEntityResponse, includes_state:
4749 raise ValueError ("Invalid entity instance ID in entity response." )
4850 entity_state = None
4951 if includes_state :
50- entity_state = str ( entity_response .entity .serializedState )
52+ entity_state = entity_response .entity .serializedState . value
5153 return EntityMetadata (
5254 id = entity_id ,
5355 last_modified = entity_response .entity .lastModifiedTime .ToDatetime (),
5456 backlog_queue_size = entity_response .entity .backlogQueueSize ,
55- locked_by = str ( entity_response .entity .lockedBy ) ,
57+ locked_by = entity_response .entity .lockedBy . value ,
5658 includes_state = includes_state ,
5759 state = entity_state
5860 )
61+
62+ @overload
63+ def get_state (self , intended_type : Type [TState ]) -> Optional [TState ]:
64+ ...
65+
66+ @overload
67+ def get_state (self , intended_type : None = None ) -> Any :
68+ ...
69+
70+ def get_state (self , intended_type : Optional [Type [TState ]] = None ) -> Union [None , TState , Any ]:
71+ """Get the current state of the entity, optionally converting it to a specified type."""
72+ if intended_type is None or self ._state is None :
73+ return self ._state
74+
75+ if isinstance (self ._state , intended_type ):
76+ return self ._state
77+
78+ try :
79+ return intended_type (self ._state ) # type: ignore[call-arg]
80+ except Exception as ex :
81+ raise TypeError (
82+ f"Could not convert state of type '{ type (self ._state ).__name__ } ' to '{ intended_type .__name__ } '"
83+ ) from ex
0 commit comments