matlab-proxy 0.9.1__py3-none-any.whl → 0.10.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of matlab-proxy might be problematic. Click here for more details.

matlab_proxy/app.py CHANGED
@@ -152,6 +152,9 @@ async def get_env_config(req):
152
152
  config = state.settings["env_config"]
153
153
  config["authEnabled"] = state.settings["mwi_is_token_auth_enabled"]
154
154
 
155
+ config["useMOS"] = mwi_env.Experimental.should_use_mos_html()
156
+ config["useMRE"] = mwi_env.Experimental.should_use_mre_html()
157
+
155
158
  # In a previously authenticated session, if the url is accessed without the token(using session cookie), send the token as well.
156
159
  config["authStatus"] = True if await token_auth.authenticate_request(req) else False
157
160
  return web.json_response(config)
matlab_proxy/app_state.py CHANGED
@@ -8,9 +8,17 @@ import os
8
8
  import time
9
9
  from collections import deque
10
10
  from datetime import datetime, timedelta, timezone
11
+ from typing import Final, Optional
11
12
 
12
13
  from matlab_proxy import util
13
- from matlab_proxy.settings import get_process_startup_timeout
14
+ from matlab_proxy.settings import (
15
+ get_process_startup_timeout,
16
+ )
17
+ from matlab_proxy.constants import (
18
+ CONNECTOR_SECUREPORT_FILENAME,
19
+ MATLAB_LOGS_FILE_NAME,
20
+ VERSION_INFO_FILE_NAME,
21
+ )
14
22
  from matlab_proxy.util import mw, mwi, system, windows
15
23
  from matlab_proxy.util.mwi import environment_variables as mwi_env
16
24
  from matlab_proxy.util.mwi import token_auth
@@ -25,7 +33,7 @@ from matlab_proxy.util.mwi.exceptions import (
25
33
  UIVisibleFatalError,
26
34
  log_error,
27
35
  )
28
- from matlab_proxy.constants import CONNECTOR_SECUREPORT_FILENAME, VERSION_INFO_FILE_NAME
36
+
29
37
 
30
38
  logger = mwi.logger.get()
31
39
 
@@ -36,7 +44,7 @@ class AppState:
36
44
  """
37
45
 
38
46
  # Constants that are applicable to AppState class
39
- MATLAB_PORT_CHECK_DELAY_IN_SECONDS = 1
47
+ MATLAB_PORT_CHECK_DELAY_IN_SECONDS: Final[int] = 1
40
48
 
41
49
  def __init__(self, settings):
42
50
  """Parameterized constructor for the AppState class.
@@ -227,64 +235,91 @@ class AppState:
227
235
  Returns:
228
236
  String: Status of MATLAB. Returns either up, down or starting.
