appmesh 1.5.9__py3-none-any.whl → 1.6.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.
appmesh/__init__.py CHANGED
@@ -5,16 +5,14 @@ App Mesh SDK package initializer.
5
5
  This module exports the main client classes used to interact with the App Mesh API.
6
6
 
7
7
  Example:
8
- from appmesh import AppMeshClient, AppMeshClientTCP
9
-
8
+ from appmesh import AppMeshClient
10
9
  client = AppMeshClient()
11
- client_tcp = AppMeshClientTCP()
12
10
  """
13
11
 
14
12
  from .app import App
15
- from .http_client import AppMeshClient
16
- from .tcp_client import AppMeshClientTCP
17
- from .http_server import AppMeshServer
18
- from .tcp_server import AppMeshServerTCP
13
+ from .client_http import AppMeshClient
14
+ from .client_tcp import AppMeshClientTCP
15
+ from .server_http import AppMeshServer
16
+ from .server_tcp import AppMeshServerTCP
19
17
 
20
18
  __all__ = ["App", "AppMeshClient", "AppMeshClientTCP", "AppMeshServer", "AppMeshServerTCP"]
appmesh/app.py CHANGED
@@ -1,3 +1,4 @@
1
+ # app.py
1
2
  """Application definition"""
2
3
 
3
4
  import json
@@ -10,9 +11,9 @@ from enum import Enum, unique
10
11
  # pylint: disable=line-too-long
11
12
 
12
13
 
13
- class App(object):
14
+ class App:
14
15
  """
15
- Represents an application in App Mesh, including configuration, resource limitations, behaviors, and permissions.
16
+ An application in App Mesh, include all the process attributes, resource limitations, behaviors, and permissions.
16
17
  """
17
18
 
18
19
  @staticmethod
@@ -23,17 +24,24 @@ class App(object):
23
24
  @staticmethod
24
25
  def _get_int_item(data: dict, key: str) -> Optional[int]:
25
26
  """Retrieve an integer value from a dictionary by key, if it exists and is a valid integer."""
26
- return int(data[key]) if (data and key in data and data[key] and isinstance(data[key], int)) else None
27
+ if data and key in data and data[key] is not None:
28
+ if isinstance(data[key], int):
29
+ return data[key]
30
+ elif isinstance(data[key], str) and data[key].isdigit():
31
+ return int(data[key])
32
+ return None
27
33
 
28
34
  @staticmethod
29
35
  def _get_bool_item(data: dict, key: str) -> Optional[bool]:
30
36
  """Retrieve a boolean value from a dictionary by key, if it exists and is boolean-like."""
31
- return bool(data[key]) if (data and key in data and data[key]) else None
37
+ if data and key in data and data[key] is not None:
38
+ return bool(data[key])
39
+ return None
32
40
 
33
41
  @staticmethod
34
42
  def _get_native_item(data: dict, key: str) -> Optional[object]:
35
43
  """Retrieve a deep copy of a value from a dictionary by key, if it exists."""
36
- return copy.deepcopy(data[key]) if (data and key in data and data[key]) else None
44
+ return copy.deepcopy(data[key]) if (data and key in data and data[key] is not None) else None
37
45
 
38
46
  @unique
39
47
  class Permission(Enum):
@@ -43,7 +51,7 @@ class App(object):
43
51
  READ = "2"
44
52
  WRITE = "3"
45
53
 
46
- class Behavior(object):
54
+ class Behavior:
47
55
  """
48
56
  Manages application error handling behavior, including exit and control behaviors.
49
57
  """
@@ -67,15 +75,15 @@ class App(object):
67
75
  self.control = App._get_native_item(data, "control") or {}
68
76
  """Exit code specific behavior (e.g, --control 0:restart --control 1:standby), higher priority than default exit behavior"""
69
77
 
70
- def set_exit_behavior(self, action: Action) -> None:
78
+ def set_exit_behavior(self, action: "App.Behavior.Action") -> None:
71
79
  """Set default behavior for application exit."""
72
80
  self.exit = action.value
73
81
 
74
- def set_control_behavior(self, control_code: int, action: Action) -> None:
82
+ def set_control_behavior(self, control_code: int, action: "App.Behavior.Action") -> None:
75
83
  """Define behavior for specific exit codes."""
76
84
  self.control[str(control_code)] = action.value
77
85
 
78
- class DailyLimitation(object):
86
+ class DailyLimitation:
79
87
  """
