appmesh 1.6.13__py3-none-any.whl → 1.6.15__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.
@@ -18,8 +18,8 @@ class AppMeshClientOAuth(AppMeshClient):
18
18
  self,
19
19
  oauth2: dict, # Required for Keycloak
20
20
  rest_url: str = "https://127.0.0.1:6060",
21
- rest_ssl_verify=AppMeshClient.DEFAULT_SSL_CA_CERT_PATH if os.path.exists(AppMeshClient.DEFAULT_SSL_CA_CERT_PATH) else False,
22
- rest_ssl_client_cert=(AppMeshClient.DEFAULT_SSL_CLIENT_CERT_PATH, AppMeshClient.DEFAULT_SSL_CLIENT_KEY_PATH) if os.path.exists(AppMeshClient.DEFAULT_SSL_CLIENT_CERT_PATH) else None,
21
+ rest_ssl_verify=AppMeshClient.DEFAULT_SSL_CA_CERT_PATH,
22
+ rest_ssl_client_cert=AppMeshClient.DEFAULT_SSL_CLIENT_CERT_PATH,
23
23
  rest_timeout=(60, 300),
24
24
  jwt_token=None, # Keycloak dict
25
25
  auto_refresh_token: bool = True, # Default to True for Keycloak
appmesh/client_tcp.py CHANGED
@@ -7,6 +7,7 @@ import os
7
7
  import socket
8
8
  import sys
9
9
  import uuid
10
+ from typing import Optional, Tuple, Union
10
11
 
11
12
  # Third-party imports
12
13
  import requests
@@ -18,8 +19,7 @@ from .tcp_transport import TCPTransport
18
19
 
19
20
 
20
21
  class AppMeshClientTCP(AppMeshClient):
21
- """
22
- Client SDK for interacting with the App Mesh service over TCP, with enhanced support for large file transfers.
22
+ """Client SDK for interacting with the App Mesh service over TCP.
23
23
 
24
24
  The `AppMeshClientTCP` class extends the functionality of `AppMeshClient` by offering a TCP-based communication layer
25
25
  for the App Mesh REST API. It overrides the file download and upload methods to support large file transfers with
@@ -28,30 +28,23 @@ class AppMeshClientTCP(AppMeshClient):
28
28
  This client is suitable for applications requiring efficient data transfers and high-throughput operations within the
29
29
  App Mesh ecosystem, while maintaining compatibility with all other attributes and methods from `AppMeshClient`.
30
30
 
31
- Dependency:
32
- - Install the required package for message serialization:
33
- pip3 install msgpack
34
-
35
- Usage:
36
- - Import the client module:
37
- from appmesh import AppMeshClientTCP
38
-
39
- Example:
40
- client = AppMeshClientTCP()
41
- client.login("your-name", "your-password")
42
- client.file_download("/tmp/os-release", "os-release")
43
-
44
31
  Attributes:
45
- - Inherits all attributes from `AppMeshClient`, including TLS secure connections and JWT-based authentication.
46
- - Optimized for TCP-based communication to provide better performance for large file transfers.
32
+ Inherits all attributes from `AppMeshClient`, including TLS secure connections and JWT-based authentication.
47
33
 
48
34
  Methods:
49
- - file_download()
50
- - file_upload()
35
+ - download_file()
36
+ - upload_file()
51
37
  - Inherits all other methods from `AppMeshClient`, providing a consistent interface for managing applications within App Mesh.
