kalavai-client 0.5.26__py3-none-any.whl → 0.5.27__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.
- kalavai_client/__init__.py +1 -1
- kalavai_client/bridge_api.py +11 -3
- kalavai_client/bridge_models.py +6 -1
- kalavai_client/cli.py +40 -58
- kalavai_client/core.py +57 -13
- kalavai_client/utils.py +18 -2
- {kalavai_client-0.5.26.dist-info → kalavai_client-0.5.27.dist-info}/METADATA +1 -1
- {kalavai_client-0.5.26.dist-info → kalavai_client-0.5.27.dist-info}/RECORD +11 -11
- {kalavai_client-0.5.26.dist-info → kalavai_client-0.5.27.dist-info}/LICENSE +0 -0
- {kalavai_client-0.5.26.dist-info → kalavai_client-0.5.27.dist-info}/WHEEL +0 -0
- {kalavai_client-0.5.26.dist-info → kalavai_client-0.5.27.dist-info}/entry_points.txt +0 -0
kalavai_client/__init__.py
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
|
2
|
-
__version__ = "0.5.
|
2
|
+
__version__ = "0.5.27"
|
kalavai_client/bridge_api.py
CHANGED
@@ -7,6 +7,7 @@ import uvicorn
|
|
7
7
|
|
8
8
|
from kalavai_client.bridge_models import (
|
9
9
|
CreatePoolRequest,
|
10
|
+
InvitesRequest,
|
10
11
|
JoinPoolRequest,
|
11
12
|
StopPoolRequest,
|
12
13
|
DeployJobRequest,
|
@@ -18,6 +19,7 @@ from kalavai_client.core import (
|
|
18
19
|
create_pool,
|
19
20
|
join_pool,
|
20
21
|
attach_to_pool,
|
22
|
+
send_invites,
|
21
23
|
stop_pool,
|
22
24
|
fetch_devices,
|
23
25
|
fetch_resources,
|
@@ -57,7 +59,9 @@ def pool_create(request: CreatePoolRequest):
|
|
57
59
|
num_gpus=request.num_gpus,
|
58
60
|
node_name=request.node_name,
|
59
61
|
only_registered_users=request.only_registered_users,
|
60
|
-
location=request.location
|
62
|
+
location=request.location,
|
63
|
+
description=request.description,
|
64
|
+
token_mode=request.token_mode
|
61
65
|
)
|
62
66
|
return result
|
63
67
|
|
@@ -108,14 +112,18 @@ def device_uncordon(request: NodesActionRequest):
|
|
108
112
|
return result
|
109
113
|
|
110
114
|
@app.get("/get_pool_token")
|
111
|
-
def
|
115
|
+
def get_token(mode: int):
|
112
116
|
|
113
117
|
return get_pool_token(mode=TokenType(mode))
|
114
118
|
|
115
119
|
@app.get("/fetch_devices")
|
116
|
-
def
|
120
|
+
def get_devices():
|
117
121
|
return fetch_devices()
|
118
122
|
|
123
|
+
@app.post("/send_pool_invites")
|
124
|
+
def send_pool_invites(request: InvitesRequest):
|
125
|
+
return send_invites(invitees=request.invitees)
|
126
|
+
|
119
127
|
@app.get("/fetch_resources")
|
120
128
|
def resources():
|
121
129
|
return fetch_resources()
|
kalavai_client/bridge_models.py
CHANGED
@@ -1,8 +1,11 @@
|
|
1
1
|
from pydantic import BaseModel
|
2
2
|
|
3
|
-
from kalavai_client.core import Job
|
3
|
+
from kalavai_client.core import Job, TokenType
|
4
4
|
|
5
5
|
|
6
|
+
class InvitesRequest(BaseModel):
|
7
|
+
invitees: list[str]
|
8
|
+
|
6
9
|
class CreatePoolRequest(BaseModel):
|
7
10
|
cluster_name: str
|
8
11
|
ip_address: str
|
@@ -11,6 +14,8 @@ class CreatePoolRequest(BaseModel):
|
|
11
14
|
node_name: str = None
|
12
15
|
only_registered_users: bool = False
|
13
16
|
location: str = None
|
17
|
+
token_mode: TokenType = TokenType.USER
|
18
|
+
description: str = ""
|
14
19
|
|
15
20
|
class NodesActionRequest(BaseModel):
|
16
21
|
nodes: list[str]
|
kalavai_client/cli.py
CHANGED
@@ -51,12 +51,15 @@ from kalavai_client.core import (
|
|
51
51
|
create_pool,
|
52
52
|
get_ip_addresses,
|
53
53
|
pause_agent,
|
54
|
+
register_pool,
|
54
55
|
resume_agent,
|
55
56
|
get_pool_token,
|
56
57
|
delete_nodes,
|
57
58
|
cordon_nodes,
|
59
|
+
stop_pool,
|
58
60
|
uncordon_nodes,
|
59
|
-
TokenType
|
61
|
+
TokenType,
|
62
|
+
unregister_pool
|
60
63
|
)
|
61
64
|
from kalavai_client.utils import (
|
62
65
|
check_gpu_drivers,
|
@@ -286,7 +289,7 @@ def location__list(*others):
|
|
286
289
|
console.log(table)
|
287
290
|
|
288
291
|
@arguably.command
|
289
|
-
def pool__publish(*others, description=None):
|
292
|
+
def pool__publish(*others, description=None, is_private=True):
|
290
293
|
"""
|
291
294
|
[AUTH] Publish pool to Kalavai platform, where other users may be able to join
|
292
295
|
"""
|
@@ -300,26 +303,29 @@ def pool__publish(*others, description=None):
|
|
300
303
|
console.log(f"[red]Problems with your pool: {str(e)}")
|
301
304
|
return
|
302
305
|
choices = select_token_type()
|
303
|
-
|
306
|
+
if choices["admin"]:
|
307
|
+
mode = TokenType.ADMIN
|
308
|
+
elif choices["user"]:
|
309
|
+
mode = TokenType.USER
|
310
|
+
else:
|
311
|
+
mode = TokenType.WORKER
|
304
312
|
|
305
313
|
if description is None:
|
306
314
|
console.log("[yellow] [Markdown] In a few words (max 500 chars), describe your goals with this cluster. Remember, this is what other users will see to decide whether to share their resources with you, [blue]so inspire them!")
|
307
|
-
description = input(f"(You can edit this later
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
console.log(f"[green]Your cluster is now
|
321
|
-
except Exception as e:
|
322
|
-
console.log(f"[red]Error when publishing cluster. {str(e)}")
|
315
|
+
description = input(f"(You can edit this later at {KALAVAI_PLATFORM_URL}\n")
|
316
|
+
cluster_name = load_server_info(data_key=CLUSTER_NAME_KEY, file=USER_LOCAL_SERVER_FILE)
|
317
|
+
|
318
|
+
result = register_pool(
|
319
|
+
cluster_name=cluster_name,
|
320
|
+
token_mode=mode,
|
321
|
+
description=description,
|
322
|
+
is_private=is_private
|
323
|
+
)
|
324
|
+
|
325
|
+
if "error" in result:
|
326
|
+
console.log(f"[red]Error when publishing cluster: {result['error']}")
|
327
|
+
else:
|
328
|
+
console.log(f"[green]Your cluster is now registered with {KALAVAI_PLATFORM_URL}")
|
323
329
|
|
324
330
|
@arguably.command
|
325
331
|
def pool__unpublish(cluster_name=None, *others):
|
@@ -335,15 +341,13 @@ def pool__unpublish(cluster_name=None, *others):
|
|
335
341
|
console.log(f"[red]Problems with your pool: {str(e)}")
|
336
342
|
return
|
337
343
|
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
+
result = unregister_pool()
|
345
|
+
if "error" in result:
|
346
|
+
console.log(f"[red]{result['error']}")
|
347
|
+
elif "warning" in result:
|
348
|
+
console.log(f"[yellow]{result['warning']}")
|
349
|
+
else:
|
344
350
|
console.log(f"[green]Your cluster has been removed from {KALAVAI_PLATFORM_URL}")
|
345
|
-
except Exception as e:
|
346
|
-
console.log(f"[red]Error when unpublishing cluster. {str(e)}")
|
347
351
|
|
348
352
|
@arguably.command
|
349
353
|
def pool__list(*others, user_only=False):
|
@@ -411,6 +415,9 @@ def pool__start(cluster_name, *others, only_registered_users: bool=False, ip_ad
|
|
411
415
|
location=location
|
412
416
|
)
|
413
417
|
|
418
|
+
if "warning" in result:
|
419
|
+
console.log(f"[yellow]Warning: {result['warning']}")
|
420
|
+
|
414
421
|
if "error" in result:
|
415
422
|
console.log(f"[red]{result}")
|
416
423
|
|
@@ -520,38 +527,13 @@ def pool__stop(*others, skip_node_deletion=False):
|
|
520
527
|
*others: all the other positional arguments go here
|
521
528
|
"""
|
522
529
|
console.log("[white] Stopping kalavai app...")
|
523
|
-
# delete local node from server
|
524
|
-
if not skip_node_deletion:
|
525
|
-
node__delete(load_server_info(data_key=NODE_NAME_KEY, file=USER_LOCAL_SERVER_FILE))
|
526
|
-
# unpublish event (only if seed node)
|
527
|
-
# TODO: no, this should be done via the platform!!!
|
528
|
-
# try:
|
529
|
-
# if CLUSTER.is_seed_node():
|
530
|
-
# console.log("Unregistering pool...")
|
531
|
-
# unregister_cluster(
|
532
|
-
# name=load_server_info(data_key=CLUSTER_NAME_KEY, file=USER_LOCAL_SERVER_FILE),
|
533
|
-
# user_cookie=USER_COOKIE)
|
534
|
-
# except Exception as e:
|
535
|
-
# console.log(f"[red][WARNING]: (ignore if not a public pool) Error when unpublishing cluster. {str(e)}")
|
536
|
-
# remove local node agent
|
537
|
-
console.log("Removing agent and local cache")
|
538
|
-
|
539
|
-
# disconnect from VPN first, then remove agent, then remove local files
|
540
|
-
console.log("Disconnecting from VPN...")
|
541
|
-
try:
|
542
|
-
vpns = leave_vpn(container_name=DEFAULT_VPN_CONTAINER_NAME)
|
543
|
-
if vpns is not None:
|
544
|
-
for vpn in vpns:
|
545
|
-
console.log(f"You have left {vpn} VPN")
|
546
|
-
except:
|
547
|
-
# no vpn
|
548
|
-
pass
|
549
530
|
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
531
|
+
result = stop_pool(skip_node_deletion=skip_node_deletion)
|
532
|
+
if "error" in result:
|
533
|
+
console.log(f"[red]{result['error']}")
|
534
|
+
else:
|
535
|
+
console.log(result)
|
536
|
+
console.log("[white] Kalavai has stopped sharing your resources. Use [yellow]kalavai pool start[white] or [yellow]kalavai pool join[white] to start again!")
|
555
537
|
|
556
538
|
@arguably.command
|
557
539
|
def pool__pause(*others):
|
kalavai_client/core.py
CHANGED
@@ -9,15 +9,19 @@ import netifaces as ni
|
|
9
9
|
from typing import Optional
|
10
10
|
from pydantic import BaseModel
|
11
11
|
from enum import Enum
|
12
|
+
import re
|
12
13
|
|
13
14
|
from kalavai_client.cluster import CLUSTER
|
14
15
|
from kalavai_client.utils import (
|
15
16
|
check_gpu_drivers,
|
16
17
|
generate_join_token,
|
18
|
+
register_cluster,
|
17
19
|
request_to_server,
|
18
20
|
load_server_info,
|
19
21
|
decode_dict,
|
20
22
|
get_vpn_details,
|
23
|
+
send_pool_invite,
|
24
|
+
unregister_cluster,
|
21
25
|
validate_join_public_seed,
|
22
26
|
generate_compose_config,
|
23
27
|
store_server_info,
|
@@ -703,7 +707,7 @@ def join_pool(token, num_gpus=None, node_name=None, ip_address=None):
|
|
703
707
|
|
704
708
|
return cluster_name
|
705
709
|
|
706
|
-
def create_pool(cluster_name: str, ip_address: str, app_values: str=None, pool_config_values: str=None, num_gpus: int=0, node_name: str=None, only_registered_users: bool=False, location: str=None):
|
710
|
+
def create_pool(cluster_name: str, ip_address: str, description: str="", token_mode: TokenType=TokenType.USER, app_values: str=None, pool_config_values: str=None, num_gpus: int=0, node_name: str=None, only_registered_users: bool=False, location: str=None):
|
707
711
|
|
708
712
|
if not check_seed_compatibility():
|
709
713
|
return {"error": "Requirements failed"}
|
@@ -829,6 +833,18 @@ def create_pool(cluster_name: str, ip_address: str, app_values: str=None, pool_c
|
|
829
833
|
# init user namespace
|
830
834
|
init_user_workspace()
|
831
835
|
|
836
|
+
# register cluster (if user is logged in)
|
837
|
+
result = register_pool(
|
838
|
+
cluster_name=cluster_name,
|
839
|
+
description=description,
|
840
|
+
is_private=True,
|
841
|
+
token_mode=token_mode)
|
842
|
+
|
843
|
+
if "error" in result:
|
844
|
+
return {"warning": result["error"]}
|
845
|
+
if "warning" in result:
|
846
|
+
return {"warning": result["warning"]}
|
847
|
+
|
832
848
|
return {"success"}
|
833
849
|
|
834
850
|
def get_pool_token(mode: TokenType):
|
@@ -887,6 +903,33 @@ def pool_init(pool_config_values_path=None):
|
|
887
903
|
return result
|
888
904
|
except Exception as e:
|
889
905
|
return {"error": f"[red]Error when connecting to kalavai service: {str(e)}"}
|
906
|
+
|
907
|
+
def register_pool(cluster_name, description, is_private=True, token_mode=TokenType.USER):
|
908
|
+
token = get_pool_token(mode=token_mode)["token"]
|
909
|
+
valid = check_token(token=token, public=not is_private)
|
910
|
+
if "error" in valid:
|
911
|
+
return {"error": valid}
|
912
|
+
try:
|
913
|
+
result = register_cluster(
|
914
|
+
name=cluster_name,
|
915
|
+
token=token,
|
916
|
+
description=description,
|
917
|
+
user_cookie=USER_COOKIE,
|
918
|
+
is_private=is_private)
|
919
|
+
|
920
|
+
return {"success": result}
|
921
|
+
except Exception as e:
|
922
|
+
return {"warning": str(e)}
|
923
|
+
|
924
|
+
def unregister_pool():
|
925
|
+
cluster_name = load_server_info(data_key=CLUSTER_NAME_KEY, file=USER_LOCAL_SERVER_FILE)
|
926
|
+
try:
|
927
|
+
unregister_cluster(
|
928
|
+
name=cluster_name,
|
929
|
+
user_cookie=USER_COOKIE)
|
930
|
+
except Exception as e:
|
931
|
+
return {"warning": str(e)}
|
932
|
+
return {"success"}
|
890
933
|
|
891
934
|
def is_connected():
|
892
935
|
if not os.path.isfile(USER_LOCAL_SERVER_FILE):
|
@@ -957,16 +1000,8 @@ def stop_pool(skip_node_deletion=False):
|
|
957
1000
|
delete_node(load_server_info(data_key=NODE_NAME_KEY, file=USER_LOCAL_SERVER_FILE))
|
958
1001
|
)
|
959
1002
|
# unpublish event (only if seed node)
|
960
|
-
|
961
|
-
|
962
|
-
# if CLUSTER.is_seed_node():
|
963
|
-
# console.log("Unregistering pool...")
|
964
|
-
# unregister_cluster(
|
965
|
-
# name=load_server_info(data_key=CLUSTER_NAME_KEY, file=USER_LOCAL_SERVER_FILE),
|
966
|
-
# user_cookie=USER_COOKIE)
|
967
|
-
# except Exception as e:
|
968
|
-
# console.log(f"[red][WARNING]: (ignore if not a public pool) Error when unpublishing cluster. {str(e)}")
|
969
|
-
# remove local node agent
|
1003
|
+
if CLUSTER.is_seed_node():
|
1004
|
+
unregister_pool()
|
970
1005
|
|
971
1006
|
# disconnect from VPN first, then remove agent, then remove local files
|
972
1007
|
try:
|
@@ -978,13 +1013,22 @@ def stop_pool(skip_node_deletion=False):
|
|
978
1013
|
# no vpn
|
979
1014
|
pass
|
980
1015
|
|
1016
|
+
# remove local node agent
|
981
1017
|
CLUSTER.remove_agent()
|
982
1018
|
|
983
1019
|
# clean local files
|
984
1020
|
cleanup_local()
|
985
1021
|
|
986
|
-
return logs
|
1022
|
+
return {"logs": logs}
|
987
1023
|
|
988
1024
|
def list_available_pools(user_only=False):
|
989
1025
|
pools = get_public_seeds(user_only=user_only, user_cookie=USER_COOKIE)
|
990
|
-
return pools
|
1026
|
+
return pools
|
1027
|
+
|
1028
|
+
def send_invites(invitees):
|
1029
|
+
result = send_pool_invite(
|
1030
|
+
cluster_name=load_server_info(data_key=CLUSTER_NAME_KEY, file=USER_LOCAL_SERVER_FILE),
|
1031
|
+
invitee_addresses=invitees,
|
1032
|
+
user_cookie=USER_COOKIE
|
1033
|
+
)
|
1034
|
+
return result
|
kalavai_client/utils.py
CHANGED
@@ -206,7 +206,7 @@ def get_vpn_details(location, user_cookie):
|
|
206
206
|
)
|
207
207
|
return vpn
|
208
208
|
|
209
|
-
def register_cluster(name, token, description, user_cookie):
|
209
|
+
def register_cluster(name, token, description, user_cookie, is_private=True):
|
210
210
|
auth = KalavaiAuthClient(
|
211
211
|
user_cookie_file=user_cookie
|
212
212
|
)
|
@@ -218,7 +218,8 @@ def register_cluster(name, token, description, user_cookie):
|
|
218
218
|
name,
|
219
219
|
user,
|
220
220
|
description,
|
221
|
-
token
|
221
|
+
token,
|
222
|
+
is_private
|
222
223
|
)
|
223
224
|
return seed
|
224
225
|
|
@@ -251,6 +252,21 @@ def validate_join_public_seed(cluster_name, join_key, user_cookie):
|
|
251
252
|
)
|
252
253
|
return seed
|
253
254
|
|
255
|
+
def send_pool_invite(cluster_name, invitee_addresses, user_cookie):
|
256
|
+
auth = KalavaiAuthClient(
|
257
|
+
user_cookie_file=user_cookie
|
258
|
+
)
|
259
|
+
if not auth.is_logged_in():
|
260
|
+
raise ValueError("Cannot notify join cluster, user is not authenticated")
|
261
|
+
user = auth.load_user_session()
|
262
|
+
result = auth.call_function(
|
263
|
+
"send_pool_invite",
|
264
|
+
user,
|
265
|
+
cluster_name,
|
266
|
+
invitee_addresses
|
267
|
+
)
|
268
|
+
return result
|
269
|
+
|
254
270
|
def validate_poolconfig(poolconfig_file):
|
255
271
|
if not Path(poolconfig_file).is_file():
|
256
272
|
return False
|
@@ -1,4 +1,4 @@
|
|
1
|
-
kalavai_client/__init__.py,sha256=
|
1
|
+
kalavai_client/__init__.py,sha256=Wek6gRlCzMJXNHhlUntIAj24wWPV3k64gGvcy5WL7rU,23
|
2
2
|
kalavai_client/__main__.py,sha256=WQUfxvRsBJH5gsCJg8pLz95QnZIj7Ol8psTO77m0QE0,73
|
3
3
|
kalavai_client/assets/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
4
4
|
kalavai_client/assets/apps.yaml,sha256=d13TzkWtqdwpWOxuoG7eG0Jp0UhVUsboS28496H8iH4,5982
|
@@ -11,15 +11,15 @@ kalavai_client/assets/pool_config_values.yaml,sha256=VrM3XHQfQo6QLZ68qvagooUptaY
|
|
11
11
|
kalavai_client/assets/user_workspace.yaml,sha256=wDvlMYknOPABAEo0dsQwU7bac8iubjAG9tdkFbJZ5Go,476
|
12
12
|
kalavai_client/assets/user_workspace_values.yaml,sha256=G0HOzQUxrDMCwuW9kbWUZaKMzDDPVwDwzBHCL2Xi2ZM,542
|
13
13
|
kalavai_client/auth.py,sha256=QsBh28L2LwjBBK6pTUE4Xu36lLDTyetyU1YfS1Hbb6g,1717
|
14
|
-
kalavai_client/bridge_api.py,sha256=
|
15
|
-
kalavai_client/bridge_models.py,sha256=
|
16
|
-
kalavai_client/cli.py,sha256=
|
14
|
+
kalavai_client/bridge_api.py,sha256=rXTz6WpzQtsDmBDUUOqPEjWx8vfiIWEfvP1iM4MYDGM,5501
|
15
|
+
kalavai_client/bridge_models.py,sha256=WwGIaWBIk4s32YemgDB2CcrrCWC-KeZjTT3iBi-kaa0,936
|
16
|
+
kalavai_client/cli.py,sha256=zQ205vqPW69oEt9EAO5wC8_yEvWbFEtLUnI90Oqt4t4,46642
|
17
17
|
kalavai_client/cluster.py,sha256=gwjmdsd--YrffT0BmZDOEpbrdm3lPskUuN5jdgcrOR0,12947
|
18
|
-
kalavai_client/core.py,sha256=
|
18
|
+
kalavai_client/core.py,sha256=Trv2DDdlBAsBYUaTKnosWrfboYRrZnRcv-jfvmG7-LU,32288
|
19
19
|
kalavai_client/env.py,sha256=Zg2pP-xGJpQumo56KMBxBLgIsBmcNN0S9R-ZP2-s630,2604
|
20
|
-
kalavai_client/utils.py,sha256=
|
21
|
-
kalavai_client-0.5.
|
22
|
-
kalavai_client-0.5.
|
23
|
-
kalavai_client-0.5.
|
24
|
-
kalavai_client-0.5.
|
25
|
-
kalavai_client-0.5.
|
20
|
+
kalavai_client/utils.py,sha256=OPmrsycNyrs2ZpTsjAzBuPN8hQNJtsYDLPKU13tnf-U,13862
|
21
|
+
kalavai_client-0.5.27.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
22
|
+
kalavai_client-0.5.27.dist-info/METADATA,sha256=5-vseYyG7Ya57UyFAqdEabXKGoFrzTMRnJgPb6FRZ6Q,14443
|
23
|
+
kalavai_client-0.5.27.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
|
24
|
+
kalavai_client-0.5.27.dist-info/entry_points.txt,sha256=9T6D45gxwzfVbglMm1r6XPdXuuZdHfy_7fCeu2jUphc,50
|
25
|
+
kalavai_client-0.5.27.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|