sunholo 0.60.4__py3-none-any.whl → 0.60.7__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.
sunholo/cli/chat_vac.py CHANGED
@@ -6,6 +6,9 @@ from ..utils.config import load_config_key
6
6
  from .run_proxy import clean_proxy_list, start_proxy, stop_proxy
7
7
 
8
8
  import uuid
9
+ import sys
10
+ import subprocess
11
+ import json
9
12
 
10
13
  from rich import print
11
14
  from .sun_rich import console
@@ -13,6 +16,7 @@ from .sun_rich import console
13
16
  from rich.prompt import Prompt
14
17
  from rich.panel import Panel
15
18
  from rich.text import Text
19
+ from rich.table import Table
16
20
 
17
21
 
18
22
  def get_service_url(vac_name, project, region):
@@ -27,9 +31,8 @@ def get_service_url(vac_name, project, region):
27
31
 
28
32
  return url
29
33
 
30
- def stream_chat_session(service_name, project, region):
34
+ def stream_chat_session(service_url, service_name):
31
35
 
32
- service_url = get_service_url(service_name, project, region)
33
36
  user_id = generate_user_id()
34
37
  chat_history = []
35
38
  while True:
@@ -90,10 +93,9 @@ def stream_chat_session(service_name, project, region):
90
93
  console.print()
91
94
  console.rule()
92
95
 
93
- def headless_mode(service_name, user_input, project, region, chat_history=None):
96
+ def headless_mode(service_url, service_name, user_input, chat_history=None):
94
97
  chat_history = chat_history or []
95
98
 
96
- service_url = get_service_url(service_name, project, region)
97
99
  user_id = generate_user_id()
98
100
  session_id = str(uuid.uuid4())
99
101
 
@@ -143,34 +145,132 @@ def headless_mode(service_name, user_input, project, region, chat_history=None):
143
145
 
144
146
 
145
147
  def vac_command(args):
146
- try:
147
- service_url = get_service_url(args.vac_name, args.project, args.region)
148
- except ValueError as e:
149
- console.print(f"[bold red]ERROR: Could not start {args.vac_name} proxy URL: {str(e)}[/bold red]")
148
+ if args.action == 'list':
149
+ list_cloud_run_services(args.project, args.region)
150
150
  return
151
-
152
- agent_name = load_config_key("agent", args.vac_name, kind="vacConfig")
151
+ elif args.action == 'get-url':
152
+ service_url = get_cloud_run_service_url(args.project, args.region, args.vac_name)
153
+ if service_url:
154
+ console.print(service_url)
155
+ return
156
+ elif args.action == 'chat':
153
157
 
154
- if args.headless:
155
- headless_mode(args.vac_name, args.user_input, args.project, args.region, args.chat_history)
156
- stop_proxy(agent_name)
157
- else:
158
- display_name = load_config_key("display_name", vector_name=args.vac_name, kind="vacConfig")
159
- description = load_config_key("description", vector_name=args.vac_name, kind="vacConfig")
158
+ if not args.no_proxy:
159
+ try:
160
+ service_url = get_service_url(args.vac_name, args.project, args.region)
161
+ except ValueError as e:
162
+ console.print(f"[bold red]ERROR: Could not start {args.vac_name} proxy URL: {str(e)}[/bold red]")
163
+ sys.exit(1)
164
+ else:
165
+ service_url = get_cloud_run_service_url(args.project, args.region, args.vac_name)
166
+ console.print(f"Not using a proxy, connecting directly to {service_url}")
167
+
168
+ agent_name = load_config_key("agent", args.vac_name, kind="vacConfig")
160
169
 
161
- if agent_name == "langserve":
162
- subtitle = f"{service_url}/{args.vac_name}/playground/"
170
+ if args.headless:
171
+ headless_mode(service_url, args.vac_name, args.user_input, args.chat_history)
163
172
  else:
164
- subtitle = f"{agent_name} - {service_url}/vac/{args.vac_name}"
173
+ display_name = load_config_key("display_name", vector_name=args.vac_name, kind="vacConfig")
174
+ description = load_config_key("description", vector_name=args.vac_name, kind="vacConfig")
175
+
176
+ if agent_name == "langserve":
177
+ subtitle = f"{service_url}/{args.vac_name}/playground/"
178
+ else:
179
+ subtitle = f"{agent_name} - {service_url}/vac/{args.vac_name}"
165
180
 
