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.
@@ -1,2 +1,2 @@
1
1
 
2
- __version__ = "0.5.26"
2
+ __version__ = "0.5.27"
@@ -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 devices(mode: int):
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 devices():
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()
@@ -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
- token = pool__token(**choices)["token"]
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 in {KALAVAI_PLATFORM_URL}\n")
308
-
309
- try:
310
- valid = check_token(token=token, public=True)
311
- if "error" in valid:
312
- raise ValueError(f"[red]Cluster must be started with a valid vpn_location to publish: {valid}")
313
- cluster_name = load_server_info(data_key=CLUSTER_NAME_KEY, file=USER_LOCAL_SERVER_FILE)
314
-
315
- register_cluster(
316
- name=cluster_name,
317
- token=token,
318
- description=description,
319
- user_cookie=USER_COOKIE)
320
- console.log(f"[green]Your cluster is now public on {KALAVAI_PLATFORM_URL}")
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
- try:
339
- if cluster_name is None:
340
- cluster_name = load_server_info(data_key=CLUSTER_NAME_KEY, file=USER_LOCAL_SERVER_FILE)
341
- unregister_cluster(
342
- name=cluster_name,
343
- user_cookie=USER_COOKIE)
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
- CLUSTER.remove_agent()
551
-
552
- # clean local files
553
- cleanup_local()
554
- console.log("[white] Kalavai has stopped sharing your resources. Use [yellow]kalavai pool start[white] or [yellow]kalavai pool join[white] to start again!")
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
- # TODO: no, this should be done via the platform!!!
961
- # try:
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,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: kalavai-client
3
- Version: 0.5.26
3
+ Version: 0.5.27
4
4
  Summary: Client app for kalavai platform
5
5
  License: Apache-2.0
6
6
  Keywords: LLM,platform
@@ -1,4 +1,4 @@
1
- kalavai_client/__init__.py,sha256=yEQn5h7HJ9p7TIniys_VwtONGK1a_jUSpvxigYZe4PI,23
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=vhkwgVOm0ZoKVz1dr-SGPQ7uMp-XPdhyzLJfKI2nsuc,5245
15
- kalavai_client/bridge_models.py,sha256=mEDdqUcK9BtijLpNo20HXuYdVccn4895hPzejSv666A,798
16
- kalavai_client/cli.py,sha256=U6Z4ESwV0L2jnKmpzEC4fKTcmrlYo4K0k9kSwUeiWL4,47700
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=fhKRW5EAFwKUFdswgcuEzbSpyHAfIOrGkyghq04ckj8,31078
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=rz5W9PRZrTpgdmOs6yeqUi4f_q_L-3BJ5g1o7Asgnyo,13386
21
- kalavai_client-0.5.26.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
22
- kalavai_client-0.5.26.dist-info/METADATA,sha256=XlK_eljvXmKS6L2-XtvPzAuwCG6bVHZGPFEBifAOjlE,14443
23
- kalavai_client-0.5.26.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
24
- kalavai_client-0.5.26.dist-info/entry_points.txt,sha256=9T6D45gxwzfVbglMm1r6XPdXuuZdHfy_7fCeu2jUphc,50
25
- kalavai_client-0.5.26.dist-info/RECORD,,
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,,