matlab-proxy 0.16.0__tar.gz → 0.18.0__tar.gz

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 (167) hide show
  1. {matlab-proxy-0.16.0/matlab_proxy.egg-info → matlab-proxy-0.18.0}/PKG-INFO +1 -1
  2. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/components/App/index.js +16 -0
  3. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/matlab_proxy/app.py +40 -24
  4. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/matlab_proxy/app_state.py +108 -4
  5. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/matlab_proxy/constants.py +1 -0
  6. matlab-proxy-0.18.0/matlab_proxy/matlab/evaluateUserMatlabCode.m +51 -0
  7. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/matlab_proxy/matlab/startup.m +2 -2
  8. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/matlab_proxy/settings.py +18 -2
  9. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/matlab_proxy/util/__init__.py +16 -7
  10. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/matlab_proxy/util/mwi/environment_variables.py +5 -0
  11. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/matlab_proxy/util/mwi/validators.py +13 -11
  12. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/matlab_proxy/util/windows.py +6 -2
  13. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0/matlab_proxy.egg-info}/PKG-INFO +1 -1
  14. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/matlab_proxy.egg-info/SOURCES.txt +1 -0
  15. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/matlab_proxy.egg-info/requires.txt +3 -1
  16. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/setup.py +8 -2
  17. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/tests/unit/test_app.py +14 -0
  18. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/tests/unit/test_app_state.py +112 -0
  19. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/tests/unit/test_settings.py +35 -0
  20. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/tests/unit/util/test_util.py +4 -1
  21. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/LICENSE.md +0 -0
  22. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/MANIFEST.in +0 -0
  23. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/README.md +0 -0
  24. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/.eslintrc.json +0 -0
  25. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/.gitignore +0 -0
  26. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/README.md +0 -0
  27. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/package-lock.json +0 -0
  28. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/package.json +0 -0
  29. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/public/favicon.ico +0 -0
  30. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/public/index.html +0 -0
  31. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/public/manifest.json +0 -0
  32. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/public/robots.txt +0 -0
  33. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/actionCreators/actionCreators.spec.js +0 -0
  34. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/actionCreators/index.js +0 -0
  35. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/actions/index.js +0 -0
  36. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/components/App/3p/css/bootstrap.min.css +0 -0
  37. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/components/App/3p/css/site7.min.css +0 -0
  38. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/components/App/3p/fonts/glyphicons-halflings-regular.eot +0 -0
  39. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/components/App/3p/fonts/glyphicons-halflings-regular.svg +0 -0
  40. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/components/App/3p/fonts/glyphicons-halflings-regular.ttf +0 -0
  41. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/components/App/3p/fonts/glyphicons-halflings-regular.woff +0 -0
  42. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/components/App/3p/fonts/glyphicons-halflings-regular.woff2 +0 -0
  43. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/components/App/3p/fonts/mathworks-eps.svg +0 -0
  44. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/components/App/3p/fonts/mathworks-eps.ttf +0 -0
  45. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/components/App/3p/fonts/mathworks-eps.woff +0 -0
  46. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/components/App/3p/fonts/mathworks-pictograms.svg +0 -0
  47. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/components/App/3p/fonts/mathworks-pictograms.ttf +0 -0
  48. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/components/App/3p/fonts/mathworks-pictograms.woff +0 -0
  49. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/components/App/3p/fonts/mathworks.svg +0 -0
  50. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/components/App/3p/fonts/mathworks.ttf +0 -0
  51. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/components/App/3p/fonts/mathworks.woff +0 -0
  52. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/components/App/3p/images/bug_reports/workaround.gif +0 -0
  53. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/components/App/3p/images/responsive/global/ico-header-account-hover.svg +0 -0
  54. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/components/App/3p/images/responsive/global/ico-header-account.svg +0 -0
  55. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/components/App/3p/images/responsive/global/ico-header-contact-hover.svg +0 -0
  56. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/components/App/3p/images/responsive/global/ico-header-contact.svg +0 -0
  57. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/components/App/3p/images/responsive/global/ico-sprite.png +0 -0
  58. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/components/App/App.css +0 -0
  59. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/components/App/App.spec.js +0 -0
  60. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/components/App/MATLAB-env-blur.png +0 -0
  61. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/components/Confirmation/Confirmation.spec.js +0 -0
  62. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/components/Confirmation/index.js +0 -0
  63. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/components/Controls/Controls.css +0 -0
  64. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/components/Controls/Controls.spec.js +0 -0
  65. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/components/Controls/feedback.svg +0 -0
  66. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/components/Controls/help.svg +0 -0
  67. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/components/Controls/index.js +0 -0
  68. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/components/Controls/restart.svg +0 -0
  69. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/components/Controls/sign-out.svg +0 -0
  70. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/components/Controls/start.svg +0 -0
  71. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/components/Controls/stop.svg +0 -0
  72. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/components/Controls/terminate.svg +0 -0
  73. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/components/EntitlementSelector/EntitlementSelector.spec.js +0 -0
  74. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/components/EntitlementSelector/index.js +0 -0
  75. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/components/Error/Error.css +0 -0
  76. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/components/Error/Error.spec.js +0 -0
  77. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/components/Error/index.js +0 -0
  78. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/components/Help/Help.css +0 -0
  79. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/components/Help/Help.spec.js +0 -0
  80. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/components/Help/index.js +0 -0
  81. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/components/Information/Information.css +0 -0
  82. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/components/Information/Information.spec.js +0 -0
  83. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/components/Information/index.js +0 -0
  84. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/components/LicensingGatherer/ExistingLicense.css +0 -0
  85. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/components/LicensingGatherer/ExistingLicense.js +0 -0
  86. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/components/LicensingGatherer/LicenseGatherer.spec.js +0 -0
  87. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/components/LicensingGatherer/LicensingGatherer.css +0 -0
  88. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/components/LicensingGatherer/MHLM.js +0 -0
  89. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/components/LicensingGatherer/NLM.js +0 -0
  90. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/components/LicensingGatherer/index.js +0 -0
  91. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/components/MatlabJsd/MatlabJsd.css +0 -0
  92. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/components/MatlabJsd/MatlabJsd.spec.js +0 -0
  93. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/components/MatlabJsd/index.js +0 -0
  94. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/components/Overlay/Overlay.css +0 -0
  95. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/components/Overlay/Overlay.spec.js +0 -0
  96. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/components/Overlay/index.js +0 -0
  97. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/components/OverlayTrigger/OverlayTrigger.css +0 -0
  98. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/components/OverlayTrigger/OverlayTrigger.spec.js +0 -0
  99. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/components/OverlayTrigger/ResizeOverlayTrigger.spec.js +0 -0
  100. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/components/OverlayTrigger/arrow.svg +0 -0
  101. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/components/OverlayTrigger/gripper.svg +0 -0
  102. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/components/OverlayTrigger/index.js +0 -0
  103. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/components/OverlayTrigger/trigger-error.svg +0 -0
  104. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/components/OverlayTrigger/trigger-ok.svg +0 -0
  105. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/constants.js +0 -0
  106. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/index.css +0 -0
  107. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/index.js +0 -0
  108. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/jest.config.json +0 -0
  109. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/logo.svg +0 -0
  110. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/reducers/index.js +0 -0
  111. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/reducers/reducers.spec.js +0 -0
  112. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/selectors/index.js +0 -0
  113. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/selectors/selectors.spec.js +0 -0
  114. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/serviceWorker.js +0 -0
  115. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/setupTests.js +0 -0
  116. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/test/utils/react-test.js +0 -0
  117. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/gui/src/test/utils/state.js +0 -0
  118. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/matlab_proxy/__init__.py +0 -0
  119. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/matlab_proxy/default_configuration.py +0 -0
  120. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/matlab_proxy/devel.py +0 -0
  121. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/matlab_proxy/icons/matlab.svg +0 -0
  122. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/matlab_proxy/util/event_loop.py +0 -0
  123. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/matlab_proxy/util/list_servers.py +0 -0
  124. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/matlab_proxy/util/mw.py +0 -0
  125. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/matlab_proxy/util/mwi/__init__.py +0 -0
  126. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/matlab_proxy/util/mwi/custom_http_headers.py +0 -0
  127. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/matlab_proxy/util/mwi/download.py +0 -0
  128. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/matlab_proxy/util/mwi/embedded_connector/__init__.py +0 -0
  129. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/matlab_proxy/util/mwi/embedded_connector/helpers.py +0 -0
  130. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/matlab_proxy/util/mwi/embedded_connector/request.py +0 -0
  131. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/matlab_proxy/util/mwi/exceptions.py +0 -0
  132. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/matlab_proxy/util/mwi/logger.py +0 -0
  133. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/matlab_proxy/util/mwi/token_auth.py +0 -0
  134. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/matlab_proxy/util/system.py +0 -0
  135. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/matlab_proxy.egg-info/dependency_links.txt +0 -0
  136. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/matlab_proxy.egg-info/entry_points.txt +0 -0
  137. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/matlab_proxy.egg-info/not-zip-safe +0 -0
  138. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/matlab_proxy.egg-info/top_level.txt +0 -0
  139. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/setup.cfg +0 -0
  140. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/tests/integration/__init__.py +0 -0
  141. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/tests/integration/integration_tests_with_license/__init__.py +0 -0
  142. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/tests/integration/integration_tests_with_license/conftest.py +0 -0
  143. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/tests/integration/integration_tests_with_license/test_http_end_points.py +0 -0
  144. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/tests/integration/integration_tests_without_license/__init__.py +0 -0
  145. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/tests/integration/integration_tests_without_license/conftest.py +0 -0
  146. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/tests/integration/integration_tests_without_license/test_matlab_is_down_if_unlicensed.py +0 -0
  147. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/tests/integration/utils/__init__.py +0 -0
  148. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/tests/integration/utils/integration_tests_utils.py +0 -0
  149. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/tests/integration/utils/licensing.py +0 -0
  150. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/tests/unit/__init__.py +0 -0
  151. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/tests/unit/conftest.py +0 -0
  152. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/tests/unit/test_constants.py +0 -0
  153. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/tests/unit/test_ddux.py +0 -0
  154. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/tests/unit/test_devel.py +0 -0
  155. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/tests/unit/test_non_dev_mode.py +0 -0
  156. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/tests/unit/util/__init__.py +0 -0
  157. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/tests/unit/util/mwi/__init__.py +0 -0
  158. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/tests/unit/util/mwi/embedded_connector/__init__.py +0 -0
  159. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/tests/unit/util/mwi/embedded_connector/test_helpers.py +0 -0
  160. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/tests/unit/util/mwi/embedded_connector/test_request.py +0 -0
  161. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/tests/unit/util/mwi/test_custom_http_headers.py +0 -0
  162. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/tests/unit/util/mwi/test_logger.py +0 -0
  163. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/tests/unit/util/mwi/test_token_auth.py +0 -0
  164. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/tests/unit/util/mwi/test_validators.py +0 -0
  165. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/tests/unit/util/test_mw.py +0 -0
  166. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/tests/utils/__init__.py +0 -0
  167. {matlab-proxy-0.16.0 → matlab-proxy-0.18.0}/tests/utils/logging_util.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: matlab-proxy
