matlab-proxy 0.23.4__py3-none-any.whl → 0.24.2__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.

Files changed (59) hide show
  1. matlab_proxy/app_state.py +48 -29
  2. matlab_proxy/gui/index.html +20 -1
  3. matlab_proxy/gui/static/css/index.BSVLACuY.css +10 -0
  4. matlab_proxy/gui/static/js/index.c3NLxnRM.js +64 -0
  5. matlab_proxy/settings.py +136 -86
  6. matlab_proxy/util/mwi/embedded_connector/helpers.py +2 -2
  7. matlab_proxy/util/mwi/embedded_connector/request.py +1 -1
  8. matlab_proxy/util/mwi/logger.py +1 -2
  9. matlab_proxy/util/mwi/validators.py +19 -11
  10. {matlab_proxy-0.23.4.dist-info → matlab_proxy-0.24.2.dist-info}/METADATA +3 -3
  11. {matlab_proxy-0.23.4.dist-info → matlab_proxy-0.24.2.dist-info}/RECORD +42 -57
  12. matlab_proxy_manager/lib/api.py +21 -18
  13. matlab_proxy_manager/storage/server.py +26 -1
  14. tests/unit/conftest.py +1 -2
  15. tests/unit/test_app_state.py +30 -3
  16. tests/unit/test_settings.py +190 -11
  17. tests/unit/util/mwi/test_logger.py +1 -2
  18. tests/unit/util/mwi/test_validators.py +12 -7
  19. matlab_proxy/gui/asset-manifest.json +0 -44
  20. matlab_proxy/gui/static/css/main.efa05ff9.css +0 -13
  21. matlab_proxy/gui/static/css/main.efa05ff9.css.map +0 -1
  22. matlab_proxy/gui/static/js/main.ce0f5505.js +0 -3
  23. matlab_proxy/gui/static/js/main.ce0f5505.js.LICENSE.txt +0 -59
  24. matlab_proxy/gui/static/js/main.ce0f5505.js.map +0 -1
  25. matlab_proxy/gui/static/media/arrow.0c2968b90bd9a64c8c3f.svg +0 -4
  26. matlab_proxy/gui/static/media/feedback.6e8d50eb812cf35e0e76.svg +0 -1
  27. matlab_proxy/gui/static/media/gripper.9defbc5e76d0de8bb6e0.svg +0 -1
  28. matlab_proxy/gui/static/media/help.15e5bfab03a2b9c7148e.svg +0 -1
  29. matlab_proxy/gui/static/media/ico-header-contact-hover.0958c44200d781def822.svg +0 -17
  30. matlab_proxy/gui/static/media/ico-header-contact.ae9169c8dcae37c6e04b.svg +0 -17
  31. matlab_proxy/gui/static/media/restart.7987508a01e84678361a.svg +0 -1
  32. matlab_proxy/gui/static/media/sign-out.08356b675ec854afaa77.svg +0 -1
  33. matlab_proxy/gui/static/media/start.50c4596fab2049b4a3a3.svg +0 -1
  34. matlab_proxy/gui/static/media/stop.30c9a9ab6d625032235a.svg +0 -1
  35. matlab_proxy/gui/static/media/terminate.7ea1363ee0fa72344ef6.svg +0 -1
  36. /matlab_proxy/gui/static/media/{MATLAB-env-blur.4fc94edbc82d3184e5cb.png → MATLAB-env-blur.NupTbPv_.png} +0 -0
  37. /matlab_proxy/gui/static/media/{glyphicons-halflings-regular.82b1212e45a2bc35dd73.woff → glyphicons-halflings-regular.BKjkU69z.woff} +0 -0
  38. /matlab_proxy/gui/static/media/{glyphicons-halflings-regular.5be1347c682810f199c7.eot → glyphicons-halflings-regular.BUJKDMgK.eot} +0 -0
  39. /matlab_proxy/gui/static/media/{glyphicons-halflings-regular.060b2710bdbbe3dfe48b.svg → glyphicons-halflings-regular.CSehLiBc.svg} +0 -0
  40. /matlab_proxy/gui/static/media/{glyphicons-halflings-regular.4692b9ec53fd5972caa2.ttf → glyphicons-halflings-regular.DrwTMapi.ttf} +0 -0
  41. /matlab_proxy/gui/static/media/{glyphicons-halflings-regular.be810be3a3e14c682a25.woff2 → glyphicons-halflings-regular.DzqM6ju8.woff2} +0 -0
  42. /matlab_proxy/gui/static/media/{ico-header-account-hover.89438e91d0632893b106.svg → ico-header-account-hover.-jQHo6Wx.svg} +0 -0
  43. /matlab_proxy/gui/static/media/{ico-header-account.86b10d7b4a2a511f6ca9.svg → ico-header-account.CJCFoo5a.svg} +0 -0
  44. /matlab_proxy/gui/static/media/{ico-sprite.cbdb66c0ea4c2a7fd21c.png → ico-sprite.DXGLgzq9.png} +0 -0
  45. /matlab_proxy/gui/static/media/{mathworks-eps.4d20e0ee46ea74bccfc1.ttf → mathworks-eps.CGNQALa9.ttf} +0 -0
  46. /matlab_proxy/gui/static/media/{mathworks-eps.df1428dfa69cea896c05.svg → mathworks-eps.DrkCtQtG.svg} +0 -0
  47. /matlab_proxy/gui/static/media/{mathworks-eps.e5c41e8478df02cbdce1.woff → mathworks-eps.Ds7lQbql.woff} +0 -0
  48. /matlab_proxy/gui/static/media/{mathworks-pictograms.3fc6513a06dce552eeb1.woff → mathworks-pictograms.BdqxEfBR.woff} +0 -0
  49. /matlab_proxy/gui/static/media/{mathworks-pictograms.f6f087b008b5a9435f26.svg → mathworks-pictograms.CCLweoD4.svg} +0 -0
  50. /matlab_proxy/gui/static/media/{mathworks-pictograms.6e128c0e7fc1a11f92ee.ttf → mathworks-pictograms.DZhFdRSm.ttf} +0 -0
  51. /matlab_proxy/gui/static/media/{mathworks.80a3218e1ba29f0573fb.svg → mathworks.C-qsbhDy.svg} +0 -0
  52. /matlab_proxy/gui/static/media/{mathworks.c422935b9ae545ac2ab5.ttf → mathworks.Ceplx86V.ttf} +0 -0
  53. /matlab_proxy/gui/static/media/{mathworks.37a563ef6aeda1593bf6.woff → mathworks.D08X1Vp8.woff} +0 -0
  54. /matlab_proxy/gui/static/media/{trigger-error.3f1c4ef23ab8f3e60b0e.svg → trigger-error.QEdsGL-m.svg} +0 -0
  55. /matlab_proxy/gui/static/media/{trigger-ok.7b9c238be42f685c4fa7.svg → trigger-ok.Dzg8OIrk.svg} +0 -0
  56. {matlab_proxy-0.23.4.dist-info → matlab_proxy-0.24.2.dist-info}/LICENSE.md +0 -0
  57. {matlab_proxy-0.23.4.dist-info → matlab_proxy-0.24.2.dist-info}/WHEEL +0 -0
  58. {matlab_proxy-0.23.4.dist-info → matlab_proxy-0.24.2.dist-info}/entry_points.txt +0 -0
  59. {matlab_proxy-0.23.4.dist-info → matlab_proxy-0.24.2.dist-info}/top_level.txt +0 -0
