appmesh 1.3.4__py3-none-any.whl → 1.3.5__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/appmesh_client.py CHANGED
@@ -29,9 +29,12 @@ DEFAULT_SSL_CA_PEM_FILE = "/opt/appmesh/ssl/ca.pem"
29
29
  DEFAULT_SSL_CLIENT_PEM_FILE = "/opt/appmesh/ssl/client.pem"
30
30
  DEFAULT_SSL_CLIENT_PEM_KEY_FILE = "/opt/appmesh/ssl/client-key.pem"
31
31
 
32
+ # TLS-optimized chunk size (slightly less than maximum TLS record size)
33
+ # leaves some room for TLS overhead (like headers) within the 16 KB limit.
34
+ TCP_CHUNK_BLOCK_SIZE = 16 * 1024 - 256 # target to 16KB
35
+ TCP_MESSAGE_HEADER_LENGTH = 4
32
36
  REST_TEXT_MESSAGE_JSON_KEY = "message"
33
37
  MESSAGE_ENCODING_UTF8 = "utf-8"
34
- TCP_MESSAGE_HEADER_LENGTH = 4
35
38
 
36
39
  HTTP_USER_AGENT = "appmesh/python"
37
40
  HTTP_USER_AGENT_TCP = "appmesh/python/tcp"
@@ -450,7 +453,7 @@ class AppMeshClient(metaclass=abc.ABCMeta):
450
453
  the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use. Defaults to ``True``.
451
454
  rest_ssl_client_cert (tuple, optional): SSL client certificate and key pair. If String, path to ssl client cert file (.pem). If Tuple, ('cert', 'key') pair.
452
455
  rest_timeout (tuple, optional): HTTP timeout, Defaults to 60 seconds for connect timeout and 300 seconds for read timeout
453
- jwt_token (str, optional): JWT token, provide correct token is same with login() & authenticate().
456
+ jwt_token (str, optional): JWT token, provide correct token is same with login() & authentication().
454
457
  """
455
458
 
456
459
  self.server_url = rest_url
@@ -1221,20 +1224,20 @@ class AppMeshClient(metaclass=abc.ABCMeta):
1221
1224
  ########################################
1222
1225
  # File management
1223
1226
  ########################################
1224
- def file_download(self, file_path: str, local_file: str, apply_file_attributes: bool = True) -> None:
1227
+ def file_download(self, remote_file: str, local_file: str, apply_file_attributes: bool = True) -> None:
1225
1228
  """Copy a remote file to local. Optionally, the local file will have the same permission as the remote file.
1226
1229
 
1227
1230
  Args:
1228
- file_path (str): the remote file path.
1231
+ remote_file (str): the remote file path.
1229
1232
  local_file (str): the local file path to be downloaded.
1230
1233
  apply_file_attributes (bool): whether to apply file attributes (permissions, owner, group) to the local file.
1231
1234
  """
1232
- resp = self._request_http(AppMeshClient.Method.GET, path="/appmesh/file/download", header={"File-Path": file_path})
1235
+ resp = self._request_http(AppMeshClient.Method.GET, path="/appmesh/file/download", header={"File-Path": remote_file})
1233
1236
  resp.raise_for_status()
1234
1237
 
1235
1238
  # Write the file content locally
1236
1239
  with open(local_file, "wb") as fp:
1237
- for chunk in resp.iter_content(chunk_size=8192): # 8 KB
1240
+ for chunk in resp.iter_content(chunk_size=8 * 1024): # 8 KB
1238
1241
  if chunk:
1239
1242
  fp.write(chunk)
1240
1243
 
@@ -1250,7 +1253,7 @@ class AppMeshClient(metaclass=abc.ABCMeta):
1250
1253
  except PermissionError:
1251
1254
  print(f"Warning: Unable to change owner/group of {local_file}. Operation requires elevated privileges.")
1252
1255
 
1253
- def file_upload(self, local_file: str, file_path: str, apply_file_attributes: bool = True) -> None:
1256
+ def file_upload(self, local_file: str, remote_file: str, apply_file_attributes: bool = True) -> None:
1254
1257
  """Upload a local file to the remote server. Optionally, the remote file will have the same permission as the local file.
1255
1258
 
1256
1259
  Dependency:
@@ -1259,7 +1262,7 @@ class AppMeshClient(metaclass=abc.ABCMeta):
1259
1262
 
1260
1263
  Args:
1261
1264
  local_file (str): the local file path.
1262
- file_path (str): the target remote file to be uploaded.
1265
+ remote_file (str): the target remote file to be uploaded.
1263
1266
  apply_file_attributes (bool): whether to upload file attributes (permissions, owner, group) along with the file.
