matlab-proxy 0.19.0__py3-none-any.whl → 0.21.0__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 (41) hide show
  1. matlab_proxy/app.py +22 -15
  2. matlab_proxy/gui/asset-manifest.json +6 -6
  3. matlab_proxy/gui/index.html +1 -1
  4. matlab_proxy/gui/static/css/main.6cd0caba.css +13 -0
  5. matlab_proxy/gui/static/css/main.6cd0caba.css.map +1 -0
  6. matlab_proxy/gui/static/js/main.61c661b8.js +3 -0
  7. matlab_proxy/gui/static/js/{main.e07799e7.js.LICENSE.txt → main.61c661b8.js.LICENSE.txt} +0 -2
  8. matlab_proxy/gui/static/js/main.61c661b8.js.map +1 -0
  9. matlab_proxy/settings.py +1 -1
  10. matlab_proxy/util/mwi/logger.py +22 -2
  11. matlab_proxy/util/windows.py +4 -1
  12. {matlab_proxy-0.19.0.dist-info → matlab_proxy-0.21.0.dist-info}/METADATA +16 -15
  13. {matlab_proxy-0.19.0.dist-info → matlab_proxy-0.21.0.dist-info}/RECORD +36 -19
  14. {matlab_proxy-0.19.0.dist-info → matlab_proxy-0.21.0.dist-info}/WHEEL +1 -1
  15. {matlab_proxy-0.19.0.dist-info → matlab_proxy-0.21.0.dist-info}/entry_points.txt +1 -0
  16. matlab_proxy-0.21.0.dist-info/top_level.txt +3 -0
  17. matlab_proxy_manager/__init__.py +6 -0
  18. matlab_proxy_manager/lib/__init__.py +1 -0
  19. matlab_proxy_manager/lib/api.py +295 -0
  20. matlab_proxy_manager/storage/__init__.py +1 -0
  21. matlab_proxy_manager/storage/file_repository.py +144 -0
  22. matlab_proxy_manager/storage/interface.py +62 -0
  23. matlab_proxy_manager/storage/server.py +144 -0
  24. matlab_proxy_manager/utils/__init__.py +1 -0
  25. matlab_proxy_manager/utils/auth.py +77 -0
  26. matlab_proxy_manager/utils/constants.py +5 -0
  27. matlab_proxy_manager/utils/environment_variables.py +46 -0
  28. matlab_proxy_manager/utils/helpers.py +284 -0
  29. matlab_proxy_manager/utils/logger.py +73 -0
  30. matlab_proxy_manager/web/__init__.py +1 -0
  31. matlab_proxy_manager/web/app.py +447 -0
  32. matlab_proxy_manager/web/monitor.py +45 -0
  33. matlab_proxy_manager/web/watcher.py +54 -0
  34. tests/unit/test_app.py +1 -1
  35. tests/unit/util/mwi/test_logger.py +38 -4
  36. matlab_proxy/gui/static/css/main.da9c4eb8.css +0 -13
  37. matlab_proxy/gui/static/css/main.da9c4eb8.css.map +0 -1
  38. matlab_proxy/gui/static/js/main.e07799e7.js +0 -3
  39. matlab_proxy/gui/static/js/main.e07799e7.js.map +0 -1
  40. matlab_proxy-0.19.0.dist-info/top_level.txt +0 -2
  41. {matlab_proxy-0.19.0.dist-info → matlab_proxy-0.21.0.dist-info}/LICENSE.md +0 -0
matlab_proxy/settings.py CHANGED
@@ -493,7 +493,7 @@ def create_xvfb_cmd():
493
493
  str(dpipe[1]),
494
494
  "-screen",
495
495
  "0",
496
- "1600x1200x24",
496
+ "3840x2160x24",
497
497
  "-dpi",
498
498
  "100",
499
499
  # "-ac",
@@ -1,4 +1,4 @@
1
- # Copyright 2020-2023 The MathWorks, Inc.
1
+ # Copyright 2020-2024 The MathWorks, Inc.
2
2
  """Functions to access & control the logging behavior of the app
3
3
  """
4
4
 
@@ -52,7 +52,17 @@ def __set_logging_configuration():
52
52
  # query for user specified environment variables
53
53
  log_level = os.getenv(
54
54
  mwi_env.get_env_name_logging_level(), __get_default_log_level()
55
- )
55
+ ).upper()
56
+
57
+ valid = __is_valid_log_level(log_level)
58
+
59
+ if not valid:
60
+ default_log_level = __get_default_log_level()
61
+ logging.warn(
62
+ f"Unknown log level '{log_level}' set. Defaulting to log level '{default_log_level}'..."
63
+ )
64
+ log_level = default_log_level
65
+
56
66
  log_file = os.getenv(mwi_env.get_env_name_log_file(), None)
57
67
 
58
68
  ## Set logging object
@@ -110,3 +120,13 @@ def __get_default_log_level():
110
120
  String: The default logging level
111
121
  """
112
122
  return "INFO"
123
+
124
+
125
+ def __is_valid_log_level(log_level):
126
+ """Helper to check if the log level is valid.
127
+
128
+ Returns:
129
+ Boolean: Whether log level exists
130
+ """
131
+
132
+ return hasattr(logging, log_level)
@@ -49,10 +49,13 @@ async def start_matlab(matlab_cmd, matlab_env):
49
49
  """