matlab_proxy/app_state.py CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright 2020-2024 The MathWorks, Inc.
1
+ # Copyright 2020-2025 The MathWorks, Inc.
2
2
 
3
3
  import asyncio
4
4
  import contextlib
@@ -10,15 +10,15 @@ import time
10
10
  import uuid
11
11
  from collections import deque
12
12
  from datetime import datetime, timedelta, timezone
13
- from typing import Final, Optional, Callable
13
+ from typing import Callable, Final, Optional
14
14
 
15
15
  from matlab_proxy import util
16
16
  from matlab_proxy.constants import (
17
+ CHECK_MATLAB_STATUS_INTERVAL_SECONDS,
17
18
  CONNECTOR_SECUREPORT_FILENAME,
18
19
  IS_CONCURRENCY_CHECK_ENABLED,
19
20
  MATLAB_LOGS_FILE_NAME,
20
21
  USER_CODE_OUTPUT_FILE_NAME,
21
- CHECK_MATLAB_STATUS_INTERVAL_SECONDS,
22
22
  )
23
23
  from matlab_proxy.settings import get_process_startup_timeout
24
24
  from matlab_proxy.util import mw, mwi, system, windows
@@ -30,10 +30,10 @@ from matlab_proxy.util.mwi.exceptions import (
30
30
  FatalError,
31
31
  LicensingError,
32
32
  MatlabError,
33
+ MatlabInstallError,
33
34
  OnlineLicensingError,
34
35
  UIVisibleFatalError,
35
36
  XvfbError,
36
- LockAcquisitionError,
37
37
  log_error,
38
38
  )