80
88
  Defines application availability within a daily time range.
81
89
  """
@@ -88,14 +96,14 @@ class App(object):
88
96
  """Start time for application availability (e.g., 09:00:00+08)."""
89
97
 
90
98
  self.daily_end = App._get_int_item(data, "daily_end")
91
- """End time for application availability (e.g., 20:00:00+08)."""
99
+ """End time for application availability (e.g., 09:00:00+08)."""
92
100
 
93
101
  def set_daily_range(self, start: datetime, end: datetime) -> None:
94
102
  """Set the valid daily start and end times."""
95
103
  self.daily_start = int(start.timestamp())
96
104
  self.daily_end = int(end.timestamp())
97
105
 
98
- class ResourceLimitation(object):
106
+ class ResourceLimitation:
99
107
  """
100
108
  Defines application resource limits, such as CPU and memory usage.
101
109
  """
@@ -217,7 +225,7 @@ class App(object):
217
225
  keys_to_delete = []
218
226
  for key, value in data.items():
219
227
  if isinstance(value, dict) and key != "metadata":
220
- clean_empty(value) # Recursive call (without check user metadata)
228
+ clean_empty(value) # Recursive call (without checking user metadata)
221
229
  if data[key] in [None, "", {}]:
222
230
  keys_to_delete.append(key) # Mark keys for deletion
223
231
 
appmesh/app_output.py CHANGED
@@ -1,3 +1,4 @@
1
+ # app_output.py
1
2
  """Application output information"""
2
3
 
3
4
  from http import HTTPStatus
@@ -8,13 +9,13 @@ from typing import Optional
8
9
 
9
10
  class AppOutput(object):
10
11
  """
11
- Represents the output information returned by the `app_output()` API, including the application's
12
- stdout content, current read position, status code, and exit code.
12
+ Represents the output information returned by the `app_output()` API.
13
+ including the application's stdout , current read position, http status code, and process exit code.
13
14
  """
14
15
 
15
16
  def __init__(self, status_code: HTTPStatus, output: str, out_position: Optional[int], exit_code: Optional[int]) -> None:
16
17
  self.status_code = status_code
17
- """HTTP status code from the `app_output()` API request, indicating the result status."""
18
+ """HTTP status code from the `app_output()` API request, indicating the http status."""
18
19
 
19
20
  self.output = output
20
21
  """Captured stdout content of the application as returned by the `app_output()` API."""
appmesh/app_run.py CHANGED
@@ -1,11 +1,12 @@
1
- """Application run object"""
1
+ # app_run.py
2
+ """Application run object for remote application execution."""
2
3
 
3
4
  from contextlib import contextmanager
4
5
 
5
6
  # pylint: disable=line-too-long
6
7
 
7
8
 
8
- class AppRun(object):
9
+ class AppRun:
9
10
  """
10
11
  Represents an application run object initiated by `run_async()` for monitoring and retrieving
11
12
  the result of a remote application run.
@@ -26,7 +27,14 @@ class AppRun(object):
26
27
 
27
28
  @contextmanager
28
29
  def forward_to(self):
29
- """Context manager to override the `forward_to` for the duration of the run."""
30
+ """Context manager to temporarily override the client's `forward_to` setting.
31
+
32
+ This ensures that operations during this run use the correct target server,
33
+ then restores the original setting when done.
34
+
35
+ Yields:
36
+ None: Context for the overridden forward_to setting.
37
+ """
30
38
  original_value = self._client.forward_to
31
39
  self._client.forward_to = self._forward_to
32
40
  try:
@@ -38,11 +46,12 @@ class AppRun(object):
38
46
  """Wait for the asynchronous run to complete.
39
47
 
40
48
  Args:
41
- stdout_print (bool, optional): If `True`, prints remote stdout to local. Defaults to `True`.
42
- timeout (int, optional): Maximum time to wait in seconds. If `0`, waits until completion. Defaults to `0`.
49
+ stdout_print: If `True`, prints remote stdout to local console. Defaults to `True`.
50
+ timeout: Maximum time to wait in seconds. If `0`, waits indefinitely until completion.
51
+ Defaults to `0`.
43
52
 
44
53
  Returns:
45
- int: Exit code if the process finishes successfully. Returns `None` on timeout or exception.
54
+ Exit code if the process finishes successfully, or `None` on timeout or exception.
46
55
  """
