11# system imports
22import time
3+ import json
34import subprocess
45import tempfile
56import shutil
6- import dataclasses
7- from typing import List , Dict , Any
7+ from typing import List , Dict
88
99# web imports
1010from flask .helpers import safe_join
1111from werkzeug .utils import secure_filename
12- from http import HTTPStatus
1312from flask_executor .futures import Future
1413
1514# lib imports
1817logger = get_logger ()
1918
2019
21- @dataclasses .dataclass
22- class Report :
23- """
24- Report dataclass to store the command's result.
25- Internal use only.
26- """
27-
28- key : str
29- report : Any
30- error : Any
31- status : str
32- start_time : float
33- end_time : float
34- returncode : int
35- process_time : float = dataclasses .field (init = False )
36-
37- def __post_init__ (self ):
38- self .process_time = self .end_time - self .start_time
39-
40- def to_dict (self ):
41- return dataclasses .asdict (self )
42-
43-
44- def run_command (cmd : List [str ], timeout : int , key : str ) -> Report :
20+ def run_command (cmd : List [str ], timeout : int , key : str ) -> Dict :
4521 """
4622 This function is called by the executor to run given command
4723 using a subprocess asynchronously.
@@ -53,7 +29,7 @@ def run_command(cmd: List[str], timeout: int, key: str) -> Report:
5329 :param timeout: int
5430 maximum timeout in seconds (default = 3600)
5531
56- :rtype Report
32+ :rtype: Dict
5733
5834 :returns:
5935 A Concurrent.Future object where future.result() is the report
@@ -85,14 +61,17 @@ def run_command(cmd: List[str], timeout: int, key: str) -> Report:
8561 stderr = str (e )
8662 logger .error (f"Job: '{ key } ' --> failed. Reason: \" { stderr } \" ." )
8763
88- return Report (
64+ end_time : float = time .time ()
65+ process_time = end_time - start_time
66+ return dict (
8967 key = key ,
9068 report = stdout ,
9169 error = stderr ,
9270 status = status ,
93- start_time = start_time ,
94- end_time = time .time (),
9571 returncode = returncode ,
72+ start_time = start_time ,
73+ end_time = end_time ,
74+ process_time = process_time ,
9675 )
9776
9877
@@ -115,18 +94,14 @@ def __parse_multipart_req(args: List[str], files) -> (List[str], str):
11594 if not fnames :
11695 raise Exception (
11796 "No filename(s) specified."
118- "Please prefix file argument(s) with @ character." ,
119- HTTPStatus .BAD_REQUEST ,
97+ "Please prefix file argument(s) with @ character."
12098 )
12199
122100 # create a new temporary directory
123101 tmpdir : str = tempfile .mkdtemp ()
124102 for fname in fnames :
125103 if fname not in files :
126- raise Exception (
127- f"No File part with filename: { fname } in request." ,
128- HTTPStatus .BAD_REQUEST ,
129- )
104+ raise Exception (f"No File part with filename: { fname } in request." )
130105 req_file = files .get (fname )
131106 filename = secure_filename (req_file .filename )
132107 # calc file location
@@ -152,10 +127,11 @@ def parse_req(self, request, base_command: str) -> (str, int, Dict, str):
152127 timeout : int = request .json .get ("timeout" , DEFAULT_TIMEOUT )
153128 callback_context = request .json .get ("callback_context" , {})
154129 elif request .files :
155- # request contains file
156- callback_context = request .form .get ("callback_context" , {})
157- received_args = request .form .getlist ("args" )
158- timeout : int = request .form .get ("timeout" , DEFAULT_TIMEOUT )
130+ # request contains file and form_data
131+ data = json .loads (request .form .get ("request_json" , "{}" ))
132+ received_args = data .get ("args" , [])
133+ timeout : int = data .get ("timeout" , DEFAULT_TIMEOUT )
134+ callback_context = data .get ("callback_context" , {})
159135 args , tmpdir = RequestParser .__parse_multipart_req (
160136 received_args , request .files
161137 )
@@ -169,7 +145,9 @@ def parse_req(self, request, base_command: str) -> (str, int, Dict, str):
169145 return cmd , timeout , callback_context , key
170146
171147 def cleanup_temp_dir (self , future : Future ) -> None :
172- key : str = future .result ().key
148+ key : str = future .result ().get ("key" , None )
149+ if not key :
150+ return None
173151 tmpdir : str = self .__tmpdirs .get (key , None )
174152 if not tmpdir :
175153 return None
0 commit comments