166
- print(
167
- Panel(description or "Starting VAC chat session",
168
- title=display_name or args.vac_name,
169
- subtitle=subtitle)
170
- )
181
+ print(
182
+ Panel(description or "Starting VAC chat session",
183
+ title=display_name or args.vac_name,
184
+ subtitle=subtitle)
185
+ )
171
186
 
172
- stream_chat_session(args.vac_name, args.project, args.region)
187
+ stream_chat_session(service_url, args.vac_name)
188
+
173
189
  stop_proxy(agent_name)
190
+
191
+
192
+ def list_cloud_run_services(project, region):
193
+ """
194
+ Lists all Cloud Run services the user has access to in a specific project and region.
195
+
196
+ Args:
197
+ project (str): The GCP project ID.
198
+ region (str): The region of the Cloud Run services.
199
+ """
200
+
201
+ # point or star?
202
+ with console.status("[bold orange]Listing Cloud Run Services[/bold orange]", spinner="star") as status:
203
+ try:
204
+ result = subprocess.run(
205
+ ["gcloud", "run", "services", "list", "--project", project, "--region", region, "--format=json"],
206
+ stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=30
207
+ )
208
+ if result.returncode != 0:
209
+ status.stop()
210
+ console.print(f"[bold red]ERROR: Unable to list Cloud Run services: {result.stderr.decode()}[/bold red]")
211
+ return
212
+
213
+ services = json.loads(result.stdout.decode())
214
+ if not services:
215
+ status.stop()
216
+ console.print("[bold red]No Cloud Run services found.[/bold red]")
217
+ return
218
+
219
+ proxies = clean_proxy_list()
220
+ status.stop()
221
+
222
+ table = Table(title="VAC Cloud Run Services")
223
+ table.add_column("Service Name")
224
+ table.add_column("Region")
225
+ table.add_column("URL")
226
+ table.add_column("Proxied")
227
+ table.add_column("Port")
228
+
229
+ for service in services:
230
+ service_name = service['metadata']['name']
231
+ service_url = service['status']['url']
232
+ if service_name in proxies:
233
+ proxied = "Yes"
234
+ proxy_port = proxies[service_name]['port']
235
+ else:
236
+ proxied = "No"
237
+ proxy_port = "-"
238
+ table.add_row(service_name, region, service_url, proxied, str(proxy_port))
239
+
240
+ console.print(table)
241
+ except Exception as e:
242
+ status.stop()
243
+ console.print(f"[bold red]ERROR: An unexpected error occurred: {e}[/bold red]")
244
+
245
+
246
+ def get_cloud_run_service_url(project, region, service_name):
247
+ """
248
+ Retrieves the URL of a specific Cloud Run service in a given project and region.
249
+
250
+ Args:
251
+ project (str): The GCP project ID.
252
+ region (str): The region of the Cloud Run service.
253
+ service_name (str): The name of the Cloud Run service.
254
+
255
+ Returns:
256
+ str: The URL of the Cloud Run service, or an error message if not found.
257
+ """
258
+ try:
259
+ result = subprocess.run(
260
+ ["gcloud", "run", "services", "describe", service_name, "--project", project, "--region", region, "--format=json"],
261
+ stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=30
262
+ )
263
+ if result.returncode != 0:
264
+ console.print(f"[bold red]ERROR: Unable to get Cloud Run service URL: {result.stderr.decode()}[/bold red]")
265
+ return None
266
+
267
+ service = json.loads(result.stdout.decode())
268
+ service_url = service['status']['url']
269
+ return service_url
270
+ except Exception as e:
271
+ console.print(f"[bold red]ERROR: An unexpected error occurred: {e}[/bold red]")
272
+ return None
273
+
174
274
 
175
275
 
176
276
  def setup_vac_subparser(subparsers):
@@ -181,8 +281,21 @@ def setup_vac_subparser(subparsers):
181
281
  subparsers: The subparsers object from argparse.ArgumentParser().