38
+
39
+ Example:
40
+ >>> from appmesh import AppMeshClientTCP
41
+ >>> client = AppMeshClientTCP()
42
+ >>> client.login("your-name", "your-password")
43
+ >>> client.download_file("/tmp/os-release", "os-release")
52
44
  """
53
45
 
54
- TCP_BLOCK_SIZE = 16 * 1024 - 128 # TLS-optimized chunk size, leaves some room for TLS overhead (like headers) within the 16 KB limit.
46
+ # TLS-optimized chunk size, leaves room for TLS overhead within the 16 KB limit
47
+ TCP_BLOCK_SIZE = 16 * 1024 - 128
55
48
  ENCODING_UTF8 = "utf-8"
56
49
  HTTP_USER_AGENT_TCP = "appmesh/python/tcp"
57
50
  HTTP_HEADER_KEY_X_SEND_FILE_SOCKET = "X-Send-File-Socket"
@@ -59,32 +52,27 @@ class AppMeshClientTCP(AppMeshClient):
59
52
 
60
53
  def __init__(
61
54
  self,
62
- rest_ssl_verify=AppMeshClient.DEFAULT_SSL_CA_CERT_PATH if os.path.exists(AppMeshClient.DEFAULT_SSL_CA_CERT_PATH) else False,
63
- rest_ssl_client_cert=None,
64
- jwt_token=None,
65
- tcp_address=("127.0.0.1", 6059),
55
+ rest_ssl_verify: Union[bool, str] = AppMeshClient.DEFAULT_SSL_CA_CERT_PATH,
56
+ rest_ssl_client_cert: Optional[Union[str, Tuple[str, str]]] = None,
57
+ jwt_token: Optional[str] = None,
58
+ tcp_address: Tuple[str, int] = ("127.0.0.1", 6059),
66
59
  ):
67
60
  """Construct an App Mesh client TCP object to communicate securely with an App Mesh server over TLS.
68
61
 
69
62
  Args:
70
- rest_ssl_verify (Union[bool, str], optional): Specifies SSL certificate verification behavior. Can be:
71
- - `True`: Uses the system’s default CA certificates to verify the server’s identity.
72
- - `False`: Disables SSL certificate verification (insecure, intended for development).
73
- - `str`: Specifies a custom CA bundle or directory for server certificate verification. If a string is provided,
74
- it should either be a file path to a custom CA certificate (CA bundle) or a directory path containing multiple
75
- certificates (CA directory).
76
-
77
- **Note**: Unlike HTTP requests, TCP connections cannot automatically retrieve intermediate or public CA certificates.
78
- When `rest_ssl_verify` is a path, it explicitly identifies a CA issuer to ensure certificate validation.
79
-
80
- rest_ssl_client_cert (Union[str, Tuple[str, str]], optional): Path to the SSL client certificate and key. If a `str`,
81
- it should be the path to a PEM file containing both the client certificate and private key. If a `tuple`, it should
82
- be a pair of paths: (`cert`, `key`), where `cert` is the client certificate file and `key` is the private key file.
83
-
84
- jwt_token (str, optional): JWT token for authentication. Used in methods requiring login and user authorization.
85
-
86
- tcp_address (Tuple[str, int], optional): Address and port for establishing a TCP connection to the server.
87
- Defaults to `("127.0.0.1", 6059)`.
63
+ rest_ssl_verify: SSL certificate verification behavior. Can be True, False, or a path to CA bundle.
64
+ - True: Use system CA certificates (e.g., /etc/ssl/certs/ on Linux)
65
+ - False: Disable verification (insecure)
66
+ - str: Path to custom CA bundle or directory
67
+ ssl_client_cert: SSL client certificate:
68
+ - str: Path to single PEM with cert+key
69
+ - tuple: (cert_path, key_path)
70
+ jwt_token: Pre-configured JWT Token for authenticating requests.
71
+ tcp_address: Server address as (host, port) tuple, defaults to ("127.0.0.1", 6059).
72
+
73
+ Note:
74
+ TCP connections require an explicit full-chain CA specification for certificate validation,
75
+ unlike HTTP, which can retrieve intermediate certificates automatically.
88
76
  """
89
77
  self.tcp_transport = TCPTransport(address=tcp_address, ssl_verify=rest_ssl_verify, ssl_client_cert=rest_ssl_client_cert)
90
78
  super().__init__(rest_ssl_verify=rest_ssl_verify, rest_ssl_client_cert=rest_ssl_client_cert, jwt_token=jwt_token)
@@ -102,93 +90,159 @@ class AppMeshClientTCP(AppMeshClient):
102
90
  self.close()
103
91
  except Exception:
104
92
  pass # Never raise in __del__
105
- super().__del__()
106
93
 
107
- def _request_http(self, method: AppMeshClient.Method, path: str, query: dict = None, header: dict = None, body=None) -> requests.Response:
94
+ def _covert_bytes(self, body) -> bytes:
95
+ """Prepare request body for transmission."""
96
+ if body is None:
97
+ return b""
98
+
99
+ if isinstance(body, (bytes, bytearray, memoryview)):
100
+ return body
101
+
102
+ if isinstance(body, str):
103
+ return body.encode(self.ENCODING_UTF8)
104
+
105
+ if isinstance(body, (dict, list)):
106
+ return json.dumps(body).encode(self.ENCODING_UTF8)
107
+
108
+ raise TypeError(f"Unsupported body type: {type(body)}")
109
+
110
+ def _request_http(self, method: AppMeshClient.Method, path: str, query: Optional[dict] = None, header: Optional[dict] = None, body=None) -> requests.Response:
108
111
  """Send HTTP request over TCP transport.
