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.
Files changed (104) hide show
  1. matlab_proxy/app.py +578 -205
  2. matlab_proxy/app_state.py +1061 -431
  3. matlab_proxy/constants.py +37 -0
  4. matlab_proxy/default_configuration.py +39 -4
  5. matlab_proxy/devel.py +18 -22
  6. matlab_proxy/gui/index.html +20 -1
  7. matlab_proxy/gui/static/css/index.BedVwcEg.css +10 -0
  8. matlab_proxy/gui/static/js/index.pQwV1obF.js +64 -0
  9. matlab_proxy/gui/static/media/MATLAB-env-blur.NupTbPv_.png +0 -0
  10. matlab_proxy/matlab/evaluateUserMatlabCode.m +51 -0
  11. matlab_proxy/matlab/startup.m +3 -28
  12. matlab_proxy/settings.py +543 -112
  13. matlab_proxy/util/__init__.py +187 -59
  14. matlab_proxy/util/cookie_jar.py +72 -0
  15. matlab_proxy/util/event_loop.py +28 -10
  16. matlab_proxy/util/list_servers.py +71 -26
  17. matlab_proxy/util/mw.py +16 -15
  18. matlab_proxy/util/mwi/download.py +136 -0
  19. matlab_proxy/util/mwi/embedded_connector/__init__.py +1 -1
  20. matlab_proxy/util/mwi/embedded_connector/helpers.py +12 -4
  21. matlab_proxy/util/mwi/embedded_connector/request.py +78 -12
  22. matlab_proxy/util/mwi/environment_variables.py +120 -27
  23. matlab_proxy/util/mwi/exceptions.py +63 -9
  24. matlab_proxy/util/mwi/logger.py +141 -27
  25. matlab_proxy/util/mwi/session_name.py +28 -0
  26. matlab_proxy/util/mwi/token_auth.py +264 -121
  27. matlab_proxy/util/mwi/validators.py +231 -88
  28. matlab_proxy/util/system.py +9 -0
  29. matlab_proxy/util/windows.py +32 -6
  30. {matlab_proxy-0.5.3.dist-info → matlab_proxy-0.30.1.dist-info}/METADATA +94 -49
  31. matlab_proxy-0.30.1.dist-info/RECORD +88 -0
  32. {matlab_proxy-0.5.3.dist-info → matlab_proxy-0.30.1.dist-info}/WHEEL +1 -2
  33. {matlab_proxy-0.5.3.dist-info → matlab_proxy-0.30.1.dist-info}/entry_points.txt +1 -1
  34. matlab_proxy_manager/README.md +85 -0
  35. matlab_proxy_manager/__init__.py +6 -0
  36. matlab_proxy_manager/lib/README.md +53 -0
  37. matlab_proxy_manager/lib/__init__.py +1 -0
  38. matlab_proxy_manager/lib/api.py +419 -0
  39. matlab_proxy_manager/storage/README.md +54 -0
  40. matlab_proxy_manager/storage/__init__.py +1 -0
  41. matlab_proxy_manager/storage/file_repository.py +144 -0
  42. matlab_proxy_manager/storage/interface.py +62 -0
  43. matlab_proxy_manager/storage/server.py +172 -0
  44. matlab_proxy_manager/utils/__init__.py +1 -0
  45. matlab_proxy_manager/utils/auth.py +77 -0
  46. matlab_proxy_manager/utils/constants.py +8 -0
  47. matlab_proxy_manager/utils/decorators.py +37 -0
  48. matlab_proxy_manager/utils/environment_variables.py +51 -0
  49. matlab_proxy_manager/utils/exceptions.py +45 -0
  50. matlab_proxy_manager/utils/helpers.py +314 -0
  51. matlab_proxy_manager/utils/logger.py +76 -0
  52. matlab_proxy_manager/web/README.md +37 -0
  53. matlab_proxy_manager/web/__init__.py +1 -0
  54. matlab_proxy_manager/web/app.py +536 -0
  55. matlab_proxy_manager/web/monitor.py +45 -0
  56. matlab_proxy_manager/web/watcher.py +65 -0
  57. matlab_proxy/gui/asset-manifest.json +0 -23
  58. matlab_proxy/gui/authorization.html +0 -115
  59. matlab_proxy/gui/bootstrap.3.4.1.min.css +0 -6
  60. matlab_proxy/gui/navbar.css +0 -8
  61. matlab_proxy/gui/signin.css +0 -42
  62. matlab_proxy/gui/static/css/main.d890078a.chunk.css +0 -13
  63. matlab_proxy/gui/static/css/main.d890078a.chunk.css.map +0 -1
  64. matlab_proxy/gui/static/js/2.13be6544.chunk.js +0 -3
  65. matlab_proxy/gui/static/js/2.13be6544.chunk.js.LICENSE.txt +0 -59
  66. matlab_proxy/gui/static/js/2.13be6544.chunk.js.map +0 -1
  67. matlab_proxy/gui/static/js/main.c311d854.chunk.js +0 -2
  68. matlab_proxy/gui/static/js/main.c311d854.chunk.js.map +0 -1
  69. matlab_proxy/gui/static/js/runtime-main.f70e4d5f.js +0 -2
  70. matlab_proxy/gui/static/js/runtime-main.f70e4d5f.js.map +0 -1
  71. matlab_proxy/gui/static/media/arrow.0c2968b9.svg +0 -4
  72. matlab_proxy/gui/static/media/feedback.6e8d50eb.svg +0 -1
  73. matlab_proxy/gui/static/media/gripper.9defbc5e.svg +0 -1
  74. matlab_proxy/gui/static/media/help.15e5bfab.svg +0 -1
  75. matlab_proxy/gui/static/media/ico-header-contact-hover.0958c442.svg +0 -17
  76. matlab_proxy/gui/static/media/ico-header-contact.ae9169c8.svg +0 -17
  77. matlab_proxy/gui/static/media/restart.7987508a.svg +0 -1
  78. matlab_proxy/gui/static/media/sign-out.08356b67.svg +0 -1
  79. matlab_proxy/gui/static/media/start.50c4596f.svg +0 -1
  80. matlab_proxy/gui/static/media/stop.30c9a9ab.svg +0 -1
  81. matlab_proxy/gui/static/media/terminate.7ea1363e.svg +0 -1
  82. matlab_proxy/gui/token.html +0 -123
  83. matlab_proxy-0.5.3.dist-info/RECORD +0 -84
  84. matlab_proxy-0.5.3.dist-info/top_level.txt +0 -1
  85. /matlab_proxy/gui/static/media/{glyphicons-halflings-regular.82b1212e.woff → glyphicons-halflings-regular.BKjkU69z.woff} +0 -0
  86. /matlab_proxy/gui/static/media/{glyphicons-halflings-regular.5be1347c.eot → glyphicons-halflings-regular.BUJKDMgK.eot} +0 -0
  87. /matlab_proxy/gui/static/media/{glyphicons-halflings-regular.060b2710.svg → glyphicons-halflings-regular.CSehLiBc.svg} +0 -0
  88. /matlab_proxy/gui/static/media/{glyphicons-halflings-regular.4692b9ec.ttf → glyphicons-halflings-regular.DrwTMapi.ttf} +0 -0
  89. /matlab_proxy/gui/static/media/{glyphicons-halflings-regular.be810be3.woff2 → glyphicons-halflings-regular.DzqM6ju8.woff2} +0 -0
  90. /matlab_proxy/gui/static/media/{ico-header-account-hover.89438e91.svg → ico-header-account-hover.-jQHo6Wx.svg} +0 -0
  91. /matlab_proxy/gui/static/media/{ico-header-account.86b10d7b.svg → ico-header-account.CJCFoo5a.svg} +0 -0
  92. /matlab_proxy/gui/static/media/{ico-sprite.cbdb66c0.png → ico-sprite.DXGLgzq9.png} +0 -0
  93. /matlab_proxy/gui/static/media/{mathworks-eps.4d20e0ee.ttf → mathworks-eps.CGNQALa9.ttf} +0 -0
  94. /matlab_proxy/gui/static/media/{mathworks-eps.df1428df.svg → mathworks-eps.DrkCtQtG.svg} +0 -0
  95. /matlab_proxy/gui/static/media/{mathworks-eps.e5c41e84.woff → mathworks-eps.Ds7lQbql.woff} +0 -0
  96. /matlab_proxy/gui/static/media/{mathworks-pictograms.3fc6513a.woff → mathworks-pictograms.BdqxEfBR.woff} +0 -0
  97. /matlab_proxy/gui/static/media/{mathworks-pictograms.f6f087b0.svg → mathworks-pictograms.CCLweoD4.svg} +0 -0
  98. /matlab_proxy/gui/static/media/{mathworks-pictograms.6e128c0e.ttf → mathworks-pictograms.DZhFdRSm.ttf} +0 -0
  99. /matlab_proxy/gui/static/media/{mathworks.80a3218e.svg → mathworks.C-qsbhDy.svg} +0 -0
  100. /matlab_proxy/gui/static/media/{mathworks.c422935b.ttf → mathworks.Ceplx86V.ttf} +0 -0
  101. /matlab_proxy/gui/static/media/{mathworks.37a563ef.woff → mathworks.D08X1Vp8.woff} +0 -0
  102. /matlab_proxy/gui/static/media/{trigger-error.3f1c4ef2.svg → trigger-error.QEdsGL-m.svg} +0 -0
  103. /matlab_proxy/gui/static/media/{trigger-ok.7b9c238b.svg → trigger-ok.Dzg8OIrk.svg} +0 -0
  104. {matlab_proxy-0.5.3.dist-info → matlab_proxy-0.30.1.dist-info/licenses}/LICENSE.md +0 -0
