sunholo 0.61.0__tar.gz → 0.61.5__tar.gz

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.
Files changed (113) hide show
  1. {sunholo-0.61.0 → sunholo-0.61.5}/PKG-INFO +2 -2
  2. {sunholo-0.61.0 → sunholo-0.61.5}/setup.py +1 -1
  3. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/agents/chat_history.py +1 -1
  4. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/cli/chat_vac.py +59 -15
  5. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/components/vectorstore.py +1 -1
  6. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/utils/config.py +6 -17
  7. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo.egg-info/PKG-INFO +2 -2
  8. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo.egg-info/SOURCES.txt +0 -1
  9. sunholo-0.61.5/tests/test_config.py +11 -0
  10. sunholo-0.61.0/test/test_dispatch_to_qa.py +0 -73
  11. sunholo-0.61.0/tests/test_config.py +0 -40
  12. {sunholo-0.61.0 → sunholo-0.61.5}/LICENSE.txt +0 -0
  13. {sunholo-0.61.0 → sunholo-0.61.5}/MANIFEST.in +0 -0
  14. {sunholo-0.61.0 → sunholo-0.61.5}/README.md +0 -0
  15. {sunholo-0.61.0 → sunholo-0.61.5}/setup.cfg +0 -0
  16. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/__init__.py +0 -0
  17. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/agents/__init__.py +0 -0
  18. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/agents/dispatch_to_qa.py +0 -0
  19. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/agents/fastapi/__init__.py +0 -0
  20. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/agents/fastapi/base.py +0 -0
  21. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/agents/fastapi/qna_routes.py +0 -0
  22. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/agents/flask/__init__.py +0 -0
  23. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/agents/flask/base.py +0 -0
  24. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/agents/flask/qna_routes.py +0 -0
  25. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/agents/langserve.py +0 -0
  26. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/agents/pubsub.py +0 -0
  27. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/agents/route.py +0 -0
  28. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/agents/special_commands.py +0 -0
  29. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/archive/__init__.py +0 -0
  30. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/archive/archive.py +0 -0
  31. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/auth/__init__.py +0 -0
  32. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/auth/run.py +0 -0
  33. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/bots/__init__.py +0 -0
  34. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/bots/discord.py +0 -0
  35. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/bots/github_webhook.py +0 -0
  36. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/bots/webapp.py +0 -0
  37. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/chunker/__init__.py +0 -0
  38. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/chunker/data_to_embed_pubsub.py +0 -0
  39. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/chunker/doc_handling.py +0 -0
  40. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/chunker/images.py +0 -0
  41. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/chunker/loaders.py +0 -0
  42. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/chunker/message_data.py +0 -0
  43. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/chunker/pdfs.py +0 -0
  44. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/chunker/publish.py +0 -0
  45. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/chunker/splitter.py +0 -0
  46. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/cli/__init__.py +0 -0
  47. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/cli/cli.py +0 -0
  48. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/cli/cli_init.py +0 -0
  49. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/cli/configs.py +0 -0
  50. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/cli/deploy.py +0 -0
  51. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/cli/merge_texts.py +0 -0
  52. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/cli/run_proxy.py +0 -0
  53. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/cli/sun_rich.py +0 -0
  54. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/components/__init__.py +0 -0
  55. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/components/llm.py +0 -0
  56. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/components/prompt.py +0 -0
  57. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/components/retriever.py +0 -0
  58. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/database/__init__.py +0 -0
  59. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/database/alloydb.py +0 -0
  60. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/database/database.py +0 -0
  61. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/database/lancedb.py +0 -0
  62. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/database/sql/sb/create_function.sql +0 -0
  63. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/database/sql/sb/create_function_time.sql +0 -0
  64. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/database/sql/sb/create_table.sql +0 -0
  65. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/database/sql/sb/delete_source_row.sql +0 -0
  66. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/database/sql/sb/return_sources.sql +0 -0
  67. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/database/sql/sb/setup.sql +0 -0
  68. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/database/static_dbs.py +0 -0
  69. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/database/uuid.py +0 -0
  70. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/embedder/__init__.py +0 -0
  71. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/embedder/embed_chunk.py +0 -0
  72. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/gcs/__init__.py +0 -0
  73. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/gcs/add_file.py +0 -0
  74. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/gcs/download_url.py +0 -0
  75. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/gcs/metadata.py +0 -0
  76. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/langfuse/__init__.py +0 -0
  77. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/langfuse/callback.py +0 -0
  78. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/langfuse/prompts.py +0 -0
  79. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/llamaindex/__init__.py +0 -0
  80. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/llamaindex/generate.py +0 -0
  81. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/llamaindex/import_files.py +0 -0
  82. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/logging.py +0 -0
  83. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/lookup/__init__.py +0 -0
  84. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/lookup/model_lookup.yaml +0 -0
  85. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/patches/__init__.py +0 -0
  86. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/patches/langchain/__init__.py +0 -0
  87. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/patches/langchain/lancedb.py +0 -0
  88. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/patches/langchain/vertexai.py +0 -0
  89. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/pubsub/__init__.py +0 -0
  90. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/pubsub/process_pubsub.py +0 -0
  91. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/pubsub/pubsub_manager.py +0 -0
  92. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/qna/__init__.py +0 -0
  93. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/qna/parsers.py +0 -0
  94. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/qna/retry.py +0 -0
  95. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/streaming/__init__.py +0 -0
  96. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/streaming/content_buffer.py +0 -0
  97. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/streaming/langserve.py +0 -0
  98. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/streaming/streaming.py +0 -0
  99. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/summarise/__init__.py +0 -0
  100. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/summarise/summarise.py +0 -0
  101. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/utils/__init__.py +0 -0
  102. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/utils/big_context.py +0 -0
  103. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/utils/config_schema.py +0 -0
  104. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/utils/gcp.py +0 -0
  105. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/utils/parsers.py +0 -0
  106. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/utils/user_ids.py +0 -0
  107. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/vertex/__init__.py +0 -0
  108. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo/vertex/init_vertex.py +0 -0
  109. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo.egg-info/dependency_links.txt +0 -0
  110. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo.egg-info/entry_points.txt +0 -0
  111. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo.egg-info/requires.txt +0 -0
  112. {sunholo-0.61.0 → sunholo-0.61.5}/sunholo.egg-info/top_level.txt +0 -0
  113. {sunholo-0.61.0 → sunholo-0.61.5}/tests/test_chat_history.py +0 -0
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: sunholo
3
- Version: 0.61.0
3
+ Version: 0.61.5
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.61.0.tar.gz
6
+ Download-URL: https://github.com/sunholo-data/sunholo-py/archive/refs/tags/v0.61.5.tar.gz
7
7
  Author: Holosun ApS