47
56
  with self.forward_to():
48
57
  return self._client.wait_for_async_run(self, stdout_print, timeout)
appmesh/appmesh_client.py CHANGED
@@ -3,6 +3,6 @@
3
3
  # Legacy Compatibility Layer
4
4
  # These imports provide backward compatibility for older code that relies on
5
5
  # AppMeshClient, App, and AppOutput classes. The updated implementation can be found
6
- # in http_client.py, where these classes are now primarily maintained.
6
+ # in client_http.py, where these classes are now primarily maintained.
7
7
 
8
- from .http_client import AppMeshClient, App, AppOutput
8
+ from .client_http import AppMeshClient, App, AppOutput
@@ -1,10 +1,11 @@
1
- # HTTP-based App Mesh Client
1
+ # client_http.py
2
2
  # pylint: disable=broad-exception-raised,line-too-long,broad-exception-caught,too-many-lines, import-outside-toplevel, protected-access
3
3
  import abc
4
4
  import base64
5
5
  import json
6
6
  import logging
7
7
  import os
8
+ import time
8
9
  from datetime import datetime
9
10
  from enum import Enum, unique
10
11
  from http import HTTPStatus
@@ -14,7 +15,6 @@ from urllib import parse
14
15
  import aniso8601
15
16
  import jwt
16
17
  import requests
17
- import time
18
18
  from .app import App
19
19
  from .app_run import AppRun
20
20
  from .app_output import AppOutput
@@ -71,6 +71,7 @@ class AppMeshClient(metaclass=abc.ABCMeta):
71
71
  - run_app_async()
72
72
  - wait_for_async_run()
73
73
  - run_app_sync()
74
+ - run_task()
74
75
 
75
76
  # System Management
76
77
  - forward_to
@@ -109,10 +110,10 @@ class AppMeshClient(metaclass=abc.ABCMeta):
109
110
  TOKEN_REFRESH_INTERVAL = 60
110
111
 
111
112
  # Platform-aware default SSL paths
112
- _SSL_DIR = "C:/local/appmesh/ssl" if os.name == "nt" else "/opt/appmesh/ssl"
113
- DEFAULT_SSL_CA_CERT_PATH = os.path.join(_SSL_DIR, "ca.pem")
114
- DEFAULT_SSL_CLIENT_CERT_PATH = os.path.join(_SSL_DIR, "client.pem")
115
- DEFAULT_SSL_CLIENT_KEY_PATH = os.path.join(_SSL_DIR, "client-key.pem")
113
+ _DEFAULT_SSL_DIR = "c:/local/appmesh/ssl" if os.name == "nt" else "/opt/appmesh/ssl"
114
+ DEFAULT_SSL_CA_CERT_PATH = os.path.join(_DEFAULT_SSL_DIR, "ca.pem")
115
+ DEFAULT_SSL_CLIENT_CERT_PATH = os.path.join(_DEFAULT_SSL_DIR, "client.pem")
116
+ DEFAULT_SSL_CLIENT_KEY_PATH = os.path.join(_DEFAULT_SSL_DIR, "client-key.pem")
116
117
 
117
118
  DEFAULT_JWT_AUDIENCE = "appmesh-service"
118
119
 
@@ -324,7 +325,7 @@ class AppMeshClient(metaclass=abc.ABCMeta):
324
325
  try:
325
326
  self.close()
326
327
  except Exception:
327
- pass # Avoid exceptions during garbage collection
328
+ pass # Never raise in __del__
328
329
 
329
330
  @property
330
331
  def jwt_token(self) -> str:
@@ -1398,9 +1399,9 @@ class AppMeshClient(metaclass=abc.ABCMeta):
1398
1399
 
1399
1400
  try:
1400
1401
  if method is AppMeshClient.Method.GET:
1401
- return self.session.get(url=rest_url, params=query, headers=header, cert=self.ssl_client_cert, verify=self.ssl_verify, timeout=self.rest_timeout)
1402
+ resp = self.session.get(url=rest_url, params=query, headers=header, cert=self.ssl_client_cert, verify=self.ssl_verify, timeout=self.rest_timeout)
1402
1403
  elif method is AppMeshClient.Method.POST:
