appmesh 0.2.2__py3-none-any.whl → 0.2.4__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
@@ -3,6 +3,7 @@
3
3
  import abc
4
4
  import aniso8601
5
5
  import base64
6
+ import copy
6
7
  import json
7
8
  import os
8
9
  import socket
@@ -16,15 +17,173 @@ from datetime import datetime
16
17
  import requests
17
18
 
18
19
 
19
- DEFAULT_TOKEN_EXPIRE_SECONDS = "P1W" # 7 days
20
- DEFAULT_RUN_APP_TIMEOUT_SECONDS = "PT1H" # 1 hour
21
- DEFAULT_RUN_APP_LIFECYCLE_SECONDS = "PT10H" # 10 hours
20
+ DEFAULT_TOKEN_EXPIRE_SECONDS = "P1W" # 7 days
21
+ DEFAULT_RUN_APP_TIMEOUT_SECONDS = "PT1H" # 1 hour
22
+ DEFAULT_RUN_APP_LIFECYCLE_SECONDS = "PT10H" # 10 hours
22
23
  REST_TEXT_MESSAGE_JSON_KEY = "message"
23
24
  MESSAGE_ENCODING_UTF8 = "utf-8"
24
25
  TCP_MESSAGE_HEADER_LENGTH = 4
25
26
  _SSL_CA_PEM_FILE = "/opt/appmesh/ssl/ca.pem"
26
27
 
27
28
 