109
112
 
110
113
  Args:
111
- method (Method): HTTP method.
112
- path (str): URI path.
113
- query (dict, optional): Query parameters.
114
- header (dict, optional): HTTP headers.
114
+ method: HTTP method.
115
+ path: URI path.
116
+ query: Query parameters.
117
+ header: HTTP headers.
115
118
  body: Request body.
116
119
 
117
120
  Returns:
118
- requests.Response: Simulated HTTP response.
121
+ Simulated HTTP response.
119
122
  """
123
+
124
+ # Check for unsupported features
125
+ if super().forward_to:
126
+ raise RuntimeError("Forward request is not supported in TCP mode")
127
+
120
128
  if not self.tcp_transport.connected():
121
129
  self.tcp_transport.connect()
122
130
 
131
+ # Prepare request message (ensure no fields are assigned None!)
123
132
  appmesh_request = RequestMessage()
124
- token = self._get_access_token()
125
- if token:
126
- appmesh_request.headers[self.HTTP_HEADER_KEY_AUTH] = token
127
- if super().forward_to and len(super().forward_to) > 0:
128
- raise Exception("Not support forward request in TCP mode")
129
- appmesh_request.headers[self.HTTP_HEADER_KEY_USER_AGENT] = self.HTTP_USER_AGENT_TCP
130
133
  appmesh_request.uuid = str(uuid.uuid1())
131
134
  appmesh_request.http_method = method.value
132
135
  appmesh_request.request_uri = path
133
136
  appmesh_request.client_addr = socket.gethostname()
137
+ appmesh_request.headers[self.HTTP_HEADER_KEY_USER_AGENT] = self.HTTP_USER_AGENT_TCP
134
138
 
135
- if body:
136
- if isinstance(body, (dict, list)):
137
- appmesh_request.body = bytes(json.dumps(body, indent=2), self.ENCODING_UTF8)
138
- elif isinstance(body, str):
139
- appmesh_request.body = bytes(body, self.ENCODING_UTF8)
140
- elif isinstance(body, bytes):
141
- appmesh_request.body = body
142
- else:
143
- raise Exception(f"UnSupported body type: {type(body)}")
139
+ # Add authentication token
140
+ token = self._get_access_token()
141
+ if token:
142
+ appmesh_request.headers[self.HTTP_HEADER_KEY_AUTH] = token
144
143
 
144
+ # Add custom headers
145
145
  if header:
146
- for k, v in header.items():
147
- appmesh_request.headers[k] = v
146
+ appmesh_request.headers.update(header)
147
+
148
+ # Add query parameters
148
149
  if query:
149
- for k, v in query.items():
150
- appmesh_request.query[k] = v
150
+ appmesh_request.query.update(query)
151
+
152
+ # Prepare body
153
+ body_bytes = self._covert_bytes(body)
154
+ if body_bytes:
155
+ appmesh_request.body = body_bytes
151
156
 
157
+ # Send request
152
158
  data = appmesh_request.serialize()
153
159
  self.tcp_transport.send_message(data)
154
160
 
161
+ # Receive response
155
162
  resp_data = self.tcp_transport.receive_message()
156
163
  if not resp_data: # Covers None and empty bytes
157
164
  self.tcp_transport.close()
158
- raise Exception("socket connection broken")
165
+ raise ConnectionError("Socket connection broken")
159
166
 
167
+ # Parse response
160
168
  appmesh_resp = ResponseMessage().deserialize(resp_data)
161
169
  response = requests.Response()
162
170
  response.status_code = appmesh_resp.http_status
163
- # response.encoding = self.ENCODING_UTF8 # only need when charset not in appmesh_resp.body_msg_type
164
- response._content = appmesh_resp.body if isinstance(appmesh_resp.body, bytes) else str(appmesh_resp.body).encode(self.ENCODING_UTF8)
165
171
  response.headers = appmesh_resp.headers
172
+
173
+ # Set response content
174
+ # response.encoding = self.ENCODING_UTF8 # only need when charset not in appmesh_resp.body_msg_type
175
+ if isinstance(appmesh_resp.body, bytes):
176
+ response._content = appmesh_resp.body
177
+ else:
178
+ response._content = str(appmesh_resp.body).encode(self.ENCODING_UTF8)
179
+
180
+ # Set content type
166
181
  if appmesh_resp.body_msg_type:
167
182
  response.headers["Content-Type"] = appmesh_resp.body_msg_type
168
183
 
169
184
  return AppMeshClient.EncodingResponse(response)
170
185
 
171
- ########################################
172
- # File management
173
- ########################################
174
- def download_file(self, remote_file: str, local_file: str, apply_file_attributes: bool = True) -> None:
186
+ def _apply_file_attributes(self, local_file: str, headers: dict) -> None:
187
+ """Apply file attributes from headers to local file."""
188
+ if sys.platform == "win32":
189
+ return
190
+
191
+ # Apply file mode
192
+ if "X-File-Mode" in headers:
193
+ try:
194
+ os.chmod(local_file, int(headers["X-File-Mode"]))
195
+ except (ValueError, OSError) as e:
196
+ self._logger.warning("Failed to set file mode: %s", e)
197
+
198
+ # Apply file ownership
199
+ if "X-File-User" in headers and "X-File-Group" in headers:
200
+ try:
201
+ file_uid = int(headers["X-File-User"])
202
+ file_gid = int(headers["X-File-Group"])
203
+ os.chown(local_file, uid=file_uid, gid=file_gid)
204
+ except (ValueError, PermissionError, OSError) as e:
205
+ if isinstance(e, PermissionError):
206
+ print(f"Warning: Unable to change owner/group of {local_file}. " "Operation requires elevated privileges.")
207
+ else:
208
+ self._logger.warning("Failed to set file ownership: %s", e)
209
+
210
+ def _get_file_attributes(self, local_file: str) -> dict:
211
+ """Get file attributes as header dictionary."""
212
+ if sys.platform == "win32":
213
+ return {}
214
+
215
+ try:
216
+ file_stat = os.stat(local_file)
217
+ return {
218
+ "X-File-Mode": str(file_stat.st_mode & 0o777),
219
+ "X-File-User": str(file_stat.st_uid),
220
+ "X-File-Group": str(file_stat.st_gid),
221
+ }
222
+ except OSError as e:
223
+ self._logger.warning("Failed to get file attributes: %s", e)
224
+ return {}
225
+
226
+ def download_file(self, remote_file: str, local_file: str, preserve_permissions: bool = True) -> None:
175
227
  """Copy a remote file to local, preserving file attributes if requested.
