diff options
author | Suchita Lad | 2025-03-26 18:01:40 +0530 |
---|---|---|
committer | Suchita Lad | 2025-03-26 18:01:40 +0530 |
commit | fc774d0e4e111edac525ff545177d1a48c399e8d (patch) | |
tree | 2594f7d7bda8ad7653704508c80c8e3207fcef07 | |
parent | 6a29c484e21bf1aff7cbf090ccba0e7381100fcd (diff) | |
download | Common-Interface-Project-fc774d0e4e111edac525ff545177d1a48c399e8d.tar.gz Common-Interface-Project-fc774d0e4e111edac525ff545177d1a48c399e8d.tar.bz2 Common-Interface-Project-fc774d0e4e111edac525ff545177d1a48c399e8d.zip |
Updated uploadscript function
-rw-r--r-- | blocks/simulationAPI/helpers/config.py | 2 | ||||
-rw-r--r-- | blocks/simulationAPI/helpers/ngspice_helper.py | 2 | ||||
-rw-r--r-- | blocks/simulationAPI/helpers/scilab_manager.py | 112 | ||||
-rw-r--r-- | blocks/simulationAPI/tasks.py | 24 | ||||
-rw-r--r-- | blocks/simulationAPI/urls.py | 2 | ||||
-rw-r--r-- | blocks/simulationAPI/views.py | 18 |
6 files changed, 93 insertions, 67 deletions
diff --git a/blocks/simulationAPI/helpers/config.py b/blocks/simulationAPI/helpers/config.py index 9bc8bce3..c1593a68 100644 --- a/blocks/simulationAPI/helpers/config.py +++ b/blocks/simulationAPI/helpers/config.py @@ -21,3 +21,5 @@ SPECIAL_CHARACTERS = r'["\'\\]' # The directory where images are created IMAGEDIR = 'images' + +REMOVEFILE = True diff --git a/blocks/simulationAPI/helpers/ngspice_helper.py b/blocks/simulationAPI/helpers/ngspice_helper.py index c5eb8e71..ad4fd778 100644 --- a/blocks/simulationAPI/helpers/ngspice_helper.py +++ b/blocks/simulationAPI/helpers/ngspice_helper.py @@ -137,7 +137,7 @@ def ExecXml(task, task_name): os.close(LOGFILEFD) update_task_status(task_id, 'STREAMING', - meta={'current_process': 'Processed Xml, Streaming Output'}) + meta={'current_process': 'Processed Xml, Streaming Output'}) cmd = "try;" cmd += "chdir('%s');" % current_dir diff --git a/blocks/simulationAPI/helpers/scilab_manager.py b/blocks/simulationAPI/helpers/scilab_manager.py index 79000d91..6e40bc3f 100644 --- a/blocks/simulationAPI/helpers/scilab_manager.py +++ b/blocks/simulationAPI/helpers/scilab_manager.py @@ -17,6 +17,7 @@ from threading import current_thread from time import time import unicodedata import uuid +import logging from simulationAPI.helpers import config @@ -66,7 +67,8 @@ SCILAB_CMD = [SCILAB, "-nouserstartup", "-nb", "-nw", - "-e", SCILAB_START] + "-e", SCILAB_START + ] USER_DATA = {} @@ -615,15 +617,22 @@ def prestart_scilab(): return (proc, log_name) -def run_scilab(command, base, createlogfile=False, timeout=70): +def run_scilab(command, base, createlogfile=False, timeout=1800): instance = get_scilab_instance() if instance is None: logger.error('cannot run command %s', command) return None - cmd = command + SCILAB_END + logger.info('Scilab instance log file: %s', instance.log_name) + cmd = command + SCILAB_END + '\n' logger.info('running command %s', cmd) instance.proc.stdin.write(cmd) + instance.proc.stdin.flush() + + # output, error = instance.proc.communicate(timeout=timeout) + # with open(instance.log_name, 'a') as log: + # log.write(output if output else '') + # log.write(error if error else '') if not createlogfile: remove(instance.log_name) @@ -673,17 +682,20 @@ def uploadscript(session, task): ''' Below route is called for uploading script file. ''' - (script, sessiondir) = add_script(session) + (script, sessiondir) = add_script(session, task) - file = task.file.name + file = task.file if not file: msg = "Upload Error\n" rv = {'msg': msg} - return JsonResponse(rv) + return rv fname = join(sessiondir, SCRIPT_FILES_FOLDER, script.script_id + '_script.sce') - file.save(fname) + # file.save(fname) + with open(fname, 'wb+') as destination: + for chunk in file.chunks(): + destination.write(chunk) script.filename = fname if is_unsafe_script(fname): @@ -691,25 +703,30 @@ def uploadscript(session, task): "Please edit the script again.\n") script.status = -1 rv = {'status': script.status, 'msg': msg} - return JsonResponse(rv) + return rv - wfname = join(sessiondir, SCRIPT_FILES_FOLDER, + wfname = join(sessiondir, WORKSPACE_FILES_FOLDER, script.script_id + '_script_workspace.dat') script.workspace_filename = wfname - command = "exec('%s');save('%s');" % (fname, wfname) + command = "try;exec('%s');save('%s');" % (fname, wfname) script.instance = run_scilab(command, script) + if script.instance is None: msg = "Resource not available" script.status = -2 rv = {'status': script.status, 'msg': msg} - return JsonResponse(rv) + return rv + + # Save workspace file in task model + task.workspace_file = wfname + task.save() msg = '' script.status = 1 - rv = {'script_id': script.script_id, 'status': script.status, 'msg': msg} - return JsonResponse(rv) + rv = {'task_id': task.task_id, 'script_id': script.script_id, 'status': script.status, 'msg': msg} + return rv def clean_output(s): @@ -724,24 +741,24 @@ def clean_output(s): return s -def getscriptoutput(session): +def getscriptoutput(session, task): ''' Below route is called for uploading script file. ''' - script = get_script(session, get_script_id()) + script = get_script(session, task) if script is None: # when called with same script_id again or with incorrect script_id logger.warning('no script') msg = "no script" rv = {'msg': msg} - return JsonResponse(rv) + return rv instance = script.instance if instance is None: logger.warning('no instance') msg = "no instance" rv = {'msg': msg} - return JsonResponse(rv) + return rv proc = instance.proc @@ -758,7 +775,7 @@ def getscriptoutput(session): msg = 'Script stopped' script.status = -5 rv = {'status': script.status, 'msg': msg, 'output': output} - return JsonResponse(rv) + return rv if returncode > 0: logger.info('return code is %s', returncode) if output: @@ -771,7 +788,7 @@ def getscriptoutput(session): "Please edit the script and execute again.\n") script.status = -3 rv = {'status': script.status, 'msg': msg, 'output': output} - return JsonResponse(rv) + return rv logger.info('workspace for %s saved in %s', script.script_id, script.workspace_filename) @@ -786,7 +803,7 @@ def getscriptoutput(session): msg = "Resource not available" script.status = -2 rv = {'status': script.status, 'msg': msg} - return JsonResponse(rv) + return rv proc = instance.proc listoutput = proc.communicate(timeout=10)[0] @@ -799,7 +816,7 @@ def getscriptoutput(session): msg = 'Script stopped' script.status = -5 rv = {'status': script.status, 'msg': msg, 'output': listoutput} - return JsonResponse(rv) + return rv if returncode > 0: logger.info('return code is %s', returncode) if listoutput: @@ -815,19 +832,19 @@ def getscriptoutput(session): rv = {'script_id': script.script_id, 'status': script.status, 'msg': msg, 'output': output, 'returncode': returncode, 'variables': variables} - return JsonResponse(rv) + return rv except subprocess.TimeoutExpired: kill_script(script) msg = 'Timeout' script.status = -4 rv = {'status': script.status, 'msg': msg} - return JsonResponse(rv) + return rv except UnicodeDecodeError: kill_script(script) msg = 'Unicode Decode Error' script.status = -6 rv = {'status': script.status, 'msg': msg} - return JsonResponse(rv) + return rv def sendfile(session): @@ -1101,37 +1118,32 @@ def add_diagram(session): return (diagram, scripts, sessiondir) -def get_script(session, script_id, scripts=None, remove=False): - if script_id is None: - return None - if not script_id: - logger.warning('no id') +def get_script(session, task, scripts=None, remove=False): + if task is None: return None if scripts is None: (__, scripts, __, __, __, __, __) = init_session(session) - if script_id not in scripts: - logger.warning('id %s not in scripts', script_id) + if task.task_id not in scripts: + logger.warning('id %s not in scripts', task.task_id) return None - script = scripts[script_id] + script = scripts[task.task_id] if remove: - del scripts[script_id] + del scripts[task.task_id] return script -def add_script(session): - (__, scripts, getscriptcount, __, __, sessiondir, __) = init_session(session) - - script_id = getscriptcount() +def add_script(session, task): + (__, scripts, __, __, __, sessiondir, __) = init_session(session) script = Script() - script.script_id = script_id + script.script_id = task.task_id script.sessiondir = sessiondir - scripts[script_id] = script + scripts[task.task_id] = script return (script, sessiondir) @@ -1192,24 +1204,6 @@ def get_request_id(request, key='id'): return '' -def get_script_id(request, key='script_id', default=''): - form = request.form - if form is None: - logger.warning('No form in request') - return default - if key not in form: - logger.warning('No %s in request.form', key) - return default - value = form[key] - if re.fullmatch(r'[0-9]+', value): - return value - displayvalue = value if len( - value) <= DISPLAY_LIMIT + 3 else value[:DISPLAY_LIMIT] + '...' - logger.warning('Invalid value %s for %s in request.form', - displayvalue, key) - return default - - def internal_fun(session, task, internal_key): (__, __, __, scifile, __, sessiondir, __) = init_session(session) @@ -1335,10 +1329,10 @@ def kill_scilab(diagram=None, session=None): stopDetailsThread(diagram) -def kill_script(script=None, session=None): +def kill_script(script=None, session=None, task=None): '''Below route is called for stopping a running script file.''' if script is None: - script = get_script(session, get_script_id(), remove=True) + script = get_script(session, task, remove=True) if script is None: # when called with same script_id again or with incorrect script_id logger.warning('no script') diff --git a/blocks/simulationAPI/tasks.py b/blocks/simulationAPI/tasks.py index e13c73bb..fe3d32b8 100644 --- a/blocks/simulationAPI/tasks.py +++ b/blocks/simulationAPI/tasks.py @@ -8,6 +8,7 @@ import traceback from blocks.celery_tasks import app from simulationAPI.helpers.ngspice_helper import ExecXml, update_task_status from simulationAPI.models import Task +from simulationAPI.helpers.scilab_manager import uploadscript logger = get_task_logger(__name__) @@ -27,6 +28,7 @@ def release_lock(lock): def process_task(self, task_id): task = Task.objects.get(task_id=task_id) session_id = task.session.session_id + task_type = task.type current_thread().name = f"{session_id[:6]}:{task_id[:8]}" lock = acquire_lock(session_id) # Prevent multiple runs per session @@ -37,16 +39,24 @@ def process_task(self, task_id): update_task_status(task_id, 'STARTED', meta={'current_process': 'Started Processing File'}) - output = ExecXml(task, self.name) - if output == "Streaming": + if task_type == 'SCRIPT': + output = uploadscript(task.session, task) state = 'STREAMING' - current_process = 'Processed Xml, Streaming Output' - elif output == "Success": - state = 'SUCCESS' - current_process = 'Processed Xml, Loading Output' + current_process = 'Processed Script, Streaming Output' + else: + output = ExecXml(task, self.name) + # Set default values + # state = 'FAILED' + # current_process = 'Unknown error occurred' + if output == "Streaming": + state = 'STREAMING' + current_process = 'Processed Xml, Streaming Output' + elif output == "Success": + state = 'SUCCESS' + current_process = 'Processed Xml, Loading Output' update_task_status(task_id, state, - meta={'current_process': current_process}) + meta={'current_process': current_process}) return output except Exception as e: diff --git a/blocks/simulationAPI/urls.py b/blocks/simulationAPI/urls.py index 5e37d066..04d91a2e 100644 --- a/blocks/simulationAPI/urls.py +++ b/blocks/simulationAPI/urls.py @@ -18,4 +18,6 @@ urlpatterns = [ path('cancel/<uuid:task_id>', simulationAPI_views.CancelTaskView.as_view(), name='cancel'), path('get_session', simulationAPI_views.get_session, name='get_session'), + + path('get_script_output/<uuid:task_id>', simulationAPI_views.GetScriptOutputView.as_view(), name='get_script_output'), ] diff --git a/blocks/simulationAPI/views.py b/blocks/simulationAPI/views.py index dd1a7758..e5ffe344 100644 --- a/blocks/simulationAPI/views.py +++ b/blocks/simulationAPI/views.py @@ -18,6 +18,7 @@ from simulationAPI.negotiation import IgnoreClientContentNegotiation from simulationAPI.serializers import TaskSerializer from simulationAPI.tasks import process_task from simulationAPI.helpers.ngspice_helper import CreateXcos +from simulationAPI.helpers.scilab_manager import getscriptoutput SCILAB_INSTANCE_TIMEOUT_INTERVAL = 300 @@ -353,6 +354,23 @@ class StreamView(APIView): yield "event: DONE\ndata: None\n\n" +class GetScriptOutputView(APIView): + """ + API endpoint to get the output of a script execution. + """ + + def get(self, request, task_id, *args, **kwargs): + + task = Task.objects.get(task_id=task_id) + session = task.session + try: + result = getscriptoutput(session, task) + return Response(result, status=status.HTTP_200_OK) + except Exception as e: + logger.error(f"Error calling getscriptoutput (Session: {session}): {str(e)}") + return Response({"error": "Internal server error"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) + + def get_session(request): if not request.session.session_key: request.session.save() # Create a new session if not already exists |