I4-0-Client-CLI 20.0.0__tar.gz
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.
- i4_0_client_cli-20.0.0/I40ClientCLI/main.py +455 -0
- i4_0_client_cli-20.0.0/I4_0_Client_CLI.egg-info/PKG-INFO +15 -0
- i4_0_client_cli-20.0.0/I4_0_Client_CLI.egg-info/SOURCES.txt +8 -0
- i4_0_client_cli-20.0.0/I4_0_Client_CLI.egg-info/dependency_links.txt +1 -0
- i4_0_client_cli-20.0.0/I4_0_Client_CLI.egg-info/entry_points.txt +2 -0
- i4_0_client_cli-20.0.0/I4_0_Client_CLI.egg-info/requires.txt +2 -0
- i4_0_client_cli-20.0.0/I4_0_Client_CLI.egg-info/top_level.txt +1 -0
- i4_0_client_cli-20.0.0/PKG-INFO +15 -0
- i4_0_client_cli-20.0.0/pyproject.toml +31 -0
- i4_0_client_cli-20.0.0/setup.cfg +4 -0
|
@@ -0,0 +1,455 @@
|
|
|
1
|
+
from I40Client import configuration as config
|
|
2
|
+
from I40Client import server_connection as server
|
|
3
|
+
from I40ClientUtils import chatbot_tools
|
|
4
|
+
import os
|
|
5
|
+
import sys
|
|
6
|
+
import json
|
|
7
|
+
import base64
|
|
8
|
+
import traceback
|
|
9
|
+
import asyncio
|
|
10
|
+
|
|
11
|
+
def main() -> None:
|
|
12
|
+
system = sys.platform
|
|
13
|
+
configFile = None
|
|
14
|
+
conversation = {"conv": [], "params_user": {}, "params_prompt": {
|
|
15
|
+
"tools": chatbot_tools.GetDefaultTools()
|
|
16
|
+
}}
|
|
17
|
+
conversationFile = None
|
|
18
|
+
|
|
19
|
+
if (
|
|
20
|
+
system != "win32" and
|
|
21
|
+
system != "darwin" and
|
|
22
|
+
system != "linux"
|
|
23
|
+
):
|
|
24
|
+
raise OSError("Unsupported OS.")
|
|
25
|
+
|
|
26
|
+
if (system == "win32"):
|
|
27
|
+
homePath = os.environ["LOCALAPPDATA"] + "/I4.0-Client"
|
|
28
|
+
elif (system == "darwin"):
|
|
29
|
+
homePath = f"{os.path.expanduser('~')}/Library/Application Support/I4.0-Client"
|
|
30
|
+
elif (system == "linux"):
|
|
31
|
+
homePath = f"{os.path.expanduser('~')}/.local/share/I4.0-Client"
|
|
32
|
+
|
|
33
|
+
if (not os.path.exists(homePath)):
|
|
34
|
+
os.mkdir(homePath)
|
|
35
|
+
|
|
36
|
+
for arg in sys.argv:
|
|
37
|
+
if (arg.startswith("--config=")):
|
|
38
|
+
configFile = arg[9:]
|
|
39
|
+
|
|
40
|
+
if (not os.path.exists(configFile) or not os.path.isfile(configFile)):
|
|
41
|
+
configFile = None
|
|
42
|
+
elif (arg.startswith("--conv-file=")):
|
|
43
|
+
conversationFile = arg[12:]
|
|
44
|
+
|
|
45
|
+
if (os.path.exists(conversationFile) and os.path.isfile(conversationFile)):
|
|
46
|
+
with open(conversationFile, "r") as f:
|
|
47
|
+
conversation = json.loads(f.read())
|
|
48
|
+
else:
|
|
49
|
+
with open(conversationFile, "x") as f:
|
|
50
|
+
f.write(json.dumps(conversation, indent = 4))
|
|
51
|
+
|
|
52
|
+
if (configFile is None):
|
|
53
|
+
configFile = f"{homePath}/config.json"
|
|
54
|
+
|
|
55
|
+
if (not os.path.exists(configFile)):
|
|
56
|
+
conf = config.ClientConfiguration()
|
|
57
|
+
|
|
58
|
+
setattr(conf, "CLIENT_ConType", input("Connection type ('websocket'): "))
|
|
59
|
+
setattr(conf, "CLIENT_Host", input("Server to connect (Host): "))
|
|
60
|
+
setattr(conf, "CLIENT_Port", int(input("Server to connect (Port): ")))
|
|
61
|
+
setattr(conf, "CLIENT_Secure", bool(int(input("Server to connect (Secure) ('0', '1'): "))))
|
|
62
|
+
setattr(conf, "CLIENT_ModelName", input("Model name: "))
|
|
63
|
+
setattr(conf, "CLIENT_Scrape_FollowGuidelines", bool(int(input("Follow websites guidelines when scrapping? ('0', '1'): "))))
|
|
64
|
+
|
|
65
|
+
with open(configFile, "x") as f:
|
|
66
|
+
f.write(json.dumps(conf.ToDict(SavePublicKey = False), indent = 4))
|
|
67
|
+
|
|
68
|
+
conf = None
|
|
69
|
+
|
|
70
|
+
if (conversationFile is None):
|
|
71
|
+
conversationFile = f"{homePath}/conversation.json"
|
|
72
|
+
|
|
73
|
+
if (not os.path.exists(conversationFile)):
|
|
74
|
+
with open(conversationFile, "x") as f:
|
|
75
|
+
f.write(json.dumps(conversation, indent = 4))
|
|
76
|
+
|
|
77
|
+
with open(configFile, "r") as f:
|
|
78
|
+
conf = json.loads(f.read())
|
|
79
|
+
|
|
80
|
+
with open(conversationFile, "r") as f:
|
|
81
|
+
conversation = json.loads(f.read())
|
|
82
|
+
|
|
83
|
+
conf = config.ClientConfiguration.FromDict(conf)
|
|
84
|
+
chatbot_tools.internet.FollowScrapeGuidelines = getattr(conf, "CLIENT_Scrape_FollowGuidelines")
|
|
85
|
+
|
|
86
|
+
print(f"Got {len(conversation['conv'])} messages from the conversation.", flush = True)
|
|
87
|
+
|
|
88
|
+
async def __socket__() -> None:
|
|
89
|
+
async def __send__(AllowTools: bool = True, Service: str = "inference") -> None:
|
|
90
|
+
await socket.Connect(Host = getattr(conf, "CLIENT_Host"), Port = getattr(conf, "CLIENT_Port"), Secure = getattr(conf, "CLIENT_Secure"))
|
|
91
|
+
|
|
92
|
+
modelInfo = await socket.GetModelInfo(getattr(conf, "CLIENT_ModelName"))
|
|
93
|
+
modelMaxSimulUsers = modelInfo["max_simul_users"] if ("max_simul_users" in modelInfo) else 1
|
|
94
|
+
queueData = await socket.GetQueueData(getattr(conf, "CLIENT_ModelName"))
|
|
95
|
+
|
|
96
|
+
if (queueData["processing_users"] >= modelMaxSimulUsers):
|
|
97
|
+
usersBefore = queueData["processing_users"] + queueData["waiting_users"]
|
|
98
|
+
print(f"{usersBefore} users are using this model. You must wait until the queue of users is less than {modelMaxSimulUsers}.", flush = True)
|
|
99
|
+
|
|
100
|
+
gen = socket.AdvancedSendAndReceive(
|
|
101
|
+
ModelName = getattr(conf, "CLIENT_ModelName"),
|
|
102
|
+
Key = None,
|
|
103
|
+
PromptConversation = conversation["conv"],
|
|
104
|
+
PromptParameters = conversation["params_prompt"],
|
|
105
|
+
UserParameters = conversation["params_user"],
|
|
106
|
+
Service = Service
|
|
107
|
+
)
|
|
108
|
+
errors = 0
|
|
109
|
+
tools = []
|
|
110
|
+
|
|
111
|
+
async for token in gen:
|
|
112
|
+
if ("conversation_result" in token):
|
|
113
|
+
conversation["conv"] = token["conversation_result"]
|
|
114
|
+
|
|
115
|
+
if ("response" in token):
|
|
116
|
+
if ("text" in token["response"]):
|
|
117
|
+
print(token["response"]["text"], end = "", flush = True)
|
|
118
|
+
|
|
119
|
+
if ("files" in token["response"]):
|
|
120
|
+
for file in token["response"]["files"]:
|
|
121
|
+
if (file["type"] == "image"):
|
|
122
|
+
fileExtension = "webp"
|
|
123
|
+
elif (file["type"] == "audio"):
|
|
124
|
+
fileExtension = "wav"
|
|
125
|
+
elif (file["type"] == "video"):
|
|
126
|
+
fileExtension = "webm"
|
|
127
|
+
else:
|
|
128
|
+
fileExtension = file["type"]
|
|
129
|
+
|
|
130
|
+
fileData = base64.b64decode(file[file["type"]])
|
|
131
|
+
fileID = 0
|
|
132
|
+
fileName = f"./file_{fileID}.{fileExtension}"
|
|
133
|
+
|
|
134
|
+
while (os.path.exists(fileName)):
|
|
135
|
+
fileID += 1
|
|
136
|
+
fileName = f"./file_{fileID}.{fileExtension}"
|
|
137
|
+
|
|
138
|
+
with open(fileName, "wb") as f:
|
|
139
|
+
f.write(fileData)
|
|
140
|
+
|
|
141
|
+
print(f"\nFile saved at '{fileName}'.", flush = True)
|
|
142
|
+
|
|
143
|
+
if ("extra" in token["response"]):
|
|
144
|
+
if ("tools" in token["response"]["extra"]):
|
|
145
|
+
tools += token["response"]["extra"]["tools"]
|
|
146
|
+
token["response"]["extra"].pop("tools")
|
|
147
|
+
|
|
148
|
+
if ("thinking" in token["response"]["extra"]):
|
|
149
|
+
token["response"]["extra"].pop("thinking")
|
|
150
|
+
|
|
151
|
+
if (len(token["response"]["extra"]) > 0):
|
|
152
|
+
print(f"Received extra data: {token['response']['extra']}", flush = True)
|
|
153
|
+
|
|
154
|
+
if ("warnings" in token):
|
|
155
|
+
for warning in token["warnings"]:
|
|
156
|
+
print(f"\nWARNING: {warning}", flush = True)
|
|
157
|
+
|
|
158
|
+
if ("errors" in token):
|
|
159
|
+
for error in token["errors"]:
|
|
160
|
+
print(f"\nERROR: {error}", flush = True)
|
|
161
|
+
|
|
162
|
+
errors += len(token["errors"])
|
|
163
|
+
|
|
164
|
+
if (len(tools) > 0 and AllowTools and modelInfo["service"] == "chatbot"):
|
|
165
|
+
toolsResponse = []
|
|
166
|
+
|
|
167
|
+
for tool in tools:
|
|
168
|
+
toolName = tool["name"]
|
|
169
|
+
toolArgs = tool["arguments"]
|
|
170
|
+
|
|
171
|
+
try:
|
|
172
|
+
toolR = chatbot_tools.ExecuteTool(toolName, toolArgs, modelInfo["ctx"], "")
|
|
173
|
+
|
|
174
|
+
if (toolR is not None):
|
|
175
|
+
toolsResponse += toolR
|
|
176
|
+
except Exception as ex:
|
|
177
|
+
print(f"\nERROR: Error processing tool ({type(ex)}): {ex}", flush = True)
|
|
178
|
+
errors += 1
|
|
179
|
+
|
|
180
|
+
if (len(toolsResponse) > 0):
|
|
181
|
+
print("", flush = True)
|
|
182
|
+
|
|
183
|
+
conversation["conv"].append({
|
|
184
|
+
"role": "tool",
|
|
185
|
+
"content": toolsResponse
|
|
186
|
+
})
|
|
187
|
+
await __send__(False, Service)
|
|
188
|
+
|
|
189
|
+
return
|
|
190
|
+
|
|
191
|
+
print("", flush = True)
|
|
192
|
+
|
|
193
|
+
if (errors > 0):
|
|
194
|
+
confirm = input("Errors during inference. Save conversation anyway? [y/N] ").strip().lower() == "y"
|
|
195
|
+
|
|
196
|
+
if (not confirm):
|
|
197
|
+
await socket.Close()
|
|
198
|
+
return
|
|
199
|
+
|
|
200
|
+
with open(conversationFile, "w") as f:
|
|
201
|
+
f.write(json.dumps(conversation, indent = 4))
|
|
202
|
+
|
|
203
|
+
await socket.Close()
|
|
204
|
+
|
|
205
|
+
socket = server.ClientSocket(
|
|
206
|
+
Type = getattr(conf, "CLIENT_ConType"),
|
|
207
|
+
Configuration = conf
|
|
208
|
+
)
|
|
209
|
+
|
|
210
|
+
while (True):
|
|
211
|
+
try:
|
|
212
|
+
mode = input("Mode ['e', 'scc', 'cc', 'pp', 'up', 'sc', 'cls', 'cs', 'h', 'c'*]: ").lower()
|
|
213
|
+
|
|
214
|
+
if (mode == "e"):
|
|
215
|
+
break
|
|
216
|
+
elif (mode == "sc"):
|
|
217
|
+
for msg in conversation["conv"]:
|
|
218
|
+
msgContent = ""
|
|
219
|
+
|
|
220
|
+
for content in msg["content"]:
|
|
221
|
+
if (content["type"] == "text"):
|
|
222
|
+
msgContent += content["text"]
|
|
223
|
+
else:
|
|
224
|
+
msgContent += "--FILE DATA--"
|
|
225
|
+
|
|
226
|
+
print(f"Message #{conversation['conv'].index(msg)}:\nRole: {msg['role']}\nContent:\n```\n{msgContent}\n```\n", flush = True)
|
|
227
|
+
|
|
228
|
+
continue
|
|
229
|
+
elif (mode == "cls"):
|
|
230
|
+
CLEAR_CMDS = ["cls", "clear"]
|
|
231
|
+
exitCode = None
|
|
232
|
+
|
|
233
|
+
for c in CLEAR_CMDS:
|
|
234
|
+
exitCode = os.system(c)
|
|
235
|
+
|
|
236
|
+
if (exitCode == 0):
|
|
237
|
+
break
|
|
238
|
+
|
|
239
|
+
if (exitCode != 0):
|
|
240
|
+
print("Could not clear screen.", flush = True)
|
|
241
|
+
|
|
242
|
+
continue
|
|
243
|
+
elif (mode == "h"):
|
|
244
|
+
print((
|
|
245
|
+
"'e' - Exit - Closes the client.\n"
|
|
246
|
+
"'scc' - Selective Clear Conversation - Delete conversation messages selectively.\n"
|
|
247
|
+
"'cc' - Clear Conversation - Clear the whole conversation.\n"
|
|
248
|
+
"'pp' - Prompt Parameters - Change the prompt parameters.\n"
|
|
249
|
+
"'up' - User Parameters - Change the user parameters.\n"
|
|
250
|
+
"'sc' - Show Conversation - Show the current conversation.\n"
|
|
251
|
+
"'cls' - Clear screen.\n"
|
|
252
|
+
"'h' - Help - Show this help message.\n"
|
|
253
|
+
"'cs' - Custom Service - Run different services.\n"
|
|
254
|
+
"'c' - Continue - Continue with inference.\n\n"
|
|
255
|
+
"* - Default option."
|
|
256
|
+
), flush = True)
|
|
257
|
+
continue
|
|
258
|
+
elif (mode == "scc"):
|
|
259
|
+
msgID = 0
|
|
260
|
+
|
|
261
|
+
while (msgID < len(conversation["conv"])):
|
|
262
|
+
msgContent = []
|
|
263
|
+
|
|
264
|
+
for content in conversation["conv"][msgID]["content"]:
|
|
265
|
+
cont = f" Type: {content['type']}\n Data: "
|
|
266
|
+
|
|
267
|
+
if (content["type"] == "text"):
|
|
268
|
+
cont += content["text"]
|
|
269
|
+
else:
|
|
270
|
+
cont += "--FILE DATA--"
|
|
271
|
+
|
|
272
|
+
msgContent.append(cont)
|
|
273
|
+
|
|
274
|
+
msgContent = "\n".join(msgContent)
|
|
275
|
+
print(f"Message #{msgID + 1}:\n Role: {conversation['conv'][msgID]['role']}\n Content:\n{msgContent}", flush = True)
|
|
276
|
+
|
|
277
|
+
confirm = input("Delete this message? [y/N] ").strip().lower() == "y"
|
|
278
|
+
|
|
279
|
+
if (confirm):
|
|
280
|
+
conversation["conv"].remove(conversation["conv"][msgID])
|
|
281
|
+
continue
|
|
282
|
+
|
|
283
|
+
msgID += 1
|
|
284
|
+
|
|
285
|
+
print("No more messages to delete.", flush = True)
|
|
286
|
+
|
|
287
|
+
with open(conversationFile, "w") as f:
|
|
288
|
+
f.write(json.dumps(conversation, indent = 4))
|
|
289
|
+
|
|
290
|
+
continue
|
|
291
|
+
elif (mode == "cc"):
|
|
292
|
+
confirm = input("WARNING!\nThis will delete ALL OF YOUR MESSAGES.\nContinue? [y/N] ").strip().lower() == "y"
|
|
293
|
+
|
|
294
|
+
if (not confirm):
|
|
295
|
+
continue
|
|
296
|
+
|
|
297
|
+
conversation["conv"].clear()
|
|
298
|
+
|
|
299
|
+
with open(conversationFile, "w") as f:
|
|
300
|
+
f.write(json.dumps(conversation, indent = 4))
|
|
301
|
+
|
|
302
|
+
continue
|
|
303
|
+
elif (mode == "pp"):
|
|
304
|
+
params = {}
|
|
305
|
+
|
|
306
|
+
while (True):
|
|
307
|
+
name = input("Prompt Parameter name (empty = continue): ")
|
|
308
|
+
|
|
309
|
+
if (len(name) == 0):
|
|
310
|
+
break
|
|
311
|
+
|
|
312
|
+
val = input("Prompt Parameter value (json:DATA, str:TEXT, int:INTEGER, float:FLOAT, bool:BOOLEAN): ")
|
|
313
|
+
|
|
314
|
+
if (val.lower().startswith("json:")):
|
|
315
|
+
val = json.loads(val[5:])
|
|
316
|
+
elif (val.lower().startswith("int:")):
|
|
317
|
+
val = int(val[4:])
|
|
318
|
+
elif (val.lower().startswith("float:")):
|
|
319
|
+
val = float(val[6:])
|
|
320
|
+
elif (val.lower().startswith("bool:")):
|
|
321
|
+
val = bool(val[5:])
|
|
322
|
+
elif (not val.lower().startswith("str:")):
|
|
323
|
+
print("Invalid value type. Try again.", flush = True)
|
|
324
|
+
continue
|
|
325
|
+
|
|
326
|
+
params[name] = val
|
|
327
|
+
|
|
328
|
+
conversation["params_prompt"] = params
|
|
329
|
+
|
|
330
|
+
with open(conversationFile, "w") as f:
|
|
331
|
+
f.write(json.dumps(conversation, indent = 4))
|
|
332
|
+
|
|
333
|
+
continue
|
|
334
|
+
elif (mode == "up"):
|
|
335
|
+
params = {}
|
|
336
|
+
|
|
337
|
+
while (True):
|
|
338
|
+
name = input("User Parameter name (empty = continue): ")
|
|
339
|
+
|
|
340
|
+
if (len(name) == 0):
|
|
341
|
+
break
|
|
342
|
+
|
|
343
|
+
val = input("User Parameter value (json:DATA, str:TEXT, int:INTEGER, float:FLOAT, bool:BOOLEAN): ")
|
|
344
|
+
|
|
345
|
+
if (val.lower().startswith("json:")):
|
|
346
|
+
val = json.loads(val[5:])
|
|
347
|
+
elif (val.lower().startswith("int:")):
|
|
348
|
+
val = int(val[4:])
|
|
349
|
+
elif (val.lower().startswith("float:")):
|
|
350
|
+
val = float(val[6:])
|
|
351
|
+
elif (val.lower().startswith("bool:")):
|
|
352
|
+
val = bool(val[5:])
|
|
353
|
+
elif (not val.lower().startswith("str:")):
|
|
354
|
+
print("Invalid value type. Try again.", flush = True)
|
|
355
|
+
continue
|
|
356
|
+
|
|
357
|
+
params[name] = val
|
|
358
|
+
|
|
359
|
+
conversation["params_user"] = params
|
|
360
|
+
|
|
361
|
+
with open(conversationFile, "w") as f:
|
|
362
|
+
f.write(json.dumps(conversation, indent = 4))
|
|
363
|
+
|
|
364
|
+
continue
|
|
365
|
+
elif (mode == "cs"):
|
|
366
|
+
service = input("Service: ")
|
|
367
|
+
elif (len(mode) > 0 and mode != "c"):
|
|
368
|
+
print("Invalid mode. Try again.")
|
|
369
|
+
continue
|
|
370
|
+
else:
|
|
371
|
+
service = "inference"
|
|
372
|
+
|
|
373
|
+
if (len(conversation["conv"]) > 0 and conversation["conv"][-1]["role"] == "user"):
|
|
374
|
+
confirm = input((
|
|
375
|
+
"The last message in the saved conversation is a user message.\n"
|
|
376
|
+
"Adding another user message to the conversation may result in unexpected behaviour.\n\n"
|
|
377
|
+
"Send current conversation? [Y/n] "
|
|
378
|
+
)).strip().lower() != "n"
|
|
379
|
+
|
|
380
|
+
if (confirm):
|
|
381
|
+
await __send__(Service = service)
|
|
382
|
+
continue
|
|
383
|
+
|
|
384
|
+
while (True):
|
|
385
|
+
msgRole = input(f"Message #{len(conversation['conv']) + 1} role (empty = continue): ")
|
|
386
|
+
|
|
387
|
+
if (len(msgRole) == 0):
|
|
388
|
+
break
|
|
389
|
+
|
|
390
|
+
msgContent = []
|
|
391
|
+
|
|
392
|
+
while (True):
|
|
393
|
+
content = {}
|
|
394
|
+
content["type"] = input(f"Message #{len(conversation['conv']) + 1} content #{len(msgContent) + 1} type (empty = continue): ")
|
|
395
|
+
|
|
396
|
+
if (len(content["type"]) == 0):
|
|
397
|
+
break
|
|
398
|
+
elif (content["type"] == "text"):
|
|
399
|
+
contTxt = ""
|
|
400
|
+
|
|
401
|
+
while (True):
|
|
402
|
+
contTxt += input("TEXT > ")
|
|
403
|
+
|
|
404
|
+
if (contTxt.endswith(" \\")):
|
|
405
|
+
contTxt = contTxt[:-2] + "\n"
|
|
406
|
+
continue
|
|
407
|
+
elif (contTxt.split("\n")[-1] == "\\"):
|
|
408
|
+
contTxt = contTxt[:-1] + "\n"
|
|
409
|
+
continue
|
|
410
|
+
|
|
411
|
+
break
|
|
412
|
+
|
|
413
|
+
content[content["type"]] = contTxt
|
|
414
|
+
else:
|
|
415
|
+
fp = input("FILE PATH > ")
|
|
416
|
+
|
|
417
|
+
if (not os.path.exists(fp)):
|
|
418
|
+
print("File does not exist. Try again.")
|
|
419
|
+
continue
|
|
420
|
+
|
|
421
|
+
with open(fp, "rb") as f:
|
|
422
|
+
content[content["type"]] = base64.b64encode(f.read()).decode("utf-8")
|
|
423
|
+
|
|
424
|
+
msgContent.append(content)
|
|
425
|
+
|
|
426
|
+
conversation["conv"].append({"role": msgRole, "content": msgContent})
|
|
427
|
+
|
|
428
|
+
await __send__(Service = service)
|
|
429
|
+
|
|
430
|
+
with open(conversationFile, "w") as f:
|
|
431
|
+
f.write(json.dumps(conversation, indent = 4))
|
|
432
|
+
except KeyboardInterrupt:
|
|
433
|
+
print("", flush = True)
|
|
434
|
+
continue
|
|
435
|
+
except Exception as ex:
|
|
436
|
+
print(f"Unexpected error (Type: {type(ex)}): {ex}", flush = True)
|
|
437
|
+
confirm = input("Ignore unexpected error? [Y/n/d] ").strip().lower()
|
|
438
|
+
|
|
439
|
+
if (confirm == "d"):
|
|
440
|
+
traceback.print_exception(ex)
|
|
441
|
+
confirm = input("Ignore unexpected error? [Y/n] ").strip().lower()
|
|
442
|
+
|
|
443
|
+
if (confirm == "n"):
|
|
444
|
+
break
|
|
445
|
+
finally:
|
|
446
|
+
await socket.Close()
|
|
447
|
+
|
|
448
|
+
await socket.Close()
|
|
449
|
+
|
|
450
|
+
asyncio.set_event_loop(asyncio.new_event_loop())
|
|
451
|
+
asyncio.get_event_loop().run_until_complete(__socket__())
|
|
452
|
+
asyncio.get_event_loop().close()
|
|
453
|
+
|
|
454
|
+
if (__name__ == "__main__"):
|
|
455
|
+
main()
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: I4_0-Client-CLI
|
|
3
|
+
Version: 20.0.0
|
|
4
|
+
Summary: Client-side CLI for I4.0.
|
|
5
|
+
Author: TAO71-AI
|
|
6
|
+
License: TAO71 I4.0 License (version 2)
|
|
7
|
+
Project-URL: Homepage, https://github.com/TAO71-AI/I4.0-NEW
|
|
8
|
+
Project-URL: Source, https://github.com/TAO71-AI/I4.0-NEW/tree/master/Client/CLI
|
|
9
|
+
Project-URL: License, https://github.com/TAO71-AI/I4.0-NEW/blob/master/LICENSE.md
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: License :: Other/Proprietary License
|
|
12
|
+
Classifier: Operating System :: OS Independent
|
|
13
|
+
Requires-Python: >=3.11
|
|
14
|
+
Requires-Dist: I4_0-Client-PY>=20.0.0
|
|
15
|
+
Requires-Dist: I4_0-Client-Utils>=20.0.0
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
pyproject.toml
|
|
2
|
+
I40ClientCLI/main.py
|
|
3
|
+
I4_0_Client_CLI.egg-info/PKG-INFO
|
|
4
|
+
I4_0_Client_CLI.egg-info/SOURCES.txt
|
|
5
|
+
I4_0_Client_CLI.egg-info/dependency_links.txt
|
|
6
|
+
I4_0_Client_CLI.egg-info/entry_points.txt
|
|
7
|
+
I4_0_Client_CLI.egg-info/requires.txt
|
|
8
|
+
I4_0_Client_CLI.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
I40ClientCLI
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: I4_0-Client-CLI
|
|
3
|
+
Version: 20.0.0
|
|
4
|
+
Summary: Client-side CLI for I4.0.
|
|
5
|
+
Author: TAO71-AI
|
|
6
|
+
License: TAO71 I4.0 License (version 2)
|
|
7
|
+
Project-URL: Homepage, https://github.com/TAO71-AI/I4.0-NEW
|
|
8
|
+
Project-URL: Source, https://github.com/TAO71-AI/I4.0-NEW/tree/master/Client/CLI
|
|
9
|
+
Project-URL: License, https://github.com/TAO71-AI/I4.0-NEW/blob/master/LICENSE.md
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: License :: Other/Proprietary License
|
|
12
|
+
Classifier: Operating System :: OS Independent
|
|
13
|
+
Requires-Python: >=3.11
|
|
14
|
+
Requires-Dist: I4_0-Client-PY>=20.0.0
|
|
15
|
+
Requires-Dist: I4_0-Client-Utils>=20.0.0
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "I4_0-Client-CLI"
|
|
7
|
+
version = "20.0.0"
|
|
8
|
+
description = "Client-side CLI for I4.0."
|
|
9
|
+
authors = [{name = "TAO71-AI"}]
|
|
10
|
+
license = {text = "TAO71 I4.0 License (version 2)"}
|
|
11
|
+
requires-python = ">=3.11"
|
|
12
|
+
dependencies = [
|
|
13
|
+
"I4_0-Client-PY>=20.0.0",
|
|
14
|
+
"I4_0-Client-Utils>=20.0.0"
|
|
15
|
+
]
|
|
16
|
+
classifiers = [
|
|
17
|
+
"Programming Language :: Python :: 3",
|
|
18
|
+
"License :: Other/Proprietary License",
|
|
19
|
+
"Operating System :: OS Independent"
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
[project.urls]
|
|
23
|
+
Homepage = "https://github.com/TAO71-AI/I4.0-NEW"
|
|
24
|
+
Source = "https://github.com/TAO71-AI/I4.0-NEW/tree/master/Client/CLI"
|
|
25
|
+
License = "https://github.com/TAO71-AI/I4.0-NEW/blob/master/LICENSE.md"
|
|
26
|
+
|
|
27
|
+
[project.scripts]
|
|
28
|
+
I40C = "I40ClientCLI.main:main"
|
|
29
|
+
|
|
30
|
+
[tool.setuptools.packages.find]
|
|
31
|
+
include = ["I40ClientCLI", "I40ClientCLI.*"]
|