229
237
  """
230
-
231
238
  # MATLAB can either be "up", "starting" or "down" state depending upon Xvfb, MATLAB and the Embedded Connector
232
- matlab = self.processes["matlab"]
233
- xvfb = self.processes["xvfb"]
239
+ # Return matlab status as "down" if the processes validation fails
240
+ if not self._are_required_processes_ready():
241
+ return "down"
242
+
243
+ # If execution reaches here, it implies that:
244
+ # 1) MATLAB process has started.
245
+ # 2) Embedded connector has not started yet.
246
+ return await self._get_matlab_connector_status()
247
+
248
+ def _are_required_processes_ready(
249
+ self, matlab_process=None, xvfb_process=None
250
+ ) -> bool:
251
+ # Update the processes to what is tracked in the instance's processes if a None is received
252
+ if matlab_process is None:
253
+ matlab_process = self.processes["matlab"]
254
+ if xvfb_process is None:
255
+ xvfb_process = self.processes["xvfb"]
234
256
 
235
257
  if system.is_linux():
236
- if xvfb is None or xvfb.returncode is not None:
258
+ if xvfb_process is None or xvfb_process.returncode is not None:
237
259
  logger.debug(
238
260
  "Xvfb has not started"
239
- if xvfb is None
240
- else f"Xvfb exited with returncode:{xvfb.returncode}"
261
+ if xvfb_process is None
262
+ else f"Xvfb exited with returncode:{xvfb_process.returncode}"
241
263
  )
242
- return "down"
264
+ return False
243
265
 
244
- if matlab is None or matlab.returncode is not None:
266
+ if matlab_process is None or matlab_process.returncode is not None:
245
267
  logger.debug(
246
268
  "MATLAB has not started"
247
- if matlab is None
248
- else f"MATLAB exited with returncode:{matlab.returncode}"
269
+ if matlab_process is None
270
+ else f"MATLAB exited with returncode:{matlab_process.returncode}"
249
271
  )
250
- return "down"
272
+ return False
251
273
 
252
274
  elif system.is_mac():
253
- if matlab is None or matlab.returncode is not None:
275
+ if matlab_process is None or matlab_process.returncode is not None:
254
276
  logger.debug(
255
277
  "MATLAB has not started"
256
- if matlab is None
257
- else f"MATLAB exited with returncode:{matlab.returncode}"
278
+ if matlab_process is None
279
+ else f"MATLAB exited with returncode:{matlab_process.returncode}"
258
280
  )
259
- return "down"
281
+ return False
260
282
 
261
283
  # For windows platform
262
284
  else:
263
- if matlab is None or not matlab.is_running():
285
+ if matlab_process is None or not matlab_process.is_running():
264
286
  logger.debug(
265
287
  "MATLAB has not started"
266
- if matlab is None
267
- else f"MATLAB exited with returncode:{matlab.wait()}"
288
+ if matlab_process is None
289
+ else f"MATLAB exited with returncode:{matlab_process.wait()}"
268
290
  )
269
- return "down"
291
+ return False
292
+
293
+ return True
294
+
295
+ def _get_token_auth_headers(self) -> Optional[dict]:
296
+ """Returns token info as headers if authentication is enabled.
297
+
298
+ Returns:
299
+ [Dict | None]: Returns token authentication headers if any.
300
+ """
301
+ return (
302
+ {self.settings["mwi_auth_token_name"]: self.settings["mwi_auth_token_hash"]}
303
+ if self.settings["mwi_is_token_auth_enabled"]
304
+ else None
305
+ )
306
+
307
+ async def _get_matlab_connector_status(self) -> str:
308
+ """Returns the status of MATLABs Embedded Connector.
270
309
 
310
+ Returns:
311
+ str: Returns any of "up", "down" or "starting" indicating the status of Embedded Connector.
312
+ """
271
313
  if not self.matlab_session_files["matlab_ready_file"].exists():
272
314
  return "starting"
273
315
 
274
- # If execution reaches here, it implies that:
275
- # 1) MATLAB process has started.
276
- # 2) Embedded connector has not started yet.
277
316
  # Proceed to query the Embedded Connector about its state.
278
317
  # matlab-proxy sends a request to itself to the endpoint: /messageservice/json/state
279
318
  # which the server redirects to the matlab_view() function to handle (which then sends the request to EC)
280
319
  # As the matlab_view is now a protected endpoint, we need to pass token information through headers.
281
320
 
282
321
  # Include token information into the headers if authentication is enabled.
283
- headers = (
284
- {self.settings["mwi_auth_token_name"]: self.settings["mwi_auth_token_hash"]}
285
- if self.settings["mwi_is_token_auth_enabled"]
286
- else None
287
- )
322
+ headers = self._get_token_auth_headers()
288
323
 
289
324
  embedded_connector_status = await mwi.embedded_connector.request.get_state(
290
325
  mwi_server_url=self.settings["mwi_server_url"],
@@ -300,16 +335,16 @@ class AppState:
300
335
  self.embedded_connector_state = embedded_connector_status
301
336
 
302
337
  if self.embedded_connector_state == "down":
303
- # So, even if the embedded connector's status is 'down', we'll
304
- # return matlab status as 'starting', because the MATLAB process itself has been created
305
- # and matlab-proxy is waiting for the embedded connector to start serving content.
338
+ # Even if the embedded connector's status is 'down', we return matlab status as
339
+ # 'starting' because the MATLAB process itself has been created and matlab-proxy
340
+ # is waiting for the embedded connector to start serving content.
306
341
  matlab_status = "starting"
307
342
 
308
343
  # Update time stamp when MATLAB state is "starting".
309
344
  if not self.embedded_connector_start_time:
310
345
  self.embedded_connector_start_time = time.time()
311
346
 
312
- # Embedded connector is also up, so set matlab_status to "up"
347
+ # Set matlab_status to "up" since embedded connector is up.
313
348
  else:
314
349
  matlab_status = "up"
315
350
 
@@ -395,12 +430,12 @@ class AppState:
395
430
  Returns:
396
431
  Boolean: True if MATLAB is Licensed. False otherwise.
397
432
  """