39
39
 
@@ -90,10 +90,6 @@ class AppState:
90
90
  self.error = settings["error"]
91
91
  self.warnings = settings["warnings"]
92
92
 
93
- if self.error is not None:
94
- self.logs["matlab"].clear()
95
- return
96
-
97
93
  # Keep track of when the Embedded connector starts.
98
94
  # Would be initialized appropriately by get_embedded_connector_state() task.
99
95
  self.embedded_connector_start_time = None
@@ -436,8 +432,10 @@ class AppState:
436
432
 
437
433
  else:
438
434
  await self.matlab_state_updater_lock.release()
439
- await self._update_matlab_state_based_on_ready_file_and_connector_status(
440
- matlab_endpoint_to_use
435
+ await (
436
+ self._update_matlab_state_based_on_ready_file_and_connector_status(
437
+ matlab_endpoint_to_use
438
+ )
441
439
  )
442
440
  logger.debug(
443
441
  f"{this_task}: Required processes are ready, Embedded Connector status is '{self.get_matlab_state()}'"
@@ -1107,6 +1105,12 @@ class AppState:
1107
1105
  Returns:
1108
1106
  (asyncio.subprocess.Process | psutil.Process): If process creation is successful, else return None.
1109
1107
  """
1108
+ # If there's no matlab_cmd available, it means that MATLAB is not available on system PATH.
1109
+ if not self.settings["matlab_cmd"]:
1110
+ raise MatlabInstallError(
1111
+ "Unable to find MATLAB on the system PATH. Add MATLAB to the system PATH, and restart matlab-proxy."
1112
+ )
1113
+
1110
1114
  if system.is_posix():
1111
1115
  import pty
1112
1116
 
@@ -1243,7 +1247,7 @@ class AppState:
1243
1247
  delay (int): time delay in seconds before retrying the file read operation
1244
1248
  """
1245
1249
  logger.debug(
1246
- f'updating matlab_port information from {self.matlab_session_files["matlab_ready_file"]}'
1250
+ f"updating matlab_port information from {self.matlab_session_files['matlab_ready_file']}"
1247
1251
  )
1248
1252
  try:
1249
1253
  await asyncio.wait_for(
@@ -1326,7 +1330,14 @@ class AppState:
1326
1330
  # Start MATLAB Process
1327
1331
  logger.debug("Starting MATLAB")
1328
1332
 
1329
- matlab = await self.__start_matlab_process(matlab_env)
1333
+ try:
1334
+ matlab = await self.__start_matlab_process(matlab_env)
1335
+
1336
+ # If there's an error with starting MATLAB, set the error to the state and matlab to None
1337
+ except MatlabInstallError as err:
1338
+ log_error(logger, err)
1339
+ self.error = err
1340
+ matlab = None
1330
1341
 
1331
1342
  # Release the lock after MATLAB process has started.
1332
1343
  await self.matlab_state_updater_lock.release()
@@ -1415,6 +1426,10 @@ class AppState:
1415
1426
  waiters = []
1416
1427
  if matlab is not None:
1417
1428
  if system.is_posix() and matlab.returncode is None:
1429
+ # Close the stderr stream to prevent indefinite hanging on it due to a child
1430
+ # process inheriting it, fixes https://github.com/mathworks/matlab-proxy/issues/44
1431
+ self._close_matlab_stderr_stream(matlab)
1432
+
1418
1433
  # Sending an exit request to the embedded connector takes time.
1419
1434
  # When MATLAB is in a "starting" state (implies the Embedded connector is not up)
1420
1435
  # OR
@@ -1427,23 +1442,9 @@ class AppState:
1427
1442
  else:
1428
1443
  logger.debug("Sending HTTP request to stop the MATLAB process...")
1429
1444
  try:
1430
- import sys
1431
-
1432
1445
  # Send HTTP request
1433
1446
  await self.__send_stop_request_to_matlab()
1434
1447
 
1435
- # Close the stderr stream to prevent indefinite hanging on it due to a child
1436
- # process inheriting it, fixes https://github.com/mathworks/matlab-proxy/issues/44
1437
- stderr_stream = matlab._transport.get_pipe_transport(
1438
- sys.stderr.fileno()
1439
- )
1440
- if stderr_stream:
1441
- logger.debug(
1442
- "Closing matlab process stderr stream: %s",
1443
- stderr_stream,
1444
- )
1445
- stderr_stream.close()
1446
-
1447
1448
  # Wait for matlab to shutdown gracefully
1448
1449
  await matlab.wait()
1449
1450
 
@@ -1461,9 +1462,10 @@ class AppState:
1461
1462
  try:
1462
1463
  matlab.terminate()
1463
1464
  await matlab.wait()
1464
- except:
1465
- pass
1466
-
1465
+ except Exception as ex:
1466
+ logger.debug(
1467
+ "Received an exception while terminating matlab: %s", ex
1468
+ )
1467
1469
  else:
1468
1470
  # In a windows system
1469
1471
  if system.is_windows() and matlab.is_running():
@@ -1533,6 +1535,23 @@ class AppState:
1533
1535
  self.matlab_port = None
1534
1536
  logger.debug("Completed Shutdown!!!")
1535
1537
 
1538
+ def _close_matlab_stderr_stream(self, matlab):
1539
+ """
1540
+ This method attempts to close the stderr stream associated with the MATLAB process
1541
+ to prevent potential resource leaks. It logs a debug message if the stream is
1542
+ successfully closed.
1543
+
1544
+ Args:
1545
+ matlab: The MATLAB process reference.
1546
+ """
1547
+ stderr_stream = matlab._transport.get_pipe_transport(sys.stderr.fileno())
1548
+ if stderr_stream:
1549
+ logger.debug(
1550
+ "Closing matlab process stderr stream: %s",
1551
+ stderr_stream,
1552
+ )
1553
+ stderr_stream.close()
1554
+
1536
1555
  async def handle_matlab_output(self):
1537
1556
  """Parse MATLAB output from stdout and raise errors if any."""
1538
1557
  matlab = self.processes["matlab"]
@@ -1 +1,20 @@
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.ce0f5505.js"></script><link href="./static/css/main.efa05ff9.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
1
+ <!-- Copyright 2025 The MathWorks, Inc. -->
2
+
3
+ <!doctype html>
4
+ <html lang="en">
5
+ <head>
6
+ <meta charset="UTF-8" />
7
+ <link rel="icon" href="./favicon.ico" />
8
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
9
+ <meta name="theme-color" content="#000000" />
10
+ <meta name="description" content="MATLAB" />
11
+ <meta name="internal_mw_identifier" content="MWI_MATLAB_PROXY_IDENTIFIER" />
12
+ <link rel="manifest" href="./manifest.json" />
13
+ <title>MATLAB</title>
14
+ <script type="module" crossorigin src="./static/js/index.c3NLxnRM.js"></script>
15
+ <link rel="stylesheet" crossorigin href="./static/css/index.BSVLACuY.css">
16
+ </head>
17
+ <body>
18
+ <div id="root"></div>
19
+ </body>
20
+ </html>