182
282
  """
183
283
  vac_parser = subparsers.add_parser('vac', help='Interact with deployed VAC services.')
184
- vac_parser.add_argument('vac_name', help='Name of the VAC service.')
185
- vac_parser.add_argument('user_input', help='User input for the VAC service when in headless mode.', nargs='?', default=None)
186
- vac_parser.add_argument('--headless', action='store_true', help='Run in headless mode.')
187
- vac_parser.add_argument('--chat_history', help='Chat history for headless mode (as JSON string).', default=None)
284
+ vac_subparsers = vac_parser.add_subparsers(dest='action', help='VAC subcommands')
285
+
286
+ # Subcommand for listing VAC services
287
+ list_parser = vac_subparsers.add_parser('list', help='List all VAC services.')
288
+
289
+ # Subcommand for getting the URL of a specific VAC service
290
+ get_url_parser = vac_subparsers.add_parser('get-url', help='Get the URL of a specific VAC service.')
291
+ get_url_parser.add_argument('vac_name', help='Name of the VAC service.')
292
+
293
+ # Subcommand for interacting with a VAC service
294
+ chat_parser = vac_subparsers.add_parser('chat', help='Interact with a VAC service.')
295
+ chat_parser.add_argument('vac_name', help='Name of the VAC service.')
296
+ chat_parser.add_argument('user_input', help='User input for the VAC service when in headless mode.', nargs='?', default=None)
297
+ chat_parser.add_argument('--headless', action='store_true', help='Run in headless mode.')
298
+ chat_parser.add_argument('--chat_history', help='Chat history for headless mode (as JSON string).', default=None)
299
+ chat_parser.add_argument('--no_proxy', action='store_true', help='Do not use the proxy and connect directly to the VAC service.')
300
+
188
301
  vac_parser.set_defaults(func=vac_command)
sunholo/cli/run_proxy.py CHANGED
@@ -109,7 +109,7 @@ def start_proxy(service_name, region, project, port=None):
109
109
  proxies = clean_proxy_list()
110
110
 
111
111
  if service_name in proxies:
112
- print(f"Proxy for service {service_name} is already running on port {proxies[service_name]['port']}.")
112
+ console.print(f"Proxy for service [bold orange]'{service_name}'[/bold orange] is already running on port {proxies[service_name]['port']}.")
113
113
  return
114
114
 
115
115
  if not port:
@@ -130,7 +130,7 @@ def start_proxy(service_name, region, project, port=None):
130
130
  }
131
131
  save_proxies(proxies)
132
132
 
133
- print(f"Proxy for {service_name} setup complete on port {port}")
133
+ console.print(f"Proxy for [bold orange]'{service_name}'[/bold orange] setup complete on port {port}")
134
134
  list_proxies()
135
135
 
136
136
  return f"http://127.0.0.1:{port}"
@@ -154,11 +154,11 @@ def stop_proxy(service_name):
154
154
  os.kill(pid, signal.SIGTERM)
155
155
  del proxies[service_name]
156
156
  save_proxies(proxies)
157
- print(f"Proxy for {service_name} stopped.")
157
+ console.print(f"Proxy for [bold orange]'{service_name}'[bold orange] stopped.")
158
158
  except ProcessLookupError:
159
- print(f"No process found with PID: {pid}")
159
+ console.print(f"No process found with PID: {pid}")
160
160
  except Exception as e:
161
- print(f"Error stopping proxy for {service_name}: {e}")
161
+ console.print(f"[bold red]Error stopping proxy for {service_name}: {e}[/bold red]")
162
162
 
163
163
  list_proxies()
164
164
 
@@ -172,69 +172,16 @@ def stop_all_proxies():
172
172
  pid = info["pid"]
173
173
  try:
174
174
  os.kill(pid, signal.SIGTERM)
175
- print(f"Proxy for {service_name} stopped.")
175
+ print(f"Proxy for [bold orange]'{service_name}'[/bold orange] stopped.")
176
176
  except ProcessLookupError:
177
177
  print(f"No process found with PID: {pid}")
178
178
  except Exception as e:
179
- print(f"Error stopping proxy for {service_name}: {e}")
179
+ print(f"Error stopping proxy for [bold orange]'{service_name}'[/bold orange]: {e}")
180
180
 
181
181
  save_proxies({})
182
182
 
183
183
  list_proxies()
184
184
 
185
- def list_cloud_run_services(project, region):
186
- """
187
- Lists all Cloud Run services the user has access to in a specific project and region.
188
-
189
- Args:
190
- project (str): The GCP project ID.
191
- region (str): The region of the Cloud Run services.
192
- """
193
-
194
- # point or star?
195
- with console.status("[bold orange]Listing Cloud Run Services[/bold orange]", spinner="star") as status:
196
- try:
197
- result = subprocess.run(
198
- ["gcloud", "run", "services", "list", "--project", project, "--region", region, "--format=json"],
199
- stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=30
200
- )
201
- if result.returncode != 0:
202
- status.stop()
203
- console.print(f"[bold red]ERROR: Unable to list Cloud Run services: {result.stderr.decode()}[/bold red]")
204
- return
205
-
206
- services = json.loads(result.stdout.decode())
207
- if not services:
208
- status.stop()
209
- console.print("[bold red]No Cloud Run services found.[/bold red]")
210
- return
211
-
212
- proxies = clean_proxy_list()
213
- status.stop()
214
-
215
- table = Table(title="VAC Cloud Run Services")
216
- table.add_column("Service Name")
217
- table.add_column("Region")
218
- table.add_column("URL")
219
- table.add_column("Proxied")
220
- table.add_column("Port")
221
-
222
- for service in services:
223
- service_name = service['metadata']['name']
224
- service_url = service['status']['url']
225
- if service_name in proxies:
226
- proxied = "Yes"
227
- proxy_port = proxies[service_name]['port']
228
- else:
229
- proxied = "No"
230
- proxy_port = "-"
231
- table.add_row(service_name, region, service_url, proxied, str(proxy_port))
232
-
233
- console.print(table)
234
- except Exception as e:
235
- status.stop()
236
- console.print(f"[bold red]ERROR: An unexpected error occurred: {e}[/bold red]")
237
-
238
185
  def list_proxies():
239
186
  """
