matlab-proxy 0.5.3__py3-none-any.whl → 0.30.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.
- matlab_proxy/app.py +578 -205
- matlab_proxy/app_state.py +1061 -431
- matlab_proxy/constants.py +37 -0
- matlab_proxy/default_configuration.py +39 -4
- matlab_proxy/devel.py +18 -22
- matlab_proxy/gui/index.html +20 -1
- matlab_proxy/gui/static/css/index.BedVwcEg.css +10 -0
- matlab_proxy/gui/static/js/index.pQwV1obF.js +64 -0
- matlab_proxy/gui/static/media/MATLAB-env-blur.NupTbPv_.png +0 -0
- matlab_proxy/matlab/evaluateUserMatlabCode.m +51 -0
- matlab_proxy/matlab/startup.m +3 -28
- matlab_proxy/settings.py +543 -112
- matlab_proxy/util/__init__.py +187 -59
- matlab_proxy/util/cookie_jar.py +72 -0
- matlab_proxy/util/event_loop.py +28 -10
- matlab_proxy/util/list_servers.py +71 -26
- matlab_proxy/util/mw.py +16 -15
- matlab_proxy/util/mwi/download.py +136 -0
- matlab_proxy/util/mwi/embedded_connector/__init__.py +1 -1
- matlab_proxy/util/mwi/embedded_connector/helpers.py +12 -4
- matlab_proxy/util/mwi/embedded_connector/request.py +78 -12
- matlab_proxy/util/mwi/environment_variables.py +120 -27
- matlab_proxy/util/mwi/exceptions.py +63 -9
- matlab_proxy/util/mwi/logger.py +141 -27
- matlab_proxy/util/mwi/session_name.py +28 -0
- matlab_proxy/util/mwi/token_auth.py +264 -121
- matlab_proxy/util/mwi/validators.py +231 -88
- matlab_proxy/util/system.py +9 -0
- matlab_proxy/util/windows.py +32 -6
- {matlab_proxy-0.5.3.dist-info → matlab_proxy-0.30.1.dist-info}/METADATA +94 -49
- matlab_proxy-0.30.1.dist-info/RECORD +88 -0
- {matlab_proxy-0.5.3.dist-info → matlab_proxy-0.30.1.dist-info}/WHEEL +1 -2
- {matlab_proxy-0.5.3.dist-info → matlab_proxy-0.30.1.dist-info}/entry_points.txt +1 -1
- matlab_proxy_manager/README.md +85 -0
- matlab_proxy_manager/__init__.py +6 -0
- matlab_proxy_manager/lib/README.md +53 -0
- matlab_proxy_manager/lib/__init__.py +1 -0
- matlab_proxy_manager/lib/api.py +419 -0
- matlab_proxy_manager/storage/README.md +54 -0
- matlab_proxy_manager/storage/__init__.py +1 -0
- matlab_proxy_manager/storage/file_repository.py +144 -0
- matlab_proxy_manager/storage/interface.py +62 -0
- matlab_proxy_manager/storage/server.py +172 -0
- matlab_proxy_manager/utils/__init__.py +1 -0
- matlab_proxy_manager/utils/auth.py +77 -0
- matlab_proxy_manager/utils/constants.py +8 -0
- matlab_proxy_manager/utils/decorators.py +37 -0
- matlab_proxy_manager/utils/environment_variables.py +51 -0
- matlab_proxy_manager/utils/exceptions.py +45 -0
- matlab_proxy_manager/utils/helpers.py +314 -0
- matlab_proxy_manager/utils/logger.py +76 -0
- matlab_proxy_manager/web/README.md +37 -0
- matlab_proxy_manager/web/__init__.py +1 -0
- matlab_proxy_manager/web/app.py +536 -0
- matlab_proxy_manager/web/monitor.py +45 -0
- matlab_proxy_manager/web/watcher.py +65 -0
- matlab_proxy/gui/asset-manifest.json +0 -23
- matlab_proxy/gui/authorization.html +0 -115
- matlab_proxy/gui/bootstrap.3.4.1.min.css +0 -6
- matlab_proxy/gui/navbar.css +0 -8
- matlab_proxy/gui/signin.css +0 -42
- matlab_proxy/gui/static/css/main.d890078a.chunk.css +0 -13
- matlab_proxy/gui/static/css/main.d890078a.chunk.css.map +0 -1
- matlab_proxy/gui/static/js/2.13be6544.chunk.js +0 -3
- matlab_proxy/gui/static/js/2.13be6544.chunk.js.LICENSE.txt +0 -59
- matlab_proxy/gui/static/js/2.13be6544.chunk.js.map +0 -1
- matlab_proxy/gui/static/js/main.c311d854.chunk.js +0 -2
- matlab_proxy/gui/static/js/main.c311d854.chunk.js.map +0 -1
- matlab_proxy/gui/static/js/runtime-main.f70e4d5f.js +0 -2
- matlab_proxy/gui/static/js/runtime-main.f70e4d5f.js.map +0 -1
- matlab_proxy/gui/static/media/arrow.0c2968b9.svg +0 -4
- matlab_proxy/gui/static/media/feedback.6e8d50eb.svg +0 -1
- matlab_proxy/gui/static/media/gripper.9defbc5e.svg +0 -1
- matlab_proxy/gui/static/media/help.15e5bfab.svg +0 -1
- matlab_proxy/gui/static/media/ico-header-contact-hover.0958c442.svg +0 -17
- matlab_proxy/gui/static/media/ico-header-contact.ae9169c8.svg +0 -17
- matlab_proxy/gui/static/media/restart.7987508a.svg +0 -1
- matlab_proxy/gui/static/media/sign-out.08356b67.svg +0 -1
- matlab_proxy/gui/static/media/start.50c4596f.svg +0 -1
- matlab_proxy/gui/static/media/stop.30c9a9ab.svg +0 -1
- matlab_proxy/gui/static/media/terminate.7ea1363e.svg +0 -1
- matlab_proxy/gui/token.html +0 -123
- matlab_proxy-0.5.3.dist-info/RECORD +0 -84
- matlab_proxy-0.5.3.dist-info/top_level.txt +0 -1
- /matlab_proxy/gui/static/media/{glyphicons-halflings-regular.82b1212e.woff → glyphicons-halflings-regular.BKjkU69z.woff} +0 -0
- /matlab_proxy/gui/static/media/{glyphicons-halflings-regular.5be1347c.eot → glyphicons-halflings-regular.BUJKDMgK.eot} +0 -0
- /matlab_proxy/gui/static/media/{glyphicons-halflings-regular.060b2710.svg → glyphicons-halflings-regular.CSehLiBc.svg} +0 -0
- /matlab_proxy/gui/static/media/{glyphicons-halflings-regular.4692b9ec.ttf → glyphicons-halflings-regular.DrwTMapi.ttf} +0 -0
- /matlab_proxy/gui/static/media/{glyphicons-halflings-regular.be810be3.woff2 → glyphicons-halflings-regular.DzqM6ju8.woff2} +0 -0
- /matlab_proxy/gui/static/media/{ico-header-account-hover.89438e91.svg → ico-header-account-hover.-jQHo6Wx.svg} +0 -0
- /matlab_proxy/gui/static/media/{ico-header-account.86b10d7b.svg → ico-header-account.CJCFoo5a.svg} +0 -0
- /matlab_proxy/gui/static/media/{ico-sprite.cbdb66c0.png → ico-sprite.DXGLgzq9.png} +0 -0
- /matlab_proxy/gui/static/media/{mathworks-eps.4d20e0ee.ttf → mathworks-eps.CGNQALa9.ttf} +0 -0
- /matlab_proxy/gui/static/media/{mathworks-eps.df1428df.svg → mathworks-eps.DrkCtQtG.svg} +0 -0
- /matlab_proxy/gui/static/media/{mathworks-eps.e5c41e84.woff → mathworks-eps.Ds7lQbql.woff} +0 -0
- /matlab_proxy/gui/static/media/{mathworks-pictograms.3fc6513a.woff → mathworks-pictograms.BdqxEfBR.woff} +0 -0
- /matlab_proxy/gui/static/media/{mathworks-pictograms.f6f087b0.svg → mathworks-pictograms.CCLweoD4.svg} +0 -0
- /matlab_proxy/gui/static/media/{mathworks-pictograms.6e128c0e.ttf → mathworks-pictograms.DZhFdRSm.ttf} +0 -0
- /matlab_proxy/gui/static/media/{mathworks.80a3218e.svg → mathworks.C-qsbhDy.svg} +0 -0
- /matlab_proxy/gui/static/media/{mathworks.c422935b.ttf → mathworks.Ceplx86V.ttf} +0 -0
- /matlab_proxy/gui/static/media/{mathworks.37a563ef.woff → mathworks.D08X1Vp8.woff} +0 -0
- /matlab_proxy/gui/static/media/{trigger-error.3f1c4ef2.svg → trigger-error.QEdsGL-m.svg} +0 -0
- /matlab_proxy/gui/static/media/{trigger-ok.7b9c238b.svg → trigger-ok.Dzg8OIrk.svg} +0 -0
- {matlab_proxy-0.5.3.dist-info → matlab_proxy-0.30.1.dist-info/licenses}/LICENSE.md +0 -0
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# Copyright 2024-2025 The MathWorks, Inc.
|
|
2
|
+
|
|
3
|
+
# This file contains functions required to enable downloads from the file browser
|
|
4
|
+
from matlab_proxy.util.mwi import logger as mwi_logger
|
|
5
|
+
from matlab_proxy.util import mwi, system
|
|
6
|
+
|
|
7
|
+
logger = mwi_logger.get()
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def _is_null_base_url(base_url):
|
|
11
|
+
return base_url == "/" or base_url == ""
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def is_download_request(req):
|
|
15
|
+
"""
|
|
16
|
+
Determine if the incoming request is for a download action.
|
|
17
|
+
|
|
18
|
+
This function checks if the request's relative URL path starts with
|
|
19
|
+
'/download/' or with '{base_url}/download/', depending on the base URL
|
|
20
|
+
specified in the application settings.
|
|
21
|
+
|
|
22
|
+
Parameters:
|
|
23
|
+
req (HTTPRequest): HTTPRequest Object
|
|
24
|
+
|
|
25
|
+
Returns:
|
|
26
|
+
- bool: True if the request is for a download, False otherwise.
|
|
27
|
+
```
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
base_url = req.app["settings"]["base_url"]
|
|
31
|
+
if _is_null_base_url(base_url):
|
|
32
|
+
return req.rel_url.path.startswith("/download")
|
|
33
|
+
else:
|
|
34
|
+
return req.rel_url.path.startswith(f"{base_url}/download")
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
async def get_download_url(req):
|
|
38
|
+
"""
|
|
39
|
+
Asynchronously generates a download URL for a file.
|
|
40
|
+
|
|
41
|
+
This function takes a request object, extracts the full path to the file, and
|
|
42
|
+
uses the MATLAB Web Interface (MWI) to generate a download URL for that file.
|
|
43
|
+
It logs the full path and the response from the MWI. If successful, it returns
|
|
44
|
+
the download URL; otherwise, it returns None.
|
|
45
|
+
|
|
46
|
+
Parameters:
|
|
47
|
+
The request object containing necessary information to process the download.
|
|
48
|
+
Returns:
|
|
49
|
+
The download URL string if successful, None otherwise.
|
|
50
|
+
Raises:
|
|
51
|
+
Logs an error message and returns None if an error occurs.
|
|
52
|
+
"""
|
|
53
|
+
full_path_to_file = _get_download_payload_path(req)
|
|
54
|
+
logger.debug(f"full_path_to_file: {full_path_to_file}")
|
|
55
|
+
|
|
56
|
+
args = [full_path_to_file, 1.0]
|
|
57
|
+
data = mwi.embedded_connector.helpers.get_data_to_feval_mcode(
|
|
58
|
+
"matlab.ui.internal.URLUtils.getURLToUserFile", *args, nargout=1
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
try:
|
|
62
|
+
state = req.app["state"]
|
|
63
|
+
headers = state._get_token_auth_headers()
|
|
64
|
+
url = mwi.embedded_connector.helpers.get_mvm_endpoint(
|
|
65
|
+
state.settings["mwi_server_url"]
|
|
66
|
+
)
|
|
67
|
+
resp_json = await mwi.embedded_connector.send_request(
|
|
68
|
+
url=url,
|
|
69
|
+
method="POST",
|
|
70
|
+
data=data,
|
|
71
|
+
headers=headers,
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
logger.debug(f"EC Response URL: {resp_json}")
|
|
75
|
+
|
|
76
|
+
resp = resp_json["messages"]["FEvalResponse"][0]
|
|
77
|
+
|
|
78
|
+
if not resp["isError"]:
|
|
79
|
+
# No error detected, proceed to fetch the results
|
|
80
|
+
download_url = resp["results"][0]
|
|
81
|
+
logger.debug(f"download_url: {download_url}")
|
|
82
|
+
base_url = req.app["settings"]["base_url"]
|
|
83
|
+
return (
|
|
84
|
+
download_url
|
|
85
|
+
if _is_null_base_url(base_url)
|
|
86
|
+
else f"{base_url}{download_url}"
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
except KeyError as key_err:
|
|
90
|
+
logger.error(f"Invalid Key Usage Detected! Check key: {key_err}")
|
|
91
|
+
pass
|
|
92
|
+
|
|
93
|
+
except Exception as err:
|
|
94
|
+
logger.error(
|
|
95
|
+
f"Failed to create download url from the Embedded Connector due to err: {err}"
|
|
96
|
+
)
|
|
97
|
+
pass
|
|
98
|
+
|
|
99
|
+
# In case of any failures.
|
|
100
|
+
return None
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def _get_download_payload_path(req):
|
|
104
|
+
"""
|
|
105
|
+
Constructs the file system path to the payload for a download request.
|
|
106
|
+
|
|
107
|
+
This function analyzes the incoming request to determine the intended file path
|
|
108
|
+
for download. It takes into account the base URL from the application settings,
|
|
109
|
+
the nature of the request (whether it's a download request), and the operating
|
|
110
|
+
system to format the path correctly. The function supports different path
|
|
111
|
+
formatting for Windows and Unix-like systems due to their differences in file
|
|
112
|
+
system path syntax.
|
|
113
|
+
|
|
114
|
+
Note:
|
|
115
|
+
This function is intended to be used internally and starts with an underscore
|
|
116
|
+
to indicate it is a private member of the module.
|
|
117
|
+
|
|
118
|
+
Args:
|
|
119
|
+
req: An object representing the incoming request, which includes the relative
|
|
120
|
+
URL from which the file path can be deduced.
|
|
121
|
+
|
|
122
|
+
Returns:
|
|
123
|
+
A string representing the file system path to the requested download payload,
|
|
124
|
+
or None if the request is not a download request.
|
|
125
|
+
"""
|
|
126
|
+
base_url = req.app["settings"]["base_url"]
|
|
127
|
+
if is_download_request(req):
|
|
128
|
+
from pathlib import Path
|
|
129
|
+
|
|
130
|
+
compare_str = (
|
|
131
|
+
"/download" if _is_null_base_url(base_url) else f"{base_url}/download"
|
|
132
|
+
)
|
|
133
|
+
|
|
134
|
+
return str(req.rel_url.path).replace(compare_str, "", 1)
|
|
135
|
+
|
|
136
|
+
return None
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
# Copyright
|
|
2
|
-
|
|
3
|
-
""" This file contains helper methods which return the details required for sending
|
|
4
|
-
a HTTP request to the Embedded Connector. """
|
|
1
|
+
# Copyright 2020-2024 The MathWorks, Inc.
|
|
5
2
|
|
|
3
|
+
"""This file contains helper methods which return the details required for sending
|
|
4
|
+
a HTTP request to the Embedded Connector."""
|
|
6
5
|
|
|
7
6
|
from matlab_proxy.util import mwi
|
|
8
7
|
from matlab_proxy.util.mwi import environment_variables as mwi_env
|
|
@@ -46,6 +45,15 @@ def get_data_for_ping_request():
|
|
|
46
45
|
return {"messages": {"Ping": [{}]}}
|
|
47
46
|
|
|
48
47
|
|
|
48
|
+
def get_data_for_matlab_busy_status_request():
|
|
49
|
+
"""Returns data required to send in the payload for a MATLAB busy/idle status request to the embedded connector
|
|
50
|
+
|
|
51
|
+
Returns:
|
|
52
|
+
dict: Payload data
|
|
53
|
+
"""
|
|
54
|
+
return {"messages": {"GetMatlabStatus": [{}]}}
|
|
55
|
+
|
|
56
|
+
|
|
49
57
|
def get_data_to_eval_mcode(m_code):
|
|
50
58
|
"""Returns the data required to send in the payload for evaluating mcode using eval function to the embedded connector.
|
|
51
59
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
# Copyright
|
|
1
|
+
# Copyright 2020-2024 The MathWorks, Inc.
|
|
2
2
|
|
|
3
|
-
"""
|
|
3
|
+
"""
|
|
4
4
|
This file contains the methods to communicate with the embedded connector.
|
|
5
5
|
"""
|
|
6
6
|
|
|
@@ -8,7 +8,15 @@ import json
|
|
|
8
8
|
|
|
9
9
|
from matlab_proxy.util.mwi.exceptions import EmbeddedConnectorError
|
|
10
10
|
|
|
11
|
-
from .
|
|
11
|
+
from matlab_proxy.util import mwi
|
|
12
|
+
|
|
13
|
+
logger = mwi.logger.get()
|
|
14
|
+
|
|
15
|
+
from .helpers import (
|
|
16
|
+
get_data_for_ping_request,
|
|
17
|
+
get_data_for_matlab_busy_status_request,
|
|
18
|
+
get_ping_endpoint,
|
|
19
|
+
)
|
|
12
20
|
|
|
13
21
|
|
|
14
22
|
async def send_request(url: str, data: dict, method: str, headers: dict = None) -> dict:
|
|
@@ -38,12 +46,16 @@ async def send_request(url: str, data: dict, method: str, headers: dict = None)
|
|
|
38
46
|
data = json.dumps(data)
|
|
39
47
|
|
|
40
48
|
try:
|
|
41
|
-
async with aiohttp.ClientSession() as session:
|
|
49
|
+
async with aiohttp.ClientSession(trust_env=True) as session:
|
|
50
|
+
logger.debug(
|
|
51
|
+
f"sending request: method={method}, url={url}, data={data}, headers={headers}, "
|
|
52
|
+
)
|
|
53
|
+
|
|
42
54
|
async with session.request(
|
|
43
|
-
method=method, url=url, data=data, headers=
|
|
55
|
+
method=method, url=url, data=data, headers=headers, ssl=False
|
|
44
56
|
) as resp:
|
|
45
|
-
|
|
46
|
-
|
|
57
|
+
logger.debug(f"response from endpoint{url} and resp={resp}")
|
|
58
|
+
if not resp.ok:
|
|
47
59
|
# Converting to dict and formatting for printing
|
|
48
60
|
data = json.loads(data)
|
|
49
61
|
|
|
@@ -56,22 +68,76 @@ async def send_request(url: str, data: dict, method: str, headers: dict = None)
|
|
|
56
68
|
raise err
|
|
57
69
|
|
|
58
70
|
|
|
59
|
-
async def get_state(mwi_server_url):
|
|
71
|
+
async def get_state(mwi_server_url, headers=None):
|
|
60
72
|
"""Returns the state of MATLAB's Embedded Connector.
|
|
61
73
|
|
|
62
74
|
Args:
|
|
63
75
|
port (int): The port on which the embedded connector is running at
|
|
64
|
-
|
|
76
|
+
headers: Headers to include with the request
|
|
65
77
|
Returns:
|
|
66
78
|
str: Either "up" or "down"
|
|
67
79
|
"""
|
|
68
80
|
data = get_data_for_ping_request()
|
|
69
81
|
url = get_ping_endpoint(mwi_server_url)
|
|
82
|
+
|
|
70
83
|
try:
|
|
71
|
-
resp = await send_request(
|
|
84
|
+
resp = await send_request(
|
|
85
|
+
url=url,
|
|
86
|
+
data=data,
|
|
87
|
+
method="POST",
|
|
88
|
+
headers=headers,
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
# Any changes in response from embedded connector would be caught by KeyError
|
|
72
92
|
if not resp["messages"]["PingResponse"][0]["messageFaults"]:
|
|
73
93
|
return "up"
|
|
74
|
-
|
|
75
|
-
|
|
94
|
+
|
|
95
|
+
except KeyError as key_err:
|
|
96
|
+
logger.error(f"Invalid Key Usage Detected! Check key: {key_err}")
|
|
97
|
+
|
|
98
|
+
except Exception as err:
|
|
99
|
+
logger.debug(
|
|
100
|
+
f"{err}: Embbeded connector is currently not responding to ping requests."
|
|
101
|
+
)
|
|
76
102
|
|
|
77
103
|
return "down"
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
async def get_busy_state(mwi_server_url, headers=None):
|
|
107
|
+
"""Returns the state of MATLAB's Embedded Connector.
|
|
108
|
+
|
|
109
|
+
Args:
|
|
110
|
+
port (int): The port on which the embedded connector is running at
|
|
111
|
+
headers: Headers to include with the request
|
|
112
|
+
Returns:
|
|
113
|
+
str: Either "idle" or "busy" when a valid response is received. Else None is returned.
|
|
114
|
+
"""
|
|
115
|
+
data = get_data_for_matlab_busy_status_request()
|
|
116
|
+
url = get_ping_endpoint(mwi_server_url)
|
|
117
|
+
|
|
118
|
+
busy_status = None
|
|
119
|
+
|
|
120
|
+
try:
|
|
121
|
+
resp = await send_request(
|
|
122
|
+
url=url,
|
|
123
|
+
data=data,
|
|
124
|
+
method="POST",
|
|
125
|
+
headers=headers,
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
busy_status = resp["messages"]["GetMatlabStatusResponse"][0]["status"].lower()
|
|
129
|
+
|
|
130
|
+
assert busy_status in [
|
|
131
|
+
"idle",
|
|
132
|
+
"busy",
|
|
133
|
+
], f"Was expecting MATLAB busy status to be either 'idle' or 'busy', but received {busy_status} instead."
|
|
134
|
+
|
|
135
|
+
except KeyError as key_err:
|
|
136
|
+
logger.error(f"Invalid Key Usage Detected! Check key: {key_err}")
|
|
137
|
+
|
|
138
|
+
except Exception as err:
|
|
139
|
+
logger.debug(
|
|
140
|
+
f"{err}: Embedded connector is currently not responding to ping requests."
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
return busy_status
|
|
@@ -1,9 +1,33 @@
|
|
|
1
|
-
# Copyright
|
|
1
|
+
# Copyright 2020-2025 The MathWorks, Inc.
|
|
2
2
|
"""This file lists and exposes the environment variables which are used by the integration."""
|
|
3
3
|
|
|
4
4
|
import os
|
|
5
5
|
|
|
6
6
|
|
|
7
|
+
def _is_env_set_to_true(env_name: str) -> bool:
|
|
8
|
+
"""Helper function that returns True if the environment variable specified is set to True.
|
|
9
|
+
|
|
10
|
+
Args:
|
|
11
|
+
env_name (str): Name of the environment variable to check the state for.
|
|
12
|
+
|
|
13
|
+
Returns:
|
|
14
|
+
bool: True if the value of the environment variable is a case insensitive match to the string "True"
|
|
15
|
+
"""
|
|
16
|
+
return os.environ.get(env_name, "false").lower() == "true"
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def _is_env_set_to_false(env_name: str) -> bool:
|
|
20
|
+
"""Helper function that returns True if the environment variable specified is set to False.
|
|
21
|
+
|
|
22
|
+
Args:
|
|
23
|
+
env_name (str): Name of the environment variable to check the state for.
|
|
24
|
+
|
|
25
|
+
Returns:
|
|
26
|
+
bool: True if the value of the environment variable is a case insensitive match to the string "False"
|
|
27
|
+
"""
|
|
28
|
+
return os.environ.get(env_name, "").lower() == "false"
|
|
29
|
+
|
|
30
|
+
|
|
7
31
|
def get_env_name_network_license_manager():
|
|
8
32
|
"""Specifies the path to valid license file or address of a network license server"""
|
|
9
33
|
return "MLM_LICENSE_FILE"
|
|
@@ -20,19 +44,10 @@ def get_env_name_logging_level():
|
|
|
20
44
|
|
|
21
45
|
|
|
22
46
|
def get_env_name_enable_web_logging():
|
|
23
|
-
"""
|
|
47
|
+
"""Enable the logging of asyncio web traffic by setting to true"""
|
|
24
48
|
return "MWI_ENABLE_WEB_LOGGING"
|
|
25
49
|
|
|
26
50
|
|
|
27
|
-
def get_old_env_name_enable_web_logging():
|
|
28
|
-
"""
|
|
29
|
-
Enable the logging of asyncio web traffic by setting to true
|
|
30
|
-
This name is deprecated and was last published in version v0.2.10 of matlab-proxy.
|
|
31
|
-
"""
|
|
32
|
-
|
|
33
|
-
return "MWI_WEB_LOGGING_ENABLED"
|
|
34
|
-
|
|
35
|
-
|
|
36
51
|
def get_env_name_log_file():
|
|
37
52
|
"""Specifies a file into which logging content is directed"""
|
|
38
53
|
return "MWI_LOG_FILE"
|
|
@@ -89,32 +104,22 @@ def get_env_name_matlab_tempdir():
|
|
|
89
104
|
|
|
90
105
|
def is_development_mode_enabled():
|
|
91
106
|
"""Returns true if the app is in development mode."""
|
|
92
|
-
return
|
|
107
|
+
return _is_env_set_to_true(get_env_name_development())
|
|
93
108
|
|
|
94
109
|
|
|
95
110
|
def is_testing_mode_enabled():
|
|
96
111
|
"""Returns true if the app is in testing mode."""
|
|
97
|
-
return (
|
|
98
|
-
is_development_mode_enabled()
|
|
99
|
-
and os.environ.get(get_env_name_testing(), "false").lower() == "true"
|
|
100
|
-
)
|
|
112
|
+
return is_development_mode_enabled() and _is_env_set_to_true(get_env_name_testing())
|
|
101
113
|
|
|
102
114
|
|
|
103
115
|
def is_web_logging_enabled():
|
|
104
116
|
"""Returns true if the web logging is required to be enabled"""
|
|
117
|
+
return _is_env_set_to_true(get_env_name_enable_web_logging())
|
|
105
118
|
|
|
106
|
-
if os.environ.get(get_old_env_name_enable_web_logging(), None) is not None:
|
|
107
|
-
from matlab_proxy.util import mwi
|
|
108
119
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
)
|
|
113
|
-
return (
|
|
114
|
-
os.environ.get(get_old_env_name_enable_web_logging(), "false").lower()
|
|
115
|
-
== "true"
|
|
116
|
-
)
|
|
117
|
-
return os.environ.get(get_env_name_enable_web_logging(), "false").lower() == "true"
|
|
120
|
+
def get_env_name_enable_ssl():
|
|
121
|
+
"""Returns the environment variable used for enabling/disabling SSL/TLS communication."""
|
|
122
|
+
return "MWI_ENABLE_SSL"
|
|
118
123
|
|
|
119
124
|
|
|
120
125
|
def get_env_name_ssl_cert_file():
|
|
@@ -135,3 +140,91 @@ def get_env_name_enable_mwi_auth_token():
|
|
|
135
140
|
def get_env_name_mwi_auth_token():
|
|
136
141
|
"""User specified token for use with Token-Based Authentication"""
|
|
137
142
|
return "MWI_AUTH_TOKEN"
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
def get_env_name_matlab_log_dir():
|
|
146
|
+
"""Returns the key used for MATLAB log dir env variable"""
|
|
147
|
+
return "MATLAB_LOG_DIR"
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
def get_env_name_mwi_use_existing_license():
|
|
151
|
+
"""Returns the environment variable name used to instruct matlab-proxy to use an existing license. Usually used by already activated MATLAB installations."""
|
|
152
|
+
return "MWI_USE_EXISTING_LICENSE"
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
def get_env_name_custom_matlab_root():
|
|
156
|
+
"""User specified path to MATLAB root"""
|
|
157
|
+
return "MWI_CUSTOM_MATLAB_ROOT"
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
def get_env_name_process_startup_timeout():
|
|
161
|
+
"""User specified timeout in seconds for processes launched by matlab-proxy"""
|
|
162
|
+
return "MWI_PROCESS_START_TIMEOUT"
|
|
163
|
+
|
|
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
|
+
|
|
170
|
+
def get_env_name_shutdown_on_idle_timeout():
|
|
171
|
+
"""User specified timeout in minutes for shutdown on idle of matlab-proxy"""
|
|
172
|
+
return "MWI_SHUTDOWN_ON_IDLE_TIMEOUT"
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
def get_env_name_session_name():
|
|
176
|
+
"""User specified session name for the MATLAB Proxy instance, used to set the browser title."""
|
|
177
|
+
return "MWI_SESSION_NAME"
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
class Experimental:
|
|
181
|
+
"""This class houses functions which are undocumented APIs and Environment variables.
|
|
182
|
+
Note: Never add any state to this class. Its only intended for use as an abstraction layer
|
|
183
|
+
for functions which are not ready for prime time.
|
|
184
|
+
"""
|
|
185
|
+
|
|
186
|
+
@staticmethod
|
|
187
|
+
def get_env_name_enable_simulink():
|
|
188
|
+
"""Returns the environment variable name used to enable simulink support"""
|
|
189
|
+
##NOTE: Simulink Online is unavailable for general use as of R2023b.
|
|
190
|
+
return "MWI_ENABLE_SIMULINK"
|
|
191
|
+
|
|
192
|
+
@staticmethod
|
|
193
|
+
def is_simulink_enabled():
|
|
194
|
+
"""Returns true if the simulink online is enabled."""
|
|
195
|
+
return _is_env_set_to_true(Experimental.get_env_name_enable_simulink())
|
|
196
|
+
|
|
197
|
+
@staticmethod
|
|
198
|
+
def get_env_name_profile_matlab_startup():
|
|
199
|
+
"""Returns the environment variable name used to enable MPA support"""
|
|
200
|
+
return "MWI_PROFILE_MATLAB_STARTUP"
|
|
201
|
+
|
|
202
|
+
@staticmethod
|
|
203
|
+
def is_matlab_startup_profiling_enabled():
|
|
204
|
+
"""Returns true if the startup profiling is enabled."""
|
|
205
|
+
return _is_env_set_to_true(Experimental.get_env_name_profile_matlab_startup())
|
|
206
|
+
|
|
207
|
+
@staticmethod
|
|
208
|
+
def get_env_name_use_cookie_cache():
|
|
209
|
+
"""Returns the environment variable name used to enable cookie jar support for matlab-proxy"""
|
|
210
|
+
return "MWI_USE_COOKIE_CACHE"
|
|
211
|
+
|
|
212
|
+
@staticmethod
|
|
213
|
+
def should_use_cookie_cache():
|
|
214
|
+
"""Returns true if the cookie jar support is enabled."""
|
|
215
|
+
return _is_env_set_to_true(Experimental.get_env_name_use_cookie_cache())
|
|
216
|
+
|
|
217
|
+
@staticmethod
|
|
218
|
+
def get_env_name_use_rich_logging():
|
|
219
|
+
"""Set to True to enable rich logging to console."""
|
|
220
|
+
return "MWI_USE_RICH_LOGGING"
|
|
221
|
+
|
|
222
|
+
@staticmethod
|
|
223
|
+
def use_rich_logger():
|
|
224
|
+
"""Returns true if the cookie jar support is enabled."""
|
|
225
|
+
return _is_env_set_to_true(Experimental.get_env_name_use_rich_logging())
|
|
226
|
+
|
|
227
|
+
@staticmethod
|
|
228
|
+
def get_licmode_override():
|
|
229
|
+
"""Returns the licmode oveerride if set"""
|
|
230
|
+
return os.environ.get("MWI_LICMODE_OVERRIDE", None)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright
|
|
1
|
+
# Copyright 2020-2025 The MathWorks, Inc.
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
class AppError(Exception):
|
|
@@ -17,9 +17,19 @@ class AppError(Exception):
|
|
|
17
17
|
self.stacktrace = stacktrace
|
|
18
18
|
|
|
19
19
|
|
|
20
|
-
class
|
|
21
|
-
"""
|
|
22
|
-
|
|
20
|
+
class FatalError(AppError):
|
|
21
|
+
"""An error which indicates that matlab-proxy web server cannot be brought up.
|
|
22
|
+
Args:
|
|
23
|
+
AppError (Class): Parent Class containing attributes to store
|
|
24
|
+
messages, logs and stacktrace.
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
pass
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class UIVisibleFatalError(AppError):
|
|
31
|
+
"""A Class with inherits from the AppError class.
|
|
32
|
+
This class is used to represent Fatal Errors which need to be propagated to the front end.
|
|
23
33
|
|
|
24
34
|
Args:
|
|
25
35
|
AppError (Class): Parent Class containing attributes to store
|
|
@@ -29,7 +39,7 @@ class InternalError(AppError):
|
|
|
29
39
|
pass
|
|
30
40
|
|
|
31
41
|
|
|
32
|
-
class MatlabInstallError(
|
|
42
|
+
class MatlabInstallError(UIVisibleFatalError):
|
|
33
43
|
"""A Class which inherits the AppError class.
|
|
34
44
|
|
|
35
45
|
This class represents errors with MATLAB Installation.
|
|
@@ -129,6 +139,19 @@ class XvfbError(AppError):
|
|
|
129
139
|
pass
|
|
130
140
|
|
|
131
141
|
|
|
142
|
+
class WindowManagerError(AppError):
|
|
143
|
+
"""A Class which inherits the AppError class.
|
|
144
|
+
|
|
145
|
+
This class represents any errors raised when instantiating a Window Manager within the Xvfb DISPLAY.
|
|
146
|
+
|
|
147
|
+
Args:
|
|
148
|
+
AppError (Class): Parent Class containing attributes to store
|
|
149
|
+
messages, logs and stacktrace.
|
|
150
|
+
"""
|
|
151
|
+
|
|
152
|
+
pass
|
|
153
|
+
|
|
154
|
+
|
|
132
155
|
class EmbeddedConnectorError(MatlabError):
|
|
133
156
|
"""A Class which inherits the MatlabError class.
|
|
134
157
|
|
|
@@ -142,6 +165,34 @@ class EmbeddedConnectorError(MatlabError):
|
|
|
142
165
|
pass
|
|
143
166
|
|
|
144
167
|
|
|
168
|
+
class InvalidTokenError(AppError):
|
|
169
|
+
"""A Class which inherits the AppError class.
|
|
170
|
+
|
|
171
|
+
This class represents token authentication errors.
|
|
172
|
+
|
|
173
|
+
Args:
|
|
174
|
+
AppError (Class): Parent Class containing attributes to store
|
|
175
|
+
messages, logs and stacktrace.
|
|
176
|
+
"""
|
|
177
|
+
|
|
178
|
+
pass
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
class LockAcquisitionError(Exception):
|
|
182
|
+
"""Exception raised when a lock is not properly acquired before modifying a variable.
|
|
183
|
+
|
|
184
|
+
This error is thrown in scenarios where:
|
|
185
|
+
1) A lock must be acquired before modifying a shared resource, but it wasn't.
|
|
186
|
+
2) The lock for a shared resource was acquired by one function, but another function attempts to modify the resource without holding the lock.
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
Args:
|
|
190
|
+
Exception : Python's inbuilt Exception Class.
|
|
191
|
+
"""
|
|
192
|
+
|
|
193
|
+
pass
|
|
194
|
+
|
|
195
|
+
|
|
145
196
|
def log_error(logger, err: Exception):
|
|
146
197
|
"""Logs any error to stdout.
|
|
147
198
|
|
|
@@ -150,7 +201,10 @@ def log_error(logger, err: Exception):
|
|
|
150
201
|
err (Class): An instance of one of the Error classes as defined above.
|
|
151
202
|
Example: OnlineLicensingError, EntitlementError
|
|
152
203
|
"""
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
204
|
+
if isinstance(err, AppError):
|
|
205
|
+
logs_str = ("\n" + "\n".join(err.logs)) if err.logs is not None else ""
|
|
206
|
+
logger.error(
|
|
207
|
+
err.message if err.message else "An Exception was raised:\n" + logs_str
|
|
208
|
+
)
|
|
209
|
+
else:
|
|
210
|
+
logger.error(err)
|