3
- Version: 0.16.0
3
+ Version: 0.18.0
4
4
  Summary: Python® package enables you to launch MATLAB® and access it from a web browser.
5
5
  Home-page: https://github.com/mathworks/matlab-proxy/
6
6
  Author: The MathWorks, Inc.
@@ -175,6 +175,22 @@ function App () {
175
175
  }
176
176
  }
177
177
 
178
+ useEffect(() => {
179
+ const handlePageHide = (event) => {
180
+ // Performs actions before the component unloads
181
+ if (isConcurrencyEnabled && !isSessionConcurrent && hasFetchedServerStatus) {
182
+ // A POST request to clear the active client when the tab/browser is closed
183
+ navigator.sendBeacon('./clear_client_id');
184
+ }
185
+ event.preventDefault();
186
+ event.returnValue = '';
187
+ };
188
+ window.addEventListener('pagehide', handlePageHide);
189
+ return () => {
190
+ window.removeEventListener('pagehide', handlePageHide);
191
+ };
192
+ }, [isConcurrencyEnabled, isSessionConcurrent, hasFetchedServerStatus]);
193
+
178
194
  useEffect(() => {
179
195
  // Initial fetch environment configuration
180
196
  if (!hasFetchedEnvConfig) {
@@ -6,7 +6,6 @@ import mimetypes
6
6
  import pkgutil
7
7
  import secrets
8
8
  import sys
9
- import uuid
10
9
 
11
10
  import aiohttp
12
11
  from aiohttp import client_exceptions, web
@@ -17,12 +16,11 @@ from cryptography import fernet
17
16
  import matlab_proxy
18
17
  from matlab_proxy import constants, settings, util
19
18
  from matlab_proxy.app_state import AppState
19
+ from matlab_proxy.constants import IS_CONCURRENCY_CHECK_ENABLED
20
20
  from matlab_proxy.util import mwi
21
+ from matlab_proxy.util.mwi import download, token_auth
21
22
  from matlab_proxy.util.mwi import environment_variables as mwi_env
22
- from matlab_proxy.util.mwi import token_auth, download
23
23
  from matlab_proxy.util.mwi.exceptions import AppError, InvalidTokenError, LicensingError
24
- from matlab_proxy.constants import IS_CONCURRENCY_CHECK_ENABLED
25
-
26
24
 
27
25
  mimetypes.add_type("font/woff", ".woff")
28
26
  mimetypes.add_type("font/woff2", ".woff2")
@@ -97,16 +95,15 @@ def marshal_error(error):
97
95
 
98
96
 
99
97
  async def create_status_response(
100
- app, loadUrl=None, client_id=None, transfer_session=False, is_desktop=False
98
+ app, loadUrl=None, client_id=None, is_active_client=None
101
99
  ):
102
100
  """Send a generic status response about the state of server, MATLAB, MATLAB Licensing and the client session status.
103
101
 
104
102
  Args:
105
103
  app (aiohttp.web.Application): Web Server
106
104
  loadUrl (String, optional): Represents the root URL. Defaults to None.
107
- client_id (String, optional): Represents the unique client_id when concurrency check is enabled. Defaults to None.
108
- transfer_session (Boolean, optional): Represents whether the connection should be transfered or not when concurrency check is enabled. Defaults to False.
109
- is_desktop (Boolean, optional): Represents whether the request is made by the desktop app or some other kernel. Defaults to False.
105
+ client_id (String, optional): Represents the generated client_id when concurrency check is enabled and client does not have a client_id. Defaults to None.
106
+ is_active_client (Boolean, optional): Represents whether the current client is the active_client when concurrency check is enabled. Defaults to None.
110
107
 
111
108
  Returns:
112
109
  JSONResponse: A JSONResponse object containing the generic state of the server, MATLAB, MATLAB Licensing and the client session status.
@@ -124,17 +121,30 @@ async def create_status_response(
124
121
  "wsEnv": state.settings.get("ws_env", ""),
125
122
  }
126
123
 
127
- if IS_CONCURRENCY_CHECK_ENABLED and is_desktop:
128
- if not client_id:
129
- client_id = str(uuid.uuid4())
130
- status["clientId"] = client_id
124
+ if client_id:
125
+ status["clientId"] = client_id
126
+ if is_active_client is not None:
127
+ status["isActiveClient"] = is_active_client
128
+
129
+ return web.json_response(status)
131
130
 
132
- if not state.active_client or transfer_session:
133
- state.active_client = client_id
134
131
 
135
- status["isActiveClient"] = True if state.active_client == client_id else False
132
+ @token_auth.authenticate_access_decorator
133
+ async def clear_client_id(req):
134
+ """API endpoint to reset the active client
136
135
 
137
- return web.json_response(status)
136
+ Args:
137
+ req (HTTPRequest): HTTPRequest Object
138
+
139
+ Returns:
140
+ Response: an empty response in JSON format
141
+ """
142
+ # Sleep for one second prior to clearing the client id to ensure that any remaining get_status responses are fully processed first.
143
+ await asyncio.sleep(1)
144
+ state = req.app["state"]
145
+ state.active_client = None
146
+ # This response is of no relevance to the front-end as the client has already exited
147
+ return web.json_response({})
138
148
 
139
149
 
140
150
  @token_auth.authenticate_access_decorator
@@ -201,15 +211,17 @@ async def get_status(req):
201
211
  JSONResponse: JSONResponse object containing information about the server, MATLAB and MATLAB Licensing.
202
212
  """
203
213
  # The client sends the CLIENT_ID as a query parameter if the concurrency check has been set to true.
214
+ state = req.app["state"]
204
215
  client_id = req.query.get("MWI_CLIENT_ID", None)
205
216
  transfer_session = json.loads(req.query.get("TRANSFER_SESSION", "false"))
206
217
  is_desktop = req.query.get("IS_DESKTOP", False)
207
218
 
219
+ generated_client_id, is_active_client = state.get_session_status(
220
+ is_desktop, client_id, transfer_session
221
+ )
222
+
208
223
  return await create_status_response(
209
- req.app,
210
- client_id=client_id,
211
- transfer_session=transfer_session,
212
- is_desktop=is_desktop,
224
+ req.app, client_id=generated_client_id, is_active_client=is_active_client
213
225
  )
214
226
 
215
227
 
@@ -409,7 +421,7 @@ async def termination_integration_delete(req):
409
421
  await req.app.cleanup()
410
422
  """When testing with pytest, its not possible to catch sys.exit(0) using the construct
411
423
  'with pytest.raises()', there by causing the test : test_termination_integration_delete()
412
- to fail. Inorder to avoid this, adding the below if condition to check to skip sys.exit(0) when testing
424
+ to fail. In order to avoid this, adding the below if condition to check to skip sys.exit(0) when testing
413
425
  """
414
426
  logger.debug("Exiting with return code 0")
415
427
  if not mwi_env.is_testing_mode_enabled():
@@ -462,7 +474,7 @@ def make_static_route_table(app):
462
474
  Returns:
463
475
  Dict: Containing information about the static files and header information.
464
476
  """
465
- from pkg_resources import resource_isdir, resource_listdir
477
+ import importlib_resources
466
478
 
467
479
  from matlab_proxy import gui
468
480
  from matlab_proxy.gui import static
@@ -479,8 +491,9 @@ def make_static_route_table(app):
479
491
  (gui.static.js.__name__, "/static/js"),
480
492
  (gui.static.media.__name__, "/static/media"),
481
493
  ]:
482
- for name in resource_listdir(mod, ""):
483
- if not resource_isdir(mod, name):
494
+ for entry in importlib_resources.files(mod).iterdir():
495
+ name = entry.name
496
+ if not importlib_resources.files(mod).joinpath(name).is_dir():
484
497
  if name != "__init__.py":
485
498
  # Special case for manifest.json
486
499
  if "manifest.json" in name:
@@ -773,6 +786,8 @@ async def cleanup_background_tasks(app):
773
786
  # Stop any running async tasks
774
787
  logger = mwi.logger.get()
775
788
  tasks = state.tasks
789
+ if state.task_detect_client_status:
790
+ tasks["detect_client_status"] = state.task_detect_client_status
776
791
  for task_name, task in tasks.items():
777
792
  if not task.cancelled():
778
793
  logger.debug(f"Cancelling MWI task: {task_name} : {task} ")
@@ -868,6 +883,7 @@ def create_app(config_name=matlab_proxy.get_default_config_name()):
868
883
  app.router.add_route("GET", f"{base_url}/get_auth_token", get_auth_token)
869
884
  app.router.add_route("GET", f"{base_url}/get_env_config", get_env_config)
870
885
  app.router.add_route("PUT", f"{base_url}/start_matlab", start_matlab)
886
+ app.router.add_route("POST", f"{base_url}/clear_client_id", clear_client_id)
871
887
  app.router.add_route("DELETE", f"{base_url}/stop_matlab", stop_matlab)
872
888
  app.router.add_route("PUT", f"{base_url}/set_licensing_info", set_licensing_info)
873
889
  app.router.add_route("PUT", f"{base_url}/update_entitlement", update_entitlement)
@@ -9,15 +9,18 @@ import time
9
9
  from collections import deque
10
10
  from datetime import datetime, timedelta, timezone
11
11
  from typing import Final, Optional
12
+ import uuid
12
13
 
13
14
  from matlab_proxy import util
14
15
  from matlab_proxy.constants import (
15
16
  CONNECTOR_SECUREPORT_FILENAME,
16
17
  MATLAB_LOGS_FILE_NAME,
18
+ IS_CONCURRENCY_CHECK_ENABLED,
19
+ USER_CODE_OUTPUT_FILE_NAME,
17
20
  )
18
- from matlab_proxy.settings import (
19
- get_process_startup_timeout,
20
- )
21
+
22
+ from matlab_proxy.settings import get_process_startup_timeout
23
+
21
24
  from matlab_proxy.util import mw, mwi, system, windows
22
25
  from matlab_proxy.util.mwi import environment_variables as mwi_env
23
26
  from matlab_proxy.util.mwi import token_auth
@@ -103,6 +106,12 @@ class AppState:
103
106
  # connected to the backend
104
107
  self.active_client = None
105
108
 
109
+ # Used to detect whether the active client is actively sending out request or is inactive
110
+ self.active_client_request_detected = False
111
+
112
+ # An event loop task to handle the detection of client activity
113
+ self.task_detect_client_status = None
114
+
106
115
  def __get_cached_config_file(self):
107
116
  """Get the cached config file
108
117
 
@@ -586,6 +595,24 @@ class AppState:
586
595
  self.matlab_session_files["matlab_ready_file"] = matlab_ready_file
587
596
 
588
597
  logger.debug(f"matlab_session_files:{self.matlab_session_files}")
598
+
599
+ # check if the user has provided any code or not
600
+ if self.settings.get("has_custom_code_to_execute"):
601
+ # Keep a reference to the user code output file in the matlab_session_files for cleanup
602
+ user_code_output_file = mwi_logs_dir / USER_CODE_OUTPUT_FILE_NAME
603
+ self.matlab_session_files["startup_code_output_file"] = (
604
+ user_code_output_file
605
+ )
606
+ logger.info(
607
+ util.prettify(
608
+ boundary_filler="*",
609
+ text_arr=[
610
+ f"When MATLAB starts, you can see the output for your startup code at:",
611
+ f"{self.matlab_session_files.get('startup_code_output_file', ' ')}",
612
+ ],
613
+ )
614
+ )
615
+
589
616
  return
590
617
 
591
618
  def create_server_info_file(self):
@@ -838,6 +865,10 @@ class AppState:
838
865
 
839
866
  return matlab
840
867
 
868
+ except UIVisibleFatalError as e:
869
+ self.error = e
870
+ log_error(logger, e)
871
+
841
872
  except Exception as err:
842
873
  self.error = err
843
874
  log_error(logger, err)
@@ -964,7 +995,7 @@ class AppState:
964
995
  )
965
996
  await self.stop_matlab(force_quit=True)
966
997
  self.error = MatlabError(
967
- "Unable to start MATLAB because of a timeout. Try again by clicking Start MATLAB."
998
+ "MATLAB startup has timed out. Click Start MATLAB to try again."
968
999
  )
969
1000
 
970
1001
  async def __read_matlab_ready_file(self, delay):
@@ -1304,3 +1335,76 @@ class AppState:
1304
1335
  if err is not None:
1305
1336
  self.error = err
1306
1337
  log_error(logger, err)
1338
+
1339
+ def get_session_status(self, is_desktop, client_id, transfer_session):
1340
+ """
1341
+ Determines the session status for a client, potentially generating a new client ID.
1342
+
1343
+ This function is responsible for managing and tracking the session status of a client.
1344
+ It can generate a new client ID if one is not provided and the conditions are met.
1345
+ It also manages the active client status within the session, especially in scenarios
1346
+ involving desktop clients and when concurrency checks are enabled.
1347
+
1348
+ Args:
1349
+ is_desktop (bool): A flag indicating whether the client is a desktop client.
1350
+ client_id (str or None): The client ID. If None, a new client ID may be generated.
1351
+ transfer_session (bool): Indicates whether the session should be transferred to this client.
1352
+
1353
+ Returns:
1354
+ tuple:
1355
+ - A 2-tuple containing the generated client ID (or None if not generated) and
1356
+ a boolean indicating whether the client is considered the active client.
1357
+ - If concurrency checks are not enabled or the client is not a desktop client, it returns None for both
1358
+ the generated client ID and the active client status.
1359
+ """
1360
+ if IS_CONCURRENCY_CHECK_ENABLED and is_desktop:
1361
+ generated_client_id = None
1362
+ if not client_id:
1363
+ generated_client_id = str(uuid.uuid4())
1364
+ client_id = generated_client_id
1365
+
1366
+ if not self.active_client or transfer_session:
1367
+ self.active_client = client_id
1368
+
1369
+ if not self.task_detect_client_status:
1370
+ # Create the loop to detect the active status of the client
1371
+ loop = util.get_event_loop()
1372
+ self.task_detect_client_status = loop.create_task(
1373
+ self.detect_active_client_status()
1374
+ )
1375
+
1376
+ if self.active_client == client_id:
1377
+ is_active_client = True
1378
+ self.active_client_request_detected = True
1379
+ else:
1380
+ is_active_client = False
1381
+ return generated_client_id, is_active_client
1382
+ return None, None
1383
+
1384
+ async def detect_active_client_status(self, sleep_time=1, max_inactive_count=10):
1385
+ """Detects whether the client is online or not by continuously checking if the active client is making requests
1386
+
1387
+ Args:
1388
+ sleep_time (int): The time in seconds for which the process waits before checking for the next get_status request from the active client.
1389
+ max_inactive_count (int): The maximum number of times the check for the request from the active_client fails before reseting the active client id.
1390
+ """
1391
+ inactive_count = 0
1392
+ while self.active_client:
1393
+ # Check if the get_status request from the active client is received or not
1394
+ await asyncio.sleep(sleep_time)
1395
+ if self.active_client_request_detected:
1396
+ self.active_client_request_detected = False
1397
+ inactive_count = 0
1398
+ else:
1399
+ inactive_count = inactive_count + 1
1400
+ if inactive_count > max_inactive_count:
1401
+ # If no request is received from the active_client for more than 10 seconds then clear the active client id
1402
+ inactive_count = 0
1403
+ self.active_client = None
1404
+ if self.task_detect_client_status:
1405
+ try:
1406
+ # Self cleanup of the task
1407
+ self.task_detect_client_status.cancel()
1408
+ self.task_detect_client_status = None
1409
+ except Exception as e:
1410
+ logger.error("Cleaning of task: 'detect_client_status' failed.")
@@ -7,6 +7,7 @@ CONNECTOR_SECUREPORT_FILENAME: Final[str] = "connector.securePort"
7
7
  VERSION_INFO_FILE_NAME: Final[str] = "VersionInfo.xml"
8
8
  MAX_HTTP_REQUEST_SIZE: Final[int] = 500_000_000 # 500MB
9
9
  MATLAB_LOGS_FILE_NAME: Final[str] = "matlab_logs.txt"
10
+ USER_CODE_OUTPUT_FILE_NAME: Final[str] = "startup_code_output.txt"
10
11
 
11
12
  # Max startup duration in seconds for processes launched by matlab-proxy
12
13
  # This constant is meant for internal use within matlab-proxy
@@ -0,0 +1,51 @@
1
+ % Copyright 2024 The MathWorks, Inc.
2
+
3
+ % Note:
4
+ % Any extra variable we are creating begins with `mwiInternal` to prevent
5
+ % potential conflicts with variables created by user code evaluated using evalc.
6
+ % Since evalc("user code") is executed in the base workspace, it might create
7
+ % variables that could overwrite our internal variables. To avoid polluting the
8
+ % user's workspace when MATLAB starts, we ensure to clear any internal variable
9
+ % that we create in the base workspace. We do not need to be concerned about
10
+ % variables in the function's workspace.
11
+
12
+ if ~isempty(getenv('MWI_MATLAB_STARTUP_SCRIPT')) && ~all(isspace(getenv('MWI_MATLAB_STARTUP_SCRIPT')))
13
+ try
14
+ % Evaluate the code from the environment variable and capture the output
15
+ mwiInternalResults = evalc(getenv('MWI_MATLAB_STARTUP_SCRIPT'));
16
+ % Write the results to the file
17
+ logOutputOrError(mwiInternalResults);
18
+ clear mwiInternalResults;
19
+ catch mwiInternalException
20
+ % Log the error message to the file
21
+ logOutputOrError(" ", mwiInternalException);
22
+ clear mwiInternalResults mwiInternalException;
23
+ error("Unable to run the startup code you specified. For details of the error, see the output file at " + fullfile(getenv('MATLAB_LOG_DIR'), "startup_code_output.txt"));
24
+ end
25
+
26
+ end
27
+
28
+ function logOutputOrError(userCodeResults, mwiInternalException)
29
+ % Logs the results of the user code execution if successful, otherwise logs the
30
+ % error information. It then closes the file handle.
31
+ %
32
+ % Inputs:
33
+ % userCodeResults - String containing the output from the user code.
34
+ % mwiInternalException - (Optional) MException object containing error details.
35
+ filePath = fullfile(getenv('MATLAB_LOG_DIR'), "startup_code_output.txt");
36
+ [fileHandle, ~] = fopen(filePath, 'w');
37
+ if nargin < 2
38
+ % Log the successful output of the user code
39
+ fprintf(fileHandle, " ");
40
+ fprintf(fileHandle, userCodeResults);
41
+ else
42
+ % Log the error information
43
+ fprintf(fileHandle, 'An error occurred in the following code:\n');
44
+ fprintf(fileHandle, getenv('MWI_MATLAB_STARTUP_SCRIPT'));
45
+ fprintf(fileHandle, '\n\nMessage: %s\n', mwiInternalException.message);
46
+ fprintf(fileHandle, '\nError Identifier: %s\n', mwiInternalException.identifier);
47
+ end
48
+ % Close the file handle
49
+ fclose(fileHandle);
50
+ end
51
+
@@ -1,4 +1,4 @@
1
- % Copyright (c) 2020-2023 The MathWorks, Inc.
1
+ % Copyright 2020-2024 The MathWorks, Inc.
2
2
 
3
3
  % Configure logged in user if possible
4
4
  if ~isempty(getenv('MW_LOGIN_USER_ID'))
@@ -34,4 +34,4 @@ end
34
34
  matlab_settings.matlab.addons.explorer.isExplorerSupported.TemporaryValue = false;
35
35
 
36
36
  clear
37
- clc
37
+ clc
@@ -366,7 +366,10 @@ def get_matlab_settings():
366
366
  flag_to_hide_desktop = ["-nodesktop"]
367
367
  if system.is_windows():
368
368
  flag_to_hide_desktop.extend(["-noDisplayDesktop", "-wait", "-log"])
369
- matlab_startup_file = str(Path(__file__).resolve().parent / "matlab" / "startup.m")
369
+
370
+ matlab_code_dir = Path(__file__).resolve().parent / "matlab"
371
+ matlab_startup_file = str(matlab_code_dir / "startup.m")
372
+ matlab_code_file = str(matlab_code_dir / "evaluateUserMatlabCode.m")
370
373
 
371
374
  matlab_version = get_matlab_version(matlab_root_path)
372
375
 
@@ -388,6 +391,18 @@ def get_matlab_settings():
388
391
  profile_matlab_startup = (
389
392
  "-timing" if mwi_env.Experimental.is_matlab_startup_profiling_enabled() else ""
390
393
  )
394
+
395
+ has_custom_code_to_execute = (
396
+ len(os.getenv(mwi_env.get_env_name_custom_matlab_code(), "").strip()) > 0
397
+ )
398
+ mp_code_to_execute = f"try; run('{matlab_startup_file}'); catch MATLABProxyInitializationError; disp(MATLABProxyInitializationError.message); end;"
399
+ custom_code_to_execute = f"try; run('{matlab_code_file}'); catch MATLABCustomStartupCodeError; disp(MATLABCustomStartupCodeError.message); end;"
400
+ code_to_execute = (
401
+ mp_code_to_execute + custom_code_to_execute
402
+ if has_custom_code_to_execute
403
+ else mp_code_to_execute
404
+ )
405
+
391
406
  return {
392
407
  "matlab_path": matlab_root_path,
393
408
  "matlab_version": matlab_version,
@@ -402,13 +417,14 @@ def get_matlab_settings():
402
417
  *mpa_flags,
403
418
  profile_matlab_startup,
404
419
  "-r",
405
- f"try; run('{matlab_startup_file}'); catch ME; disp(ME.message); end;",
420
+ code_to_execute,
406
421
  ],
407
422
  "ws_env": ws_env,
408
423
  "mwa_api_endpoint": f"https://login{ws_env_suffix}.mathworks.com/authenticationws/service/v4",
409
424
  "mhlm_api_endpoint": f"https://licensing{ws_env_suffix}.mathworks.com/mls/service/v1/entitlement/list",
410
425
  "mwa_login": f"https://login{ws_env_suffix}.mathworks.com",
411
426
  "nlm_conn_str": nlm_conn_str,
427
+ "has_custom_code_to_execute": has_custom_code_to_execute,
412
428
  }
413
429
 
414
430
 
@@ -11,6 +11,9 @@ import matlab_proxy
11
11
  from matlab_proxy.util import mwi, system
12
12
  from matlab_proxy.util.event_loop import *
13
13
  from matlab_proxy.util.mwi import environment_variables as mwi_env
14
+ from matlab_proxy.util.mwi.exceptions import (
15
+ UIVisibleFatalError,
16
+ )
14
17
 
15
18
  logger = mwi.logger.get()
16
19
 
@@ -181,7 +184,7 @@ def prettify(boundary_filler=" ", text_arr=[]):
181
184
  return result
182
185
 
183
186
 
184
- def get_child_processes(parent_process):
187
+ def get_child_processes(parent_process, max_attempts=10, sleep_interval=1):
185
188
  """Get list of child processes from a parent process.
186
189
 
187
190
  Args:
@@ -199,7 +202,6 @@ def get_child_processes(parent_process):
199
202
  # to get hold child processes
200
203
  parent_process_psutil = psutil.Process(parent_process.pid)
201
204
 
202
- max_attempts = 10
203
205
  child_processes = None
204
206
  for _ in range(max_attempts):
205
207
  try:
@@ -212,17 +214,24 @@ def get_child_processes(parent_process):
212
214
 
213
215
  if not child_processes:
214
216
  logger.debug("Waiting for the child processes to be created...")
217
+ time.sleep(sleep_interval)
215
218
  continue
216
219
 
220
+ else:
221
+ logger.debug(f"Found the child process: {child_processes[0]}")
222
+ break
223
+
217
224
  except AssertionError as err:
218
225
  raise err
219
226
 
220
- if child_processes:
221
- break
222
- time.sleep(0.1)
223
-
224
227
  if not child_processes:
225
- raise RuntimeError("No child processes found after multiple attempts.")
228
+ logger.debug(
229
+ f"MATLAB process was not found while searching for the child processes."
230
+ )
231
+
232
+ raise UIVisibleFatalError(
233
+ "Unable to create MATLAB process. Click Start MATLAB to try again."
234
+ )
226
235
 
227
236
  return child_processes
228
237
 
@@ -162,6 +162,11 @@ def get_env_name_process_startup_timeout():
162
162
  return "MWI_PROCESS_START_TIMEOUT"
163
163
 
164
164
 
165
+ def get_env_name_custom_matlab_code():
166
+ """User specified MATLAB code that will be executed by matlab-proxy upon its start"""
167
+ return "MWI_MATLAB_STARTUP_SCRIPT"
168
+
169
+
165
170
  class Experimental:
166
171
  """This class houses functions which are undocumented APIs and Environment variables.
167
172
  Note: Never add any state to this class. Its only intended for use as an abstraction layer
@@ -1,31 +1,30 @@
1
1
  # Copyright 2020-2024 The MathWorks, Inc.
2
2
  """This file contains validators for various runtime artifacts.
3
- A validator is defined as a function which verifies the input and
4
- returns it unchanged if validation passes.
3
+ A validator is defined as a function which verifies the input and
4
+ returns it unchanged if validation passes.
5
5
  Returning inputs allows validators to be used inline with the input.
6
6
 
7
- Example:
7
+ Example:
8
8
  Original code: if( input ):
9
9
  With validator: if (valid(input)):
10
10
 
11
11
  Exceptions are thrown to signal failure.
12
12
  """
13
+
13
14
  import errno
14
15
  import os
15
- from pathlib import Path
16
- import pkg_resources
17
16
  import socket
17
+ from pathlib import Path
18
18
  from typing import List
19
19
 
20
-
21
20
  import matlab_proxy
22
21
  from matlab_proxy import util
23
- from matlab_proxy.util import system
24
22
  from matlab_proxy.constants import VERSION_INFO_FILE_NAME
23
+ from matlab_proxy.util import system
25
24
 
26
25
  from . import environment_variables as mwi_env
27
26
  from . import logger as mwi_logger
28
- from .exceptions import MatlabInstallError, FatalError
27
+ from .exceptions import FatalError, MatlabInstallError
29
28
 
30
29
  logger = mwi_logger.get()
31
30
 
@@ -213,10 +212,13 @@ def __get_configs():
213
212
  Dict: Contains all the values present in 'matlab_web_desktop_configs' entry_point from all the packages
214
213
  installed in the current environment.
215
214
  """
215
+ import importlib_metadata
216
+
217
+ matlab_proxy_eps = importlib_metadata.entry_points(
218
+ group=matlab_proxy.get_entrypoint_name()
219
+ )
216
220
  configs = {}
217
- for entry_point in pkg_resources.iter_entry_points(
218
- matlab_proxy.get_entrypoint_name()
219
- ):
221
+ for entry_point in matlab_proxy_eps:
220
222
  configs[entry_point.name.lower()] = entry_point.load()
221
223
 
222
224
  return configs
@@ -1,9 +1,12 @@
1
- # Copyright 2022-2023 The MathWorks, Inc.
1
+ # Copyright 2022-2024 The MathWorks, Inc.
2
2
  import asyncio
3
3
 
4
4
  from matlab_proxy import util
5
5
  from matlab_proxy.util import mwi
6
6
  from matlab_proxy.util.mwi import environment_variables as mwi_env
7
+ from matlab_proxy.util.mwi.exceptions import (
8
+ UIVisibleFatalError,
9
+ )
7
10
 
8
11
 
9
12
  """ This file contains methods specific to non-posix / windows OS.
@@ -77,8 +80,9 @@ async def start_matlab(matlab_cmd, matlab_env):
77
80
  "MATLAB.exe" == matlab.name()
78
81
  ), "Expecting the child process name to be MATLAB.exe"