29
+ def _get_str_item(data, key):
30
+ return str(data[key]) if (data and key in data and data[key]) else None
31
+
32
+
33
+ def _get_int_item(data, key):
34
+ return int(data[key]) if (data and key in data and data[key]) else None
35
+
36
+
37
+ def _get_bool_item(data, key):
38
+ return bool(data[key]) if (data and key in data and data[key]) else None
39
+
40
+
41
+ def _get_dict_item(data, key):
42
+ return data[key] if (data and key in data and data[key]) else None
43
+
44
+
45
+ class App(object):
46
+ """
47
+ App object present an application in App Mesh
48
+ """
49
+
50
+ class Behavior(object):
51
+ """
52
+ Application error handling behavior definition object
53
+ """
54
+
55
+ def __init__(self, data=None) -> None:
56
+ if isinstance(data, (str, bytes, bytearray)):
57
+ data = json.loads(data)
58
+ self.exit = _get_str_item(data, "exit")
59
+ self.control = copy.deepcopy(data)
60
+
61
+ class DailyLimitation(object):
62
+ """
63
+ Application avialable day time definition object
64
+ """
65
+
66
+ def __init__(self, data=None) -> None:
67
+ if isinstance(data, (str, bytes, bytearray)):
68
+ data = json.loads(data)
69
+ self.daily_start = _get_int_item(data, "daily_start")
70
+ self.daily_end = _get_int_item(data, "daily_end")
71
+
72
+ class ResourceLimitation(object):
73
+ """
74
+ Application cgroup limitation definition object
75
+ """
76
+
77
+ def __init__(self, data=None) -> None:
78
+ if isinstance(data, (str, bytes, bytearray)):
79
+ data = json.loads(data)
80
+ self.cpu_shares = _get_int_item(data, "cpu_shares")
81
+ self.memory_mb = _get_int_item(data, "memory_mb")
82
+ self.memory_virt_mb = _get_int_item(data, "memory_virt_mb")
83
+
84
+ def __init__(self, data=None):
85
+ """Construct an App Mesh Application object
86
+
87
+ Args:
88
+ data (str | dict | json, optional): application definition data
89
+ """
90
+
91
+ if isinstance(data, (str, bytes, bytearray)):
92
+ data = json.loads(data)
93
+
94
+ # mandatory parameters
95
+ self.name = _get_str_item(data, "name")
96
+ self.command = _get_str_item(data, "command")
97
+
98
+ self.shell = _get_bool_item(data, "shell")
99
+ self.description = _get_str_item(data, "description")
100
+ self.metadata = _get_str_item(data, "metadata")
101
+ self.working_dir = _get_str_item(data, "working_dir")
102
+ self.status = _get_int_item(data, "status")
103
+ self.docker_image = _get_str_item(data, "docker_image")
104
+ self.stdout_cache_num = _get_int_item(data, "stdout_cache_num")
105
+
106
+ self.start_time = _get_int_item(data, "start_time")
107
+ self.end_time = _get_int_item(data, "end_time")
108
+ self.interval = _get_int_item(data, "interval")
109
+ self.cron = _get_bool_item(data, "cron")
110
+ self.daily_limitation = App.DailyLimitation(_get_dict_item(data, "daily_limitation"))
111
+
112
+ self.retention = _get_str_item(data, "retention")
113
+ self.extra_time = _get_str_item(data, "extra_time")
114
+
115
+ self.health_check_cmd = _get_str_item(data, "health_check_cmd")
116
+ self.permission = _get_int_item(data, "permission")
117
+ self.behavior = App.Behavior(_get_dict_item(data, "behavior"))
118
+
119
+ self.env = dict()
120
+ if data and "env" in data:
121
+ for k, v in data["env"].items():
122
+ self.env[k] = v
123
+ self.sec_env = dict()
124
+ if data and "sec_env" in data:
125
+ for k, v in data["sec_env"].items():
126
+ self.sec_env[k] = v
127
+ self.pid = _get_int_item(data, "pid")
128
+ self.resource_limit = App.ResourceLimitation(_get_dict_item(data, "resource_limit"))
129
+
130
+ # readonly attributes
131
+ self.owner = _get_str_item(data, "owner")
132
+ self.pstree = _get_str_item(data, "pstree")
133
+ self.container_id = _get_str_item(data, "container_id")
134
+ self.memory = _get_int_item(data, "memory")
135
+ self.cpu = _get_int_item(data, "cpu")
136
+ self.fd = _get_int_item(data, "fd")
137
+ self.last_start_time = _get_int_item(data, "last_start_time")
138
+ self.last_exit_time = _get_int_item(data, "last_exit_time")
139
+ self.health = _get_int_item(data, "health")
140
+ self.version = _get_int_item(data, "version")
141
+ self.return_code = _get_int_item(data, "return_code")
142
+
143
+ def __str__(self) -> str:
144
+ output = copy.deepcopy(self.__dict__)
145
+ output["behavior"] = copy.deepcopy(self.behavior.__dict__)
146
+ output["daily_limitation"] = copy.deepcopy(self.daily_limitation.__dict__)
147
+ output["resource_limit"] = copy.deepcopy(self.resource_limit.__dict__)
148
+
149
+ def clean_empty_item(data, key) -> None:
150
+ value = data[key]
151
+ if not value:
152
+ del data[key]
153
+ elif isinstance(value, dict):
154
+ for k in list(value):
155
+ clean_empty_item(value, k)
156
+
157
+ for k in list(output):
158
+ clean_empty_item(output, k)
159
+ for k in list(output):
160
+ clean_empty_item(output, k)
161
+ return json.dumps(output, indent=2)
162
+
163
+
164
+ class Run(object):
165
+ """
166
+ Application run object indicate to a remote run from run_async()
167
+ """
168
+
169
+ def __init__(self, client, app_name: str, process_id: str):
170
+ self.app_name = app_name
171
+ self.proc_uid = process_id
172
+ self.__client = client
173
+
174
+ def wait(self, stdout_print: bool = True, timeout: int = 0) -> int:
175
+ """Wait for an async run to be finished
176
+
177
+ Args:
178
+ run (Run): asyncrized run result from run_async().
179
+ stdout_print (bool, optional): print remote stdout to local or not.
180
+ timeout (int, optional): wait max timeout seconds and return if not finished, 0 means wait until finished
181
+
182
+ Returns:
183
+ int: return exit code if process finished, return None for timeout or exception.
184
+ """
185
+ return self.__client.run_async_wait(self, stdout_print, timeout)
186
+
28
187
 
29
188
  class AppMeshClient(metaclass=abc.ABCMeta):
30
189
  """
@@ -36,17 +195,17 @@ class AppMeshClient(metaclass=abc.ABCMeta):
36
195
 
37
196
  class Method(Enum):
38
197
  """REST methods"""
198
+
39
199
  GET = "GET"
40
200
  PUT = "PUT"
41
201
  POST = "POST"
42
202
  DELETE = "DELETE"
43
203
  POST_STREAM = "POST_STREAM"
44
204
 
45
-
46
205
  def __init__(
47
206
  self,
48
- auth_enable: bool=True,
49
- rest_url: str="https://127.0.0.1:6060",
207
+ auth_enable: bool = True,
208
+ rest_url: str = "https://127.0.0.1:6060",
50
209
  rest_ssl_verify=_SSL_CA_PEM_FILE,
51
210
  rest_timeout=(60, 300),
52
211
  jwt_token=None,
@@ -62,7 +221,7 @@ class AppMeshClient(metaclass=abc.ABCMeta):
62
221
  """
