@@ -136,6 +136,12 @@ def stop(self):
136136 def __sync_response (cls , status_code : int , request_id : str , data ) -> Dict :
137137 return {"action" : "response" , "request_id" : request_id , "status_code" : status_code , "data" : data }
138138
139+ def __stream_response (self , request_id : str , data : str ):
140+ self .ws .send (data = json .dumps ({"action" : "stream" , "request_id" : request_id , "data" : data }))
141+
142+ def __close_stream_response (self , request_id : str , data : str ):
143+ self .ws .send (data = json .dumps ({"action" : "stream" , "request_id" : request_id , "data" : data , "close" : True }))
144+
139145 def __exec_external_request (self , action_request : ExternalActionRequest , validate_timestamp : bool ):
140146 logging .debug (f"Callback `{ action_request .body .action_name } ` { to_safe_str (action_request .body .action_params )} " )
141147 sync_response = action_request .request_id != "" # if request_id is set, we need to write back the response
@@ -175,6 +181,23 @@ def __exec_external_request(self, action_request: ExternalActionRequest, validat
175181 http_code = 200 if response .get ("success" ) else 500
176182 self .ws .send (data = json .dumps (self .__sync_response (http_code , action_request .request_id , response )))
177183
184+ def __exec_external_stream_request (self , action_request : ExternalActionRequest , validate_timestamp : bool ):
185+ logging .debug (f"Callback `{ action_request .body .action_name } ` { to_safe_str (action_request .body .action_params )} " )
186+
187+ validation_response = self .__validate_request (action_request , validate_timestamp )
188+ if validation_response .http_code != 200 :
189+ req_json = action_request .json (exclude = {"body" })
190+ body_json = action_request .body .json (exclude = {"action_params" }) # action params already printed above
191+ logging .error (f"Failed to validate action request { req_json } { body_json } " )
192+ self .__close_stream_response (action_request .request_id , validation_response .dict (exclude = {"http_code" }))
193+ return
194+
195+ res = self .event_handler .run_external_stream_action (action_request .body .action_name ,
196+ action_request .body .action_params ,
197+ lambda data : self .__stream_response (request_id = action_request .request_id , data = data ))
198+ res = "" if res .get ("success" ) else json .dumps (res )
199+ self .__close_stream_response (action_request .request_id , res )
200+
178201 def _process_action (self , action : ExternalActionRequest , validate_timestamp : bool ) -> None :
179202 self ._executor .submit (self ._process_action_sync , action , validate_timestamp )
180203
@@ -189,7 +212,10 @@ def _process_action_sync(self, action: ExternalActionRequest, validate_timestamp
189212 else :
190213 ctx = nullcontext ()
191214 with ctx :
192- self .__exec_external_request (action , validate_timestamp )
215+ if action .stream :
216+ self .__exec_external_stream_request (action , validate_timestamp )
217+ else :
218+ self .__exec_external_request (action , validate_timestamp )
193219 except Exception :
194220 logging .error (
195221 f"Failed to run incoming event { self ._stringify_incoming_event (action .dict ())} " ,
0 commit comments