398
-
399
433
  if self.licensing is not None:
400
- if self.licensing["type"] == "nlm":
401
- if self.licensing["conn_str"] is not None:
434
+ logger.debug(f"Licensing type: {self.licensing.get('type')}")
435
+ if self.licensing.get("type") == "nlm":
436
+ if self.licensing.get("conn_str") is not None:
402
437
  return True
403
- elif self.licensing["type"] == "mhlm":
438
+ elif self.licensing.get("type") == "mhlm":
404
439
  if (
405
440
  self.licensing.get("identity_token") is not None
406
441
  and self.licensing.get("source_id") is not None
@@ -408,7 +443,7 @@ class AppState:
408
443
  and self.licensing.get("entitlement_id") is not None
409
444
  ):
410
445
  return True
411
- elif self.licensing["type"] == "existing_license":
446
+ elif self.licensing.get("type") == "existing_license":
412
447
  return True
413
448
  return False
414
449
 
@@ -514,7 +549,7 @@ class AppState:
514
549
  def create_logs_dir_for_MATLAB(self):
515
550
  """Creates the root folder where MATLAB writes the ready file and updates attibutes on self."""
516
551
 
517
- # NOTE It is not guranteed that the port will remain free!
552
+ # NOTE It is not guaranteed that the port will remain free!
518
553
  # FIXME Because of https://github.com/http-party/node-http-proxy/issues/1342 the
519
554
  # node application in development mode always uses port 31515 to bypass the
520
555
  # reverse proxy. Once this is addressed, remove this special case.
@@ -644,10 +679,41 @@ class AppState:
644
679
  # The mwi_logs_dir is where MATLAB will write any subsequent logs
645
680
  matlab_env["MATLAB_LOG_DIR"] = str(self.mwi_logs_dir)
646
681
 
682
+ # Set MW_CONNECTOR_CONTEXT_ROOT for MPA
683
+ if mwi_env.Experimental.is_mpa_enabled():
684
+ matlab_env["MW_CONNECTOR_CONTEXT_ROOT"] = self.settings.get("base_url", "/")
685
+ logger.info(
686
+ f"MW_CONNECTOR_CONTEXT_ROOT is set to: {matlab_env['MW_CONNECTOR_CONTEXT_ROOT']}"
687
+ )
688
+
689
+ # Setup Simulink Online which requires a pre-warm stage
690
+ if mwi_env.Experimental.is_simulink_enabled():
691
+ logger.info("Enabling usage of Simulink Online...")
692
+ matlab_env["PREWARM_SIMULINK"] = "true"
693
+
647
694
  # Env setup related to logging
648
695
  # Very verbose logging in debug mode
649
696
  if logger.isEnabledFor(logging.getLevelName("DEBUG")):