63
222
  self.server_url = rest_url
64
223
  self.jwt_auth_enable = auth_enable
65
- self.__jwt_token = token
224
+ self.__jwt_token = jwt_token
66
225
  self.ssl_verify = rest_ssl_verify
67
226
  self.rest_timeout = rest_timeout
68
227
 
@@ -87,7 +246,7 @@ class AppMeshClient(metaclass=abc.ABCMeta):
87
246
  ########################################
88
247
  # Security
89
248
  ########################################
90
- def login(self, user_name: str, user_pwd: str, timeout_seconds = DEFAULT_TOKEN_EXPIRE_SECONDS) -> str:
249
+ def login(self, user_name: str, user_pwd: str, timeout_seconds=DEFAULT_TOKEN_EXPIRE_SECONDS) -> str:
91
250
  """Login with user name and password
92
251
 
93
252
  Args:
@@ -133,7 +292,7 @@ class AppMeshClient(metaclass=abc.ABCMeta):
133
292
  if self.jwt_auth_enable:
134
293
  self.jwt_token = token
135
294
  headers = {}
136
- if permission is not None:
295
+ if permission:
137
296
  headers["Auth-Permission"] = permission
138
297
  resp = self._request_http(AppMeshClient.Method.POST, path="/appmesh/auth", header=headers)
139
298
  if resp.status_code == HTTPStatus.OK:
@@ -147,28 +306,39 @@ class AppMeshClient(metaclass=abc.ABCMeta):
147
306
  ########################################
148
307
  # Application view
149
308
  ########################################
150
- def app_view(self, app_name: str):
151
- """Get application information in JSON format
309
+ def app_view(self, app_name: str) -> App:
310
+ """Get one application information
152
311
 
153
312
  Args:
154
313
  app_name (str): the application name.
155
314
 
156
315
  Returns:
157
- bool: success or failure.
158
- dict: the application JSON both contain static configuration and runtime information.
316
+ App: the application object both contain static configuration and runtime information.
317
+
318
+ Exception:
319
+ failed request or no such application
159
320
  """
160
321
  resp = self._request_http(AppMeshClient.Method.GET, path=f"/appmesh/app/{app_name}")
161
- return (resp.status_code == HTTPStatus.OK), resp.json()
322
+ if resp.status_code != HTTPStatus.OK:
323
+ raise Exception(resp.text)
324
+ return App(resp.json())
162
325
 
163
326
  def app_view_all(self):
164
- """Get all applications in JSON format
327
+ """Get all applications
165
328
 
166
329
  Returns:
167
- bool: success or failure.
168
- dict: the application JSON both contain static configuration and runtime information, only return applications that the user has permissions.
330
+ list: the application object both contain static configuration and runtime information, only return applications that the user has permissions.
331
+
332
+ Exception:
333
+ failed request or no such application
169
334
  """
170
335
  resp = self._request_http(AppMeshClient.Method.GET, path="/appmesh/applications")
171
- return (resp.status_code == HTTPStatus.OK), resp.json()
336
+ if resp.status_code != HTTPStatus.OK:
337
+ raise Exception(resp.text)
338
+ apps = []
339
+ for app in resp.json():
340
+ apps.append(App(app))
341
+ return apps
172
342
 
173
343
  def app_output(self, app_name: str, stdout_position: int = 0, stdout_index: int = 0, stdout_maxsize: int = 10240, process_uuid: str = "", timeout: int = 0):
174
344
  """Get application stdout/stderr
@@ -218,18 +388,22 @@ class AppMeshClient(metaclass=abc.ABCMeta):
218
388
  ########################################
219
389
  # Application manage
220
390
  ########################################
221
- def app_add(self, app_json: dict):
391
+ def app_add(self, app: App) -> App:
222
392
  """Register an application
223
393
 
224
394
  Args:
225
- app_json (dict): the application definition.
395
+ app (App): the application definition.
226
396
 
227
397
  Returns:
228
- bool: success or failure.
229
- dict: resigtered application in JSON format.
398
+ App: resigtered application object.
399
+
400
+ Exception:
401
+ failed request
230
402
  """