1264
1267
  """
1265
1268
  if not os.path.exists(local_file):
@@ -1268,13 +1271,13 @@ class AppMeshClient(metaclass=abc.ABCMeta):
1268
1271
  from requests_toolbelt import MultipartEncoder
1269
1272
 
1270
1273
  with open(file=local_file, mode="rb") as fp:
1271
- encoder = MultipartEncoder(fields={"filename": os.path.basename(file_path), "file": ("filename", fp, "application/octet-stream")})
1272
- header = {"File-Path": file_path, "Content-Type": encoder.content_type}
1274
+ encoder = MultipartEncoder(fields={"filename": os.path.basename(remote_file), "file": ("filename", fp, "application/octet-stream")})
1275
+ header = {"File-Path": remote_file, "Content-Type": encoder.content_type}
1273
1276
 
1274
1277
  # Include file attributes (permissions, owner, group) if requested
1275
1278
  if apply_file_attributes:
1276
1279
  file_stat = os.stat(local_file)
1277
- header["File-Mode"] = str(file_stat.st_mode)
1280
+ header["File-Mode"] = str(file_stat.st_mode & 0o777) # Mask to keep only permission bits
1278
1281
  header["File-User"] = str(file_stat.st_uid)
1279
1282
  header["File-Group"] = str(file_stat.st_gid)
1280
1283
 
@@ -1486,13 +1489,13 @@ class AppMeshClientTCP(AppMeshClient):
1486
1489
  rest_ssl_verify (str, optional): (optional) SSL CA certification. Either a boolean, in which case it controls whether we verify
1487
1490
  the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use. Defaults to ``True``.
1488
1491
  rest_ssl_client_cert (tuple, optional): SSL client certificate and key pair . If String, path to ssl client cert file (.pem). If Tuple, ('cert', 'key') pair.
1489
- jwt_token (str, optional): JWT token, provide correct token is same with login() & authenticate().
1492
+ jwt_token (str, optional): JWT token, provide correct token is same with login() & authentication().
1490
1493
 
1491
1494
  tcp_address (tuple, optional): TCP connect address.
1492
1495
  """
1493
- super().__init__(rest_ssl_verify=rest_ssl_verify, rest_ssl_client_cert=rest_ssl_client_cert, jwt_token=jwt_token)
1494
1496
  self.tcp_address = tcp_address
1495
1497
  self.__socket_client = None
1498
+ super().__init__(rest_ssl_verify=rest_ssl_verify, rest_ssl_client_cert=rest_ssl_client_cert, jwt_token=jwt_token)
1496
1499
 
1497
1500
  def __del__(self) -> None:
1498
1501
  """De-construction"""
@@ -1501,15 +1504,31 @@ class AppMeshClientTCP(AppMeshClient):
1501
1504
  def __connect_socket(self) -> None:
1502
1505
  """Establish tcp connection"""
1503
1506
  context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH)
1507
+ # Set minimum TLS version
1504
1508
  if hasattr(context, "minimum_version"):
1505
1509
  context.minimum_version = ssl.TLSVersion.TLSv1_2
1506
1510
  else:
1507
1511
  context.options |= ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1
1508
- if self.ssl_verify:
1509
- context.verify_mode = ssl.CERT_REQUIRED
1510
- if isinstance(self.ssl_verify, str):
1511
- # Load server-side certificate authority (CA) certificates
1512
- context.load_verify_locations(self.ssl_verify)
1512
+ # Configure SSL verification
1513
+ if not self.ssl_verify:
1514
+ context.verify_mode = ssl.CERT_NONE
1515
+ else:
1516
+ context.verify_mode = ssl.CERT_REQUIRED # Require certificate verification
1517
+ context.load_default_certs() # Load system's default CA certificates
1518
+ if isinstance(self.ssl_verify, str):
1519
+ if os.path.isfile(self.ssl_verify):
1520
+ # Add custom CA certificate file
1521
+ try:
1522
+ context.load_verify_locations(cafile=self.ssl_verify)
1523
+ except ssl.SSLError:
1524
+ # If loading fails, try using just the default CAs
1525
+ context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH)
1526
+ elif os.path.isdir(self.ssl_verify):
1527
+ # Load CA certificates from directory
1528
+ context.load_verify_locations(capath=self.ssl_verify)
1529
+ else:
1530
+ raise ValueError(f"ssl_verify path '{self.ssl_verify}' is neither a file nor a directory")
1531
+
1513
1532
  if self.ssl_client_cert is not None:
1514
1533
  # Load client-side certificate and private key
1515
1534
  context.load_cert_chain(certfile=self.ssl_client_cert[0], keyfile=self.ssl_client_cert[1])
@@ -1657,15 +1676,15 @@ class AppMeshClientTCP(AppMeshClient):
1657
1676
  ########################################
1658
1677
  # File management
1659
1678
  ########################################
1660
- def file_download(self, file_path: str, local_file: str, apply_file_attributes: bool = True) -> None:
1679
+ def file_download(self, remote_file: str, local_file: str, apply_file_attributes: bool = True) -> None:
1661
1680
  """Copy a remote file to local, the local file will have the same permission as the remote file
1662
1681
 
1663
1682
  Args:
1664
- file_path (str): the remote file path.
1683
+ remote_file (str): the remote file path.
1665
1684
  local_file (str): the local file path to be downloaded.
1666
1685
  apply_file_attributes (bool): whether to apply file attributes (permissions, owner, group) to the local file.
1667
1686
  """
