sunholo 0.60.5__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
@@ -7,6 +7,8 @@ from .run_proxy import clean_proxy_list, start_proxy, stop_proxy
7
7
 
8
8
  import uuid
9
9
  import sys
10
+ import subprocess
11
+ import json
10
12
 
11
13
  from rich import print
12
14
  from .sun_rich import console
@@ -14,6 +16,7 @@ from .sun_rich import console
14
16
  from rich.prompt import Prompt
15
17
  from rich.panel import Panel
16
18
  from rich.text import Text
19
+ from rich.table import Table
17
20
 
18
21
 
19
22
  def get_service_url(vac_name, project, region):
@@ -28,9 +31,8 @@ def get_service_url(vac_name, project, region):
28
31
 
29
32
  return url
30
33
 
31
- def stream_chat_session(service_name, project, region):
34
+ def stream_chat_session(service_url, service_name):
32
35
 
33
- service_url = get_service_url(service_name, project, region)
34
36
  user_id = generate_user_id()
35
37
  chat_history = []
36
38
  while True:
@@ -91,10 +93,9 @@ def stream_chat_session(service_name, project, region):
91
93
  console.print()
92
94
  console.rule()
93
95
 
94
- 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):
95
97
  chat_history = chat_history or []
96
98
 
97
- service_url = get_service_url(service_name, project, region)
98
99
  user_id = generate_user_id()
99
100
  session_id = str(uuid.uuid4())
100
101
 
@@ -144,34 +145,132 @@ def headless_mode(service_name, user_input, project, region, chat_history=None):
144
145
 
145
146
 
146
147
  def vac_command(args):
147
- try:
148
- service_url = get_service_url(args.vac_name, args.project, args.region)
149
- except ValueError as e:
150
- console.print(f"[bold red]ERROR: Could not start {args.vac_name} proxy URL: {str(e)}[/bold red]")
151
- sys.exit(1)
152
-
153
- agent_name = load_config_key("agent", args.vac_name, kind="vacConfig")
148
+ if args.action == 'list':
149
+ list_cloud_run_services(args.project, args.region)
150
+ return
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':
154
157
 
155
- if args.headless:
156
- headless_mode(args.vac_name, args.user_input, args.project, args.region, args.chat_history)
157
- stop_proxy(agent_name)
158
- else:
159
- display_name = load_config_key("display_name", vector_name=args.vac_name, kind="vacConfig")
160
- 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")
161
169
 
162
- if agent_name == "langserve":
163
- 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)
164
172
  else:
165
- 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}"
166
180
 
167
- print(
168
- Panel(description or "Starting VAC chat session",
169
- title=display_name or args.vac_name,
170
- subtitle=subtitle)
171
- )
181
+ print(
182
+ Panel(description or "Starting VAC chat session",
183
+ title=display_name or args.vac_name,
184
+ subtitle=subtitle)
185
+ )
172
186
 
173
- stream_chat_session(args.vac_name, args.project, args.region)
187
+ stream_chat_session(service_url, args.vac_name)
188
+
174
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
+
175
274
 
176
275
 
177
276
  def setup_vac_subparser(subparsers):
@@ -182,8 +281,21 @@ def setup_vac_subparser(subparsers):
182
281
  subparsers: The subparsers object from argparse.ArgumentParser().
183
282
  """
184
283
  vac_parser = subparsers.add_parser('vac', help='Interact with deployed VAC services.')
185
- vac_parser.add_argument('vac_name', help='Name of the VAC service.')
186
- vac_parser.add_argument('user_input', help='User input for the VAC service when in headless mode.', nargs='?', default=None)
187
- vac_parser.add_argument('--headless', action='store_true', help='Run in headless mode.')
188
- 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
+
189
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.5
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.5.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=0ta0uXsGJQlUHrSiMY7wbUp9AaljLJA5R8xDIF2isgk,6857
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.5.dist-info/LICENSE.txt,sha256=SdE3QjnD3GEmqqg9EX3TM9f7WmtOzqS1KJve8rhbYmU,11345
100
- sunholo-0.60.5.dist-info/METADATA,sha256=bYtLnWZBwnj6r_Nzbc6TqFANw0lZuv9OCk4eldL_RZQ,8057
101
- sunholo-0.60.5.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
102
- sunholo-0.60.5.dist-info/entry_points.txt,sha256=bZuN5AIHingMPt4Ro1b_T-FnQvZ3teBes-3OyO0asl4,49
103
- sunholo-0.60.5.dist-info/top_level.txt,sha256=wt5tadn5--5JrZsjJz2LceoUvcrIvxjHJe-RxuudxAk,8
104
- sunholo-0.60.5.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,,