@@ -0,0 +1,314 @@
1
+ # Copyright 2024-2025 The MathWorks, Inc.
2
+ import asyncio
3
+ import http
4
+ import os
5
+ import socket
6
+ import time
7
+ from contextlib import contextmanager
8
+ from pathlib import Path
9
+ from typing import Dict, Generator, Optional, Tuple
10
+ from urllib.parse import urlparse
11
+
12
+ import psutil
13
+ import requests
14
+ from aiohttp import web
15
+ from requests.adapters import HTTPAdapter
16
+ from urllib3.util.retry import Retry
17
+
18
+ from matlab_proxy import settings
19
+ from matlab_proxy_manager.storage.file_repository import FileRepository
20
+ from matlab_proxy_manager.utils import logger
21
+
22
+ log = logger.get()
23
+
24
+
25
+ def is_server_ready(url: Optional[str], retries: int = 2, backoff_factor=None) -> bool:
26
+ """
27
+ Check if the server at the given URL is ready.
28
+
29
+ Args:
30
+ url (str): The URL of the server.
31
+
32
+ Returns:
33
+ bool: True if the server is ready, False otherwise.
34
+ """
35
+ try:
36
+ # Validate URL
37
+ parsed_url = urlparse(url)
38
+ if not all([parsed_url.scheme, parsed_url.netloc]):
39
+ log.debug("Invalid URL provided: %s", url)
40
+ return False
41
+
42
+ matlab_proxy_index_page_identifier = "MWI_MATLAB_PROXY_IDENTIFIER"
43
+ resp = requests_retry_session(
44
+ retries=retries, backoff_factor=backoff_factor
45
+ ).get(f"{url}", verify=False)
46
+ log.debug("Response status code from server readiness: %s", resp.status_code)
47
+ return (
48
+ resp.status_code == http.HTTPStatus.OK
49
+ and matlab_proxy_index_page_identifier in resp.text
50
+ )
51
+ except Exception as e:
52
+ log.debug("Couldn't reach the server with error: %s", e)
53
+ return False
54
+
55
+
56
+ def requests_retry_session(
57
+ retries=3, backoff_factor=0.1, session=None
58
+ ) -> requests.Session:
59
+ """
60
+ Create a requests session with retry logic.
61
+
62
+ Args:
63
+ retries (int): The number of retries.
64
+ backoff_factor (float): The backoff factor for retries.
65
+ session (requests.Session, optional): An existing requests session.
66
+
67
+ Returns:
68
+ requests.Session: The requests session with retry logic.
69
+ """
70
+ session = session or requests.session()
71
+ retry = Retry(
72
+ total=retries,
73
+ read=retries,
74
+ connect=retries,
75
+ backoff_factor=backoff_factor,
76
+ allowed_methods=frozenset(["DELETE", "GET", "POST"]),
77
+ )
78
+ adapter = HTTPAdapter(max_retries=retry)
79
+ session.mount("http://", adapter)
80
+ session.mount("https://", adapter)
81
+ return session
82
+
83
+
84
+ def does_process_exist(pid: Optional[str]) -> bool:
85
+ """
86
+ Checks if the parent process is alive.
87
+
88
+ Returns:
89
+ bool: True if the parent process is alive, False otherwise.
90
+ """
91
+ return bool(pid and psutil.pid_exists(int(pid)))
92
+
93
+
94
+ def convert_mwi_env_vars_to_header_format(
95
+ env_vars: Dict[str, str], prefix: str
96
+ ) -> Dict[str, str]:
97
+ """
98
+ Parse and transform environment variables with a specific prefix.
99
+
100
+ Args:
101
+ env_vars (dict): The environment variables.
102
+ prefix (str): The prefix to filter the environment variables.
103
+
104
+ Returns:
105
+ dict: The transformed environment variables.
106
+ """
107
+ return {
108
+ key.replace("_", "-"): value
109
+ for key, value in env_vars.items()
110
+ if key.startswith(prefix)
111
+ }
112
+
113
+
114
+ def create_and_get_proxy_manager_data_dir() -> Path:
115
+ """
116
+ Create and get the proxy manager data directory.
117
+
118
+ Returns:
119
+ Path: The path to the proxy manager data directory.
120
+ """
121
+
122
+ config_dir = settings.get_mwi_config_folder(dev=False)
123
+ data_dir = Path(config_dir, "proxy_manager")
124
+ Path.mkdir(data_dir, parents=True, exist_ok=True)
125
+ return data_dir
126
+
127
+
128
+ async def delete_dangling_servers(app: web.Application) -> None:
129
+ """
130
+ Delete dangling matlab proxy servers that are no longer alive.
131
+
132
+ Args:
133
+ app (web.Application): aiohttp web application
134
+ """
135
+ is_delete_successful = _are_orphaned_servers_deleted()
136
+ log.debug("Deleted dangling matlab proxy servers: %s", is_delete_successful)
137
+
138
+
139
+ def _are_orphaned_servers_deleted(predicate: Optional[str] = "") -> bool:
140
+ """
141
+ Get all the files under the proxy manager directory, check the status of the servers,
142
+ and delete orphaned servers and their corresponding files.
143
+
144
+ - Checks if the parent PID of each server is still alive. If not, sends a SIGKILL
145
+ to the server and deletes the corresponding file.
146
+ - Checks if the servers in those files are still alive by sending GET requests to
147
+ their absolute URLs. If not, deletes the corresponding file.
148
+
149
+ Returns:
150
+ bool: True if any server was deleted, False otherwise.
151
+ """
152
+ data_dir = create_and_get_proxy_manager_data_dir()
153
+ storage = FileRepository(data_dir)
154
+ servers: dict = storage.get_all()
155
+
156
+ def _matches_predicate(filename: str) -> bool:
157
+ return filename.split("_")[0] == str(predicate)
158
+
159
+ # Checks only a subset of servers (that matches the parent_pid of the caller)
160
+ # to reduce the MATLAB proxy startup time
161
+ if predicate:
162
+ servers = {
163
+ filename: server
164
+ for filename, server in servers.items()
165
+ if _matches_predicate(Path(filename).stem)
166
+ }
167
+ if not servers:
168
+ log.debug("Parent pid not matched, nothing to cleanup")
169
+ return True
170
+
171
+ return _delete_server_and_file(storage, servers)
172
+
173
+
174
+ def _delete_server_and_file(storage, servers) -> bool:
175
+ is_server_deleted = False
176
+ for filename, server in servers.items():
177
+ if not server.is_server_alive():
178
+ log.debug("Server is not alive, cleaning up files")
179
+ try:
180
+ storage.delete(os.path.basename(filename))
181
+ except Exception as ex:
182
+ log.debug("Failed to delete file: %s", ex)
183
+ is_server_deleted = True
184
+ elif not does_process_exist(server.parent_pid):
185
+ log.debug("Server's parent is gone, shutting down matlab proxy")
186
+ try:
187
+ server.shutdown()
188
+ except Exception as ex:
189
+ log.debug("Failed to shutdown the matlab proxy server: %s", ex)
190
+ finally:
191
+ # Ensures files are cleaned up even if shutdown fails
192
+ storage.delete(os.path.basename(filename))
193
+ is_server_deleted = True
194
+
195
+ return is_server_deleted
196
+
197
+
198
+ async def poll_for_server_deletion(app: web.Application) -> None:
199
+ """
200
+ Poll for server deletion for a specified timeout period.
201
+
202
+ This function continuously checks if orphaned servers are deleted within a
203
+ specified timeout period. If servers are deleted, it breaks out of the loop.
204
+
205
+ Logs the status of server deletion attempts.
206
+ """
207
+ timeout_in_seconds: int = 2
208
+ log.debug("Interrupt/termination signal caught, cleaning up resources")
209
+ start_time = time.time()
210
+
211
+ try:
212
+ while time.time() - start_time < timeout_in_seconds:
213
+ is_server_deleted = _are_orphaned_servers_deleted()
214
+ if is_server_deleted:
215
+ log.debug("Servers deleted, breaking out of loop")
216
+ break
217
+ log.debug("Servers not deleted, waiting")
218
+ # Sleep for a short interval before polling again
219
+ await asyncio.sleep(0.5)
220
+ except Exception as ex:
221
+ log.debug("Error while polling for server deletion: %s", ex)
222
+
223
+
224
+ @contextmanager
225
+ def find_free_port() -> Generator[Tuple[str, socket.socket], None, None]:
226
+ """
227
+ Context manager for finding a free port on the system.
228
+
229
+ This function creates a socket, binds it to an available port, and yields
230
+ the port number along with the socket object. The socket is automatically
231
+ closed when exiting the context.
232
+
233
+ Yields:
234
+ Tuple[str, socket.socket]: A tuple containing:
235
+ - str: The free port number as a string.
236
+ - socket.socket: The socket object.
237
+ """
238
+ s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
239
+ s.bind(("", 0))
240
+ port = str(s.getsockname()[1])
241
+ try:
242
+ yield port, s
243
+ finally:
244
+ try:
245
+ s.close()
246
+ except OSError as ex:
247
+ # Socket already closed, log and ignore the exception
248
+ log.debug("Failed to close socket: %s", ex)
249
+
250
+
251
+ def pre_load_from_state_file(data_dir: str) -> Dict[str, str]:
252
+ """
253
+ Pre-load server states from the state files in the specified data directory.
254
+
255
+ Args:
256
+ data_dir (Path): The directory containing the state files.
257
+
258
+ Returns:
259
+ Dict[str, Dict]: A dictionary with server IDs as keys and server states as values.
260
+ """
261
+ storage = FileRepository(data_dir)
262
+ servers = storage.get_all()
263
+ return {server.id: server.as_dict() for server in servers.values()}
264
+
265
+
266
+ def is_only_reference(file_path: str) -> bool:
267
+ """
268
+ Check if the specified file is the only file in its directory.
269
+
270
+ Args:
271
+ file_path (str): The path to the file.
272
+
273
+ Returns:
274
+ bool: True if the file is the only file in its directory, False otherwise.
275
+ """
276
+ parent_dir = Path(file_path).parent.absolute()
277
+ files = os.listdir(parent_dir)
278
+ return len(files) == 1 and files[0] == os.path.basename(file_path)
279
+
280
+
281
+ def create_state_file(data_dir, server_process, filename: str):
282
+ """
283
+ Create a state file in the specified data directory.
284
+
285
+ This function creates a state file for the given server process in the specified
286
+ data directory. It logs the process and handles any exceptions that might occur.
287
+
288
+ Args:
289
+ data_dir: The directory where the state file will be created.
290
+ server_process (ServerProcess): The server process for which the state file is created.
291
+ filename (str): The name of the state file to be created.
292
+
293
+ Raises:
294
+ IOError: If there is an error creating the state file or adding the server
295
+ process to the repository.
296
+ """
297
+ try:
298
+ storage = FileRepository(data_dir)
299
+ storage.add(server=server_process, filename=filename)
300
+ log.debug("State file %s created in %s", filename, data_dir)
301
+ except Exception as e:
302
+ log.error(
303
+ "Failed to create state file %s in %s, error: %s", filename, data_dir, e
304
+ )
305
+ raise IOError(
306
+ f"Failed to create state file {filename} in {data_dir}, error: {e}"
307
+ ) from e
308
+
309
+
310
+ def render_error_page(error_msg: str) -> web.Response:
311
+ """Returns 503 with error text"""
312
+ return web.HTTPServiceUnavailable(
313
+ text=f'<p style="color: red;">{error_msg}</p>', content_type="text/html"
314
+ )
@@ -0,0 +1,76 @@
1
+ # Copyright 2024-2025 The MathWorks, Inc.
2
+ # Helper functions to access & control the logging behavior of the app
3
+
4
+ import logging
5
+ import os
6
+
7
+
8
+ # TODO: Consolidate all logging setup into a common module (MATLABProxy, MATLABKernel, MATLABProxyManager)
9
+ def get(init=False):
10
+ """Get the logger used by this application.
11
+ Set init=True to initialize the logger
12
+ Returns:
13
+ Logger: The logger used by this application.
14
+ """
15
+ if init is True:
16
+ return __set_logging_configuration()
17
+
18
+ return __get_mw_logger()
19
+
20
+
21
+ def __get_mw_logger_name():
22
+ """Name of logger used by the app
23
+
24
+ Returns:
25
+ String: The name of the Logger.
26
+ """
27
+ return "MATLABProxyManager"
28
+
29
+
30
+ def __get_mw_logger():
31
+ """Returns logger for use in this app.
32
+
33
+ Returns:
34
+ Logger: A logger object
35
+ """
36
+ return logging.getLogger(__get_mw_logger_name())
37
+
38
+
39
+ def __set_logging_configuration():
40
+ """Sets the logging environment for the app
41
+
42
+ Returns:
43
+ Logger: Logger object with the set configuration.
44
+ """
45
+ # query for user specified environment variables
46
+ log_level = os.getenv(__get_env_name_logging_level(), __get_default_log_level())
47
+
48
+ ## Set logging object
49
+ logger = __get_mw_logger()
50
+
51
+ # log_level is either set by environment or is the default value.
52
+ logger.info("Initializing logger with log_level: %s", log_level)
53
+ logger.setLevel(log_level)
54
+
55
+ # Allow other libraries used by this integration to
56
+ # also print their logs at the specified level
57
+ logging.basicConfig(level=log_level)
58
+
59
+ # Suppress debug logs from the watchdog module
60
+ logging.getLogger("watchdog").setLevel(logging.WARNING)
61
+
62
+ return logger
63
+
64
+
65
+ def __get_env_name_logging_level():
66
+ """Specifies the logging level used by app's loggers"""
67
+ return "MWI_MPM_LOG_LEVEL"
68
+
69
+
70
+ def __get_default_log_level():
71
+ """The default logging level used by this application.
72
+
73
+ Returns:
74
+ String: The default logging level
75
+ """
76
+ return "INFO"
@@ -0,0 +1,37 @@
1
+ # MATLAB Proxy Manager - Web
2
+
3
+ This README is intended for MathWorks&reg; developers only.
4
+ The web module is an important component of the matlab-proxy-manager, responsible for initiating the proxy manager in process mode. This module is specifically designed to be utilized within the Jupyter ecosystem, facilitating seamless integration with Jupyter Server Proxy.
5
+
6
+ ## Key Features
7
+ ### Process Mode Execution:
8
+
9
+ The web module contains the code necessary to start the MATLAB proxy manager in process mode. This mode is essential for managing MATLAB sessions within a Jupyter environment, allowing users to interact with MATLAB through a web-based interface.
10
+
11
+ ### Integration with Jupyter Server Proxy:
12
+
13
+ The web module is accessed exclusively by the Jupyter Server Proxy. It ensures that MATLAB can be launched and managed effectively as part of a Jupyter session, providing a seamless user experience.
14
+
15
+ ### Environment Variable Configuration:
16
+
17
+ The web module relies on three critical environment variables to function correctly:
18
+ 1. MWI_MPM_PORT: Specifies the port on which the proxy manager should start. This allows for flexible configuration and ensures that the proxy manager can be accessed on the appropriate network endpoint.
19
+ 2. MWI_MPM_AUTH_TOKEN: Used for secure communication between the Jupyter Server Proxy and the proxy manager. This token ensures that only authorized requests can interact with the proxy manager, enhancing security.
20
+ 3. MWI_MPM_PARENT_PID: Provides context for the process, allowing resources to be filtered based on their originating parent process. This is particularly useful for distinguishing resources started by different Jupyter servers.
21
+
22
+ ### Support for Proxy Workflow:
23
+
24
+ The web module supports the proxy workflow, which is activated when the MATLAB Web Desktop is launched. This workflow ensures that users can access MATLAB's graphical interface through their web browser, maintaining a consistent and interactive experience.
25
+
26
+ ## Usage
27
+ The web module is typically invoked by the Jupyter Server Proxy and does not require direct interaction from end-users. However, it is essential to ensure that the necessary environment variables are correctly set before launching the module.
28
+
29
+ ## Design Considerations
30
+ 1. Security: The use of an authentication token ensures secure communication between components, preventing unauthorized access.
31
+ 2. Flexibility: By leveraging environment variables, the web module can be easily configured to meet the specific needs of different deployment environments.
32
+
33
+ ---
34
+
35
+ Copyright 2024 The MathWorks, Inc.
36
+
37
+ ---
@@ -0,0 +1 @@
1
+ # Copyright 2024 The MathWorks, Inc.