240
187
  Lists all running proxies.
@@ -283,7 +230,5 @@ def setup_proxy_subparser(subparsers):
283
230
  stop_all_parser = proxy_subparsers.add_parser('stop-all', help='Stop all running proxies.')
284
231
  stop_all_parser.set_defaults(func=lambda args: stop_all_proxies())
285
232
 
286
- list_services_parser = proxy_subparsers.add_parser('list-vacs', help='List all Cloud Run VAC services.')
287
- list_services_parser.set_defaults(func=lambda args: list_cloud_run_services(args.project, args.region))
288
233
 
289
234
 
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: sunholo
3
- Version: 0.60.4
3
+ Version: 0.60.7
4
4
  Summary: Large Language Model DevOps - a package to help deploy LLMs to the Cloud.
5
5
  Home-page: https://github.com/sunholo-data/sunholo-py
6
- Download-URL: https://github.com/sunholo-data/sunholo-py/archive/refs/tags/v0.60.4.tar.gz
6
+ Download-URL: https://github.com/sunholo-data/sunholo-py/archive/refs/tags/v0.60.7.tar.gz
7
7
  Author: Holosun ApS
8
8
  Author-email: multivac@sunholo.com
9
9
  License: Apache License, Version 2.0
@@ -32,13 +32,13 @@ sunholo/chunker/pdfs.py,sha256=daCZ1xjn1YvxlifIyxskWNpLJLe-Q9D_Jq12MWx3tZo,2473
32
32
  sunholo/chunker/publish.py,sha256=PoT8q3XJeFCg10WrLkYhuaaXIrGVkvUD3-R9IfoWoH4,2703
33
33
  sunholo/chunker/splitter.py,sha256=FLkDhkePkg_zGQpFBK13Cznw575D-Rf9pcaCpc1HUxY,6726
34
34
  sunholo/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
