appmesh 1.5.7__py3-none-any.whl → 1.5.9__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/http_client.py +14 -5
- appmesh/http_server.py +52 -23
- appmesh/tcp_server.py +10 -8
- appmesh/tcp_transport.py +2 -1
- {appmesh-1.5.7.dist-info → appmesh-1.5.9.dist-info}/METADATA +1 -1
- {appmesh-1.5.7.dist-info → appmesh-1.5.9.dist-info}/RECORD +8 -8
- {appmesh-1.5.7.dist-info → appmesh-1.5.9.dist-info}/WHEEL +0 -0
- {appmesh-1.5.7.dist-info → appmesh-1.5.9.dist-info}/top_level.txt +0 -0
appmesh/http_client.py
CHANGED
@@ -108,9 +108,11 @@ class AppMeshClient(metaclass=abc.ABCMeta):
|
|
108
108
|
DURATION_TWO_DAYS_HALF_ISO = "P2DT12H"
|
109
109
|
TOKEN_REFRESH_INTERVAL = 60
|
110
110
|
|
111
|
-
|
112
|
-
|
113
|
-
|
111
|
+
# 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")
|
114
116
|
|
115
117
|
DEFAULT_JWT_AUDIENCE = "appmesh-service"
|
116
118
|
|
@@ -1209,7 +1211,7 @@ class AppMeshClient(metaclass=abc.ABCMeta):
|
|
1209
1211
|
else:
|
1210
1212
|
raise TypeError(f"Invalid timeout type: {str(timeout)}")
|
1211
1213
|
|
1212
|
-
def run_task(self, app_name: str, data: str) -> str:
|
1214
|
+
def run_task(self, app_name: str, data: str, timeout: int = 300) -> str:
|
1213
1215
|
"""Client send an invocation message to a running App Mesh application and wait for result.
|
1214
1216
|
|
1215
1217
|
This method posts the provided `data` to the App Mesh service which will
|
@@ -1218,11 +1220,18 @@ class AppMeshClient(metaclass=abc.ABCMeta):
|
|
1218
1220
|
Args:
|
1219
1221
|
app_name (str): Name of the target application (as registered in App Mesh).
|
1220
1222
|
data (str): Payload to deliver to the application. Typically a string.
|
1223
|
+
timeout (int): Maximum time in seconds to wait for a response from the application. Defaults to 60 seconds.
|
1221
1224
|
|
1222
1225
|
Returns:
|
1223
1226
|
str: The HTTP response body returned by the remote application/service.
|
1224
1227
|
"""
|
1225
|
-
|
1228
|
+
path = f"/appmesh/app/{app_name}/task"
|
1229
|
+
resp = self._request_http(
|
1230
|
+
AppMeshClient.Method.POST,
|
1231
|
+
path=path,
|
1232
|
+
body=data,
|
1233
|
+
query={"timeout": str(timeout)},
|
1234
|
+
)
|
1226
1235
|
if resp.status_code != HTTPStatus.OK:
|
1227
1236
|
raise Exception(resp.text)
|
1228
1237
|
|
appmesh/http_server.py
CHANGED
@@ -2,11 +2,15 @@
|
|
2
2
|
# pylint: disable=line-too-long,broad-exception-raised,broad-exception-caught,import-outside-toplevel,protected-access
|
3
3
|
|
4
4
|
import abc
|
5
|
+
import logging
|
5
6
|
import os
|
6
7
|
import time
|
8
|
+
from typing import Optional, Tuple
|
7
9
|
from http import HTTPStatus
|
8
10
|
from .http_client import AppMeshClient
|
9
11
|
|
12
|
+
logger = logging.getLogger(__name__)
|
13
|
+
|
10
14
|
|
11
15
|
class AppMeshServer(metaclass=abc.ABCMeta):
|
12
16
|
"""
|
@@ -21,17 +25,27 @@ class AppMeshServer(metaclass=abc.ABCMeta):
|
|
21
25
|
- task_return(): return results to the invoking client
|
22
26
|
|
23
27
|
Example:
|
24
|
-
|
25
|
-
payload =
|
26
|
-
|
28
|
+
context = appmesh.AppMeshServer()
|
29
|
+
payload = context.task_fetch()
|
30
|
+
result = do_something_with(payload)
|
31
|
+
context.task_return(result)
|
27
32
|
"""
|
28
33
|
|
29
34
|
def __init__(
|
30
35
|
self,
|
31
36
|
rest_url: str = "https://127.0.0.1:6060",
|
32
37
|
rest_ssl_verify=AppMeshClient.DEFAULT_SSL_CA_CERT_PATH if os.path.exists(AppMeshClient.DEFAULT_SSL_CA_CERT_PATH) else False,
|
33
|
-
rest_ssl_client_cert=(
|
34
|
-
|
38
|
+
rest_ssl_client_cert=(
|
39
|
+
(
|
40
|
+
AppMeshClient.DEFAULT_SSL_CLIENT_CERT_PATH,
|
41
|
+
AppMeshClient.DEFAULT_SSL_CLIENT_KEY_PATH,
|
42
|
+
)
|
43
|
+
if os.path.exists(AppMeshClient.DEFAULT_SSL_CLIENT_CERT_PATH)
|
44
|
+
else None
|
45
|
+
),
|
46
|
+
rest_timeout: Tuple[float, float] = (60, 300),
|
47
|
+
*,
|
48
|
+
logger_: Optional[logging.Logger] = None,
|
35
49
|
):
|
36
50
|
"""Initialize an App Mesh HTTP client for interacting with the App Mesh server via secure HTTPS.
|
37
51
|
|
@@ -39,29 +53,41 @@ class AppMeshServer(metaclass=abc.ABCMeta):
|
|
39
53
|
follows the same parameters as `AppMeshClient`.
|
40
54
|
"""
|
41
55
|
self._client = AppMeshClient(rest_url, rest_ssl_verify, rest_ssl_client_cert, rest_timeout)
|
56
|
+
self._logger = logger_ or logger
|
57
|
+
|
58
|
+
@staticmethod
|
59
|
+
def _get_runtime_env() -> Tuple[str, str]:
|
60
|
+
"""Read and validate required runtime environment variables."""
|
61
|
+
process_id = os.getenv("APP_MESH_PROCESS_ID")
|
62
|
+
app_name = os.getenv("APP_MESH_APPLICATION_NAME")
|
63
|
+
if not process_id:
|
64
|
+
raise Exception("Missing environment variable: APP_MESH_PROCESS_ID. This must be set by App Mesh service.")
|
65
|
+
if not app_name:
|
66
|
+
raise Exception("Missing environment variable: APP_MESH_APPLICATION_NAME. This must be set by App Mesh service.")
|
67
|
+
return process_id, app_name
|
42
68
|
|
43
69
|
def task_fetch(self) -> str:
|
44
|
-
"""Fetch
|
70
|
+
"""Fetch task data in the currently running App Mesh application process.
|
45
71
|
|
46
|
-
|
47
|
-
|
48
|
-
environment variables set by the runtime:
|
72
|
+
Used by App Mesh application process to obtain the payload from App Mesh service
|
73
|
+
that a client pushed to it.
|
49
74
|
|
50
|
-
- APP_MESH_PROCESS_ID: the process UUID for this invocation
|
51
|
-
- APP_MESH_APPLICATION_NAME: the application name
|
52
75
|
|
53
76
|
Returns:
|
54
77
|
str: The payload provided by the client as returned by the service.
|
55
78
|
"""
|
56
|
-
|
57
|
-
|
79
|
+
process_id, app_name = self._get_runtime_env()
|
80
|
+
path = f"/appmesh/app/{app_name}/task"
|
81
|
+
|
58
82
|
while True:
|
59
83
|
resp = self._client._request_http(
|
60
84
|
AppMeshClient.Method.GET,
|
61
|
-
path=
|
62
|
-
query={"process_uuid":
|
85
|
+
path=path,
|
86
|
+
query={"process_uuid": process_id},
|
63
87
|
)
|
88
|
+
|
64
89
|
if resp.status_code != HTTPStatus.OK:
|
90
|
+
self._logger.warning(f"task_fetch failed with status {resp.status_code}: {resp.text}, retrying...")
|
65
91
|
time.sleep(0.1)
|
66
92
|
continue
|
67
93
|
|
@@ -70,20 +96,23 @@ class AppMeshServer(metaclass=abc.ABCMeta):
|
|
70
96
|
def task_return(self, result: str) -> None:
|
71
97
|
"""Return the result of a server-side invocation back to the original client.
|
72
98
|
|
73
|
-
|
74
|
-
the invoking client can retrieve it.
|
75
|
-
`task_fetch` are required to identify the target process.
|
99
|
+
Used by App Mesh application process to posts the `result` to App Mesh service
|
100
|
+
after processed payload data so the invoking client can retrieve it.
|
76
101
|
|
77
102
|
Args:
|
78
103
|
result (str): Result payload to be delivered back to the client.
|
79
104
|
"""
|
80
|
-
|
81
|
-
|
105
|
+
process_id, app_name = self._get_runtime_env()
|
106
|
+
path = f"/appmesh/app/{app_name}/task"
|
107
|
+
|
82
108
|
resp = self._client._request_http(
|
83
109
|
AppMeshClient.Method.PUT,
|
84
|
-
path=
|
85
|
-
query={"process_uuid":
|
110
|
+
path=path,
|
111
|
+
query={"process_uuid": process_id},
|
86
112
|
body=result,
|
87
113
|
)
|
114
|
+
|
88
115
|
if resp.status_code != HTTPStatus.OK:
|
89
|
-
|
116
|
+
msg = f"task_return failed with status {resp.status_code}: {resp.text}"
|
117
|
+
self._logger.error(msg)
|
118
|
+
raise Exception(msg)
|
appmesh/tcp_server.py
CHANGED
@@ -2,32 +2,34 @@
|
|
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
|
+
import logging
|
6
|
+
from typing import Optional, Tuple
|
5
7
|
from .http_client import AppMeshClient
|
6
8
|
from .tcp_client import AppMeshClientTCP
|
7
9
|
from .http_server import AppMeshServer
|
8
10
|
|
11
|
+
logger = logging.getLogger(__name__)
|
12
|
+
|
9
13
|
|
10
14
|
class AppMeshServerTCP(AppMeshServer):
|
11
15
|
"""
|
12
|
-
Server SDK for interacting with the local App Mesh service over TCP.
|
13
|
-
|
14
|
-
Attributes:
|
15
|
-
- Inherits all attributes from `AppMeshServer`.
|
16
|
-
|
17
|
-
Methods:
|
18
|
-
- Inherits all methods from `AppMeshServer`.
|
16
|
+
Server SDK for interacting with the local App Mesh service over TCP (TLS).
|
19
17
|
"""
|
20
18
|
|
21
19
|
def __init__(
|
22
20
|
self,
|
23
21
|
rest_ssl_verify=AppMeshClient.DEFAULT_SSL_CA_CERT_PATH if os.path.exists(AppMeshClient.DEFAULT_SSL_CA_CERT_PATH) else False,
|
24
22
|
rest_ssl_client_cert=None,
|
25
|
-
tcp_address=("localhost", 6059),
|
23
|
+
tcp_address: Tuple[str, int] = ("localhost", 6059),
|
24
|
+
*,
|
25
|
+
logger_: Optional[logging.Logger] = None,
|
26
26
|
):
|
27
27
|
"""Construct an App Mesh server TCP object to communicate securely with an App Mesh server over TLS.
|
28
28
|
|
29
29
|
Args:
|
30
30
|
follows the same parameters as `AppMeshClientTCP`.
|
31
31
|
"""
|
32
|
+
# Deliberately avoid calling super().__init__ to inject a TCP client while keeping the same public API.
|
32
33
|
object.__init__(self)
|
33
34
|
self._client = AppMeshClientTCP(rest_ssl_verify=rest_ssl_verify, rest_ssl_client_cert=rest_ssl_client_cert, tcp_address=tcp_address)
|
35
|
+
self._logger = logger_ or logger
|
appmesh/tcp_transport.py
CHANGED
@@ -67,6 +67,7 @@ class TCPTransport:
|
|
67
67
|
context.options |= ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1
|
68
68
|
# Configure SSL verification
|
69
69
|
if not self.ssl_verify:
|
70
|
+
context.check_hostname = False
|
70
71
|
context.verify_mode = ssl.CERT_NONE
|
71
72
|
else:
|
72
73
|
context.verify_mode = ssl.CERT_REQUIRED # Require certificate verification
|
@@ -94,7 +95,7 @@ class TCPTransport:
|
|
94
95
|
# Create a TCP socket
|
95
96
|
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
96
97
|
sock.setblocking(True)
|
97
|
-
sock.settimeout(30) # Connection timeout set to 30 seconds
|
98
|
+
# sock.settimeout(30) # Connection timeout set to 30 seconds
|
98
99
|
try:
|
99
100
|
# Wrap the socket with SSL/TLS
|
100
101
|
ssl_socket = context.wrap_socket(sock, server_hostname=self.tcp_address[0])
|
@@ -3,13 +3,13 @@ appmesh/app.py,sha256=9Q-SOOej-MH13BU5Dv2iTa-p-sECCJQp6ZX9DjWWmwE,10526
|
|
3
3
|
appmesh/app_output.py,sha256=JK_TMKgjvaw4n_ys_vmN5S4MyWVZpmD7NlKz_UyMIM8,1015
|
4
4
|
appmesh/app_run.py,sha256=9ISKGZ3k3kkbQvSsPfRfkOLqD9xhbqNOM7ork9F4w9c,1712
|
5
5
|
appmesh/appmesh_client.py,sha256=0ltkqHZUq094gKneYmC0bEZCP0X9kHTp9fccKdWFWP0,339
|
6
|
-
appmesh/http_client.py,sha256=
|
7
|
-
appmesh/http_server.py,sha256=
|
6
|
+
appmesh/http_client.py,sha256=LKLzFK2Ngp6dCA1kXYQ673o_MCrY3lE01LLJIUpSkEQ,57578
|
7
|
+
appmesh/http_server.py,sha256=HOE6DMzmo6FR16aSUQjSDLua_Q8o8807MNhPaAt-abs,4264
|
8
8
|
appmesh/tcp_client.py,sha256=yi0n2NpBBCA-JHYWQPPE_1euE7Oz6JHBe1op7lypTXY,10999
|
9
9
|
appmesh/tcp_messages.py,sha256=w1Kehz_aX4X2CYAUsy9mFVJRhxnLQwwc6L58W4YkQqs,969
|
10
|
-
appmesh/tcp_server.py,sha256=
|
11
|
-
appmesh/tcp_transport.py,sha256
|
12
|
-
appmesh-1.5.
|
13
|
-
appmesh-1.5.
|
14
|
-
appmesh-1.5.
|
15
|
-
appmesh-1.5.
|
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,,
|
File without changes
|
File without changes
|