650
- matlab_env["MW_DIAGNOSTIC_DEST"] = "stdout"
697
+ mwi_log_file = self.settings.get("mwi_log_file", None)
698
+ # If a log file is supplied to write matlab-proxy server logs,
699
+ # use it to write MATLAB logs too.
700
+ if mwi_log_file:
701
+ # Append MATLAB logs to matlab-proxy logs
702
+ matlab_env["MW_DIAGNOSTIC_DEST"] = f"file,append={mwi_log_file}"
703
+
704
+ elif system.is_posix():
705
+ matlab_env["MW_DIAGNOSTIC_DEST"] = "stdout"
706
+
707
+ else:
708
+ # On windows stdout is not supported yet.
709
+ # So, use the default log file for MATLAB logs
710
+ matlab_logs_file = self.mwi_logs_dir / MATLAB_LOGS_FILE_NAME
711
+ # Write MATLAB logs
712
+ matlab_env["MW_DIAGNOSTIC_DEST"] = f"file={matlab_logs_file}"
713
+
714
+ logger.info(
715
+ f"Writing MATLAB process logs to: {matlab_env['MW_DIAGNOSTIC_DEST']}"
716
+ )
651
717
  matlab_env[
652
718
  "MW_DIAGNOSTIC_SPEC"
653
719
  ] = "connector::http::server=all;connector::lifecycle=all"
@@ -755,6 +821,139 @@ class AppState:
755
821
  # If something went wrong in starting matlab, return None
756
822
  return None
757
823
 