35
- sunholo/cli/chat_vac.py,sha256=038AkvGDEK5cBWqQTRrTQYCsa1FDWzZGHaHOyrS2lFE,6841
35
+ sunholo/cli/chat_vac.py,sha256=8iSda-K3w0zHLrMkjck919kVgM5vJNrLAbEj0zKVIKw,11361
36
36
  sunholo/cli/cli.py,sha256=LWA5OveHx3ocy9KD1XwAwosBFrTUwifArIbltYgpul4,2420
37
37
  sunholo/cli/cli_init.py,sha256=JMZ9AX2cPDZ-_mv3adiv2ToFVNyRPtjk9Biszl1kiR0,2358
38
38
  sunholo/cli/configs.py,sha256=QUM9DvKOdZmEQRM5uI3Nh887T0YDiSMr7O240zTLqws,4546
39
39
  sunholo/cli/deploy.py,sha256=zxdwUsRTRMC8U5vyRv0JiKBLFn84Ug_Tc88-_h9hJSs,1609
40
40
  sunholo/cli/merge_texts.py,sha256=U9vdMwKmcPoc6iPOWX5MKSxn49dNGbNzVLw8ui5PhEU,1823
41
- sunholo/cli/run_proxy.py,sha256=kYi3LnMdi27IqzA-k37WyT8AnFifn5ePP7jNK-8UmhE,9694
41
+ sunholo/cli/run_proxy.py,sha256=53bRzm6IVf5SB07fiwqKpJrGQBTt3xAWi-669w6VYSU,7591
42
42
  sunholo/cli/sun_rich.py,sha256=UpMqeJ0C8i0pkue1AHnnyyX0bFJ9zZeJ7HBR6yhuA8A,54
43
43
  sunholo/components/__init__.py,sha256=RJGNEihwvRIiDScKis04RHJv4yZGI1UpXlOmuCptNZI,208
44
44
  sunholo/components/llm.py,sha256=T4we3tGmqUj4tPwxQr9M6AXv_BALqZV_dRSvINan-oU,10374
@@ -96,9 +96,9 @@ sunholo/utils/parsers.py,sha256=OrHmASqIbI45atVOhiGodgLvnfrzkvVzyHnSvAXD89I,3841
96
96
  sunholo/utils/user_ids.py,sha256=SQd5_H7FE7vcTZp9AQuQDWBXd4FEEd7TeVMQe1H4Ny8,292
97
97
  sunholo/vertex/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
98
98
  sunholo/vertex/init_vertex.py,sha256=JDMUaBRdednzbKF-5p33qqLit2LMsvgvWW-NRz0AqO0,1801
99
- sunholo-0.60.4.dist-info/LICENSE.txt,sha256=SdE3QjnD3GEmqqg9EX3TM9f7WmtOzqS1KJve8rhbYmU,11345
100
- sunholo-0.60.4.dist-info/METADATA,sha256=nHPHNqcRw2WAX2guIAM0QXFVcQLx3FzlB024g-jfK4k,8057
101
- sunholo-0.60.4.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
102
- sunholo-0.60.4.dist-info/entry_points.txt,sha256=bZuN5AIHingMPt4Ro1b_T-FnQvZ3teBes-3OyO0asl4,49
103
- sunholo-0.60.4.dist-info/top_level.txt,sha256=wt5tadn5--5JrZsjJz2LceoUvcrIvxjHJe-RxuudxAk,8
104
- sunholo-0.60.4.dist-info/RECORD,,
99
+ sunholo-0.60.7.dist-info/LICENSE.txt,sha256=SdE3QjnD3GEmqqg9EX3TM9f7WmtOzqS1KJve8rhbYmU,11345
100
+ sunholo-0.60.7.dist-info/METADATA,sha256=UqURElBg2H6zB4MKBSBwTktG2AeeClFUcGVVr_BPSW4,8057
101
+ sunholo-0.60.7.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
102
+ sunholo-0.60.7.dist-info/entry_points.txt,sha256=bZuN5AIHingMPt4Ro1b_T-FnQvZ3teBes-3OyO0asl4,49
103
+ sunholo-0.60.7.dist-info/top_level.txt,sha256=wt5tadn5--5JrZsjJz2LceoUvcrIvxjHJe-RxuudxAk,8
104
+ sunholo-0.60.7.dist-info/RECORD,,