231
- resp = self._request_http(AppMeshClient.Method.PUT, path="/appmesh/app/{0}".format(app_json["name"]), body=app_json)
232
- return (resp.status_code == HTTPStatus.OK), resp.json()
403
+ resp = self._request_http(AppMeshClient.Method.PUT, path="/appmesh/app/{0}".format(app.name), body=str(app))
404
+ if resp.status_code != HTTPStatus.OK:
405
+ raise Exception(resp.text)
406
+ return App(resp.json())
233
407
 
234
408
  def app_delete(self, app_name: str):
235
409
  """Remove an application.
@@ -414,7 +588,7 @@ class AppMeshClient(metaclass=abc.ABCMeta):
414
588
  """
415
589
  resp = self._request_http(AppMeshClient.Method.POST, path="/appmesh/config", body={"LogLevel": level})
416
590
  if resp.status_code == HTTPStatus.OK:
417
- return True,resp.json()["LogLevel"]
591
+ return True, resp.json()["LogLevel"]
418
592
  return (resp.status_code == HTTPStatus.OK), resp.json()
419
593
 
420
594
  ########################################
@@ -763,15 +937,15 @@ class AppMeshClient(metaclass=abc.ABCMeta):
763
937
 
764
938
  def run_async(
765
939
  self,
766
- app_json: dict,
767
- max_time_seconds = DEFAULT_RUN_APP_TIMEOUT_SECONDS,
768
- life_cycle_seconds = DEFAULT_RUN_APP_LIFECYCLE_SECONDS,
940
+ app: App,
941
+ max_time_seconds=DEFAULT_RUN_APP_TIMEOUT_SECONDS,
942
+ life_cycle_seconds=DEFAULT_RUN_APP_LIFECYCLE_SECONDS,
769
943
  ):
770
944
  """Asyncrized run a command remotely, 'name' attribute in app_json dict used to run an existing application
771
945
  Asyncrized run will not block process
772
946
 
773
947
  Args:
774
- app_json (dict): application JSON dict.
948
+ app (App): application object.
775
949
  max_time_seconds (int | str, optional): max run time for the remote process, support ISO 8601 durations (e.g., 'P1Y2M3DT4H5M6S' 'P5W').
776
950
  life_cycle_seconds (int | str, optional): max lifecycle time for the remote process. support ISO 8601 durations (e.g., 'P1Y2M3DT4H5M6S' 'P5W').
777
951
 
@@ -782,25 +956,19 @@ class AppMeshClient(metaclass=abc.ABCMeta):
782
956
  path = "/appmesh/app/run"
783
957
  resp = self._request_http(
784
958
  AppMeshClient.Method.POST,
785
- body=app_json,
959
+ body=str(app),
786
960
  path=path,
787
961
  query={"timeout": self._parse_duration(max_time_seconds), "lifecycle": self._parse_duration(life_cycle_seconds)},
788
962
  )
789
- if resp.status_code == HTTPStatus.OK:
790
- app_name = resp.json()["name"]
791
- process_uuid = resp.json()["process_uuid"]
792
- return (app_name, process_uuid)
793
- else:
794
- print(resp.text)
795
- return None
963
+ if resp.status_code != HTTPStatus.OK:
964
+ raise Exception(resp.text)
965
+ return Run(self, resp.json()["name"], resp.json()["process_uuid"])
796
966
 
797
- def run_async_wait(self, async_tuple: tuple, stdout_print: bool = True, timeout: int = 0) -> int:
967
+ def run_async_wait(self, run: Run, stdout_print: bool = True, timeout: int = 0) -> int:
798
968
  """Wait for an async run to be finished
799
969
 
800
970
  Args:
801
- async_tuple (tuple): asyncrized run result from run_async().
802
- async_tuple[0] app_name: application name from run_async
803
- async_tuple[1] process_uuid: process uuid
971
+ run (Run): asyncrized run result from run_async().
804
972
  stdout_print (bool, optional): print remote stdout to local or not.
805
973
  timeout (int, optional): wait max timeout seconds and return if not finished, 0 means wait until finished
806
974
 
@@ -808,23 +976,21 @@ class AppMeshClient(metaclass=abc.ABCMeta):
808
976
  int: return exit code if process finished, return None for timeout or exception.