176
228
 
177
229
  Args:
178
- remote_file (str): Remote file path.
179
- local_file (str): Local destination path.
180
- apply_file_attributes (bool): Apply remote file permissions/ownership locally.
230
+ remote_file: Remote file path.
231
+ local_file: Local destination path.
232
+ preserve_permissions: Apply remote file permissions/ownership locally.
181
233
  """
182
234
  header = {
183
235
  AppMeshClient.HTTP_HEADER_KEY_X_FILE_PATH: remote_file,
184
236
  self.HTTP_HEADER_KEY_X_RECV_FILE_SOCKET: "true",
185
237
  }
238
+
186
239
  resp = self._request_http(AppMeshClient.Method.GET, path="/appmesh/file/download", header=header)
187
240
  resp.raise_for_status()
188
241
 
189
242
  if self.HTTP_HEADER_KEY_X_RECV_FILE_SOCKET not in resp.headers:
190
- raise ValueError(f"Server did not respond with socket transfer option: {self.HTTP_HEADER_KEY_X_RECV_FILE_SOCKET}")
243
+ raise ValueError(f"Server did not respond with socket transfer option: " f"{self.HTTP_HEADER_KEY_X_RECV_FILE_SOCKET}")
191
244
 
245
+ # Download file chunks
192
246
  with open(local_file, "wb") as fp:
193
247
  while True:
194
248
  chunk_data = self.tcp_transport.receive_message()
@@ -196,50 +250,43 @@ class AppMeshClientTCP(AppMeshClient):
196
250
  break
197
251
  fp.write(chunk_data)
198
252
 
199
- if apply_file_attributes and sys.platform != "win32":
200
- if "X-File-Mode" in resp.headers:
201
- os.chmod(path=local_file, mode=int(resp.headers["X-File-Mode"]))
202
- if "X-File-User" in resp.headers and "X-File-Group" in resp.headers:
203
- file_uid = int(resp.headers["X-File-User"])
204
- file_gid = int(resp.headers["X-File-Group"])
205
- try:
206
- os.chown(path=local_file, uid=file_uid, gid=file_gid)
207
- except PermissionError:
208
- print(f"Warning: Unable to change owner/group of {local_file}. Operation requires elevated privileges.")
209
-
210
- def upload_file(self, local_file: str, remote_file: str, apply_file_attributes: bool = True) -> None:
253
+ # Apply file attributes if requested
254
+ if preserve_permissions:
255
+ self._apply_file_attributes(local_file, resp.headers)
256
+
257
+ def upload_file(self, local_file: str, remote_file: str, preserve_permissions: bool = True) -> None:
211
258
  """Upload a local file to remote server, preserving file attributes if requested.