1403
- return self.session.post(
1404
+ resp = self.session.post(
1404
1405
  url=rest_url,
1405
1406
  params=query,
1406
1407
  headers=header,
@@ -1410,12 +1411,21 @@ class AppMeshClient(metaclass=abc.ABCMeta):
1410
1411
  timeout=self.rest_timeout,
1411
1412
  )
1412
1413
  elif method is AppMeshClient.Method.POST_STREAM:
1413
- return self.session.post(url=rest_url, params=query, headers=header, data=body, cert=self.ssl_client_cert, verify=self.ssl_verify, stream=True, timeout=self.rest_timeout)
1414
+ resp = self.session.post(url=rest_url, params=query, headers=header, data=body, cert=self.ssl_client_cert, verify=self.ssl_verify, stream=True, timeout=self.rest_timeout)
1414
1415
  elif method is AppMeshClient.Method.DELETE:
1415
- return self.session.delete(url=rest_url, headers=header, cert=self.ssl_client_cert, verify=self.ssl_verify, timeout=self.rest_timeout)
1416
+ resp = self.session.delete(url=rest_url, headers=header, cert=self.ssl_client_cert, verify=self.ssl_verify, timeout=self.rest_timeout)
1416
1417
  elif method is AppMeshClient.Method.PUT:
1417
- return self.session.put(url=rest_url, params=query, headers=header, data=body, cert=self.ssl_client_cert, verify=self.ssl_verify, timeout=self.rest_timeout)
1418
+ resp = self.session.put(url=rest_url, params=query, headers=header, data=body, cert=self.ssl_client_cert, verify=self.ssl_verify, timeout=self.rest_timeout)
1418
1419
  else:
1419
1420
  raise Exception("Invalid http method", method)
1421
+
1422
+ # Ensure response text decoding uses UTF-8 by default
1423
+ try:
1424
+ resp.encoding = "utf-8"
1425
+ except Exception:
1426
+ # If setting encoding fails for any reason, ignore and return the response as-is
1427
+ pass
1428
+
1429
+ return resp
1420
1430
  except requests.exceptions.RequestException as e:
1421
1431
  raise Exception(f"HTTP request failed: {str(e)}")
@@ -1,4 +1,4 @@
1
- # TCP-based App Mesh Client
1
+ # client_tcp.py
2
2
  # pylint: disable=line-too-long,broad-exception-raised,broad-exception-caught,import-outside-toplevel,protected-access
3
3
 
4
4
  import json
@@ -6,7 +6,7 @@ import os
6
6
  import socket
7
7
  import uuid
8
8
  import requests
9
- from .appmesh_client import AppMeshClient
9
+ from .client_http import AppMeshClient
10
10
  from .tcp_transport import TCPTransport
11
11
  from .tcp_messages import RequestMessage, ResponseMessage
12
12
 
@@ -28,10 +28,10 @@ class AppMeshClientTCP(AppMeshClient):
28
28
 
29
29
  Usage:
30
30
  - Import the client module:
31
- from appmesh import appmesh_client
31
+ from appmesh import AppMeshClientTCP
32
32
 
33
33
  Example:
34
- client = appmesh_client.AppMeshClientTCP()
34
+ client = AppMeshClientTCP()
35
35
  client.login("your-name", "your-password")
36
36
  client.file_download("/tmp/os-release", "os-release")
37
37
 
@@ -83,20 +83,34 @@ class AppMeshClientTCP(AppMeshClient):
83
83
  self.tcp_transport = TCPTransport(address=tcp_address, ssl_verify=rest_ssl_verify, ssl_client_cert=rest_ssl_client_cert)
84
84
  super().__init__(rest_ssl_verify=rest_ssl_verify, rest_ssl_client_cert=rest_ssl_client_cert, jwt_token=jwt_token)
85
85
 
86
+ def close(self):
87
+ """Close the connection and release resources."""
88
+ if hasattr(self, "tcp_transport") and self.tcp_transport:
89
+ self.tcp_transport.close()
90
+ self.tcp_transport = None
91
+ return super().close()
92
+
93
+ def __del__(self):
94
+ """Ensure resources are properly released when the object is garbage collected."""
95
+ try:
96
+ self.close()
97
+ except Exception:
98
+ pass # Never raise in __del__
99
+ super().__del__()
100
+
86
101
  def _request_http(self, method: AppMeshClient.Method, path: str, query: dict = None, header: dict = None, body=None) -> requests.Response:
87
- """TCP API
102
+ """Send HTTP request over TCP transport.
88
103
 
89
104
  Args:
90
- method (Method): AppMeshClient.Method.
91
- path (str): URI patch str.
92
- query (dict, optional): HTTP query parameters.
105
+ method (Method): HTTP method.
106
+ path (str): URI path.
107
+ query (dict, optional): Query parameters.
93
108
  header (dict, optional): HTTP headers.
94
- body (_type_, optional): object to send in the body of the :class:`Request`.
109
+ body: Request body.
95
110
 
96
111
  Returns:
97
- requests.Response: HTTP response
112
+ requests.Response: Simulated HTTP response.
98
113
  """
99
-
100
114
  if not self.tcp_transport.connected():
101
115
  self.tcp_transport.connect()
102
116
 
@@ -110,8 +124,9 @@ class AppMeshClientTCP(AppMeshClient):
110
124
  appmesh_request.http_method = method.value
111
125
  appmesh_request.request_uri = path
112
126
  appmesh_request.client_addr = socket.gethostname()
127
+
113
128
  if body:
114
- if isinstance(body, dict) or isinstance(body, list):
129
+ if isinstance(body, (dict, list)):
115
130
  appmesh_request.body = bytes(json.dumps(body, indent=2), self.ENCODING_UTF8)
116
131
  elif isinstance(body, str):
117
132
  appmesh_request.body = bytes(body, self.ENCODING_UTF8)
@@ -119,20 +134,23 @@ class AppMeshClientTCP(AppMeshClient):
119
134
  appmesh_request.body = body
120
135
  else:
121
136
  raise Exception(f"UnSupported body type: {type(body)}")
137
+
122
138
  if header:
123
139
  for k, v in header.items():
124
140
  appmesh_request.headers[k] = v
125
141
  if query:
126
142
  for k, v in query.items():
127
143
  appmesh_request.querys[k] = v
144
+
128
145
  data = appmesh_request.serialize()
129
146
  self.tcp_transport.send_message(data)
130
147
 
131
148
  resp_data = self.tcp_transport.receive_message()
132
- if resp_data is None or len(resp_data) == 0:
149
+ if not resp_data: # Covers None and empty bytes
133
150
  self.tcp_transport.close()
134
151
  raise Exception("socket connection broken")
135
- appmesh_resp = ResponseMessage().desirialize(resp_data)
152
+
153
+ appmesh_resp = ResponseMessage().deserialize(resp_data)
136
154
  response = requests.Response()
137
155
  response.status_code = appmesh_resp.http_status
138
156
  response.encoding = self.ENCODING_UTF8
@@ -140,24 +158,27 @@ class AppMeshClientTCP(AppMeshClient):
140
158
  response.headers = appmesh_resp.headers
141
159
  if appmesh_resp.body_msg_type:
142
160
  response.headers["Content-Type"] = appmesh_resp.body_msg_type
161
+
143
162
  return response
144
163
 
145
164
  ########################################
146
165
  # File management
147
166
  ########################################
148
167
  def download_file(self, remote_file: str, local_file: str, apply_file_attributes: bool = True) -> None:
149
- """Copy a remote file to local, the local file will have the same permission as the remote file
168
+ """Copy a remote file to local, preserving file attributes if requested.
150
169
 
151
170
  Args:
152
- remote_file (str): the remote file path.
153
- local_file (str): the local file path to be downloaded.
154
- apply_file_attributes (bool): whether to apply file attributes (permissions, owner, group) to the local file.
171
+ remote_file (str): Remote file path.
172
+ local_file (str): Local destination path.
173
+ apply_file_attributes (bool): Apply remote file permissions/ownership locally.
155
174
  """
156
- header = {AppMeshClient.HTTP_HEADER_KEY_X_FILE_PATH: remote_file}
157
- header[self.HTTP_HEADER_KEY_X_RECV_FILE_SOCKET] = "true"
175
+ header = {
176
+ AppMeshClient.HTTP_HEADER_KEY_X_FILE_PATH: remote_file,
177
+ self.HTTP_HEADER_KEY_X_RECV_FILE_SOCKET: "true",
178
+ }
158
179
  resp = self._request_http(AppMeshClient.Method.GET, path="/appmesh/file/download", header=header)
159
-
160
180
  resp.raise_for_status()
181
+
161
182
  if self.HTTP_HEADER_KEY_X_RECV_FILE_SOCKET not in resp.headers:
162
183
  raise ValueError(f"Server did not respond with socket transfer option: {self.HTTP_HEADER_KEY_X_RECV_FILE_SOCKET}")
163
184
 
@@ -180,23 +201,22 @@ class AppMeshClientTCP(AppMeshClient):
180
201
  print(f"Warning: Unable to change owner/group of {local_file}. Operation requires elevated privileges.")
181
202
 
182
203
  def upload_file(self, local_file: str, remote_file: str, apply_file_attributes: bool = True) -> None:
183
- """Upload a local file to the remote server, the remote file will have the same permission as the local file
184
-
185
- Dependency:
186
- sudo apt install python3-pip
187
- pip3 install requests_toolbelt
204
+ """Upload a local file to remote server, preserving file attributes if requested.
188
205
 
189
206
  Args:
190
- local_file (str): the local file path.
191
- remote_file (str): the target remote file to be uploaded.
192
- apply_file_attributes (bool): whether to upload file attributes (permissions, owner, group) along with the file.
207
+ local_file (str): Local file path.
208
+ remote_file (str): Remote destination path.
209
+ apply_file_attributes (bool): Upload file permissions/ownership metadata.
193
210
  """
194
211
  if not os.path.exists(local_file):
195
212
  raise FileNotFoundError(f"Local file not found: {local_file}")
196
213
 
197
214
  with open(file=local_file, mode="rb") as fp:
198
- header = {AppMeshClient.HTTP_HEADER_KEY_X_FILE_PATH: remote_file, "Content-Type": "text/plain"}
199
- header[self.HTTP_HEADER_KEY_X_SEND_FILE_SOCKET] = "true"
215
+ header = {
216
+ AppMeshClient.HTTP_HEADER_KEY_X_FILE_PATH: remote_file,
217
+ "Content-Type": "text/plain",
218
+ self.HTTP_HEADER_KEY_X_SEND_FILE_SOCKET: "true",
219
+ }
200
220
 
201
221
  if apply_file_attributes:
202
222
  file_stat = os.stat(local_file)
@@ -205,8 +225,8 @@ class AppMeshClientTCP(AppMeshClient):
205
225
  header["X-File-Group"] = str(file_stat.st_gid)
206
226
 
207
227
  resp = self._request_http(AppMeshClient.Method.POST, path="/appmesh/file/upload", header=header)
208
-
209
228
  resp.raise_for_status()
229
+
210
230
  if self.HTTP_HEADER_KEY_X_SEND_FILE_SOCKET not in resp.headers:
211
231
  raise ValueError(f"Server did not respond with socket transfer option: {self.HTTP_HEADER_KEY_X_SEND_FILE_SOCKET}")
212
232
 
@@ -214,6 +234,6 @@ class AppMeshClientTCP(AppMeshClient):
214
234
  while True:
215
235
  chunk_data = fp.read(chunk_size)
216
236
  if not chunk_data:
217
- self.tcp_transport.send_message([])
237
+ self.tcp_transport.send_message([]) # EOF signal
218
238
  break
219
239
  self.tcp_transport.send_message(chunk_data)
@@ -1,4 +1,4 @@
1
- # TCP-based App Mesh Server
1
+ # server_http.py
2
2
  # pylint: disable=line-too-long,broad-exception-raised,broad-exception-caught,import-outside-toplevel,protected-access
3
3
 
4
4
  import abc
@@ -7,7 +7,7 @@ import os
7
7
  import time
8
8
  from typing import Optional, Tuple
9
9
  from http import HTTPStatus
10
- from .http_client import AppMeshClient
10
+ from .client_http import AppMeshClient
11
11
 
12
12
  logger = logging.getLogger(__name__)
13
13
 
@@ -1,12 +1,12 @@
1
- # TCP-based App Mesh Server
1
+ # server_tcp.py
2
2
  # pylint: disable=line-too-long,broad-exception-raised,broad-exception-caught,import-outside-toplevel,protected-access
3
3
 
4
4
  import os
5
5
  import logging
6
6
  from typing import Optional, Tuple
7
- from .http_client import AppMeshClient
8
- from .tcp_client import AppMeshClientTCP
9
- from .http_server import AppMeshServer
7
+ from .client_http import AppMeshClient
8
+ from .client_tcp import AppMeshClientTCP
9
+ from .server_http import AppMeshServer
10
10
 
11
11
  logger = logging.getLogger(__name__)
12
12
 
@@ -31,5 +31,6 @@ class AppMeshServerTCP(AppMeshServer):
31
31
  """
32
32
  # Deliberately avoid calling super().__init__ to inject a TCP client while keeping the same public API.
33
33
  object.__init__(self)
34
+ # super().__init__(rest_ssl_verify=rest_ssl_verify, rest_ssl_client_cert=rest_ssl_client_cert)
34
35
  self._client = AppMeshClientTCP(rest_ssl_verify=rest_ssl_verify, rest_ssl_client_cert=rest_ssl_client_cert, tcp_address=tcp_address)
35
36
  self._logger = logger_ or logger
appmesh/tcp_messages.py CHANGED
@@ -4,7 +4,7 @@ import msgpack
4
4
 
5
5
 
6
6
  class RequestMessage:
7
- """HTTP request message"""
7
+ """TCP request message for HTTP-like communication"""
8
8
 
9
9
  uuid: str = ""
10
10
  request_uri: str = ""
@@ -24,7 +24,7 @@ class RequestMessage:
24
24
 
25
25
 
26
26
  class ResponseMessage:
27
- """HTTP response message"""
27
+ """TCP response message for HTTP-like communication"""
28
28
 
29
29
  uuid: str = ""
30
30
  request_uri: str = ""
@@ -33,7 +33,7 @@ class ResponseMessage:
33
33
  body: str = ""
34
34
  headers: dict = {}
35
35
 
36
- def desirialize(self, buf: bytes):
36
+ def deserialize(self, buf: bytes):
37
37
  """Deserialize response message"""
38
38
  dic = msgpack.unpackb(buf)
39
39
  for k, v in dic.items():
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: appmesh
3
- Version: 1.5.9
3
+ Version: 1.6.0
4
4
  Summary: Client SDK for App Mesh
5
5
  Home-page: https://github.com/laoshanxi/app-mesh
6
6
  Author: laoshanxi
@@ -102,7 +102,7 @@ Refer to the [Installation doc](https://app-mesh.readthedocs.io/en/latest/Instal
102
102
  | GUI | √ | √ |
103
103
  | Virtual Network | | √ |
104
104
  | Monitor tools | √ | √ |
105
- | [Remote API call](https://app-mesh.readthedocs.io/en/latest/RemoteTask.html) | √ | |
105
+ | [Remote task](https://app-mesh.readthedocs.io/en/latest/RemoteTask.html) | √ | |
106
106
 
107
107
  ---
108
108
 
@@ -126,6 +126,7 @@ Refer to the [Installation doc](https://app-mesh.readthedocs.io/en/latest/Instal
126
126
  - [Python parallel run](https://app-mesh.readthedocs.io/en/latest/success/python_parallel_run.html)
127
127
  - [Secure consul cluster](https://app-mesh.readthedocs.io/en/latest/success/secure_consul_cluster.html)
128
128
  - [JWT service with REST and UI](https://github.com/laoshanxi/app-mesh/blob/main/script/docker-compose-auth-service.yaml)
129
+ - [Remote task execute](https://app-mesh.readthedocs.io/en/latest/RemoteTask.html)
129
130
 
130
131
  ---
131
132
 
@@ -0,0 +1,15 @@
1
+ appmesh/__init__.py,sha256=_I-kLcLy7DM3gG2JJTRM_hUxBu3zvIPm2wCsz3NYes4,493
2
+ appmesh/app.py,sha256=4lo66ob1ZFDgL8VYKxH4_sh-vbHcGkZNThURE0go-d4,10732
3
+ appmesh/app_output.py,sha256=vfn322AyixblI8DbXds08h6L_ybObiaRSifsA1-Xcoo,1035
4
+ appmesh/app_run.py,sha256=TJ9xVX8xqUN9-OOmr_8JlgXoyg3hTmDFNKvGf4w_oR4,1980
5
+ appmesh/appmesh_client.py,sha256=7yy9c_ygJbqMekrUsHWmRObwHLK82qP65xQLXxfGd8U,339
6
+ appmesh/client_http.py,sha256=jUIZJHrnu2-r6N6Cd9lQNPeQcZefB7ENl6DUn8Mugck,57896
7
+ appmesh/client_tcp.py,sha256=hE0T_2Z0OQZdF5zi--iuvu2_-ka0DfSSQ4BP3oHlg44,11243
8
+ appmesh/server_http.py,sha256=zr9sfS8g_mtP2kuAfmz-qU7rLSFTVt3srbFXaCbl8Y0,4253
9
+ appmesh/server_tcp.py,sha256=biBFF5IGWFOw2ru831cfmzn1DVXcBm9e-W6CP2VkfzE,1444
10
+ appmesh/tcp_messages.py,sha256=4XRv5lSm_8ElMg_37SuyIRrfxI7XFNNP_7SdO7us3PA,1023
11
+ appmesh/tcp_transport.py,sha256=3B0w8AHXnb-E49Odxm5bPNBve1P-YiMHNDxFO2YYYVE,8690
12
+ appmesh-1.6.0.dist-info/METADATA,sha256=VKKRa3mUsX0oahVUosSDJCR4mlsqTX-ua51-JskhSwk,11847
13
+ appmesh-1.6.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
14
+ appmesh-1.6.0.dist-info/top_level.txt,sha256=-y0MNQOGJxUzLdHZ6E_Rfv5_LNCkV-GTmOBME_b6pg8,8
15
+ appmesh-1.6.0.dist-info/RECORD,,
@@ -1,15 +0,0 @@
1
- appmesh/__init__.py,sha256=fQHuLWBaMZmbs5i5AV4KIXhv9YlIWkhYIv9WSLGNLm4,548
2
- appmesh/app.py,sha256=9Q-SOOej-MH13BU5Dv2iTa-p-sECCJQp6ZX9DjWWmwE,10526
3
- appmesh/app_output.py,sha256=JK_TMKgjvaw4n_ys_vmN5S4MyWVZpmD7NlKz_UyMIM8,1015
4
- appmesh/app_run.py,sha256=9ISKGZ3k3kkbQvSsPfRfkOLqD9xhbqNOM7ork9F4w9c,1712
5
- appmesh/appmesh_client.py,sha256=0ltkqHZUq094gKneYmC0bEZCP0X9kHTp9fccKdWFWP0,339
6
- appmesh/http_client.py,sha256=LKLzFK2Ngp6dCA1kXYQ673o_MCrY3lE01LLJIUpSkEQ,57578
7
- appmesh/http_server.py,sha256=HOE6DMzmo6FR16aSUQjSDLua_Q8o8807MNhPaAt-abs,4264
8
- appmesh/tcp_client.py,sha256=yi0n2NpBBCA-JHYWQPPE_1euE7Oz6JHBe1op7lypTXY,10999
9
- appmesh/tcp_messages.py,sha256=w1Kehz_aX4X2CYAUsy9mFVJRhxnLQwwc6L58W4YkQqs,969
10
- appmesh/tcp_server.py,sha256=42YW3-hU82AwhE32DF4Gn6GucSg5qNJavP7xGSrpBVc,1353
11
- appmesh/tcp_transport.py,sha256=3B0w8AHXnb-E49Odxm5bPNBve1P-YiMHNDxFO2YYYVE,8690
12
- appmesh-1.5.9.dist-info/METADATA,sha256=xe1V09bjxrLUnSkEzfdjvbSRwwBYShEgYh2rk8gVd3s,11768
13
- appmesh-1.5.9.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
14
- appmesh-1.5.9.dist-info/top_level.txt,sha256=-y0MNQOGJxUzLdHZ6E_Rfv5_LNCkV-GTmOBME_b6pg8,8
15
- appmesh-1.5.9.dist-info/RECORD,,