1212from sqlalchemy import func , or_ , select , text
1313from starlette .responses import JSONResponse
1414
15- from config .config import UPLOAD_FOLDER
1615from model .task import (
1716 ComparisonMetrics ,
1817 ComparisonRequest ,
2928 TaskResultRsp ,
3029 TaskStatusRsp ,
3130)
32- from utils .logger import be_logger as logger
31+ from utils .be_config import UPLOAD_FOLDER
32+ from utils .logger import logger
3333
3434
3535async def get_tasks_svc (
@@ -53,7 +53,7 @@ async def get_tasks_svc(
5353 Returns:
5454 A `TaskResponse` object containing the list of tasks and pagination details.
5555 """
56- task_list = []
56+ task_list : List [ Dict ] = []
5757 pagination = Pagination ()
5858 try :
5959 db = request .state .db
@@ -100,27 +100,67 @@ async def get_tasks_svc(
100100 )
101101
102102 # Format the task data for the response.
103- task_list = [
104- {
103+ task_list = []
104+ for task in tasks :
105+ # Convert headers from JSON string back to a list of objects for the frontend.
106+ # headers_list = []
107+ # if task.headers:
108+ # try:
109+ # headers_dict = json.loads(task.headers)
110+ # headers_list = [
111+ # {"key": k, "value": v} for k, v in headers_dict.items()
112+ # ]
113+ # except json.JSONDecodeError:
114+ # logger.warning(
115+ # f"Could not parse headers JSON for task {task.id}: {task.headers}"
116+ # )
117+
118+ # Convert cookies from JSON string back to a list of objects for the frontend.
119+ # cookies_list = []
120+ # if task.cookies:
121+ # try:
122+ # cookies_dict = json.loads(task.cookies)
123+ # cookies_list = [
124+ # {"key": k, "value": v} for k, v in cookies_dict.items()
125+ # ]
126+ # except json.JSONDecodeError:
127+ # logger.warning(
128+ # f"Could not parse cookies JSON for task {task.id}: {task.cookies}"
129+ # )
130+
131+ # Parse field_mapping from JSON string back to dictionary
132+ field_mapping_dict = {}
133+ if task .field_mapping :
134+ try :
135+ field_mapping_dict = json .loads (task .field_mapping )
136+ except json .JSONDecodeError :
137+ logger .warning (
138+ f"Could not parse field_mapping JSON for task { task .id } : { task .field_mapping } "
139+ )
140+
141+ task_data = {
105142 "id" : task .id ,
106143 "name" : task .name ,
107144 "status" : task .status ,
108145 "target_host" : task .target_host ,
109146 "api_path" : task .api_path ,
110147 "model" : task .model ,
111148 "request_payload" : task .request_payload ,
112- "field_mapping" : task . field_mapping ,
149+ "field_mapping" : field_mapping_dict ,
113150 "concurrent_users" : task .concurrent_users ,
114151 "duration" : task .duration ,
115152 "spawn_rate" : task .spawn_rate ,
116153 "chat_type" : task .chat_type ,
117154 "stream_mode" : str (task .stream_mode ).lower () == "true" ,
118- "error_message" : task .error_message ,
155+ "headers" : "" ,
156+ "cookies" : "" ,
157+ "cert_config" : "" ,
158+ "system_prompt" : task .system_prompt or "" ,
159+ "test_data" : task .test_data or "" ,
119160 "created_at" : task .created_at .isoformat () if task .created_at else None ,
120161 "updated_at" : task .updated_at .isoformat () if task .updated_at else None ,
121162 }
122- for task in tasks
123- ]
163+ task_list .append (task_data )
124164 except Exception as e :
125165 logger .error (f"Error getting tasks: { e } " , exc_info = True )
126166 return TaskResponse (data = [], pagination = Pagination (), status = "error" )
@@ -227,17 +267,19 @@ async def create_task_svc(request: Request, body: TaskCreateReq):
227267 # Convert absolute paths to relative paths for cross-service compatibility
228268 if cert_file :
229269 # Convert backend upload path to relative path that st_engine can access
230- if cert_file .startswith ("/app/upload_files/" ):
231- cert_file = cert_file .replace ("/app/upload_files/" , "" )
232- elif UPLOAD_FOLDER in cert_file :
270+ if cert_file .startswith (UPLOAD_FOLDER + "/" ):
233271 cert_file = cert_file .replace (UPLOAD_FOLDER + "/" , "" )
272+ elif cert_file .startswith ("/app/upload_files/" ):
273+ # For backward compatibility with existing Docker paths
274+ cert_file = cert_file .replace ("/app/upload_files/" , "" )
234275
235276 if key_file :
236277 # Convert backend upload path to relative path that st_engine can access
237- if key_file .startswith ("/app/upload_files/" ):
238- key_file = key_file .replace ("/app/upload_files/" , "" )
239- elif UPLOAD_FOLDER in key_file :
278+ if key_file .startswith (UPLOAD_FOLDER + "/" ):
240279 key_file = key_file .replace (UPLOAD_FOLDER + "/" , "" )
280+ elif key_file .startswith ("/app/upload_files/" ):
281+ # For backward compatibility with existing Docker paths
282+ key_file = key_file .replace ("/app/upload_files/" , "" )
241283
242284 # Convert headers from a list of objects to a dictionary, then to a JSON string.
243285 headers = {
@@ -278,12 +320,12 @@ async def create_task_svc(request: Request, body: TaskCreateReq):
278320 status = "created" ,
279321 error_message = "" ,
280322 system_prompt = body .system_prompt ,
281- user_prompt = body .user_prompt ,
282323 cert_file = cert_file ,
283324 key_file = key_file ,
284325 api_path = body .api_path ,
285326 request_payload = body .request_payload ,
286327 field_mapping = field_mapping_json ,
328+ test_data = body .test_data ,
287329 )
288330
289331 db .add (new_task )
@@ -433,11 +475,11 @@ async def get_task_svc(request: Request, task_id: str):
433475 "headers" : headers_list ,
434476 "cookies" : cookies_list ,
435477 "cert_config" : {"cert_file" : task .cert_file , "key_file" : task .key_file },
436- "system_prompt" : task .system_prompt ,
437- "user_prompt" : task .user_prompt ,
478+ "system_prompt" : task .system_prompt or "" ,
438479 "api_path" : task .api_path ,
439480 "request_payload" : task .request_payload ,
440481 "field_mapping" : field_mapping_dict ,
482+ "test_data" : task .test_data or "" ,
441483 "error_message" : task .error_message ,
442484 "created_at" : task .created_at .isoformat () if task .created_at else None ,
443485 "updated_at" : task .updated_at .isoformat () if task .updated_at else None ,
@@ -738,11 +780,12 @@ def _prepare_request_payload(body: TaskCreateReq) -> Dict:
738780 """Prepare request payload based on API path and configuration."""
739781 if body .api_path == "/v1/chat/completions" :
740782 # Use the traditional chat completions format
741- messages = []
742- if body .system_prompt :
743- messages .append ({"role" : "system" , "content" : body .system_prompt })
744-
745- messages .append ({"role" : "user" , "content" : body .user_prompt or "Hi" })
783+ messages = [
784+ {
785+ "role" : "user" ,
786+ "content" : "Hi" ,
787+ }
788+ ]
746789
747790 return {
748791 "model" : body .model ,
@@ -931,7 +974,7 @@ async def _handle_streaming_response(response, full_url: str) -> Dict:
931974 }
932975
933976 # For testing purposes, we limit the time and data we collect
934- max_chunks = 200 # max chunks to collect for testing
977+ max_chunks = 300 # max chunks to collect for testing
935978 max_duration = 15 # max duration to wait for testing
936979
937980 start_time = asyncio .get_event_loop ().time ()
0 commit comments