212
259
 
213
260
  Args:
214
- local_file (str): Local file path.
215
- remote_file (str): Remote destination path.
216
- apply_file_attributes (bool): Upload file permissions/ownership metadata.
261
+ local_file: Local file path.
262
+ remote_file: Remote destination path.
263
+ preserve_permissions: Upload file permissions/ownership metadata.
217
264
  """
218
265
  if not os.path.exists(local_file):
219
266
  raise FileNotFoundError(f"Local file not found: {local_file}")
220
267
 
221
- with open(file=local_file, mode="rb") as fp:
222
- header = {
223
- AppMeshClient.HTTP_HEADER_KEY_X_FILE_PATH: remote_file,
224
- "Content-Type": "text/plain",
225
- self.HTTP_HEADER_KEY_X_SEND_FILE_SOCKET: "true",
226
- }
268
+ # Prepare headers
269
+ header = {
270
+ AppMeshClient.HTTP_HEADER_KEY_X_FILE_PATH: remote_file,
271
+ "Content-Type": "text/plain",
272
+ self.HTTP_HEADER_KEY_X_SEND_FILE_SOCKET: "true",
273
+ }
227
274
 
228
- if apply_file_attributes:
229
- file_stat = os.stat(local_file)
230
- header["X-File-Mode"] = str(file_stat.st_mode & 0o777) # Mask to keep only permission bits
231
- header["X-File-User"] = str(file_stat.st_uid)
232
- header["X-File-Group"] = str(file_stat.st_gid)
275
+ # Add file attributes if requested
276
+ if preserve_permissions:
277
+ header.update(self._get_file_attributes(local_file))
233
278
 
234
- resp = self._request_http(AppMeshClient.Method.POST, path="/appmesh/file/upload", header=header)
235
- resp.raise_for_status()
279
+ # Initiate upload
280
+ resp = self._request_http(AppMeshClient.Method.POST, path="/appmesh/file/upload", header=header)
281
+ resp.raise_for_status()
236
282
 
237
- if self.HTTP_HEADER_KEY_X_SEND_FILE_SOCKET not in resp.headers:
238
- raise ValueError(f"Server did not respond with socket transfer option: {self.HTTP_HEADER_KEY_X_SEND_FILE_SOCKET}")
283
+ if self.HTTP_HEADER_KEY_X_SEND_FILE_SOCKET not in resp.headers:
284
+ raise ValueError(f"Server did not respond with socket transfer option: " f"{self.HTTP_HEADER_KEY_X_SEND_FILE_SOCKET}")
239
285
 
240
- chunk_size = self.TCP_BLOCK_SIZE
286
+ # Upload file chunks
287
+ with open(local_file, "rb") as fp:
241
288
  while True:
242
- chunk_data = fp.read(chunk_size)
289
+ chunk_data = fp.read(self.TCP_BLOCK_SIZE)
243
290
  if not chunk_data:
244
291
  self.tcp_transport.send_message([]) # EOF signal
245
292
  break
appmesh/server_http.py CHANGED
@@ -1,6 +1,8 @@
1
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
+ """HTTP server SDK implementation for App Mesh."""
5
+
4
6
  # Standard library imports
5
7
  import abc
6
8
  import logging
@@ -16,8 +18,7 @@ logger = logging.getLogger(__name__)
16
18
 
17
19
 
18
20
  class AppMeshServer(metaclass=abc.ABCMeta):
19
- """
20
- Server SDK for App Mesh application interacting with the local App Mesh REST service over HTTPS.
21
+ """Server SDK for App Mesh application interacting with the local App Mesh REST service over HTTPS.
21
22
 
22
23
  Build-in runtime environment variables required:
23
24
  - APP_MESH_PROCESS_KEY
@@ -34,18 +35,13 @@ class AppMeshServer(metaclass=abc.ABCMeta):
34
35
  context.task_return(result)
35
36
  """