824
+ async def __force_stop_matlab(self, error, task):
825
+ """A private method to update self.error and force stop matlab"""
826
+ self.error = MatlabError(error)
827
+ logger.error(f"{task}: {error}")
828
+
829
+ # If force_quit is not set to True, stop_matlab() would try to
830
+ # send a HTTP request to the Embedded Connector (which is already "down")
831
+ await self.stop_matlab(force_quit=True)
832
+
833
+ async def __track_embedded_connector_state(self):
834
+ """track_embedded_connector_state is an asyncio task to track the status of MATLAB Embedded Connector.
835
+ This task will start and stop with the MATLAB process.
836
+ """
837
+ this_task = "track_embedded_connector_state:"
838
+ logger.debug(f"{this_task}: Starting task...")
839
+
840
+ while True:
841
+ if self.embedded_connector_state == "up":
842
+ logger.debug(
843
+ f"{this_task}: MATLAB Embedded Connector is up, not checking for any errors in MATLABs stderr pipe. Sleeping for 10 seconds..."
844
+ )
845
+ # Embedded connector is up, sleep for 10 seconds and recheck again
846
+ await asyncio.sleep(10)
847
+ continue
848
+
849
+ # Embedded connector is down, so check for how long it has been down and error out if necessary
850
+ # embedded_connector_start_time variable is updated by get_matlab_state().
851
+ else:
852
+ # If its not yet set, sleep for 1 second and recheck again
853
+ if not self.embedded_connector_start_time:
854
+ await asyncio.sleep(1)
855
+ continue
856
+
857
+ else:
858
+ time_diff = time.time() - self.embedded_connector_start_time
859
+ if time_diff > self.PROCESS_TIMEOUT:
860
+ # Since max allowed startup time has elapsed, it means that MATLAB is in a stuck state and cannot be launched.
861
+ # Set the error and stop matlab.
862
+ user_visible_error = "Unable to start MATLAB.\nTry again by clicking Start MATLAB."
863
+
864
+ if system.is_windows():
865
+ # In WINDOWS systems, errors are raised as UI windows and cannot be captured programmatically.
866
+ # So, raise a generic error wherever appropriate
867
+ generic_error = f"MATLAB did not start in {int(self.PROCESS_TIMEOUT)} seconds. Use Windows Remote Desktop to check for any errors."
868
+ logger.error(f":{this_task}: {generic_error}")
869
+ if len(self.logs["matlab"]) == 0:
870
+ await self.__force_stop_matlab(
871
+ user_visible_error, this_task
872
+ )
873
+ # Breaking out of the loop to end this task as matlab-proxy was unable to launch MATLAB successfully
874
+ # even after waiting for self.PROCESS_TIMEOUT
875
+ break
876
+ else:
877
+ # Do not stop the MATLAB process or break from the loop (the error type is unknown)
878
+ self.error = MatlabError(generic_error)
879
+ await asyncio.sleep(5)
880
+ continue
881
+
882
+ else:
883
+ # If there are no logs after the max startup time has elapsed, it means that MATLAB is in a stuck state and cannot be launched.
884
+ # Set the error and stop matlab.
885
+ logger.error(
886
+ f":{this_task}: MATLAB did not start in {int(self.PROCESS_TIMEOUT)} seconds!"
887
+ )
888
+ if len(self.logs["matlab"]) == 0:
889
+ await self.__force_stop_matlab(
890
+ user_visible_error, this_task
891
+ )
892
+ # Breaking out of the loop to end this task as matlab-proxy was unable to launch MATLAB successfully
893
+ # even after waiting for self.PROCESS_TIMEOUT
894
+ break
895
+
896
+ else:
897
+ logger.debug(
898
+ f"{this_task}: MATLAB has been in a 'starting' state for {int(time_diff)} seconds. Sleeping for 1 second..."
899
+ )
900
+ await asyncio.sleep(1)
901
+
902
+ async def __matlab_stderr_reader_posix(self):
903
+ """matlab_stderr_reader_posix is an asyncio task which reads the stderr pipe of the MATLAB process, parses it
904
+ and updates state variables accordingly.
905
+ """
906
+ if system.is_posix():
907
+ matlab = self.processes["matlab"]
908
+ logger.debug("matlab_stderr_reader_posix() task: Starting task...")
909
+
910
+ while not matlab.stderr.at_eof():
911
+ logger.debug(
912
+ "matlab_stderr_reader_posix() task: Waiting to read data from stderr pipe..."
913
+ )
914
+ line = await matlab.stderr.readline()
915
+ if line is None:
916
+ logger.debug(
917
+ "matlab_stderr_reader_posix() task: Received data from stderr pipe appending to logs..."
918
+ )
919
+ break
920
+ self.logs["matlab"].append(line)
921
+ await self.handle_matlab_output()
922
+
923
+ async def __update_matlab_port(self, delay: int):
924
+ """Task to populate matlab_port from the matlab ready file. Times out if max_duration is breached
925
+
926
+ Args:
927
+ delay (int): time delay in seconds before retrying the file read operation
928
+ """
929
+ logger.debug(
930
+ f'updating matlab_port information from {self.matlab_session_files["matlab_ready_file"]}'
931
+ )
932
+ try:
933
+ await asyncio.wait_for(
934
+ self.__read_matlab_ready_file(delay),
935
+ self.PROCESS_TIMEOUT,
936
+ )
937
+ except asyncio.TimeoutError:
938
+ logger.debug(
939
+ "Timeout error received while updating matlab port, stopping matlab!"
940
+ )
941
+ await self.stop_matlab(force_quit=True)
942
+ self.error = MatlabError(
943
+ "Unable to start MATLAB because of a timeout. Try again by clicking Start MATLAB."
944
+ )
945
+
946
+ async def __read_matlab_ready_file(self, delay):
947
+ # reads with delays from the file where connector has written its port information
948
+ while not self.matlab_session_files["matlab_ready_file"].exists():
949
+ await asyncio.sleep(delay)
950
+
951
+ with open(self.matlab_session_files["matlab_ready_file"]) as f:
952
+ self.matlab_port = int(f.read())
953
+ logger.debug(
954
+ f"MATLAB Ready file successfully read, matlab_port set to: {self.matlab_port}"
955
+ )
956
+
758
957
  async def start_matlab(self, restart_matlab=False):