809
977
  """
810
978
  exit_code = None
811
- if async_tuple is not None:
812
- app_name = async_tuple[0]
813
- process_uuid = async_tuple[1]
979
+ if run:
814
980
  output_position = 0
815
981
  start = datetime.now()
816
982
  interval = 1 if self.__class__.__name__ == "AppMeshClient" else 1000
817
- while len(process_uuid) > 0:
983
+ while len(run.proc_uid) > 0:
818
984
  success, output, position, exit_code = self.app_output(
819
- app_name=app_name, stdout_position=output_position, stdout_index=0, process_uuid=process_uuid, timeout=interval
985
+ app_name=run.app_name, stdout_position=output_position, stdout_index=0, process_uuid=run.proc_uid, timeout=interval
820
986
  )
821
- if output is not None and stdout_print:
987
+ if output and stdout_print:
822
988
  print(output, end="")
823
989
  if position is not None:
824
990
  output_position = position
825
991
  if exit_code is not None:
826
992
  # success
827
- self.app_delete(app_name)
993
+ self.app_delete(run.app_name)
828
994
  break
829
995
  if not success:
830
996
  # failed
@@ -836,16 +1002,16 @@ class AppMeshClient(metaclass=abc.ABCMeta):
836
1002
 
837
1003
  def run_sync(
838
1004
  self,
839
- app_json: dict,
1005
+ app: App,
840
1006
  stdout_print: bool = True,
841
- max_time_seconds = DEFAULT_RUN_APP_TIMEOUT_SECONDS,
842
- life_cycle_seconds = DEFAULT_RUN_APP_LIFECYCLE_SECONDS,
1007
+ max_time_seconds=DEFAULT_RUN_APP_TIMEOUT_SECONDS,
1008
+ life_cycle_seconds=DEFAULT_RUN_APP_LIFECYCLE_SECONDS,
843
1009
  ) -> int:
844
1010
  """Block run a command remotely, 'name' attribute in app_json dict used to run an existing application
845
1011
  The synchronized run will block the process until the remote run is finished then return the result from HTTP response
846
1012
 
847
1013
  Args:
848
- app_json (dict): application JSON dict.
1014
+ app (App): application object.
849
1015
  stdout_print (bool, optional): whether print remote stdout to local or not. Defaults to True.
850
1016
  max_time_seconds (int | str, optional): max run time for the remote process. support ISO 8601 durations (e.g., 'P1Y2M3DT4H5M6S' 'P5W').
851
1017
  life_cycle_seconds (int | str, optional): max lifecycle time for the remote process. support ISO 8601 durations (e.g., 'P1Y2M3DT4H5M6S' 'P5W').
@@ -856,7 +1022,7 @@ class AppMeshClient(metaclass=abc.ABCMeta):
856
1022
  path = "/appmesh/app/syncrun"
857
1023
  resp = self._request_http(
858
1024
  AppMeshClient.Method.POST,
859
- body=app_json,
1025
+ body=str(app),
860
1026
  path=path,
861
1027
  query={"timeout": self._parse_duration(max_time_seconds), "lifecycle": self._parse_duration(life_cycle_seconds)},
862
1028
  )
@@ -884,7 +1050,7 @@ class AppMeshClient(metaclass=abc.ABCMeta):
884
1050
  requests.Response: HTTP response
885
1051
  """
886
1052
  rest_url = parse.urljoin(self.server_url, path)
887
- if self.jwt_token is not None:
1053
+ if self.jwt_token:
888
1054
  header["Authorization"] = "Bearer " + self.jwt_token
889
1055
 
890
1056
  if method is AppMeshClient.Method.GET:
@@ -969,10 +1135,10 @@ class AppMeshClientTCP(AppMeshClient):
969
1135
  while length:
970
1136
  chunk = self.__socket_client.recv(length)
971
1137
  if not chunk:
972
- raise EOFError('socket closed')
1138
+ raise EOFError("socket closed")
973
1139
  length -= len(chunk)
974
1140
  fragments.append(chunk)
975
- return b''.join(fragments)
1141
+ return b"".join(fragments)
976
1142
 
977
1143
  def _request_http(self, method: AppMeshClient.Method, path: str, query: dict = {}, header: dict = {}, body=None) -> requests.Response:
978
1144
  """TCP API