50
50
  import psutil
51
51
 
52
+ # The stdout is used to suppress the MATLAB outputs from being shown in the terminal.
53
+ # We set it to DEVNULL instead of PIPE because PIPE has a limited buffer size and can
54
+ # block the process if the output exceeds the buffer limit.
52
55
  intermediate_proc = await asyncio.create_subprocess_exec(
53
56
  *matlab_cmd,
54
57
  env=matlab_env,
55
- stdout=asyncio.subprocess.PIPE,
58
+ stdout=asyncio.subprocess.DEVNULL,
56
59
  stderr=asyncio.subprocess.STDOUT,
57
60
  )
58
61
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: matlab-proxy
3
- Version: 0.19.0
3
+ Version: 0.21.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.
@@ -17,24 +17,25 @@ Classifier: Programming Language :: Python :: 3.10
17
17
  Classifier: Programming Language :: Python :: 3.11
18
18
  Requires-Python: ~=3.8
19
19
  Description-Content-Type: text/markdown
20
- Requires-Dist: aiohttp >=3.7.4
20
+ Requires-Dist: aiohttp>=3.7.4
21
21
  Requires-Dist: aiohttp-session[secure]
22
22
  Requires-Dist: importlib-metadata
23
23
  Requires-Dist: importlib-resources
24
24
  Requires-Dist: psutil
25
+ Requires-Dist: watchdog
25
26
  Provides-Extra: dev
26
- Requires-Dist: aiohttp-devtools ; extra == 'dev'
27
- Requires-Dist: black ; extra == 'dev'
28
- Requires-Dist: pytest ; extra == 'dev'
29
- Requires-Dist: pytest-env ; extra == 'dev'
30
- Requires-Dist: pytest-cov ; extra == 'dev'
31
- Requires-Dist: pytest-timeout ; extra == 'dev'
32
- Requires-Dist: pytest-mock ; extra == 'dev'
33
- Requires-Dist: pytest-aiohttp ; extra == 'dev'
34
- Requires-Dist: psutil ; extra == 'dev'
35
- Requires-Dist: urllib3 ; extra == 'dev'
36
- Requires-Dist: requests ; extra == 'dev'
37
- Requires-Dist: pytest-playwright ; extra == 'dev'
27
+ Requires-Dist: aiohttp-devtools; extra == "dev"
28
+ Requires-Dist: black; extra == "dev"
29
+ Requires-Dist: pytest; extra == "dev"
30
+ Requires-Dist: pytest-env; extra == "dev"
31
+ Requires-Dist: pytest-cov; extra == "dev"
32
+ Requires-Dist: pytest-timeout; extra == "dev"
33
+ Requires-Dist: pytest-mock; extra == "dev"
34
+ Requires-Dist: pytest-aiohttp; extra == "dev"
35
+ Requires-Dist: psutil; extra == "dev"
36
+ Requires-Dist: urllib3; extra == "dev"
37
+ Requires-Dist: requests; extra == "dev"
38
+ Requires-Dist: pytest-playwright; extra == "dev"
38
39
 
39
40
  # MATLAB Proxy