1668
- header = {"File-Path": file_path}
1687
+ header = {"File-Path": remote_file}
1669
1688
  header[HTTP_HEADER_KEY_X_RECV_FILE_SOCKET] = "true"
1670
1689
  resp = self._request_http(AppMeshClient.Method.GET, path="/appmesh/file/download", header=header)
1671
1690
 
@@ -1695,7 +1714,7 @@ class AppMeshClientTCP(AppMeshClient):
1695
1714
  except PermissionError:
1696
1715
  print(f"Warning: Unable to change owner/group of {local_file}. Operation requires elevated privileges.")
1697
1716
 
1698
- def file_upload(self, local_file: str, file_path: str, apply_file_attributes: bool = True) -> None:
1717
+ def file_upload(self, local_file: str, remote_file: str, apply_file_attributes: bool = True) -> None:
1699
1718
  """Upload a local file to the remote server, the remote file will have the same permission as the local file
1700
1719
 
1701
1720
  Dependency:
@@ -1704,19 +1723,19 @@ class AppMeshClientTCP(AppMeshClient):
1704
1723
 
1705
1724
  Args:
1706
1725
  local_file (str): the local file path.
1707
- file_path (str): the target remote file to be uploaded.
1726
+ remote_file (str): the target remote file to be uploaded.
1708
1727
  apply_file_attributes (bool): whether to upload file attributes (permissions, owner, group) along with the file.
1709
1728
  """
1710
1729
  if not os.path.exists(local_file):
1711
1730
  raise FileNotFoundError(f"Local file not found: {local_file}")
1712
1731
 
1713
1732
  with open(file=local_file, mode="rb") as fp:
1714
- header = {"File-Path": file_path, "Content-Type": "text/plain"}
1733
+ header = {"File-Path": remote_file, "Content-Type": "text/plain"}
1715
1734
  header[HTTP_HEADER_KEY_X_SEND_FILE_SOCKET] = "true"
1716
1735
 
1717
1736
  if apply_file_attributes:
1718
1737
  file_stat = os.stat(local_file)
1719
- header["File-Mode"] = str(file_stat.st_mode)
1738
+ header["File-Mode"] = str(file_stat.st_mode & 0o777) # Mask to keep only permission bits
1720
1739
  header["File-User"] = str(file_stat.st_uid)
1721
1740
  header["File-Group"] = str(file_stat.st_gid)
1722
1741
 
@@ -1727,9 +1746,7 @@ class AppMeshClientTCP(AppMeshClient):
1727
1746
  if HTTP_HEADER_KEY_X_SEND_FILE_SOCKET not in resp.headers:
1728
1747
  raise ValueError(f"Server did not respond with socket transfer option: {HTTP_HEADER_KEY_X_SEND_FILE_SOCKET}")
1729
1748
 
1730
- # TLS-optimized chunk size (slightly less than maximum TLS record size)
1731
- # leaves some room for TLS overhead (like headers) within the 16 KB limit.
1732
- chunk_size = 16 * 1024 - 512 # target to 16KB
1749
+ chunk_size = TCP_CHUNK_BLOCK_SIZE
1733
1750
  while True:
1734
1751
  chunk_data = fp.read(chunk_size)
1735
1752
  if not chunk_data:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: appmesh
3
- Version: 1.3.4
3
+ Version: 1.3.5
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,6 @@
1
+ appmesh/__init__.py,sha256=xRdXeFHEieRauuJZElbEBASgXG0ZzU1a5_0isAhM7Gw,11
2
+ appmesh/appmesh_client.py,sha256=bduPEDpI36XQyK_U9y3EvpZvO9CbpDeAB5402yf9qhU,69329
3
+ appmesh-1.3.5.dist-info/METADATA,sha256=VSkQis_Azjvw2FwjrK8qjOvYKw2WRNB37J2tYm_KEbw,11191
4
+ appmesh-1.3.5.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
5
+ appmesh-1.3.5.dist-info/top_level.txt,sha256=-y0MNQOGJxUzLdHZ6E_Rfv5_LNCkV-GTmOBME_b6pg8,8
6
+ appmesh-1.3.5.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.2.0)
2
+ Generator: setuptools (75.3.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,6 +0,0 @@
1
- appmesh/__init__.py,sha256=xRdXeFHEieRauuJZElbEBASgXG0ZzU1a5_0isAhM7Gw,11
2
- appmesh/appmesh_client.py,sha256=6lnfsR6SAhF66jWBPIVPbC43LPhyAL3amBHxSx30Cu4,68327
3
- appmesh-1.3.4.dist-info/METADATA,sha256=TZjYqpu2P33ZcN7ue8uTAMobwavbud7_zr9Eo2si7NY,11191
4
- appmesh-1.3.4.dist-info/WHEEL,sha256=OVMc5UfuAQiSplgO0_WdW7vXVGAt9Hdd6qtN4HotdyA,91
5
- appmesh-1.3.4.dist-info/top_level.txt,sha256=-y0MNQOGJxUzLdHZ6E_Rfv5_LNCkV-GTmOBME_b6pg8,8
6
- appmesh-1.3.4.dist-info/RECORD,,