@@ -988,12 +1154,13 @@ class AppMeshClientTCP(AppMeshClient):
988
1154
  requests.Response: HTTP response
989
1155
  """
990
1156
  import msgpack
1157
+
991
1158
  class RequestMsg:
992
1159
  uuid: str = ""
993
1160
  request_uri: str = ""
994
1161
  http_method: str = ""
995
1162
  client_addr: str = ""
996
- body: bytes = b''
1163
+ body: bytes = b""
997
1164
  headers: dict = {}
998
1165
  querys: dict = {}
999
1166
 
@@ -1009,17 +1176,16 @@ class AppMeshClientTCP(AppMeshClient):
1009
1176
  request_uri: str = ""
1010
1177
  http_status: int = 0
1011
1178
  body_msg_type: str = ""
1012
- body: bytes = b''
1179
+ body: bytes = b""
1013
1180
  headers: dict = {}
1014
1181
 
1015
1182
  def desirialize(self, buf: bytes):
1016
1183
  dic = msgpack.unpackb(buf)
1017
- for k,v in dic.items():
1184
+ for k, v in dic.items():
1018
1185
  setattr(self, k, v)
1019
1186
  return self
1020
1187
 
1021
-
1022
- if super().jwt_token is not None:
1188
+ if super().jwt_token:
1023
1189
  header["Authorization"] = "Bearer " + super().jwt_token
1024
1190
  if self.__socket_client is None:
1025
1191
  self.__connect_socket()
@@ -1079,8 +1245,7 @@ class AppMeshClientTCP(AppMeshClient):
1079
1245
  Returns:
1080
1246
  bool: success or failure.
1081
1247
  """
1082
- resp = self._request_http(
1083
- AppMeshClient.Method.GET, path="/appmesh/file/download", header={"File-Path": file_path})
1248
+ resp = self._request_http(AppMeshClient.Method.GET, path="/appmesh/file/download", header={"File-Path": file_path})
1084
1249
  if resp.status_code == HTTPStatus.OK:
1085
1250
  with open(local_file, "wb") as fp:
1086
1251
  chunk_data = bytes()
@@ -1130,7 +1295,7 @@ class AppMeshClientTCP(AppMeshClient):
1130
1295
  # https://stackoverflow.com/questions/22567306/python-requests-file-upload
1131
1296
  resp = self._request_http(AppMeshClient.Method.POST, path="/appmesh/file/upload", header=header)
1132
1297
  if resp.status_code == HTTPStatus.OK:
1133
- chunk_size = 1024*4 # 131072 bytes, default max ssl buffer size
1298
+ chunk_size = 1024 * 4 # 131072 bytes, default max ssl buffer size
1134
1299
  chunk_data = fp.read(chunk_size)
1135
1300
  while chunk_data:
1136
1301
  self.__socket_client.sendall(len(chunk_data).to_bytes(TCP_MESSAGE_HEADER_LENGTH, "big", signed=False))
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: appmesh
3
- Version: 0.2.2
3
+ Version: 0.2.4
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=8lR_gF4_BYzWgg63XBIaJuSGJeSE7jt066v1QLFq-pc,49634
3
+ appmesh-0.2.4.dist-info/METADATA,sha256=LtKj7oblEzep3qW4RhcsWUt1oCgyUj5Nv_i-BWfE2uI,10620
4
+ appmesh-0.2.4.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
5
+ appmesh-0.2.4.dist-info/top_level.txt,sha256=-y0MNQOGJxUzLdHZ6E_Rfv5_LNCkV-GTmOBME_b6pg8,8
6
+ appmesh-0.2.4.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.38.4)
2
+ Generator: bdist_wheel (0.40.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=zt-lh9SoCM-ESoyPmymPKl0RLezy5cHLoIO3X43iC5c,43891
3
- appmesh-0.2.2.dist-info/METADATA,sha256=D4Qzb8cl-433r_8xJ2a1If7kCS79ZHQMc5YNofl7ydQ,10620
4
- appmesh-0.2.2.dist-info/WHEEL,sha256=2wepM1nk4DS4eFpYrW1TTqPcoGNfHhhO_i5m4cOimbo,92
5
- appmesh-0.2.2.dist-info/top_level.txt,sha256=-y0MNQOGJxUzLdHZ6E_Rfv5_LNCkV-GTmOBME_b6pg8,8
6
- appmesh-0.2.2.dist-info/RECORD,,