40
41
  [![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/mathworks/matlab-proxy/run-tests.yml?branch=main&logo=github)](https://github.com/mathworks/matlab-proxy/actions)   [![PyPI badge](https://img.shields.io/pypi/v/matlab-proxy.svg?logo=pypi)](https://pypi.python.org/pypi/matlab-proxy)   [![codecov](https://codecov.io/gh/mathworks/matlab-proxy/branch/main/graph/badge.svg?token=ZW3SESKCSS)](https://codecov.io/gh/mathworks/matlab-proxy)   [![Downloads](https://static.pepy.tech/personalized-badge/matlab-proxy?period=month&units=international_system&left_color=grey&right_color=blue&left_text=PyPI%20downloads/month)](https://pepy.tech/project/matlab-proxy)
@@ -201,7 +202,7 @@ $ pip install --upgrade matlab-proxy>=0.5.0
201
202
 
202
203
  ### Windows Subsystem for Linux (WSL 2)
203
204
 
204
- To install `matlab-proxy` in WSL 2, follow the steps mentioned in the [Installation Guide for WSL 2](./installation/wsl2/README.md).
205
+ To install `matlab-proxy` in WSL 2, follow the steps mentioned in the [Installation Guide for WSL 2](./install_guides/wsl2/README.md).
205
206
 
206
207
  ## Using an already activated MATLAB with matlab-proxy
207
208
  `matlab-proxy` version `v0.7.0` introduces support for using an existing MATLAB license. Use the Existing License option only if you have an activated MATLAB. This allows you to start MATLAB without authenticating every time.
@@ -1,24 +1,24 @@
1
1
  matlab_proxy/__init__.py,sha256=6cwi8buKCMtw9OeWaOYUHEoqwl5MyJ_s6GxgNuqPuNg,1673
2
- matlab_proxy/app.py,sha256=6_zql3Uv0gT1pSBDdesZ_FSFqtPWt--YIVyh3cj4d_g,34379
2
+ matlab_proxy/app.py,sha256=0conSbbVwaYdWtbA_ZTUk2lLDZYsLIBQiBqNKYj0rho,34713
3
3
  matlab_proxy/app_state.py,sha256=pt6s3Yy6NV6LB-GxT1Y4cOpeDaTFMm_ItN_qPstDTwE,71296
4
4
  matlab_proxy/constants.py,sha256=-gEUNjBATe3_4Cd7CN-VhkEn-iMRfiZ-zdDDD6fM_II,1161
5
5
  matlab_proxy/default_configuration.py,sha256=DxQaHzAivzstiPl_nDfxs8SOyP9oaK9v3RP4LtroJl4,843
6
6
  matlab_proxy/devel.py,sha256=nR6XPVBUEdQ-RZGtYvX1YHTp8gj9cuw5Hp8ahasMBc8,14310
7
- matlab_proxy/settings.py,sha256=Jrk6vkYCKt-cFogkkNpfMcEzZcrDgzfeHqSl6ndgkUA,26722
7
+ matlab_proxy/settings.py,sha256=63pyCUvT7WLBRUpUr3F4r4nL13pQ2Hn6-oZODAhuGLo,26722
8
8
  matlab_proxy/gui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
- matlab_proxy/gui/asset-manifest.json,sha256=DvwTnv61wL1g9_YFg4tttJTsaU4QS9atCESSS1tXSAg,3516
9
+ matlab_proxy/gui/asset-manifest.json,sha256=IarJ9XmKoHJovFfsx1gHk1frgKLGgyCzzYmZNz1DT3A,3516
10
10
  matlab_proxy/gui/favicon.ico,sha256=7w7Ki1uQP2Rgwc64dOV4-NrTu97I3WsZw8OvRSoY1A0,130876
11
- matlab_proxy/gui/index.html,sha256=QfpshVMgl83FzcW82qdNIaGRp-KJ0oIIErk0wDK_Gps,637
11
+ matlab_proxy/gui/index.html,sha256=BvGtBVGQxdCjSKGhUFEXZPK3SaFXB7TF3gbFxyx7miQ,637
12
12
  matlab_proxy/gui/manifest.json,sha256=NwDbrALM5auYyj2bbEf4aGwAUDqNl1FzMFQpPiG2Ty4,286
13
13
  matlab_proxy/gui/robots.txt,sha256=kNJLw79pisHhc3OVAimMzKcq3x9WT6sF9IS4xI0crdI,67
14
14
  matlab_proxy/gui/static/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
15
  matlab_proxy/gui/static/css/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
- matlab_proxy/gui/static/css/main.da9c4eb8.css,sha256=etg2mMerqvNiYKBJgve5vBUc-X8ZnnCVnf5gc-DMaPA,274453
17
- matlab_proxy/gui/static/css/main.da9c4eb8.css.map,sha256=favITMsubUPvF7E0vWcdc2RXJ9Pj5ljIWdPuhSBfDVU,351326
16
+ matlab_proxy/gui/static/css/main.6cd0caba.css,sha256=Ks90yx_8kQC9UQXlkvh5ecz2vk2jEN2FKkMCLn0hTb8,269168
17
+ matlab_proxy/gui/static/css/main.6cd0caba.css.map,sha256=-pczDWw0U0T9Yd7pVYDklDlsc6OJqxCYlGmS6qtAhqU,350517
18
18
  matlab_proxy/gui/static/js/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
- matlab_proxy/gui/static/js/main.e07799e7.js,sha256=rtgmv7rYVVOVheycw3zNBjIyKv63qeTRgZ4zmO4HxCs,298414
20
- matlab_proxy/gui/static/js/main.e07799e7.js.LICENSE.txt,sha256=3cj3DrwM51esz1ogL9VVU1ZyXyXJ6u-Ec2CI9CCcI_A,1689
21
- matlab_proxy/gui/static/js/main.e07799e7.js.map,sha256=nCto0v-cMAs0t2YmSz2UqwJ3PlWgoW6aLRNYo67Nie0,955674
19
+ matlab_proxy/gui/static/js/main.61c661b8.js,sha256=w44nS4qbZOF7mS5ASEhmhDPLk1KPDP4f4qF3eNZRzBg,283166
20
+ matlab_proxy/gui/static/js/main.61c661b8.js.LICENSE.txt,sha256=uJRPpXtA1Wzfw2dMAUGOPgwqYk2GvDcIafoGMMNLECQ,1539
21
+ matlab_proxy/gui/static/js/main.61c661b8.js.map,sha256=02MznaDjhNTG_3yo4quVaeyxtnsJVacK_LbN4pTXJdA,911172
22
22
  matlab_proxy/gui/static/media/MATLAB-env-blur.4fc94edbc82d3184e5cb.png,sha256=QpmQTLDvBu2-b7ev83Rvpt0Q72R6wdQGkuJMPPpjv7M,220290
23
23
  matlab_proxy/gui/static/media/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
24
24
  matlab_proxy/gui/static/media/arrow.0c2968b90bd9a64c8c3f.svg,sha256=XtmvDWzGZnwCZm08TKBnqt5hc1wphJnNupG0Fx_faAY,327
@@ -59,18 +59,35 @@ matlab_proxy/util/event_loop.py,sha256=sX_0tKlirCY5ImLxkss_XO4Ksj65u6JHtwMj25oGL
59
59
  matlab_proxy/util/list_servers.py,sha256=M93coVZjyQCdIvCCxsNOU_XDWNjBSysOJ5tWXaTjP8Y,1369
60
60
  matlab_proxy/util/mw.py,sha256=dLGSdfcTZiwKR1MMZA-39o-8na13IEPZOGBqcaHmKVI,11086
61
61
  matlab_proxy/util/system.py,sha256=XoT3Rv5MwPkdfhk2oMvUwxxlzZmADMlxzi9IRQyGgbA,1692
62
- matlab_proxy/util/windows.py,sha256=J5O-wihOxEex43_AzwvFylNlN4hcZdO6KD5cpLv1FX8,3538
62
+ matlab_proxy/util/windows.py,sha256=_5gl2IyHIfw8-D3_G5uHkycZVGGFVXtjkd6_aP3g2Ts,3785
63
63
  matlab_proxy/util/mwi/__init__.py,sha256=zI-X1lafr8H3j17PyA0oSZ0q5nINfK-WDA7VmJKmSAQ,158
64
64
  matlab_proxy/util/mwi/custom_http_headers.py,sha256=kfDjSnEXEVzoF2pZuEn76LKayeD2WKoQEDu2Y9EMOAo,7154
65
65
  matlab_proxy/util/mwi/download.py,sha256=-GJj3yOsL4vF_9baqRXkgBI-vu_OwjZMQVkJXFS8GMc,4965
66
66
  matlab_proxy/util/mwi/environment_variables.py,sha256=sOfmL8PjQONgkJdegdotLbsqHsWJDsjS7kak0TJtVKU,7441
67
67
  matlab_proxy/util/mwi/exceptions.py,sha256=3jklFU6br2_pSSsATCRDY3A5fTzk6ekJ4M69sunwxBk,5114
68
- matlab_proxy/util/mwi/logger.py,sha256=e7wTPclrtJ-aX5mPk_pUJMX7-1QD_snGBW1P2ks-ETE,3311
68
+ matlab_proxy/util/mwi/logger.py,sha256=EHHr6OWlXe6yVX0RPh57HSE7lz6MhWmwLQIpe_SlsC0,3803
69
69
  matlab_proxy/util/mwi/token_auth.py,sha256=UbIWqo7qADaZdijFvorLYsZbxzaB8TycGP8nk305ru0,9997
70
70
  matlab_proxy/util/mwi/validators.py,sha256=br-22Gyef_vxVSSH2Qkb97Nfph9sfl7fyhQ8-LWkBP4,12600
71
71
  matlab_proxy/util/mwi/embedded_connector/__init__.py,sha256=Vfl2hNC7V1IwoK9_wrwfENs4BC8P-Mvvqh4BNGi2n48,119
72
72
  matlab_proxy/util/mwi/embedded_connector/helpers.py,sha256=aOn-AvcDy6jBQJIffiv_agIa4UVldAIl3--QnDpXWDM,3656
73
73
  matlab_proxy/util/mwi/embedded_connector/request.py,sha256=-IzTDjy3qViHfLJpK3OnFtEyV7dgwJKPQAfav9lqILc,4317
74
+ matlab_proxy_manager/__init__.py,sha256=CMqm2aSYUWo5sxV3vyqWudrQU31muouSqZRDesJNJSA,178
75
+ matlab_proxy_manager/lib/__init__.py,sha256=KfwQxxM5a1kMRtNbhz8tb7YfHp8e2d0tNLB55wYvDS8,37
76
+ matlab_proxy_manager/lib/api.py,sha256=X-VSbZ41TPosqGODve8PSG6G9dZfqi0kmY_iGWFW3EA,10615
77
+ matlab_proxy_manager/storage/__init__.py,sha256=KfwQxxM5a1kMRtNbhz8tb7YfHp8e2d0tNLB55wYvDS8,37
78
+ matlab_proxy_manager/storage/file_repository.py,sha256=U4FAw0zFN9z7YNlaMsYZXWm5ccs3rp3bzZL-W2BNhxA,5187
79
+ matlab_proxy_manager/storage/interface.py,sha256=pnRRD0Ku3gzbruAOM3J3NI2Kk8do3-_yRw9Pag1IqnE,1883
80
+ matlab_proxy_manager/storage/server.py,sha256=kQ4jtG2xqCa8c7zqDBFYxOhxMxwZwqTIITBxcJRDcvE,4848
81
+ matlab_proxy_manager/utils/__init__.py,sha256=KfwQxxM5a1kMRtNbhz8tb7YfHp8e2d0tNLB55wYvDS8,37
82
+ matlab_proxy_manager/utils/auth.py,sha256=60vi16eQ7LWp3I4CNv2easTjObw50irEm518fiMA5YI,2526
83
+ matlab_proxy_manager/utils/constants.py,sha256=pyg-bkk6wWfmy60nvhroZDMZt__FcbZbuvU-b9m2Fkg,163
84
+ matlab_proxy_manager/utils/environment_variables.py,sha256=rbDeWnyJp77Yr6btK3eXKZQ5thwiwhOGZcvDetGPOH8,1436
85
+ matlab_proxy_manager/utils/helpers.py,sha256=5yTRM0NjGUC6lcQ6O8ilDrG2AnICGfvJYdIPho41Egw,9193
86
+ matlab_proxy_manager/utils/logger.py,sha256=GSRGD-yf518o-2b1BxEeJYuNiEz2eEqpl0Solqbwpb4,1869
87
+ matlab_proxy_manager/web/__init__.py,sha256=KfwQxxM5a1kMRtNbhz8tb7YfHp8e2d0tNLB55wYvDS8,37
88
+ matlab_proxy_manager/web/app.py,sha256=Lu6sl3Mft98oL-Z1NwBdmmG1OvnwYEN31pU2bOdzFi0,16572
89
+ matlab_proxy_manager/web/monitor.py,sha256=Gj0DxwX0c1PEAly5jWmuIGqNJYGDDjTkQIzbVXu4zCQ,1589
90
+ matlab_proxy_manager/web/watcher.py,sha256=aNa_UDwvzaZrIdHyvWGX7dILH199uc6xVH4odrKU5-E,1817
74
91
  tests/integration/__init__.py,sha256=ttzJ8xKWGxOJZz56qOiWOn6sp5LGomkZMn_w4KJLRMU,42
75
92
  tests/integration/integration_tests_with_license/__init__.py,sha256=vVYZCur-QhmIGCxUmn-WZjIywtDQidaLDmlmrRHRlgY,37
76
93
  tests/integration/integration_tests_with_license/conftest.py,sha256=sCaIXB8d4vf05C7JWSVA7g5gnPjbpRq3dftuBpWyp1s,1599
@@ -83,7 +100,7 @@ tests/integration/utils/integration_tests_utils.py,sha256=IbJ9CedFHiz3k85FBY-8Gw
83
100
  tests/integration/utils/licensing.py,sha256=rEBjvMXO8R3mL6KnePu2lojmOsjD4GXl9frf9N0Wacs,4842
84
101
  tests/unit/__init__.py,sha256=KfwQxxM5a1kMRtNbhz8tb7YfHp8e2d0tNLB55wYvDS8,37
85
102
  tests/unit/conftest.py,sha256=Hfxq3h8IZuLJkRMh5jdEFiq78CIAdKvm-6KryRDZ0FY,1918
86
- tests/unit/test_app.py,sha256=LkIqION-F_4dDpbT0VXzdL_ue-1HGXhPRP9-AprcRKY,38443
103
+ tests/unit/test_app.py,sha256=15kSWsfIEQpGzr6QoDoFpV501SYA5XkszrwDp8pJi74,38442
87
104
  tests/unit/test_app_state.py,sha256=ZtM79HAe5W6pVVWV-NICjDJBlmuxJ4NnZn-urGGtH-E,33429
88
105
  tests/unit/test_constants.py,sha256=2nXxTmDP8utr8krsfZ4c_Bh4_mWPcDO5uI8MXeq4Usg,158
89
106
  tests/unit/test_ddux.py,sha256=a2J2iM8j_nnfJVuMI38p5AjwrRdoMj3N88gFgS2I4hg,713
@@ -96,7 +113,7 @@ tests/unit/util/test_util.py,sha256=gecUFSVIg4a9s3Ljl0A7eSSY5jN4vH668CbjnTpi198,
96
113
  tests/unit/util/mwi/__init__.py,sha256=pl5jqyCHEwZEviiL8OC-SHulb1rBecstQCFF6qVjL9Y,37
97
114
  tests/unit/util/mwi/test_custom_http_headers.py,sha256=UfrhclS0j6WhShtg1ki2oF1kK8JqRC29uevH4tuDqF4,11182
98
115
  tests/unit/util/mwi/test_download.py,sha256=jYwPJFYGrPKqnkIJW42XYSe1fowmzChAkOx0k0xVldo,4779
99
- tests/unit/util/mwi/test_logger.py,sha256=zWImNitMYKPJunXWJjEDEtCEKwBz615PC844ZLwoxIg,1845
116
+ tests/unit/util/mwi/test_logger.py,sha256=2VFoVlMLgsSWtDn0iVxHNArGBfN-IgWehuoaLvWlS6U,3151
100
117
  tests/unit/util/mwi/test_token_auth.py,sha256=-eBsaQ5JC7pyd9PXt48Rqs4cWjg6I-eOkp_gFVEwYhk,10538
101
118
  tests/unit/util/mwi/test_validators.py,sha256=rzSmifQdPWZ5ZjecShBpC_RYL55_smCsG248h2JzUDU,11467
102
119
  tests/unit/util/mwi/embedded_connector/__init__.py,sha256=pl5jqyCHEwZEviiL8OC-SHulb1rBecstQCFF6qVjL9Y,37
@@ -104,9 +121,9 @@ tests/unit/util/mwi/embedded_connector/test_helpers.py,sha256=vYTWNUTuDeaygo16JG
104
121
  tests/unit/util/mwi/embedded_connector/test_request.py,sha256=PR-jddnXDEiip-lD7A_QSvRwEkwo3eQ8owZlk-r9vnk,1867
105
122
  tests/utils/__init__.py,sha256=ttzJ8xKWGxOJZz56qOiWOn6sp5LGomkZMn_w4KJLRMU,42
106
123
  tests/utils/logging_util.py,sha256=VBy_NRvwau3C_CVTBjK5RMROrQimnJYHO2U0aKSZiRw,2234
107
- matlab_proxy-0.19.0.dist-info/LICENSE.md,sha256=oF0h3UdSF-rlUiMGYwi086ZHqelzz7yOOk9HFDv9ELo,2344
108
- matlab_proxy-0.19.0.dist-info/METADATA,sha256=UPcQ8G3Z3NGsFcIrXpEhDj-RVJMAIDYQSNZxCFWf4HY,10177
109
- matlab_proxy-0.19.0.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
110
- matlab_proxy-0.19.0.dist-info/entry_points.txt,sha256=DbBLYgnRt8UGiOpd0zHigRTyyMdZYhMdvCvSYP7wPN0,244
111
- matlab_proxy-0.19.0.dist-info/top_level.txt,sha256=9uVTjsUCAS4TwsxueTBxrBg3PdBiTSsYowAkHPv9VY0,19
112
- matlab_proxy-0.19.0.dist-info/RECORD,,
124
+ matlab_proxy-0.21.0.dist-info/LICENSE.md,sha256=oF0h3UdSF-rlUiMGYwi086ZHqelzz7yOOk9HFDv9ELo,2344
125
+ matlab_proxy-0.21.0.dist-info/METADATA,sha256=gnssXFWPF13KwXQjNiEuEaaE1IN-zOHHslCQ8TnnpGU,10190
126
+ matlab_proxy-0.21.0.dist-info/WHEEL,sha256=eOLhNAGa2EW3wWl_TU484h7q1UNgy0JXjjoqKoxAAQc,92
127
+ matlab_proxy-0.21.0.dist-info/entry_points.txt,sha256=ZAlCUsgKzGcAeQaMZOq31FrTB5tQ8Ypq8Op_8U600-A,305
128
+ matlab_proxy-0.21.0.dist-info/top_level.txt,sha256=KF-347aoRGsfHTpiSqfIPUZ95bzK5-oMIu8S_TUcu-w,40
129
+ matlab_proxy-0.21.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.43.0)
2
+ Generator: bdist_wheel (0.44.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,6 +1,7 @@
1
1
  [console_scripts]
2
2
  matlab-proxy-app = matlab_proxy.app:main
3
3
  matlab-proxy-app-list-servers = matlab_proxy.util.list_servers:print_server_info
4
+ matlab-proxy-manager-app = matlab_proxy_manager.web.app:main
4
5
 
5
6
  [matlab_proxy_configs]
6
7
  default_configuration_matlab_proxy = matlab_proxy.default_configuration:config
@@ -0,0 +1,3 @@
1
+ matlab_proxy
2
+ matlab_proxy_manager
3
+ tests
@@ -0,0 +1,6 @@
1
+ # Copyright 2024 The MathWorks, Inc.
2
+
3
+
4
+ def get_executable_name() -> str:
5
+ """Fetches and returns matlab proxy manager executable name"""
6
+ return "matlab-proxy-manager-app"
@@ -0,0 +1 @@
1
+ # Copyright 2024 The MathWorks, Inc.
@@ -0,0 +1,295 @@
1
+ # Copyright 2024 The MathWorks, Inc.
2
+ import asyncio
3
+ import os
4
+ import secrets
5
+ import subprocess
6
+ from typing import Optional
7
+
8
+ import matlab_proxy
9
+ import matlab_proxy.util.system as mwi_sys
10
+ from matlab_proxy_manager.storage.file_repository import FileRepository
11
+ from matlab_proxy_manager.storage.server import ServerProcess
12
+ from matlab_proxy_manager.utils import constants, helpers, logger
13
+
14
+ # Used to list all the public-facing APIs exported by this module.
15
+ __all__ = ["shutdown", "start_matlab_proxy_for_kernel", "start_matlab_proxy_for_jsp"]
16
+
17
+ log = logger.get()
18
+ shutdown_lock = asyncio.Lock()
19
+ log = logger.get(init=True)
20
+
21
+
22
+ async def start_matlab_proxy_for_kernel(
23
+ caller_id: str, parent_id: str, is_isolated_matlab: bool
24
+ ):
25
+ """
26
+ Starts a MATLAB proxy server specifically for MATLAB Kernel.
27
+
28
+ This function is a wrapper around the `start_matlab_proxy` function, with mpm_auth_token
29
+ set to None, for starting the MATLAB proxy server via proxy manager.
30
+ """
31
+ return await _start_matlab_proxy(
32
+ caller_id=caller_id, ctx=parent_id, is_isolated_matlab=is_isolated_matlab
33
+ )
34
+
35
+
36
+ async def start_matlab_proxy_for_jsp(
37
+ parent_id: str, is_isolated_matlab: bool, mpm_auth_token: str
38
+ ):
39
+ """
40
+ Starts a MATLAB proxy server specifically for Jupyter Server Proxy (JSP) - Open MATLAB launcher.
41
+
42
+ This function is a wrapper around the `start_matlab_proxy` function, providing
43
+ a more specific context (mpm_auth_token) for starting the MATLAB proxy server via proxy manager.
44
+ """
45
+ return await _start_matlab_proxy(
46
+ caller_id="jsp",
47
+ ctx=parent_id,
48
+ is_isolated_matlab=is_isolated_matlab,
49
+ mpm_auth_token=mpm_auth_token,
50
+ )
51
+
52
+
53
+ async def _start_matlab_proxy(**options) -> Optional[dict]:
54
+ """
55
+ Start a MATLAB proxy server.
56
+
57
+ This function starts a MATLAB proxy server based on the provided context and caller ID.
58
+ It handles the creation of new servers and the reuse of existing ones.
59
+
60
+ Args (keyword arguments):
61
+ - caller_id (str): The identifier for the caller (kernel id for kernels, "jsp" for JSP).
62
+ - ctx (str): The context in which the server is being started (parent pid).
63
+ - is_isolated_matlab (bool, optional): Whether to start an isolated MATLAB proxy instance.
64
+ Defaults to False.
65
+ - mpm_auth_token (str, optional): The MATLAB proxy manager token. If not provided,
66
+ a new token is generated. Defaults to None.
67
+
68
+ Returns:
69
+ ServerProcess: The process representing the MATLAB proxy server.
70
+
71
+ Raises:
72
+ ValueError: If `caller_id` is "default" and `is_isolated_matlab` is True.
73
+ """
74
+ caller_id: str = options.get("caller_id")
75
+ ctx: str = options.get("ctx")
76
+ is_isolated_matlab: bool = options.get("is_isolated_matlab", False)
77
+ mpm_auth_token: Optional[str] = options.get("mpm_auth_token", None)
78
+
79
+ if is_isolated_matlab and caller_id == "default":
80
+ raise ValueError(
81
+ "Caller id cannot be default when isolated_matlab is set to true"
82
+ )
83
+
84
+ mpm_auth_token = mpm_auth_token or secrets.token_hex(32)
85
+
86
+ # Cleanup stale entries before starting new instance of matlab proxy server
87
+ helpers._are_orphaned_servers_deleted(ctx)
88
+
89
+ ident = caller_id if is_isolated_matlab else "default"
90
+ key = f"{ctx}_{ident}"
91
+ log.debug("Starting matlab proxy using %s, %s, %s", ctx, ident, is_isolated_matlab)
92
+
93
+ data_dir = helpers.create_and_get_proxy_manager_data_dir()
94
+ server_process = ServerProcess.find_existing_server(data_dir, key)
95
+
96
+ if server_process:
97
+ log.debug("Found existing server for aliasing")
98
+
99
+ # Create a backend file for this caller for reference tracking
100
+ helpers.create_state_file(data_dir, server_process, f"{ctx}_{caller_id}")
101
+
102
+ # Create a new matlab proxy server
103
+ else:
104
+ server_process: ServerProcess | None = (
105
+ await _start_subprocess_and_check_for_readiness(
106
+ ident, ctx, key, is_isolated_matlab, mpm_auth_token
107
+ )
108
+ )
109
+
110
+ # Store the newly created server into filesystem
111
+ if server_process:
112
+ helpers.create_state_file(data_dir, server_process, f"{ctx}_{caller_id}")
113
+
114
+ return server_process.as_dict() if server_process else None
115
+
116
+
117
+ async def _start_subprocess_and_check_for_readiness(
118
+ server_id: str, ctx: str, key: str, isolated: bool, mpm_auth_token: str
119
+ ) -> Optional[ServerProcess]:
120
+ """
121
+ Starts a MATLAB proxy server.
122
+
123
+ This function performs the following steps:
124
+ 1. Prepares the command and environment variables required to start the MATLAB proxy server.
125
+ 2. Initializes the MATLAB proxy process.
126
+ 3. Checks if the MATLAB proxy server is ready.
127
+ 4. Creates and returns a ServerProcess instance if the server is ready.
128
+
129
+ Returns:
130
+ Optional[ServerProcess]: An instance of ServerProcess if the server is successfully started,
131
+ otherwise None.
132
+ """
133
+ log.debug("Starting new matlab proxy server")
134
+
135
+ # Prepare matlab proxy command and required environment variables
136
+ matlab_proxy_cmd, matlab_proxy_env = _prepare_cmd_and_env_for_matlab_proxy()
137
+
138
+ # Start the matlab proxy process
139
+ process_id, url, mwi_base_url = await _start_subprocess(
140
+ matlab_proxy_cmd, matlab_proxy_env, server_id
141
+ )
142
+
143
+ server_process = None
144
+
145
+ # Check for the matlab proxy server readiness
146
+ if helpers.is_server_ready(f"{url}{mwi_base_url}"):
147
+ log.debug("Matlab proxy process info: %s, %s", url, mwi_base_url)
148
+ server_process = ServerProcess(
149
+ server_url=url,
150
+ mwi_base_url=mwi_base_url,
151
+ headers=helpers.convert_mwi_env_vars_to_header_format(
152
+ matlab_proxy_env, "MWI"
153
+ ),
154
+ pid=process_id,
155
+ parent_pid=ctx,
156
+ id=key,
157
+ type="named" if isolated else "shared",
158
+ mpm_auth_token=mpm_auth_token,
159
+ )
160
+ else:
161
+ log.error("Could not start matlab proxy")
162
+
163
+ return server_process
164
+
165
+
166
+ def _prepare_cmd_and_env_for_matlab_proxy():
167
+ """
168
+ Prepare the command and environment variables for starting the MATLAB proxy.
169
+
170
+ Returns:
171
+ Tuple: A tuple containing the MATLAB proxy command and environment variables.
172
+ """
173
+ from jupyter_matlab_proxy import config
174
+
175
+ # Get the command to start matlab-proxy
176
+ matlab_proxy_cmd: list = [
177
+ matlab_proxy.get_executable_name(),
178
+ "--config",
179
+ config.get("extension_name"),
180
+ ]
181
+
182
+ input_env: dict = {
183
+ "MWI_AUTH_TOKEN": secrets.token_urlsafe(32),
184
+ }
185
+
186
+ matlab_proxy_env: dict = os.environ.copy()
187
+ matlab_proxy_env.update(input_env)
188
+
189
+ return matlab_proxy_cmd, matlab_proxy_env
190
+
191
+
192
+ async def _start_subprocess(cmd, env, server_id) -> Optional[int]:
193
+ """
194
+ Initializes and starts a subprocess using the specified command and provided environment.
195
+
196
+ Returns:
197
+ Optional[int]: The process ID if the process is successfully created, otherwise None.
198
+ """
199
+ process = None
200
+ mwi_base_url: str = f"{constants.MWI_BASE_URL_PREFIX}{server_id}"
201
+
202
+ # Get a free port, closer to starting the matlab proxy appx
203
+ port: str = helpers.find_free_port()
204
+ env.update(
205
+ {
206
+ "MWI_APP_PORT": port,
207
+ "MWI_BASE_URL": mwi_base_url,
208
+ }
209
+ )
210
+
211
+ # Using loopback address so that DNS resolution doesn't add latency in Windows
212
+ url: str = f"http://127.0.0.1:{port}"
213
+
214
+ if mwi_sys.is_posix():
215
+ process = await asyncio.create_subprocess_exec(
216
+ *cmd,
217
+ env=env,
218
+ )
219
+ log.debug("Started matlab proxy subprocess for posix")
220
+ else:
221
+ process = subprocess.Popen(
222
+ cmd,
223
+ env=env,
224
+ )
225
+ log.debug("Started matlab proxy subprocess for windows")
226
+
227
+ if not process:
228
+ log.error("Matlab proxy process not created %d", process.returncode)
229
+ return None
230
+
231
+ process_pid = process.pid
232
+ log.debug("MATLAB proxy info: pid = %s, rc = %s", process_pid, process.returncode)
233
+ return process_pid, url, mwi_base_url
234
+
235
+
236
+ async def shutdown(parent_pid: str, caller_id: str, mpm_auth_token: str):
237
+ """
238
+ Shutdown the MATLAB proxy server if the provided authentication token is valid.
239
+
240
+ This function attempts to shut down the MATLAB proxy server identified by the
241
+ given context and ID, provided the correct authentication token is supplied.
242
+ It ensures that the shutdown process is thread-safe using an asyncio lock.
243
+
244
+ Args:
245
+ parent_pid (str): The context identifier for the server.
246
+ caller_id (str): The unique identifier for the server.
247
+ mpm_auth_token (str): The authentication token for proxy manager and client communication.
248
+
249
+ Returns:
250
+ Optional[None]: Returns None if the shutdown process is successful or if
251
+ required arguments are missing.
252
+
253
+ Raises:
254
+ FileNotFoundError: If the state file for the server does not exist.
255
+ ValueError: If the authentication token is invalid.
256
+ Exception: If any other error occurs during the shutdown process.
257
+ """
258
+ if not parent_pid or not caller_id or not mpm_auth_token:
259
+ log.debug(
260
+ "Required arguments (parent_pid | caller_id | mpm_auth_token) for shutdown missing"
261
+ )
262
+ return
263
+
264
+ try:
265
+ data_dir = helpers.create_and_get_proxy_manager_data_dir()
266
+ storage = FileRepository(data_dir)
267
+ filename = f"{parent_pid}_{caller_id}"
268
+ full_file_path, server = storage.get(filename)
269
+
270
+ if not server:
271
+ log.debug("State file for this server not found, filename: %s", filename)
272
+ return
273
+
274
+ if mpm_auth_token != server.mpm_auth_token:
275
+ raise ValueError("Invalid authentication token")
276
+
277
+ # Using asyncio lock to ensure thread-safe shutdown: clicking shutdown
278
+ # all on Kernel UI sends shutdown request in parallel which could lead
279
+ # to a scenario where the kernels' shutdown just cleans the files from
280
+ # filesystem and doesn't shut down the backend matlab proxy server.
281
+ async with shutdown_lock:
282
+ if helpers.is_only_reference(full_file_path):
283
+ server.shutdown()
284
+
285
+ # Delete the file for this server
286
+ storage.delete(f"{filename}.info")
287
+ except FileNotFoundError as e:
288
+ log.error("State file for server %s not found: %s", filename, e)
289
+ return
290
+ except ValueError as e:
291
+ log.error("Authentication error for server %s: %s", filename, e)
292
+ return
293
+ except Exception as e:
294
+ log.error("Error during shutdown of server %s: %s", filename, e)
295
+ raise
@@ -0,0 +1 @@
1
+ # Copyright 2024 The MathWorks, Inc.