36
37
 
38
+ _RETRY_DELAY_SECONDS = 0.1
39
+
37
40
  def __init__(
38
41
  self,
39
42
  rest_url: str = "https://127.0.0.1:6060",
40
- rest_ssl_verify=AppMeshClient.DEFAULT_SSL_CA_CERT_PATH if os.path.exists(AppMeshClient.DEFAULT_SSL_CA_CERT_PATH) else False,
41
- rest_ssl_client_cert=(
42
- (
43
- AppMeshClient.DEFAULT_SSL_CLIENT_CERT_PATH,
44
- AppMeshClient.DEFAULT_SSL_CLIENT_KEY_PATH,
45
- )
46
- if os.path.exists(AppMeshClient.DEFAULT_SSL_CLIENT_CERT_PATH)
47
- else None
48
- ),
43
+ rest_ssl_verify: Union[bool, str] = AppMeshClient.DEFAULT_SSL_CA_CERT_PATH,
44
+ rest_ssl_client_cert: Optional[Union[str, Tuple[str, str]]] = None,
49
45
  rest_timeout: Tuple[float, float] = (60, 300),
50
46
  *,
51
47
  logger_: Optional[logging.Logger] = None,
@@ -63,6 +59,7 @@ class AppMeshServer(metaclass=abc.ABCMeta):
63
59
  """Read and validate required runtime environment variables."""
64
60
  process_key = os.getenv("APP_MESH_PROCESS_KEY")
65
61
  app_name = os.getenv("APP_MESH_APPLICATION_NAME")
62
+
66
63
  if not process_key:
67
64
  raise Exception("Missing environment variable: APP_MESH_PROCESS_KEY. This must be set by App Mesh service.")
68
65
  if not app_name:
@@ -75,43 +72,43 @@ class AppMeshServer(metaclass=abc.ABCMeta):
75
72
  Used by App Mesh application process to obtain the payload from App Mesh service
76
73
  that a client pushed to it.
77
74
 
78
-
79
75
  Returns:
80
- Union[str, bytes]: The payload provided by the client as returned by the service.
76
+ The payload provided by the client as returned by the service.
81
77
  """
82
78
  pkey, app_name = self._get_runtime_env()
83
79
  path = f"/appmesh/app/{app_name}/task"
80
+ query_params = {"process_key": pkey}
84
81
 
85
82
  while True:
86
83
  resp = self._client._request_http(
87
84
  AppMeshClient.Method.GET,
88
85
  path=path,
89
- query={"process_key": pkey},
86
+ query=query_params,
90
87
  )
91
88
 
92
- if resp.status_code != HTTPStatus.OK:
93
- self._logger.warning(f"task_fetch failed with status {resp.status_code}: {resp.text}, retrying...")
94
- time.sleep(0.1)
95
- continue
89
+ if resp.status_code == HTTPStatus.OK:
90
+ return resp.content
96
91
 
97
- return resp.content
92
+ self._logger.warning("task_fetch failed with status %d: %s, retrying...", resp.status_code, resp.text)
93
+ time.sleep(self._RETRY_DELAY_SECONDS)
98
94
 
99
95
  def task_return(self, result: Union[str, bytes]) -> None:
100
96
  """Return the result of a server-side invocation back to the original client.
101
97
 
102
- Used by App Mesh application process to posts the `result` to App Mesh service
103
- after processed payload data so the invoking client can retrieve it.
98
+ Used by App Mesh application process to post the `result` to App Mesh service
99
+ after processing payload data so the invoking client can retrieve it.
104
100
 
105
101
  Args:
106
- result (Union[str, bytes]): Result payload to be delivered back to the client.
102
+ result: Result payload to be delivered back to the client.
107
103
  """
108
104
  pkey, app_name = self._get_runtime_env()
109
105
  path = f"/appmesh/app/{app_name}/task"
106
+ query_params = {"process_key": pkey}
110
107
 
111
108
  resp = self._client._request_http(
112
109
  AppMeshClient.Method.PUT,
113
110
  path=path,
114
- query={"process_key": pkey},
111
+ query=query_params,
115
112
  body=result,
116
113
  )
117
114
 
appmesh/server_tcp.py CHANGED
@@ -3,8 +3,7 @@
3
3
 
4
4
  # Standard library imports
5
5
  import logging
6
- import os
7
- from typing import Optional, Tuple
6
+ from typing import Optional, Tuple, Union
8
7
 
9
8
  # Local imports
10
9
  from .client_http import AppMeshClient
@@ -15,14 +14,12 @@ logger = logging.getLogger(__name__)
15
14
 
16
15
 
17
16
  class AppMeshServerTCP(AppMeshServer):
18
- """
19
- Server SDK for interacting with the local App Mesh service over TCP (TLS).
20
- """
17
+ """Server SDK for interacting with the local App Mesh service over TCP (TLS)."""
21
18
 
22
19
  def __init__(
23
20
  self,
24
- rest_ssl_verify=AppMeshClient.DEFAULT_SSL_CA_CERT_PATH if os.path.exists(AppMeshClient.DEFAULT_SSL_CA_CERT_PATH) else False,
25
- rest_ssl_client_cert=None,
21
+ rest_ssl_verify: Union[bool, str] = AppMeshClient.DEFAULT_SSL_CA_CERT_PATH,
22
+ rest_ssl_client_cert: Optional[Union[str, Tuple[str, str]]] = None,
26
23
  tcp_address: Tuple[str, int] = ("127.0.0.1", 6059),
27
24
  *,
28
25
  logger_: Optional[logging.Logger] = None,
@@ -34,6 +31,5 @@ class AppMeshServerTCP(AppMeshServer):
34
31
  """
35
32
  # Deliberately avoid calling super().__init__ to inject a TCP client while keeping the same public API.
36
33
  object.__init__(self)
37
- # super().__init__(rest_ssl_verify=rest_ssl_verify, rest_ssl_client_cert=rest_ssl_client_cert)
38
34
  self._client = AppMeshClientTCP(rest_ssl_verify=rest_ssl_verify, rest_ssl_client_cert=rest_ssl_client_cert, tcp_address=tcp_address)
39
35
  self._logger = logger_ or logger
appmesh/tcp_transport.py CHANGED
@@ -29,12 +29,10 @@ class TCPTransport:
29
29
 
30
30
  Args:
31
31
  address: Server address as (host, port) tuple.
32
-
33
32
  ssl_verify: SSL server verification mode:
34
33
  - True: Use system CA certificates
35
34
  - False: Disable verification (insecure)
36
35
  - str: Path to custom CA bundle or directory
37
-
38
36
  ssl_client_cert: SSL client certificate:
39
37
  - str: Path to PEM file with cert and key
40
38
  - tuple: (cert_path, key_path)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: appmesh
3
- Version: 1.6.13
3
+ Version: 1.6.15
4
4
  Summary: Client SDK for App Mesh
5
5
  Home-page: https://github.com/laoshanxi/app-mesh
6
6
  Author: laoshanxi
@@ -0,0 +1,16 @@
1
+ appmesh/__init__.py,sha256=on6GmTTwo6mrRbw_XUuf8sZdl5zBYsGT4CSf8l__NnI,2488
2
+ appmesh/app.py,sha256=bJyv_uOSMj5esMgkFWuvpMPS5ayFTBJLVll2Tvw8xB4,11213
3
+ appmesh/app_output.py,sha256=s6eqevFxETTVXSPTJX6JyGNpHHILv4ZyM7YWvlkuqQs,741
4
+ appmesh/app_run.py,sha256=m3ihaacx84o1rl2Oc3EbnppW8D-PTxdehftbWRe8rPk,1732
5
+ appmesh/appmesh_client.py,sha256=ywB2222PtJUffdfdxZcBfdhZs1KYyc7JvzMxwuK2qyI,378
6
+ appmesh/client_http.py,sha256=shkpXDEMtxExIgbeLUUknLJjkAYMCmL7rIK_kc1xgXs,48821
7
+ appmesh/client_http_oauth.py,sha256=zES-f6AnG6dUo754zd-HM6Pvu4vp_64vTKT61npY6HE,5934
8
+ appmesh/client_tcp.py,sha256=K3IneOSl8xiOIC9z4jHK_4Mhq2n8eeUDASvXJQiRjfQ,11817
9
+ appmesh/server_http.py,sha256=g2NYREF-f-vnSFVntAJDc0H43v_kNEqS7M4y7Q_DpEY,4193
10
+ appmesh/server_tcp.py,sha256=GXEVDmYwM19ZUKkRXm8eEzBep9rE1vzV-PwaTlROpFU,1364
11
+ appmesh/tcp_messages.py,sha256=E0cKWUta7NjuLoTGk-Z9CvbdZyakwG7hO8st_07E5L4,1991
12
+ appmesh/tcp_transport.py,sha256=nkml2hqSkyeJrGDKGAYjWDgOnSyYMEImVT1PQ6jeudk,8163
13
+ appmesh-1.6.15.dist-info/METADATA,sha256=dity7yE2WHJTKe3Hph5FLM1N2aKnVjQ9wHIHwO9UR_o,11814
14
+ appmesh-1.6.15.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
15
+ appmesh-1.6.15.dist-info/top_level.txt,sha256=-y0MNQOGJxUzLdHZ6E_Rfv5_LNCkV-GTmOBME_b6pg8,8
16
+ appmesh-1.6.15.dist-info/RECORD,,
@@ -1,16 +0,0 @@
1
- appmesh/__init__.py,sha256=on6GmTTwo6mrRbw_XUuf8sZdl5zBYsGT4CSf8l__NnI,2488
2
- appmesh/app.py,sha256=5kzQCvGH3LRRUTHsI2_MKEPD3M2qs8kvTxLhbNUqit4,10601
3
- appmesh/app_output.py,sha256=s6eqevFxETTVXSPTJX6JyGNpHHILv4ZyM7YWvlkuqQs,741
4
- appmesh/app_run.py,sha256=m3ihaacx84o1rl2Oc3EbnppW8D-PTxdehftbWRe8rPk,1732
5
- appmesh/appmesh_client.py,sha256=ywB2222PtJUffdfdxZcBfdhZs1KYyc7JvzMxwuK2qyI,378
6
- appmesh/client_http.py,sha256=FXCldfTZVU_5RSuSknlH1K2UiC6gOeotj-4NDQzdEhY,60752
7
- appmesh/client_http_oauth.py,sha256=1d51o0JX_xtB8d2bEuM7_XJHcwMnhcjkbIq7GE1Zxm8,6120
8
- appmesh/client_tcp.py,sha256=RX3T3OG4iOAju8ZPOnTjI_y97Y23_kWoNDjmKjtrBeU,11524
9
- appmesh/server_http.py,sha256=wfyiIa2zC-uJR2ZNTGMjYWheqAfSRl0aAv5b_GYcwpE,4343
10
- appmesh/server_tcp.py,sha256=J65kmN7DJftyW1LlF--S3keQ6VGmqXb778E79I1R0_k,1488
11
- appmesh/tcp_messages.py,sha256=E0cKWUta7NjuLoTGk-Z9CvbdZyakwG7hO8st_07E5L4,1991
12
- appmesh/tcp_transport.py,sha256=oUpcBXOaJhG5Hs6yqt9UG8_eENu0cEdNZIyC87LqI7Q,8165
13
- appmesh-1.6.13.dist-info/METADATA,sha256=BJJB6M94Sz2yytdr9WRxCf56q1-LCzQ-2zQAfP5_1eU,11814
14
- appmesh-1.6.13.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
15
- appmesh-1.6.13.dist-info/top_level.txt,sha256=-y0MNQOGJxUzLdHZ6E_Rfv5_LNCkV-GTmOBME_b6pg8,8
16
- appmesh-1.6.13.dist-info/RECORD,,