759
958
  """Start MATLAB.
760
959
 
@@ -816,145 +1015,16 @@ class AppState:
816
1015
  logger.debug(f"Started MATLAB (PID={matlab.pid})")
817
1016
  self.processes["matlab"] = matlab
818
1017
 
819
- async def __track_embedded_connector_state():
820
- """track_embedded_connector_state is an asyncio task to track the status of MATLAB Embedded Connector.
821
- This task will start and stop with the MATLAB process.
822
- """
823
- this_task = "track_embedded_connector_state:"
824
- logger.debug(f"{this_task}: Starting task...")
825
-
826
- while True:
827
- if self.embedded_connector_state == "up":
828
- logger.debug(
829
- f"{this_task}: MATLAB Embedded Connector is up, not checking for any errors in MATLABs stderr pipe. Sleeping for 10 seconds..."
830
- )
831
- # Embedded connector is up, sleep for 10 seconds and recheck again
832
- await asyncio.sleep(10)
833
- continue
834
-
835
- # Embedded connector is down, so check for how long it has been down and error out if necessary
836
- # embedded_connector_start_time variable is updated by get_matlab_state().
837
- else:
838
- # If its not yet set, sleep for 1 second and recheck again
839
- if not self.embedded_connector_start_time:
840
- await asyncio.sleep(1)
841
- continue
842
-
843
- else:
844
- time_diff = time.time() - self.embedded_connector_start_time
845
- if time_diff > self.PROCESS_TIMEOUT:
846
- # Since max allowed startup time has elapsed, it means that MATLAB is in a stuck state and cannot be launched.
847
- # Set the error and stop matlab.
848
- user_visible_error = "Unable to start MATLAB.\nTry again by clicking Start MATLAB."
849
-
850
- async def __force_stop_matlab(error):
851
- """A private method to update self.error and force stop matlab"""
852
- self.error = MatlabError(error)
853
- logger.error(f"{this_task}: {error}")
854
-
855
- # If force_quit is not set to True, stop_matlab() would try to
856
- # send a HTTP request to the Embedded Connector (which is already "down")
857
- await self.stop_matlab(force_quit=True)
858
-
859
- if system.is_windows():
860
- # In WINDOWS systems, errors are raised as UI windows and cannot be captured programmatically.
861
- # So, raise a generic error wherever appropriate
862
- generic_error = f"MATLAB did not start in {int(self.PROCESS_TIMEOUT)} seconds. Use Windows Remote Desktop to check for any errors."
863
- logger.error(f":{this_task}: {generic_error}")
864
- if len(self.logs["matlab"]) == 0:
865
- await __force_stop_matlab(user_visible_error)
866
- # Breaking out of the loop to end this task as matlab-proxy was unable to launch MATLAB successfully
867
- # even after waiting for self.PROCESS_TIMEOUT
868
- break
869
- else:
870
- # Do not stop the MATLAB process or break from the loop (the error type is unknown)
871
- self.error = MatlabError(generic_error)
872
- await asyncio.sleep(5)
873
- continue
874
-
875
- else:
876
- # If there are no logs after the max startup time has elapsed, it means that MATLAB is in a stuck state and cannot be launched.
877
- # Set the error and stop matlab.
878
- logger.error(
879
- f":{this_task}: MATLAB did not start in {int(self.PROCESS_TIMEOUT)} seconds!"
880
- )
881
- if len(self.logs["matlab"]) == 0:
882
- await __force_stop_matlab(user_visible_error)
883
- # Breaking out of the loop to end this task as matlab-proxy was unable to launch MATLAB successfully
884
- # even after waiting for self.PROCESS_TIMEOUT
885
- break
886
-
887
- else:
888
- logger.debug(
889
- f"{this_task}: MATLAB has been in a 'starting' state for {int(time_diff)} seconds. Sleeping for 1 second..."
890
- )
891
- await asyncio.sleep(1)
892
-
893
- async def __matlab_stderr_reader_posix():
894
- """matlab_stderr_reader_posix is an asyncio task which reads the stderr pipe of the MATLAB process, parses it
895
- and updates state variables accordingly.
896
- """
897
- if system.is_posix():
898
- matlab = self.processes["matlab"]
899
- logger.debug("matlab_stderr_reader_posix() task: Starting task...")
900
-
901
- while not matlab.stderr.at_eof():
902
- logger.debug(
903
- "matlab_stderr_reader_posix() task: Waiting to read data from stderr pipe..."
904
- )
905
- line = await matlab.stderr.readline()
906
- if line is None:
907
- logger.debug(
908
- "matlab_stderr_reader_posix() task: Received data from stderr pipe appending to logs..."
909
- )
910
- break
911
- self.logs["matlab"].append(line)
912
- await self.handle_matlab_output()
913
-
914
- async def __update_matlab_port(delay: int):
915
- """Task to populate matlab_port from the matlab ready file. Times out if max_duration is breached
916
-
917
- Args:
918
- delay (int): time delay in seconds before retrying the file read operation
919
- """
920
- logger.debug(
921
- f'updating matlab_port information from {self.matlab_session_files["matlab_ready_file"]}'
922
- )
923
- try:
924
- await asyncio.wait_for(
925
- __read_matlab_ready_file(delay),
926
- self.PROCESS_TIMEOUT,
927
- )
928
- except asyncio.TimeoutError:
929
- logger.debug(
930
- "Timeout error received while updating matlab port, stopping matlab!"
931
- )
932
- await self.stop_matlab(force_quit=True)
933
- self.error = MatlabError(
934
- "Unable to start MATLAB because of a timeout. Try again by clicking Start MATLAB."
935
- )
936
-
937
- async def __read_matlab_ready_file(delay):
938
- # reads with delays from the file where connector has written its port information
939
- while not self.matlab_session_files["matlab_ready_file"].exists():
940
- await asyncio.sleep(delay)
941
-
942
- with open(self.matlab_session_files["matlab_ready_file"]) as f:
943
- self.matlab_port = int(f.read())
944
- logger.debug(
945
- f"MATLAB Ready file successfully read, matlab_port set to: {self.matlab_port}"
946
- )
947
-
948
1018
  loop = util.get_event_loop()
949
1019
  # Start all tasks relevant to MATLAB process
950
1020
  self.tasks["matlab_stderr_reader_posix"] = loop.create_task(
951
- __matlab_stderr_reader_posix()
1021
+ self.__matlab_stderr_reader_posix()
952
1022
  )
953
1023
  self.tasks["track_embedded_connector_state"] = loop.create_task(
954
- __track_embedded_connector_state()
1024
+ self.__track_embedded_connector_state()
955
1025
  )
956
1026
  self.tasks["update_matlab_port"] = loop.create_task(
957
- __update_matlab_port(self.MATLAB_PORT_CHECK_DELAY_IN_SECONDS)
1027
+ self.__update_matlab_port(self.MATLAB_PORT_CHECK_DELAY_IN_SECONDS)
958
1028
  )
959
1029
 
960
1030
  """