8
8
  Author-email: multivac@sunholo.com
9
9
  License: Apache License, Version 2.0
@@ -1,7 +1,7 @@
1
1
  from setuptools import setup, find_packages
2
2
 
3
3
  # Define your base version
4
- version = '0.61.0'
4
+ version = '0.61.5'
5
5
 
6
6
  setup(
7
7
  name='sunholo',
@@ -74,7 +74,7 @@ def embeds_to_json(message: dict):
74
74
  # Output: '[{"type": "image", "url": "https://example.com/image.png"}]'
75
75
  ```
76
76
  """
77
- if len(message['embeds'] > 0):
77
+ if 'embeds' in message and len(message['embeds']) > 0:
78
78
  return json.dumps(message.get("embeds"))
79
79
  else:
80
80
  return ""
@@ -9,6 +9,7 @@ import uuid
9
9
  import sys
10
10
  import subprocess
11
11
  import json
12
+ import requests
12
13
 
13
14
  from rich import print
14
15
  from .sun_rich import console
@@ -143,27 +144,46 @@ def headless_mode(service_url, service_name, user_input, chat_history=None):
143
144
 
144
145
  return chat_history
145
146
 
147
+ def resolve_service_url(args):
148
+
149
+ if args.url_override:
150
+
151
+ return args.url_override
152
+
153
+ if not args.no_proxy:
154
+ try:
155
+ service_url = get_service_url(args.vac_name, args.project, args.region)
156
+ except ValueError as e:
157
+ console.print(f"[bold red]ERROR: Could not start {args.vac_name} proxy URL: {str(e)}[/bold red]")
158
+ sys.exit(1)
159
+ else:
160
+ console.print(f"Not using a proxy, connecting directly to {service_url}")
161
+
162
+ agent_url = load_config_key("agent_url", args.vac_name, "vacConfig")
163
+ if agent_url:
164
+ console.print("Found agent_url within vacConfig: {agent_url}")
165
+
166
+ service_url = agent_url or get_cloud_run_service_url(args.project, args.region, args.vac_name)
167
+
168
+ return service_url
146
169
 
147
170
  def vac_command(args):
171
+
172
+ service_url = resolve_service_url(args)
173
+
148
174
  if args.action == 'list':
175
+
149
176
  list_cloud_run_services(args.project, args.region)
177
+
150
178
  return
179
+
151
180
  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':
157
181
 
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}")
182
+ console.print(service_url)
183
+
184
+ return
185
+
186
+ elif args.action == 'chat':
167
187
 
168
188
  agent_name = load_config_key("agent", args.vac_name, kind="vacConfig")
169
189
 
@@ -188,6 +208,24 @@ def vac_command(args):
188
208
 
189
209
  stop_proxy(agent_name, stop_local=False)
190
210
 
211
+ elif args.action == 'invoke':
212
+ try:
213
+ json_data = json.loads(args.data)
214
+ except json.JSONDecodeError as err:
215
+ console.print(f"[bold red]ERROR: invalid JSON: {str(err)} [/bold red]")
216
+ sys.exit(1)
217
+
218
+ invoke_vac(service_url, json_data)
219
+
220
+ def invoke_vac(service_url, data):
221
+ try:
222
+ headers = {"Content-Type": "application/json"}
223
+ response = requests.post(service_url, headers=headers, data=json.dumps(data))
224
+ response.raise_for_status()
225
+ print(response.json())
226
+ except requests.exceptions.RequestException as e:
227
+ console.print(f"[bold red]ERROR: Failed to invoke VAC: {e}[/bold red]")
228
+
191
229
 
192
230
  def list_cloud_run_services(project, region):
193
231
  """
@@ -281,6 +319,8 @@ def setup_vac_subparser(subparsers):
281
319
  subparsers: The subparsers object from argparse.ArgumentParser().
282
320
  """
283
321
  vac_parser = subparsers.add_parser('vac', help='Interact with deployed VAC services.')
322
+ vac_parser.add_argument('--url_override', help='Override the VAC service URL.')
323
+ vac_parser.add_argument('--no-proxy', action='store_true', help='Do not use the proxy and connect directly to the VAC service.')
284
324
  vac_subparsers = vac_parser.add_subparsers(dest='action', help='VAC subcommands')
285
325
 
286
326
  # Subcommand for listing VAC services
@@ -296,6 +336,10 @@ def setup_vac_subparser(subparsers):
296
336
  chat_parser.add_argument('user_input', help='User input for the VAC service when in headless mode.', nargs='?', default=None)
297
337
  chat_parser.add_argument('--headless', action='store_true', help='Run in headless mode.')
298
338
  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.')
339
+
340
+ # Subcommand for invoking a VAC service directly
341
+ invoke_parser = vac_subparsers.add_parser('invoke', help='Invoke a VAC service directly with custom data.')
342
+ invoke_parser.add_argument('vac_name', help='Name of the VAC service.')
343
+ invoke_parser.add_argument('data', help='Data to send to the VAC service (as JSON string).')
300
344
 
301
345
  vac_parser.set_defaults(func=vac_command)
@@ -45,7 +45,7 @@ def pick_vectorstore(vs_str, vector_name, embeddings, read_only=None):
45
45
  return vectorstore
46
46
 
47
47
  elif vs_str == 'cloudsql' or vs_str == 'postgres':
48
- from langchain.vectorstores.pgvector import PGVector
48
+ from langchain_community.vectorstores import PGVector
49
49
 
50
50
  log.debug("Inititaing CloudSQL/Postgres pgvector")
51
51
  #setup_cloudsql(vector_name)
@@ -75,7 +75,7 @@ def load_all_configs():
75
75
  if filename in config_cache:
76
76
  cached_config, cache_time = config_cache[filename]
77
77
  if (current_time - cache_time) < timedelta(minutes=5):
78
- log.info(f"Returning cached config for {filename}")
78
+ log.debug(f"Returning cached config for {filename}")
79
79
  config = cached_config
80
80
  else:
81
81
  config = reload_config_file(config_file, filename)
@@ -167,7 +167,7 @@ def load_config(filename: str=None) -> tuple[dict, str]:
167
167
 
168
168
  return config, filename
169
169
 
170
- def load_config_key(key: str, vector_name: str, kind: str=None):
170
+ def load_config_key(key: str, vector_name: str, kind: str):
171
171
  """
172
172
  Load a specific key from a configuration file.
173
173
 
@@ -192,27 +192,16 @@ def load_config_key(key: str, vector_name: str, kind: str=None):
192
192
 
193
193
  configs_by_kind = load_all_configs()
194
194
 
195
- if kind:
196
- log.debug(f"Got kind: {kind} - applying to configs")
195
+ log.debug(f"Got kind: {kind} - applying to configs")
197
196
 
198
197
  if not configs_by_kind:
199
198
  log.warning("Did not load configs via folder")
200
199
 
201
- if kind and configs_by_kind.get(kind):
202
- config = configs_by_kind[kind]
203
- filename = kind
204
- else:
205
- config, filename = load_config(filename)
200
+ config = configs_by_kind[kind]
206
201
 
207
- log.debug(f"Fetching '{key}' for '{vector_name}'")
208
202
  apiVersion = config.get('apiVersion')
209
- kind = config.get('kind')
210
- vac = config.get('vac')
211
203
 
212
- if not apiVersion or not kind:
213
- raise ValueError("Deprecated config file, move to config with `apiVersion` and `kind` set")
214
-
215
- log.debug(f"Loaded config file {kind}/{apiVersion}")
204
+ log.debug(f"Fetching '{key}' for '{vector_name}' from '{kind}/{apiVersion}'")
216
205
 
217
206
  if kind == 'vacConfig':
218
207
  if vector_name == 'global':
@@ -226,7 +215,7 @@ def load_config_key(key: str, vector_name: str, kind: str=None):
226
215
  raise ValueError("Deprecated config file, move to config with `vac:` at top level for `vector_name`")
227
216
  vac_config = vac.get(vector_name)
228
217
  if not vac_config:
229
- raise ValueError(f"No config array was found for {vector_name} in {filename}")
218
+ raise ValueError(f"No config array was found for {vector_name} in {kind}")
230
219
 
231
220
  log.debug(f'vac_config: {vac_config} for {vector_name} - fetching "{key}"')
232
221
  key_value = vac_config.get(key)
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: sunholo
3
- Version: 0.61.0
3
+ Version: 0.61.5
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.61.0.tar.gz
6
+ Download-URL: https://github.com/sunholo-data/sunholo-py/archive/refs/tags/v0.61.5.tar.gz
7
7
  Author: Holosun ApS
8
8
  Author-email: multivac@sunholo.com
9
9
  License: Apache License, Version 2.0
@@ -106,6 +106,5 @@ sunholo/utils/parsers.py
106
106
  sunholo/utils/user_ids.py
107
107
  sunholo/vertex/__init__.py
108
108
  sunholo/vertex/init_vertex.py
109
- test/test_dispatch_to_qa.py
110
109
  tests/test_chat_history.py
111
110
  tests/test_config.py
@@ -0,0 +1,11 @@
1
+ import pytest
2
+ from unittest.mock import patch, mock_open
3
+ from sunholo.utils import config
4
+
5
+ def test_load_config():
6
+ expected_config = {"key": "value"}
7
+ with pytest.raises(FileNotFoundError):
8
+ config.load_config("non_existent_file")
9
+ with patch("builtins.open", mock_open(read_data='{"key": "value"}'), create=True):
10
+ result, _ = config.load_config("mock_file.json")
11
+ assert result == expected_config
@@ -1,73 +0,0 @@
1
- import pytest
2
- import requests_mock
3
- from sunholo.agents import dispatch_to_qa
4
-
5
-
6
- def setup():
7
- user_input = 'mock_user_input'
8
- chat_history = 'mock_chat_history'
9
- vector_name = 'mock_vector_name'
10
- stream = 'mock_stream'
11
- return user_input, chat_history, vector_name, stream
12
-
13
-
14
- def test_prep_request_payload():
15
- user_input, chat_history, vector_name, stream = setup()
16
- # Call 'prep_request_payload' with the mock data
17
- qna_endpoint, qna_data = dispatch_to_qa.prep_request_payload(user_input, chat_history, vector_name, stream)
18
- # Check the returned 'qna_endpoint' and 'qna_data'
19
- assert qna_endpoint == 'expected_qna_endpoint'
20
- assert qna_data == 'expected_qna_data'
21
-
22
-
23
- def test_send_to_qa():
24
- user_input, chat_history, vector_name, stream = setup()
25
- mock_qna_endpoint = 'http://mock.qna.endpoint'
26
- mock_response = {'status': 'success'}
27
- with requests_mock.Mocker() as m:
28
- m.post(mock_qna_endpoint, json=mock_response)
29
- response = dispatch_to_qa.send_to_qa(user_input, chat_history, vector_name, stream)
30
- assert response == mock_response
31
-
32
- # Scenario where 'stream' is True and the response is a generator that yields response content chunks
33
- mock_response_chunk = 'mock_response_chunk'
34
- m.post(mock_qna_endpoint, text=mock_response_chunk)
35
- response = dispatch_to_qa.send_to_qa(user_input, chat_history, vector_name, True)
36
- assert next(response) == mock_response_chunk
37
-
38
- # Scenario where an HTTP error occurs
39
- m.post(mock_qna_endpoint, status_code=500)
40
- response = dispatch_to_qa.send_to_qa(user_input, chat_history, vector_name, stream)
41
- assert 'Error' in response
42
-
43
- # Scenario where any other error occurs
44
- m.post(mock_qna_endpoint, exc=requests_mock.exceptions.ReadTimeout)
45
- response = dispatch_to_qa.send_to_qa(user_input, chat_history, vector_name, stream)
46
- assert 'Error' in response
47
-
48
-
49
- def test_send_to_qa_async():
50
- user_input, chat_history, vector_name, stream = setup()
51
- mock_qna_endpoint = 'http://mock.qna.endpoint'
52
- mock_response = {'status': 'success'}
53
- import aiohttp
54
-
55
- @pytest.mark.asyncio
56
- async def test_send_to_qa_async():
57
- user_input, chat_history, vector_name, stream = setup()
58
- mock_qna_endpoint = 'http://mock.qna.endpoint'
59
- mock_response = {'status': 'success'}
60
- async with aiohttp.ClientSession() as session:
61
- async with session.post(mock_qna_endpoint, json=mock_response) as resp:
62
- response = await dispatch_to_qa.send_to_qa_async(user_input, chat_history, vector_name, stream)
63
- assert response == mock_response
64
-
65
- # Scenario where an HTTP error occurs
66
- async with session.post(mock_qna_endpoint, status=500) as resp:
67
- response = await dispatch_to_qa.send_to_qa_async(user_input, chat_history, vector_name, stream)
68
- assert 'Error' in response
69
-
70
- # Scenario where any other error occurs
71
- async with session.post(mock_qna_endpoint, raise_for_status=False) as resp:
72
- response = await dispatch_to_qa.send_to_qa_async(user_input, chat_history, vector_name, stream)
73
- assert 'Error' in response
@@ -1,40 +0,0 @@
1
- import pytest
2
- from sunholo.utils import config
3
-
4
- # Test for the `load_config` function
5
- def test_load_config():
6
- # Assuming the function is supposed to load a configuration from a file
7
- # and return a dictionary with the configuration data
8
- expected_config = {"key": "value"}
9
- with pytest.raises(FileNotFoundError):
10
- config.load_config("non_existent_file")
11
- with pytest.mock.patch("builtins.open", pytest.mock.mock_open(read_data="key: value"), create=True):
12
- assert config.load_config("mock_file.yaml") == expected_config
13
-
14
- # Test for the `load_config_key` function
15
- def test_load_config_key():
16
- # Assuming the function is supposed to load a specific key from the configuration
17
- expected_value = "value"
18
- with pytest.raises(KeyError):
19
- config.load_config_key("non_existent_key", "mock_vector_name")
20
- with pytest.mock.patch("sunholo.utils.config.load_all_configs", return_value={"mock_vector_name": {"key": "value"}}):
21
- assert config.load_config_key("key", "mock_vector_name") == expected_value
22
-
23
- # Test for the `get_module_filepath` function
24
- def test_get_module_filepath():
25
- # Assuming the function is supposed to return the absolute path of a module file
26
- expected_path = "/absolute/path/to/module/file"
27
- with pytest.mock.patch("os.path.dirname", return_value="/absolute/path/to"):
28
- assert config.get_module_filepath("module/file") == expected_path
29
-
30
- # Test for the `fetch_config` function
31
- def test_fetch_config():
32
- # Assuming the function is supposed to fetch configuration from a cloud storage bucket
33
- expected_update_time = "2022-01-01T00:00:00Z"
34
- with pytest.mock.patch("google.cloud.storage.Client") as mock_client:
35
- mock_bucket = mock_client.return_value.get_bucket.return_value
36
- mock_blob = mock_bucket.get_blob.return_value
37
- mock_blob.updated = expected_update_time
38
- assert config.fetch_config("bucket_name", "blob_name") == expected_update_time
39
- mock_bucket.get_blob.return_value = None
40
- assert config.fetch_config("bucket_name", "blob_name") is None
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes