Skip to content

Commit f72cde7

Browse files
committed
Remove circular import
1 parent 3556389 commit f72cde7

File tree

12 files changed

+126
-122
lines changed

12 files changed

+126
-122
lines changed

docs/features.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ Entities can be defined using either function-based or class-based syntax.
6666

6767
```python
6868
# Funtion-based entity
69-
def counter(ctx: task.EntityContext, input: int):
69+
def counter(ctx: entities.EntityContext, input: int):
7070
state = ctx.get_state(int, 0)
7171
if ctx.operation == "add":
7272
state += input

durabletask/client.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
import grpc
1212
from google.protobuf import wrappers_pb2
1313

14-
from durabletask.entities.entity_instance_id import EntityInstanceId
14+
from durabletask.entities import EntityInstanceId
1515
import durabletask.internal.helpers as helpers
1616
import durabletask.internal.orchestrator_service_pb2 as pb
1717
import durabletask.internal.orchestrator_service_pb2_grpc as stubs

durabletask/entities/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
from durabletask.entities.entity_instance_id import EntityInstanceId
77
from durabletask.entities.durable_entity import DurableEntity
88
from durabletask.entities.entity_lock import EntityLock
9+
from durabletask.entities.entity_context import EntityContext
910

10-
__all__ = ["EntityInstanceId", "DurableEntity", "EntityLock"]
11+
__all__ = ["EntityInstanceId", "DurableEntity", "EntityLock", "EntityContext"]
1112

1213
PACKAGE_NAME = "durabletask.entities"

durabletask/entities/durable_entity.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
from typing import Any, Optional, Type, TypeVar, overload
22

3-
from durabletask.entities.entity_instance_id import EntityInstanceId
4-
from durabletask.task import EntityContext
3+
from durabletask.entities import EntityContext, EntityInstanceId
54

65
TState = TypeVar("TState")
76

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
2+
from typing import Any, Optional, Type, TypeVar, overload
3+
import uuid
4+
from durabletask.entities import EntityInstanceId
5+
from durabletask.internal import helpers, shared
6+
from durabletask.internal.entity_state_shim import StateShim
7+
import durabletask.internal.orchestrator_service_pb2 as pb
8+
9+
TState = TypeVar("TState")
10+
11+
12+
class EntityContext:
13+
def __init__(self, orchestration_id: str, operation: str, state: StateShim, entity_id: EntityInstanceId):
14+
self._orchestration_id = orchestration_id
15+
self._operation = operation
16+
self._state = state
17+
self._entity_id = entity_id
18+
19+
@property
20+
def orchestration_id(self) -> str:
21+
"""Get the ID of the orchestration instance that scheduled this entity.
22+
23+
Returns
24+
-------
25+
str
26+
The ID of the current orchestration instance.
27+
"""
28+
return self._orchestration_id
29+
30+
@property
31+
def operation(self) -> str:
32+
"""Get the operation associated with this entity invocation.
33+
34+
The operation is a string that identifies the specific action being
35+
performed on the entity. It can be used to distinguish between
36+
multiple operations that are part of the same entity invocation.
37+
38+
Returns
39+
-------
40+
str
41+
The operation associated with this entity invocation.
42+
"""
43+
return self._operation
44+
45+
@overload
46+
def get_state(self, intended_type: Type[TState], default: TState) -> TState:
47+
...
48+
49+
@overload
50+
def get_state(self, intended_type: Type[TState]) -> Optional[TState]:
51+
...
52+
53+
@overload
54+
def get_state(self, intended_type: None = None, default: Any = None) -> Any:
55+
...
56+
57+
def get_state(self, intended_type: Optional[Type[TState]] = None, default: Optional[TState] = None) -> Optional[TState] | Any:
58+
return self._state.get_state(intended_type, default)
59+
60+
def set_state(self, new_state: Any):
61+
self._state.set_state(new_state)
62+
63+
def signal_entity(self, entity_instance_id: EntityInstanceId, operation: str, input: Optional[Any] = None) -> None:
64+
encoded_input = shared.to_json(input) if input is not None else None
65+
self._state.add_operation_action(
66+
pb.OperationAction(
67+
sendSignal=pb.SendSignalAction(
68+
instanceId=str(entity_instance_id),
69+
name=operation,
70+
input=helpers.get_string_value(encoded_input),
71+
scheduledTime=None,
72+
requestTime=None,
73+
parentTraceContext=None,
74+
)
75+
)
76+
)
77+
78+
def schedule_new_orchestration(self, orchestration_name: str, input: Optional[Any] = None, instance_id: Optional[str] = None) -> str:
79+
encoded_input = shared.to_json(input) if input is not None else None
80+
if not instance_id:
81+
instance_id = uuid.uuid4().hex
82+
self._state.add_operation_action(
83+
pb.OperationAction(
84+
startNewOrchestration=pb.StartNewOrchestrationAction(
85+
instanceId=instance_id,
86+
name=orchestration_name,
87+
input=helpers.get_string_value(encoded_input),
88+
version=None,
89+
scheduledTime=None,
90+
requestTime=None,
91+
parentTraceContext=None
92+
)
93+
)
94+
)
95+
return instance_id
96+
97+
@property
98+
def entity_id(self) -> EntityInstanceId:
99+
"""Get the ID of the entity instance.
100+
101+
Returns
102+
-------
103+
str
104+
The ID of the current entity instance.
105+
"""
106+
return self._entity_id

durabletask/internal/helpers.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
from google.protobuf import timestamp_pb2, wrappers_pb2
99

10-
from durabletask.entities.entity_instance_id import EntityInstanceId
10+
from durabletask.entities import EntityInstanceId
1111
import durabletask.internal.orchestrator_service_pb2 as pb
1212

1313
# TODO: The new_xxx_event methods are only used by test code and should be moved elsewhere

durabletask/internal/orchestration_entity_context.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
from durabletask.internal.helpers import get_string_value
55
import durabletask.internal.orchestrator_service_pb2 as pb
6-
from durabletask.entities.entity_instance_id import EntityInstanceId
6+
from durabletask.entities import EntityInstanceId
77

88

99
class OrchestrationEntityContext:

durabletask/task.py

Lines changed: 2 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,15 @@
77
import math
88
from abc import ABC, abstractmethod
99
from datetime import datetime, timedelta
10-
from typing import Any, Callable, Generator, Generic, Optional, Type, TypeVar, Union, overload
11-
import uuid
10+
from typing import Any, Callable, Generator, Generic, Optional, TypeVar, Union
1211

13-
from durabletask.entities import DurableEntity, EntityInstanceId, EntityLock
14-
from durabletask.internal import shared
15-
from durabletask.internal.entity_state_shim import StateShim
12+
from durabletask.entities import DurableEntity, EntityInstanceId, EntityLock, EntityContext
1613
import durabletask.internal.helpers as pbh
1714
import durabletask.internal.orchestrator_service_pb2 as pb
1815

1916
T = TypeVar('T')
2017
TInput = TypeVar('TInput')
2118
TOutput = TypeVar('TOutput')
22-
TState = TypeVar("TState")
2319

2420

2521
class OrchestrationContext(ABC):
@@ -515,103 +511,6 @@ def task_id(self) -> int:
515511
return self._task_id
516512

517513

518-
class EntityContext:
519-
def __init__(self, orchestration_id: str, operation: str, state: StateShim, entity_id: EntityInstanceId):
520-
self._orchestration_id = orchestration_id
521-
self._operation = operation
522-
self._state = state
523-
self._entity_id = entity_id
524-
525-
@property
526-
def orchestration_id(self) -> str:
527-
"""Get the ID of the orchestration instance that scheduled this entity.
528-
529-
Returns
530-
-------
531-
str
532-
The ID of the current orchestration instance.
533-
"""
534-
return self._orchestration_id
535-
536-
@property
537-
def operation(self) -> str:
538-
"""Get the operation associated with this entity invocation.
539-
540-
The operation is a string that identifies the specific action being
541-
performed on the entity. It can be used to distinguish between
542-
multiple operations that are part of the same entity invocation.
543-
544-
Returns
545-
-------
546-
str
547-
The operation associated with this entity invocation.
548-
"""
549-
return self._operation
550-
551-
@overload
552-
def get_state(self, intended_type: Type[TState], default: TState) -> TState:
553-
...
554-
555-
@overload
556-
def get_state(self, intended_type: Type[TState]) -> Optional[TState]:
557-
...
558-
559-
@overload
560-
def get_state(self, intended_type: None = None, default: Any = None) -> Any:
561-
...
562-
563-
def get_state(self, intended_type: Optional[Type[TState]] = None, default: Optional[TState] = None) -> Optional[TState] | Any:
564-
return self._state.get_state(intended_type, default)
565-
566-
def set_state(self, new_state: Any):
567-
self._state.set_state(new_state)
568-
569-
def signal_entity(self, entity_instance_id: EntityInstanceId, operation: str, input: Optional[Any] = None) -> None:
570-
encoded_input = shared.to_json(input) if input is not None else None
571-
self._state.add_operation_action(
572-
pb.OperationAction(
573-
sendSignal=pb.SendSignalAction(
574-
instanceId=str(entity_instance_id),
575-
name=operation,
576-
input=pbh.get_string_value(encoded_input),
577-
scheduledTime=None,
578-
requestTime=None,
579-
parentTraceContext=None,
580-
)
581-
)
582-
)
583-
584-
def schedule_new_orchestration(self, orchestration_name: str, input: Optional[Any] = None, instance_id: Optional[str] = None) -> str:
585-
encoded_input = shared.to_json(input) if input is not None else None
586-
if not instance_id:
587-
instance_id = uuid.uuid4().hex
588-
self._state.add_operation_action(
589-
pb.OperationAction(
590-
startNewOrchestration=pb.StartNewOrchestrationAction(
591-
instanceId=instance_id,
592-
name=orchestration_name,
593-
input=pbh.get_string_value(encoded_input),
594-
version=None,
595-
scheduledTime=None,
596-
requestTime=None,
597-
parentTraceContext=None
598-
)
599-
)
600-
)
601-
return instance_id
602-
603-
@property
604-
def entity_id(self) -> EntityInstanceId:
605-
"""Get the ID of the entity instance.
606-
607-
Returns
608-
-------
609-
str
610-
The ID of the current entity instance.
611-
"""
612-
return self._entity_id
613-
614-
615514
# Orchestrators are generators that yield tasks and receive/return any type
616515
Orchestrator = Callable[[OrchestrationContext, TInput], Union[Generator[Task, Any, Any], TOutput]]
617516

durabletask/worker.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
from durabletask.internal import helpers
2222
from durabletask.internal.entity_state_shim import StateShim
2323
from durabletask.internal.helpers import new_timestamp
24-
from durabletask.entities import DurableEntity, EntityLock, EntityInstanceId
24+
from durabletask.entities import DurableEntity, EntityLock, EntityInstanceId, EntityContext
2525
from durabletask.internal.orchestration_entity_context import OrchestrationEntityContext
2626
import durabletask.internal.helpers as ph
2727
import durabletask.internal.exceptions as pe
@@ -978,7 +978,6 @@ def call_entity(
978978
self,
979979
entity_id: EntityInstanceId,
980980
operation: str,
981-
*,
982981
input: Optional[TInput] = None,
983982
) -> task.Task:
984983
id = self.next_sequence_number()
@@ -1774,7 +1773,7 @@ def execute(
17741773
)
17751774

17761775
entity_input = shared.from_json(encoded_input) if encoded_input else None
1777-
ctx = task.EntityContext(orchestration_id, operation, state, entity_id)
1776+
ctx = EntityContext(orchestration_id, operation, state, entity_id)
17781777

17791778
if isinstance(fn, type) and issubclass(fn, DurableEntity):
17801779
if self._registry.entity_instances.get(str(entity_id), None):

examples/entities/function_based_entity.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from durabletask.azuremanaged.worker import DurableTaskSchedulerWorker
1111

1212

13-
def counter(ctx: task.EntityContext, input: int) -> Optional[int]:
13+
def counter(ctx: entities.EntityContext, input: int) -> Optional[int]:
1414
if ctx.operation == "set":
1515
ctx.set_state(input)
1616
if ctx.operation == "add":

0 commit comments

Comments
 (0)