@@ -980,7 +1050,7 @@ class AppState:
980
1050
  except asyncio.CancelledError:
981
1051
  pass
982
1052
  If the request fails, the server process exits with error code 1.
983
-
1053
+
984
1054
  url = self.settings["mwi_server_url"] + "/terminate_integration"
985
1055
 
986
1056
  try:
@@ -998,7 +1068,7 @@ class AppState:
998
1068
  await matlab.wait()
999
1069
  except:
1000
1070
  logger.info(
1001
- f"Exception occured during termination of MATLAB process with PID: {matlab.pid}!"
1071
+ f"Exception occurred during termination of MATLAB process with PID: {matlab.pid}!"
1002
1072
  )
1003
1073
  pass
1004
1074
 
@@ -1026,12 +1096,16 @@ class AppState:
1026
1096
 
1027
1097
  try:
1028
1098
  data = mwi.embedded_connector.helpers.get_data_to_eval_mcode("exit")
1099
+ headers = self._get_token_auth_headers()
1029
1100
  url = mwi.embedded_connector.helpers.get_mvm_endpoint(
1030
1101
  self.settings["mwi_server_url"]
1031
1102
  )
1032
1103
 
1033
1104
  resp_json = await mwi.embedded_connector.send_request(
1034
- url=url, method="POST", data=data, headers=None
1105
+ url=url,
1106
+ method="POST",
1107
+ data=data,
1108
+ headers=headers,
1035
1109
  )
1036
1110
 
1037
1111
  if resp_json["messages"]["EvalResponse"][0]["isError"]:
