sunholo 0.76.5__py3-none-any.whl → 0.76.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/auth/run.py CHANGED
@@ -66,12 +66,12 @@ def get_cloud_run_token(vector_name):
66
66
  }
67
67
  log.info(f"Authenticating for run_url {run_url} from {caller_frame.f_code.co_name}")
68
68
  id_token = get_id_token(run_url)
69
-
69
+ #log.info(f"id_token {id_token}")
70
70
  return id_token
71
71
 
72
72
  def get_header(vector_name) -> Optional[dict]:
73
73
  id_token = get_cloud_run_token(vector_name)
74
-
74
+
75
75
  headers = {"Authorization": f"Bearer {id_token}"}
76
- #log.info(f"id_token {id_token}")
76
+
77
77
  return headers
@@ -12,9 +12,10 @@ def process_azure_blob_event(events: list) -> tuple:
12
12
  tuple: A tuple containing the blob URL, attributes as metadata, and the vector name.
13
13
 
14
14
  Example of Event Grid schema:
15
+ ```
15
16
  {
16
- "topic": "/subscriptions/{subscription-id}/resourceGroups/{resource-group}/providers/Microsoft.Storage/storageAccounts/{storage-account}",
17
- "subject": "/blobServices/default/containers/{container}/blobs/{blob}",
17
+ "topic": "/subscriptions/subscription-id/resourceGroups/resource-group/providers/Microsoft.Storage/storageAccounts/storage-account",
18
+ "subject": "/blobServices/default/containers/container/blobs/blob",
18
19
  "eventType": "Microsoft.Storage.BlobCreated",
19
20
  "eventTime": "2021-01-01T12:34:56.789Z",
20
21
  "id": "event-id",
@@ -26,8 +27,8 @@ def process_azure_blob_event(events: list) -> tuple:
26
27
  "contentType": "application/octet-stream",
27
28
  "contentLength": 524288,
28
29
  "blobType": "BlockBlob",
29
- "url": "https://{storage-account}.blob.core.windows.net/{container}/{blob}",
30
- "sequencer": "0000000000000000000000000000000000000000000000000000000000000000",
30
+ "url": "https://storage-account.blob.core.windows.net/container/blob",
31
+ "sequencer": "0000000000000000000000000",
31
32
  "storageDiagnostics": {
32
33
  "batchId": "batch-id"
33
34
  }
@@ -35,6 +36,7 @@ def process_azure_blob_event(events: list) -> tuple:
35
36
  "dataVersion": "",
36
37
  "metadataVersion": "1"
37
38
  }
39
+ ```
38
40
  """
39
41
  storage_blob_created_event = "Microsoft.Storage.BlobCreated"
40
42
 
sunholo/cli/vertex.py CHANGED
@@ -12,15 +12,14 @@ def deploy_extension(args):
12
12
  tool_example_file=args.tool_example_file,
13
13
  open_api_file=args.open_api_file,
14
14
  service_account=args.service_account,
15
- project_id=args.project,
16
15
  bucket_name=args.bucket_name
17
16
  )
18
- extensions = vex.list_extensions(args.project)
17
+ extensions = vex.list_extensions()
19
18
  console.print(extensions)
20
19
 
21
20
  def list_extensions(args):
22
- vex = VertexAIExtensions()
23
- extensions = vex.list_extensions(args.project)
21
+ vex = VertexAIExtensions(args.project)
22
+ extensions = vex.list_extensions()
24
23
  console.print(extensions)
25
24
 
26
25
  def setup_vertex_subparser(subparsers):
@@ -7,6 +7,7 @@ from .init import init_vertex
7
7
  from ..logging import log
8
8
  from ..utils.gcp_project import get_gcp_project
9
9
  from ..utils.parsers import validate_extension_id
10
+ from ..utils.gcp import is_running_on_cloudrun
10
11
  from ..auth import get_local_gcloud_token, get_cloud_run_token
11
12
  import base64
12
13
  import json
@@ -19,7 +20,7 @@ class VertexAIExtensions:
19
20
 
20
21
  ```python
21
22
  from sunholo.vertex import VertexAIExtensions
22
- vex = VertexAIExtensions()
23
+ vex = VertexAIExtensions(project_id='your-project')
23
24
  vex.list_extensions()
24
25
  # [{'resource_name': 'projects/374404277595/locations/us-central1/extensions/770924776838397952',
25
26
  # 'display_name': 'Code Interpreter',
@@ -53,7 +54,7 @@ class VertexAIExtensions:
53
54
  """
