1
+ #!/usr/bin/env python3
2
+ """
3
+ Workflow and Activity Registry for Cadence Python Client.
4
+
5
+ This module provides a registry system for managing workflows and activities,
6
+ similar to the Go client's registry.go implementation.
7
+ """
8
+
9
+ import logging
10
+ from typing import Callable , Dict , Optional , Unpack , TypedDict
11
+
12
+
13
+ logger = logging .getLogger (__name__ )
14
+
15
+
16
+ class RegisterWorkflowOptions (TypedDict , total = False ):
17
+ """Options for registering a workflow."""
18
+ name : Optional [str ]
19
+ alias : Optional [str ]
20
+
21
+
22
+ class RegisterActivityOptions (TypedDict , total = False ):
23
+ """Options for registering an activity."""
24
+ name : Optional [str ]
25
+ alias : Optional [str ]
26
+
27
+
28
+ class Registry :
29
+ """
30
+ Registry for managing workflows and activities.
31
+
32
+ This class provides functionality to register, retrieve, and manage
33
+ workflows and activities in a Cadence application.
34
+ """
35
+
36
+ def __init__ (self ):
37
+ """Initialize the registry."""
38
+ self ._workflows : Dict [str , Callable ] = {}
39
+ self ._activities : Dict [str , Callable ] = {}
40
+ self ._workflow_aliases : Dict [str , str ] = {} # alias -> name mapping
41
+ self ._activity_aliases : Dict [str , str ] = {} # alias -> name mapping
42
+
43
+ def workflow (
44
+ self ,
45
+ func : Optional [Callable ] = None ,
46
+ ** kwargs : Unpack [RegisterWorkflowOptions ]
47
+ ) -> Callable :
48
+ """
49
+ Register a workflow function.
50
+
51
+ This method can be used as a decorator or called directly.
52
+
53
+ Args:
54
+ func: The workflow function to register
55
+ **kwargs: Options for registration (name, alias)
56
+
57
+ Returns:
58
+ The decorated function or the function itself
59
+
60
+ Raises:
61
+ KeyError: If workflow name already exists
62
+ """
63
+ options = RegisterWorkflowOptions (** kwargs )
64
+
65
+ def decorator (f : Callable ) -> Callable :
66
+ workflow_name = options .get ('name' ) or f .__name__
67
+
68
+ if workflow_name in self ._workflows :
69
+ raise KeyError (f"Workflow '{ workflow_name } ' is already registered" )
70
+
71
+ self ._workflows [workflow_name ] = f
72
+
73
+ # Register alias if provided
74
+ alias = options .get ('alias' )
75
+ if alias :
76
+ if alias in self ._workflow_aliases :
77
+ raise KeyError (f"Workflow alias '{ alias } ' is already registered" )
78
+ self ._workflow_aliases [alias ] = workflow_name
79
+
80
+ logger .info (f"Registered workflow '{ workflow_name } '" )
81
+ return f
82
+
83
+ if func is None :
84
+ return decorator
85
+ return decorator (func )
86
+
87
+ def activity (
88
+ self ,
89
+ func : Optional [Callable ] = None ,
90
+ ** kwargs : Unpack [RegisterActivityOptions ]
91
+ ) -> Callable :
92
+ """
93
+ Register an activity function.
94
+
95
+ This method can be used as a decorator or called directly.
96
+
97
+ Args:
98
+ func: The activity function to register
99
+ **kwargs: Options for registration (name, alias)
100
+
101
+ Returns:
102
+ The decorated function or the function itself
103
+
104
+ Raises:
105
+ KeyError: If activity name already exists
106
+ """
107
+ options = RegisterActivityOptions (** kwargs )
108
+
109
+ def decorator (f : Callable ) -> Callable :
110
+ activity_name = options .get ('name' ) or f .__name__
111
+
112
+ if activity_name in self ._activities :
113
+ raise KeyError (f"Activity '{ activity_name } ' is already registered" )
114
+
115
+ self ._activities [activity_name ] = f
116
+
117
+ # Register alias if provided
118
+ alias = options .get ('alias' )
119
+ if alias :
120
+ if alias in self ._activity_aliases :
121
+ raise KeyError (f"Activity alias '{ alias } ' is already registered" )
122
+ self ._activity_aliases [alias ] = activity_name
123
+
124
+ logger .info (f"Registered activity '{ activity_name } '" )
125
+ return f
126
+
127
+ if func is None :
128
+ return decorator
129
+ return decorator (func )
130
+
131
+ def get_workflow (self , name : str ) -> Callable :
132
+ """
133
+ Get a registered workflow by name.
134
+
135
+ Args:
136
+ name: Name or alias of the workflow
137
+
138
+ Returns:
139
+ The workflow function
140
+
141
+ Raises:
142
+ KeyError: If workflow is not found
143
+ """
144
+ # Check if it's an alias
145
+ actual_name = self ._workflow_aliases .get (name , name )
146
+
147
+ if actual_name not in self ._workflows :
148
+ raise KeyError (f"Workflow '{ name } ' not found in registry" )
149
+
150
+ return self ._workflows [actual_name ]
151
+
152
+ def get_activity (self , name : str ) -> Callable :
153
+ """
154
+ Get a registered activity by name.
155
+
156
+ Args:
157
+ name: Name or alias of the activity
158
+
159
+ Returns:
160
+ The activity function
161
+
162
+ Raises:
163
+ KeyError: If activity is not found
164
+ """
165
+ # Check if it's an alias
166
+ actual_name = self ._activity_aliases .get (name , name )
167
+
168
+ if actual_name not in self ._activities :
169
+ raise KeyError (f"Activity '{ name } ' not found in registry" )
170
+
171
+ return self ._activities [actual_name ]
172
+
173
+
174
+
0 commit comments