@@ -1061,7 +1135,7 @@ class AppState:
1061
1135
  session_file.unlink()
1062
1136
 
1063
1137
  # In posix systems, variable matlab is an instance of asyncio.subprocess.Process()
1064
- # In windows systems, variable matlab is an isntance of psutil.Process()
1138
+ # In windows systems, variable matlab is an instance of psutil.Process()
1065
1139
  matlab = self.processes["matlab"]
1066
1140
 
1067
1141
  waiters = []
matlab_proxy/constants.py CHANGED
@@ -1,12 +1,14 @@
1
- # Copyright (c) 2023 The MathWorks, Inc.
1
+ # Copyright 2023 The MathWorks, Inc.
2
+ from typing import Final
2
3
 
3
4
  """This module defines project-level constants"""
4
5
 
5
- CONNECTOR_SECUREPORT_FILENAME = "connector.securePort"
6
- VERSION_INFO_FILE_NAME = "VersionInfo.xml"
7
- MAX_HTTP_REQUEST_SIZE = 500_000_000 # 500MB
6
+ CONNECTOR_SECUREPORT_FILENAME: Final[str] = "connector.securePort"
7
+ VERSION_INFO_FILE_NAME: Final[str] = "VersionInfo.xml"
8
+ MAX_HTTP_REQUEST_SIZE: Final[int] = 500_000_000 # 500MB
9
+ MATLAB_LOGS_FILE_NAME: Final[str] = "matlab_logs.txt"
8
10
 
9
11
  # Max startup duration in seconds for processes launched by matlab-proxy
10
12
  # This constant is meant for internal use within matlab-proxy
11
13
  # Clients of this package should use settings.py::get_process_startup_timeout() function
12
- DEFAULT_PROCESS_START_TIMEOUT = 120
14
+ DEFAULT_PROCESS_START_TIMEOUT: Final[int] = 600
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "files": {
3
3
  "main.css": "./static/css/main.aa888962.css",
4
- "main.js": "./static/js/main.daea642c.js",
4
+ "main.js": "./static/js/main.fbc5c728.js",
5
5
  "static/media/mathworks-pictograms.svg?20181009": "./static/media/mathworks-pictograms.f6f087b008b5a9435f26.svg",
6
6
  "static/media/MATLAB-env-blur.png": "./static/media/MATLAB-env-blur.4fc94edbc82d3184e5cb.png",
7
7
  "static/media/mathworks.svg?20181004": "./static/media/mathworks.80a3218e1ba29f0573fb.svg",
@@ -35,10 +35,10 @@
35
35
  "static/media/gripper.svg": "./static/media/gripper.9defbc5e76d0de8bb6e0.svg",
36
36
  "static/media/arrow.svg": "./static/media/arrow.0c2968b90bd9a64c8c3f.svg",
37
37
  "main.aa888962.css.map": "./static/css/main.aa888962.css.map",
38
- "main.daea642c.js.map": "./static/js/main.daea642c.js.map"
38
+ "main.fbc5c728.js.map": "./static/js/main.fbc5c728.js.map"
39
39
  },
40
40
  "entrypoints": [
41
41
  "static/css/main.aa888962.css",
42
- "static/js/main.daea642c.js"
42
+ "static/js/main.fbc5c728.js"
43
43
  ]
44
44
  }
@@ -1 +1 @@
1
- <!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="./favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="MATLAB"/><meta name="internal_mw_identifier" content="MWI_MATLAB_PROXY_IDENTIFIER"/><link rel="manifest" href="./manifest.json"/><title>MATLAB</title><script defer="defer" src="./static/js/main.daea642c.js"></script><link href="./static/css/main.aa888962.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
1
+ <!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="./favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="MATLAB"/><meta name="internal_mw_identifier" content="MWI_MATLAB_PROXY_IDENTIFIER"/><link rel="manifest" href="./manifest.json"/><title>MATLAB</title><script defer="defer" src="./static/js/main.fbc5c728.js"></script><link href="./static/css/main.aa888962.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>