54
55
  def __init__(self, project_id=None):
55
56
  if extensions is None:
56
- raise ImportError("VertexAIExtensions needs vertexai.previewextensions to be installed. Install via `pip install sunholo[gcp]`")
57
+ raise ImportError("VertexAIExtensions needs vertexai.preview extensions to be installed. Install via `pip install sunholo'[gcp]'`")
57
58
 
58
59
  self.CODE_INTERPRETER_WRITTEN_FILES = []
59
60
  self.css_styles = """
@@ -71,12 +72,13 @@ class VertexAIExtensions:
71
72
  self.manifest = {}
72
73
  self.created_extensions = []
73
74
  self.bucket_name = os.getenv('EXTENSIONS_BUCKET')
74
- init_vertex(location=self.location, project_id=project_id)
75
+ self.project_id = project_id or get_gcp_project()
76
+ self.access_token = None
77
+ init_vertex(location=self.location, project_id=self.project_id)
75
78
 
76
- def list_extensions(self, project_id:str=None):
77
- project_id = project_id or get_gcp_project()
78
- log.info(f"Creating extension within {project_id=}")
79
- the_list = extensions.Extension.list(project=project_id)
79
+ def list_extensions(self):
80
+ log.info(f"Creating extension within {self.project_id=}")
81
+ the_list = extensions.Extension.list(project=self.project_id)
80
82
 
81
83
  extensions_list = []
82
84
  for ext in the_list:
@@ -109,12 +111,25 @@ class VertexAIExtensions:
109
111
 
110
112
  return self_uri
111
113
 
112
- def upload_openapi_file(self, filename: str):
114
+ def upload_openapi_file(self, filename: str, vac:str=None):
115
+ if vac:
116
+ from ..agents.route import route_vac
117
+ import yaml
118
+
119
+ new_url = route_vac(vac)
120
+
121
+ log.info(f'Overwriting extension URL with VAC url for {vac=} - {new_url=}')
122
+
123
+ openapi = yaml.safe_load(filename)
124
+
125
+ openapi['servers'][0]['url'] = new_url
126
+ with open(filename, 'w') as file:
127
+ yaml.dump(openapi, file, sort_keys=False)
128
+
113
129
  self.validate_openapi(filename)
114
130
  if not self.bucket_name:
115
131
  raise ValueError('Please specify env var EXTENSIONS_BUCKET for location to upload openapi spec')
116
132
 
117
-
118
133
  self.openapi_file_gcs = self.upload_to_gcs(filename)
119
134
 
120
135
  def load_tool_use_examples(self, filename: str):
@@ -126,21 +141,25 @@ class VertexAIExtensions:
126
141
  # google.cloud.aiplatform_v1beta1.types.ToolUseExample
127
142
  return self.tool_use_examples
128
143
 
144
+ def get_auth_token(self):
145
+ from google.auth import default
146
+ from google.auth.transport.requests import Request
147
+
148
+ credentials, project_id = default()
149
+ credentials.refresh(Request())
150
+ self.access_token = credentials.token
151
+
152
+ return self.access_token
129
153
 
130
154
  def update_tool_use_examples_via_patch(self):
131
155
  import requests
132
156
  import json
133
- from google.auth import default
134
- from google.auth.transport.requests import Request
135
157
 
136
158
  extension = self.created_extension
137
159
  if extension is None:
138
160
  raise ValueError("Need to create the extension first")
139
161
 
140
- # Get the access token using Google authentication
141
- credentials, project_id = default()
142
- credentials.refresh(Request())
143
- access_token = credentials.token
162
+ self.get_auth_token()
144
163
 
145
164
  ENDPOINT=f"{self.location}-aiplatform.googleapis.com"
146
165
  URL=f"https://{ENDPOINT}/v1beta1"
@@ -151,7 +170,7 @@ class VertexAIExtensions:
151
170
  url = f"{URL}/{extension_id}"
152
171
  log.info(f"PATCH {url}")
153
172
  headers = {
154
- "Authorization": f"Bearer {access_token}",
173
+ "Authorization": f"Bearer {self.access_token}",
155
174
  "Content-Type": "application/json"
156
175
  }
157
176
 
@@ -202,25 +221,24 @@ class VertexAIExtensions:
202
221
  tool_example_file: str = None,
203
222
  runtime_config: dict = None,
204
223
  service_account: str = None,
205
- project_id: str = None,
206
- bucket_name: str = None):
224
+ bucket_name: str = None,
225
+ vac: str = None):
207
226
 
208
- project_id = project_id or get_gcp_project()
209
- log.info(f"Creating extension within {project_id=}")
210
- extension_name = f"projects/{project_id}/locations/us-central1/extensions/{validate_extension_id(display_name)}"
227
+ log.info(f"Creating extension within {self.project_id=}")
228
+ extension_name = f"projects/{self.project_id}/locations/us-central1/extensions/{validate_extension_id(display_name)}"
211
229
 
212
230
  if bucket_name:
213
231
  log.info(f"Setting extension bucket name to {bucket_name}")
214
232
  self.bucket_name = bucket_name
215
233
 
216
- listed_extensions = self.list_extensions(project_id)
234
+ listed_extensions = self.list_extensions()
217
235
  log.info(f"Listing extensions:\n {listed_extensions}")
218
236
  for ext in listed_extensions:
219
237
  if ext.get('display_name') == display_name:
220
238
  raise NameError(f"display_name {display_name} already exists. Delete it or rename your new extension")
221
239
 
222
240
  if open_api_file:
223
- self.upload_openapi_file(open_api_file)
241
+ self.upload_openapi_file(open_api_file, vac)
224
242
 
225
243
  manifest = self.create_extension_manifest(
226
244
  display_name,
@@ -254,48 +272,49 @@ class VertexAIExtensions:
254
272
  operation_id: str,
255
273
  operation_params: dict,
256
274
  extension_id: str=None,
257
- project_id: str=None,
275
+ extension_display_name: str=None,
258
276
  vac: str=None):
259
-
260
- init_vertex(location=self.location, project_id=project_id)
261
277
 
262
- if not extension_id:
263
- extension_name = self.created_extension.resource_name
264
- if extension_name is None:
265
- raise ValueError("Must specify extension_id or init one with class")
266
- else:
278
+ if extension_display_name:
279
+ extensions = self.list_extensions()
280
+ for extension in extensions:
281
+ if extension.get('display_name') == extension_display_name:
282
+ log.info(f"Found extension_id for '{extension_display_name}'")
283
+ extension_id = extension['resource_name']
284
+ break
285
+
286
+ if extension_id:
267
287
  extension_id = str(extension_id)
268
288
  if not extension_id.startswith("projects/"):
269
- project_id = project_id or get_gcp_project()
270
- extension_name = f"projects/{project_id}/locations/{self.location}/extensions/{extension_id}"
289
+ extension_name = f"projects/{self.project_id}/locations/{self.location}/extensions/{extension_id}"
271
290
  else:
272
291
  extension_name = extension_id
292
+ else:
293
+ extension_name = self.created_extension.resource_name
294
+ if not extension_name:
295
+ raise ValueError("Must specify extension_id or extension_name - both were None")
273
296
 
274
297
  extension = extensions.Extension(extension_name)
275
298
 
276
- log.info(f"Executing extension {extension_name=} with {operation_id=} and {operation_params=}")
277
-
278
- # local testing auth
279
- from ..utils.gcp import is_running_on_cloudrun
280
- auth_config=None # on cloud run it sorts itself out via default creds(?)
281
-
299
+ auth_config=None
282
300
  if not is_running_on_cloudrun():
283
301
 
284
302
  log.warning("Using local authentication via gcloud")
285
303
  auth_config = {
286
304
  "authType": "OAUTH",
287
- "oauth_config": {"access_token": f"'{get_local_gcloud_token()}'"}
305
+ "oauth_config": {"access_token": f"{get_local_gcloud_token()}"}
288
306
  }
289
307
  elif vac:
290
308
  log.info(f"Using authentication via Cloud Run via {vac=}")
291
309
 
292
310
  auth_config = {
293
311
  "authType": "OAUTH",
294
- "oauth_config": {"access_token": f"'{get_cloud_run_token(vac)}'"}
312
+ "oauth_config": {"access_token": f"{get_cloud_run_token(vac)}"}
295
313
  }
296
314
  else:
297
315
  log.warning("No vac configuration and not running locally so no authentication being set for this extension API call")
298
316
 
317
+ log.info(f"Executing extension {extension_name=} with {operation_id=} and {operation_params=}")
299
318
  response = extension.execute(
300
319
  operation_id=operation_id,
301
320
  operation_params=operation_params,
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: sunholo
3
- Version: 0.76.5
3
+ Version: 0.76.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.76.5.tar.gz
6
+ Download-URL: https://github.com/sunholo-data/sunholo-py/archive/refs/tags/v0.76.7.tar.gz
7
7
  Author: Holosun ApS
8
8
  Author-email: multivac@sunholo.com
9
9
  License: Apache License, Version 2.0
@@ -20,9 +20,9 @@ sunholo/archive/archive.py,sha256=C-UhG5x-XtZ8VheQp92IYJqgD0V3NFQjniqlit94t18,11
20
20
  sunholo/auth/__init__.py,sha256=TeP-OY0XGxYV_8AQcVGoh35bvyWhNUcMRfhuD5l44Sk,91
21
21
  sunholo/auth/gcloud.py,sha256=PdbwkuTdRi4RKBmgG9uwsReegqC4VG15_tw5uzmA7Fs,298
22
22
  sunholo/auth/refresh.py,sha256=uOdT7oQRVl0YsUP__NXj6PdUdLyXFSv2ylwF283esuw,1831
23
- sunholo/auth/run.py,sha256=TMuJrgHKm_4Tu9GafX844LNjDwOFfbEJRr7ve7H87kg,2724
23
+ sunholo/auth/run.py,sha256=3f2VKjIPePWz7o5EPetXF7JBCr-FNk9lOPJ-2qNTk0I,2724
24
24
  sunholo/azure/__init__.py,sha256=S1WQ5jndzNgzhSBh9UpX_yw7hRVm3hCzkAWNxUdK4dA,48
25
- sunholo/azure/event_grid.py,sha256=Gky7D5a-xxMzbcst_wOFfcI8AH5qOzWbKbt5iqOTr6U,2606
25
+ sunholo/azure/event_grid.py,sha256=uXunwdjVLxNRf38aTRPoC9HXxFEFlL8JH9dijaOlF8M,2567
26
26
  sunholo/bots/__init__.py,sha256=EMFd7e2z68l6pzYOnkzHbLd2xJRvxTKFRNCTuhZ8hIw,130
27
27
  sunholo/bots/discord.py,sha256=cCFae5K1BCa6JVkWGLh_iZ9qFO1JpXb6K4eJrlDfEro,2442
28
28
  sunholo/bots/github_webhook.py,sha256=5pQPRLM_wxxcILVaIzUDV8Kt7Arcm2dL1r1kMMHA524,9629
@@ -49,7 +49,7 @@ sunholo/cli/merge_texts.py,sha256=U9vdMwKmcPoc6iPOWX5MKSxn49dNGbNzVLw8ui5PhEU,18
49
49
  sunholo/cli/run_proxy.py,sha256=OeR12ZfnasbJ-smBZQznmGufoDa4iNjUN9FCFo5JxSc,11520
50
50
  sunholo/cli/sun_rich.py,sha256=UpMqeJ0C8i0pkue1AHnnyyX0bFJ9zZeJ7HBR6yhuA8A,54
51
51
  sunholo/cli/swagger.py,sha256=absYKAU-7Yd2eiVNUY-g_WLl2zJfeRUNdWQ0oH8M_HM,1564
52
- sunholo/cli/vertex.py,sha256=yN1ezeiweV1UIBZYvDYgtyMS0dXH374rYMxVVHid9UY,2101
52
+ sunholo/cli/vertex.py,sha256=8130YCarxHL1UC3aqblNmUwGZTXbkdL4Y_FOnZJsWiI,2056
53
53
  sunholo/components/__init__.py,sha256=IDoylb74zFKo6NIS3RQqUl0PDFBGVxM1dfUmO7OJ44U,176
54
54
  sunholo/components/llm.py,sha256=T4we3tGmqUj4tPwxQr9M6AXv_BALqZV_dRSvINan-oU,10374
55
55
  sunholo/components/retriever.py,sha256=BFUw_6turT3CQJZWv_uXylmH5fHdb0gKfKJrQ_j6MGY,6533
@@ -120,13 +120,13 @@ sunholo/utils/timedelta.py,sha256=BbLabEx7_rbErj_YbNM0MBcaFN76DC4PTe4zD2ucezg,49
120
120
  sunholo/utils/user_ids.py,sha256=SQd5_H7FE7vcTZp9AQuQDWBXd4FEEd7TeVMQe1H4Ny8,292
121
121
  sunholo/utils/version.py,sha256=P1QAJQdZfT2cMqdTSmXmcxrD2PssMPEGM-WI6083Fck,237
122
122
  sunholo/vertex/__init__.py,sha256=XH7FUKxdIgN9H2iDcWxL3sRnVHC3297G24RqEn4Ob0Y,240
123
- sunholo/vertex/extensions_class.py,sha256=TsPU3N-peHTrP3ObMdyfi3wiYKrcpcCY56GurcXsOFU,18345
123
+ sunholo/vertex/extensions_class.py,sha256=UARBnhOmxuqRGX3ooWrJujMXc0iKtx1HkCTnK0VEJmY,19006
124
124
  sunholo/vertex/init.py,sha256=aLdNjrX3bUPfnWRhKUg5KUxSu0Qnq2YvuFNsgml4QEY,2866
125
125
  sunholo/vertex/memory_tools.py,sha256=pomHrDKqvY8MZxfUqoEwhdlpCvSGP6KmFJMVKOimXjs,6842
126
126
  sunholo/vertex/safety.py,sha256=S9PgQT1O_BQAkcqauWncRJaydiP8Q_Jzmu9gxYfy1VA,2482
127
- sunholo-0.76.5.dist-info/LICENSE.txt,sha256=SdE3QjnD3GEmqqg9EX3TM9f7WmtOzqS1KJve8rhbYmU,11345
128
- sunholo-0.76.5.dist-info/METADATA,sha256=2R-hFbzaL8QjpAGtqR5iAtM7fD82_98tWT92vUU1FdY,7136
129
- sunholo-0.76.5.dist-info/WHEEL,sha256=Z4pYXqR_rTB7OWNDYFOm1qRk0RX6GFP2o8LgvP453Hk,91
130
- sunholo-0.76.5.dist-info/entry_points.txt,sha256=bZuN5AIHingMPt4Ro1b_T-FnQvZ3teBes-3OyO0asl4,49
131
- sunholo-0.76.5.dist-info/top_level.txt,sha256=wt5tadn5--5JrZsjJz2LceoUvcrIvxjHJe-RxuudxAk,8
132
- sunholo-0.76.5.dist-info/RECORD,,
127
+ sunholo-0.76.7.dist-info/LICENSE.txt,sha256=SdE3QjnD3GEmqqg9EX3TM9f7WmtOzqS1KJve8rhbYmU,11345
128
+ sunholo-0.76.7.dist-info/METADATA,sha256=CpUNghG6Y3R7SvzGvB-Mr4HVcMxh_H4fI8phNUs5SSw,7136
129
+ sunholo-0.76.7.dist-info/WHEEL,sha256=Z4pYXqR_rTB7OWNDYFOm1qRk0RX6GFP2o8LgvP453Hk,91
130
+ sunholo-0.76.7.dist-info/entry_points.txt,sha256=bZuN5AIHingMPt4Ro1b_T-FnQvZ3teBes-3OyO0asl4,49
131
+ sunholo-0.76.7.dist-info/top_level.txt,sha256=wt5tadn5--5JrZsjJz2LceoUvcrIvxjHJe-RxuudxAk,8
132
+ sunholo-0.76.7.dist-info/RECORD,,