99
1010from simpleflow import Workflow , format
1111from simpleflow .command import get_progression_callback , get_workflow_type , with_format
12+ from simpleflow .history import History
1213from simpleflow .swf import helpers
1314from simpleflow .swf .mapper .models import WorkflowExecution
1415from simpleflow .swf .utils import set_workflow_class_name
15- from simpleflow .utils import import_from_module
16+ from simpleflow .utils import import_from_module , json_dumps
1617
1718
1819class Status (str , Enum ):
@@ -28,6 +29,13 @@ class CloseStatus(str, Enum):
2829 continued_as_new = "continued_as_new"
2930
3031
32+ class OutputFormat (str , Enum ):
33+ events = "events"
34+ raw = "raw"
35+ cooked = "cooked"
36+ cooked_alt = "cooked_alt"
37+
38+
3139app = typer .Typer (no_args_is_help = True )
3240
3341TIMESTAMP_FORMATS = [
@@ -140,6 +148,79 @@ def get_infos():
140148 print (with_format (ctx .parent )(get_infos )())
141149
142150
151+ _NOTSET = object ()
152+
153+
154+ @app .command ()
155+ def history (
156+ ctx : typer .Context ,
157+ domain : Annotated [str , typer .Option (envvar = "SWF_DOMAIN" )],
158+ workflow_id : str ,
159+ run_id : str | None = None ,
160+ output_format : Annotated [OutputFormat , typer .Option ("--output-format" , "--of" )] = OutputFormat .events ,
161+ reverse_order : bool = False ,
162+ ):
163+ # print(ctx)
164+ # format = ctx.parent.parent.params.get("format")
165+ # print(format)
166+ from simpleflow .swf .mapper .models .history .base import History as BaseHistory
167+
168+ ex = helpers .get_workflow_execution (domain , workflow_id , run_id )
169+ if not ex :
170+ print (f"Execution { workflow_id } { run_id } not found" if run_id else f"Workflow { workflow_id } not found" )
171+ ctx .exit (1 )
172+ events = ex .history_events (
173+ callback = get_progression_callback ("events" ),
174+ reverse_order = reverse_order ,
175+ )
176+ if output_format == OutputFormat .events :
177+ pass
178+ else :
179+ raw_history = BaseHistory .from_event_list (events )
180+ history = History (raw_history )
181+ if output_format == OutputFormat .raw :
182+ events = []
183+ for event in history .events :
184+ e = {}
185+ for k in ["id" , "type" , "state" , "timestamp" , "input" , "control" , * event .__dict__ ]:
186+ if k .startswith ("_" ) or k == "raw" :
187+ continue
188+ v = getattr (event , k , _NOTSET )
189+ if v is _NOTSET :
190+ continue
191+ e [k ] = v
192+ events .append (e )
193+ elif output_format == OutputFormat .cooked :
194+ history .parse ()
195+ events = {
196+ "workflow" : history .workflow ,
197+ "activities" : history .activities ,
198+ "child_workflows" : history .child_workflows ,
199+ "markers" : history .markers ,
200+ "timers" : history .timers ,
201+ "signals" : history .signals ,
202+ "signal_lists" : history .signal_lists ,
203+ "external_workflows_signaling" : history .external_workflows_signaling ,
204+ "signaled_workflows" : history .signaled_workflows ,
205+ }
206+ elif output_format == OutputFormat .cooked_alt :
207+ history .parse ()
208+ events = {
209+ "workflow" : [t for t in history .tasks if t .type == "child_workflow" ],
210+ "activities" : [t for t in history .tasks if t .type == "activity" ],
211+ "child_workflows" : history .child_workflows ,
212+ "markers" : history .markers ,
213+ "timers" : history .timers ,
214+ "signals" : [t for t in history .tasks if t .type == "signal" ],
215+ "signal_lists" : history .signal_lists ,
216+ "external_workflows_signaling" : history .external_workflows_signaling ,
217+ "signaled_workflows" : history .signaled_workflows ,
218+ }
219+ else :
220+ raise NotImplementedError
221+ print (json_dumps (events ))
222+
223+
143224if __name__ == "__main__" :
144225 # from click.core import Command
145226 #
0 commit comments