79
82
 
80
- except AssertionError as err:
83
+ except (AssertionError, UIVisibleFatalError) as err:
81
84
  raise err
85
+
82
86
  except psutil.NoSuchProcess:
83
87
  # We reach here when the intermediate process launched by matlab-proxy died
84
88
  # before we can query for its child processes. Hence, to find the actual MATLAB
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: matlab-proxy
3
- Version: 0.16.0
3
+ Version: 0.18.0
4
4
  Summary: Python® package enables you to launch MATLAB® and access it from a web browser.
5
5
  Home-page: https://github.com/mathworks/matlab-proxy/
6
6
  Author: The MathWorks, Inc.
@@ -113,6 +113,7 @@ matlab_proxy.egg-info/not-zip-safe
113
113
  matlab_proxy.egg-info/requires.txt
114
114
  matlab_proxy.egg-info/top_level.txt
115
115
  matlab_proxy/icons/matlab.svg
116
+ matlab_proxy/matlab/evaluateUserMatlabCode.m
116
117
  matlab_proxy/matlab/startup.m
117
118
  matlab_proxy/util/__init__.py
118
119
  matlab_proxy/util/event_loop.py
@@ -1,6 +1,8 @@
1
1
  aiohttp>=3.7.4
2
- psutil
3
2
  aiohttp_session[secure]
3
+ importlib-metadata
4
+ importlib-resources
5
+ psutil
4
6
 
5
7
  [dev]
6
8
  aiohttp-devtools
@@ -63,14 +63,20 @@ TESTS_REQUIRES = [
63
63
  "pytest-playwright",
64
64
  ]
65
65
 
66
- INSTALL_REQUIRES = ["aiohttp>=3.7.4", "psutil", "aiohttp_session[secure]"]
66
+ INSTALL_REQUIRES = [
67
+ "aiohttp>=3.7.4",
68
+ "aiohttp_session[secure]",
69
+ "importlib-metadata",
70
+ "importlib-resources",
71
+ "psutil",
72
+ ]
67
73
 
68
74
  HERE = Path(__file__).parent.resolve()
69
75
  long_description = (HERE / "README.md").read_text()
70
76
 
71
77
  setuptools.setup(
72
78
  name="matlab-proxy",
73
- version="0.16.0",
79
+ version="0.18.0",
74
80
  url=config["doc_url"],
75
81
  author="The MathWorks, Inc.",
76
82
  author_email="cloud@mathworks.com",