sunholo 0.101.2__tar.gz → 0.101.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 (164) hide show
  1. {sunholo-0.101.2 → sunholo-0.101.5}/PKG-INFO +2 -2
  2. {sunholo-0.101.2 → sunholo-0.101.5}/setup.py +1 -1
  3. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/invoke/async_class.py +34 -41
  4. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo.egg-info/PKG-INFO +2 -2
  5. {sunholo-0.101.2 → sunholo-0.101.5}/tests/test_async.py +5 -0
  6. {sunholo-0.101.2 → sunholo-0.101.5}/LICENSE.txt +0 -0
  7. {sunholo-0.101.2 → sunholo-0.101.5}/MANIFEST.in +0 -0
  8. {sunholo-0.101.2 → sunholo-0.101.5}/README.md +0 -0
  9. {sunholo-0.101.2 → sunholo-0.101.5}/setup.cfg +0 -0
  10. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/__init__.py +0 -0
  11. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/agents/__init__.py +0 -0
  12. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/agents/chat_history.py +0 -0
  13. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/agents/dispatch_to_qa.py +0 -0
  14. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/agents/fastapi/__init__.py +0 -0
  15. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/agents/fastapi/base.py +0 -0
  16. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/agents/fastapi/qna_routes.py +0 -0
  17. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/agents/flask/__init__.py +0 -0
  18. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/agents/flask/base.py +0 -0
  19. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/agents/flask/qna_routes.py +0 -0
  20. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/agents/flask/vac_routes.py +0 -0
  21. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/agents/langserve.py +0 -0
  22. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/agents/pubsub.py +0 -0
  23. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/agents/route.py +0 -0
  24. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/agents/special_commands.py +0 -0
  25. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/agents/swagger.py +0 -0
  26. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/archive/__init__.py +0 -0
  27. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/archive/archive.py +0 -0
  28. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/auth/__init__.py +0 -0
  29. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/auth/gcloud.py +0 -0
  30. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/auth/refresh.py +0 -0
  31. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/auth/run.py +0 -0
  32. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/azure/__init__.py +0 -0
  33. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/azure/auth.py +0 -0
  34. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/azure/blobs.py +0 -0
  35. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/azure/event_grid.py +0 -0
  36. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/bots/__init__.py +0 -0
  37. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/bots/discord.py +0 -0
  38. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/bots/github_webhook.py +0 -0
  39. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/bots/webapp.py +0 -0
  40. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/chunker/__init__.py +0 -0
  41. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/chunker/azure.py +0 -0
  42. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/chunker/doc_handling.py +0 -0
  43. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/chunker/encode_metadata.py +0 -0
  44. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/chunker/images.py +0 -0
  45. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/chunker/loaders.py +0 -0
  46. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/chunker/message_data.py +0 -0
  47. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/chunker/pdfs.py +0 -0
  48. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/chunker/process_chunker_data.py +0 -0
  49. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/chunker/publish.py +0 -0
  50. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/chunker/pubsub.py +0 -0
  51. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/chunker/splitter.py +0 -0
  52. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/cli/__init__.py +0 -0
  53. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/cli/chat_vac.py +0 -0
  54. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/cli/cli.py +0 -0
  55. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/cli/cli_init.py +0 -0
  56. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/cli/configs.py +0 -0
  57. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/cli/deploy.py +0 -0
  58. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/cli/embedder.py +0 -0
  59. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/cli/merge_texts.py +0 -0
  60. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/cli/run_proxy.py +0 -0
  61. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/cli/sun_rich.py +0 -0
  62. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/cli/swagger.py +0 -0
  63. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/cli/vertex.py +0 -0
  64. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/components/__init__.py +0 -0
  65. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/components/llm.py +0 -0
  66. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/components/retriever.py +0 -0
  67. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/components/vectorstore.py +0 -0
  68. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/custom_logging.py +0 -0
  69. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/database/__init__.py +0 -0
  70. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/database/alloydb.py +0 -0
  71. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/database/alloydb_client.py +0 -0
  72. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/database/database.py +0 -0
  73. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/database/lancedb.py +0 -0
  74. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/database/sql/sb/create_function.sql +0 -0
  75. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/database/sql/sb/create_function_time.sql +0 -0
  76. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/database/sql/sb/create_table.sql +0 -0
  77. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/database/sql/sb/delete_source_row.sql +0 -0
  78. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/database/sql/sb/return_sources.sql +0 -0
  79. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/database/sql/sb/setup.sql +0 -0
  80. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/database/static_dbs.py +0 -0
  81. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/database/uuid.py +0 -0
  82. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/discovery_engine/__init__.py +0 -0
  83. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/discovery_engine/chunker_handler.py +0 -0
  84. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/discovery_engine/create_new.py +0 -0
  85. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/discovery_engine/discovery_engine_client.py +0 -0
  86. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/discovery_engine/get_ai_search_chunks.py +0 -0
  87. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/embedder/__init__.py +0 -0
  88. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/embedder/embed_chunk.py +0 -0
  89. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/excel/__init__.py +0 -0
  90. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/excel/plugin.py +0 -0
  91. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/gcs/__init__.py +0 -0
  92. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/gcs/add_file.py +0 -0
  93. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/gcs/download_folder.py +0 -0
  94. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/gcs/download_url.py +0 -0
  95. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/gcs/extract_and_sign.py +0 -0
  96. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/gcs/metadata.py +0 -0
  97. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/genai/__init__.py +0 -0
  98. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/genai/images.py +0 -0
  99. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/genai/init.py +0 -0
  100. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/genai/process_funcs_cls.py +0 -0
  101. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/genai/safety.py +0 -0
  102. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/invoke/__init__.py +0 -0
  103. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/invoke/direct_vac_func.py +0 -0
  104. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/invoke/invoke_vac_utils.py +0 -0
  105. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/langfuse/__init__.py +0 -0
  106. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/langfuse/callback.py +0 -0
  107. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/langfuse/evals.py +0 -0
  108. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/langfuse/prompts.py +0 -0
  109. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/llamaindex/__init__.py +0 -0
  110. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/llamaindex/get_files.py +0 -0
  111. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/llamaindex/import_files.py +0 -0
  112. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/llamaindex/llamaindex_class.py +0 -0
  113. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/llamaindex/user_history.py +0 -0
  114. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/lookup/__init__.py +0 -0
  115. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/lookup/model_lookup.yaml +0 -0
  116. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/patches/__init__.py +0 -0
  117. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/patches/langchain/__init__.py +0 -0
  118. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/patches/langchain/lancedb.py +0 -0
  119. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/patches/langchain/vertexai.py +0 -0
  120. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/pubsub/__init__.py +0 -0
  121. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/pubsub/process_pubsub.py +0 -0
  122. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/pubsub/pubsub_manager.py +0 -0
  123. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/qna/__init__.py +0 -0
  124. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/qna/parsers.py +0 -0
  125. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/qna/retry.py +0 -0
  126. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/streaming/__init__.py +0 -0
  127. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/streaming/content_buffer.py +0 -0
  128. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/streaming/langserve.py +0 -0
  129. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/streaming/stream_lookup.py +0 -0
  130. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/streaming/streaming.py +0 -0
  131. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/summarise/__init__.py +0 -0
  132. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/summarise/summarise.py +0 -0
  133. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/terraform/__init__.py +0 -0
  134. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/terraform/tfvars_editor.py +0 -0
  135. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/tools/__init__.py +0 -0
  136. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/tools/web_browser.py +0 -0
  137. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/utils/__init__.py +0 -0
  138. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/utils/api_key.py +0 -0
  139. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/utils/big_context.py +0 -0
  140. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/utils/config.py +0 -0
  141. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/utils/config_class.py +0 -0
  142. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/utils/config_schema.py +0 -0
  143. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/utils/gcp.py +0 -0
  144. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/utils/gcp_project.py +0 -0
  145. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/utils/mime.py +0 -0
  146. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/utils/parsers.py +0 -0
  147. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/utils/timedelta.py +0 -0
  148. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/utils/user_ids.py +0 -0
  149. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/utils/version.py +0 -0
  150. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/vertex/__init__.py +0 -0
  151. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/vertex/extensions_call.py +0 -0
  152. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/vertex/extensions_class.py +0 -0
  153. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/vertex/genai_functions.py +0 -0
  154. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/vertex/init.py +0 -0
  155. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/vertex/memory_tools.py +0 -0
  156. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/vertex/safety.py +0 -0
  157. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo/vertex/type_dict_to_json.py +0 -0
  158. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo.egg-info/SOURCES.txt +0 -0
  159. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo.egg-info/dependency_links.txt +0 -0
  160. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo.egg-info/entry_points.txt +0 -0
  161. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo.egg-info/requires.txt +0 -0
  162. {sunholo-0.101.2 → sunholo-0.101.5}/sunholo.egg-info/top_level.txt +0 -0
  163. {sunholo-0.101.2 → sunholo-0.101.5}/tests/test_chat_history.py +0 -0
  164. {sunholo-0.101.2 → sunholo-0.101.5}/tests/test_config.py +0 -0
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: sunholo
3
- Version: 0.101.2
3
+ Version: 0.101.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.101.2.tar.gz
6
+ Download-URL: https://github.com/sunholo-data/sunholo-py/archive/refs/tags/v0.101.5.tar.gz
7
7
  Author: Holosun ApS
8
8
  Author-email: multivac@sunholo.com
9
9
  License: Apache License, Version 2.0
@@ -1,6 +1,6 @@
1
1
  from setuptools import setup, find_packages
2
2
 
3
- version = '0.101.2'
3
+ version = '0.101.5'
4
4
 
5
5
  setup(
6
6
  name='sunholo',
@@ -8,17 +8,23 @@ from tenacity import AsyncRetrying, retry_if_exception_type, wait_random_exponen
8
8
  log = setup_logging("sunholo_AsyncTaskRunner")
9
9
 
10
10
  class AsyncTaskRunner:
11
- def __init__(self, retry_enabled=False, retry_kwargs=None):
11
+ def __init__(self, retry_enabled=False, retry_kwargs=None, timeout=120):
12
12
  self.tasks = []
13
13
  self.retry_enabled = retry_enabled
14
14
  self.retry_kwargs = retry_kwargs or {}
15
+ self.timeout = timeout
15
16
 
16
- def add_task(self, func: Callable[..., Any], *args: Any):
17
+ def add_task(self, func: Callable[..., Any], *args: Any, **kwargs: Any):
17
18
  """
18
- Adds a task to the list of tasks to be executed.
19
+ Adds a task to the list of tasks to be executed, supporting both positional and keyword arguments.
20
+
21
+ Args:
22
+ func: The function to be executed.
23
+ *args: Positional arguments for the function.
24
+ **kwargs: Keyword arguments for the function.
19
25
  """
20
- log.info(f"Adding task: {func.__name__} with args: {args}")
21
- self.tasks.append((func.__name__, func, args))
26
+ log.info(f"Adding task: {func.__name__} with args: {args}, kwargs: {kwargs}")
27
+ self.tasks.append((func.__name__, func, args, kwargs))
22
28
 
23
29
  async def run_async_as_completed(self) -> AsyncGenerator[Dict[str, Any], None]:
24
30
  """
@@ -26,53 +32,36 @@ class AsyncTaskRunner:
26
32
  while periodically sending heartbeat messages.
27
33
  """
28
34
  log.info("Running tasks asynchronously and yielding results as they complete")
29
-
30
- # Create a queue for inter-coroutine communication
31
35
  queue = asyncio.Queue()
32
-
33
- # List to keep track of all running tasks and their heartbeats
34
36
  task_infos = []
35
37
 
36
- # Start all tasks and their corresponding heartbeats
37
- for name, func, args in self.tasks:
38
- # Create an event to signal task completion to the heartbeat
38
+ for name, func, args, kwargs in self.tasks:
39
+ log.info(f"Executing task: {name=}, {func=} with args: {args}, kwargs: {kwargs}")
39
40
  completion_event = asyncio.Event()
40
-
41
- # Start the main task with retries
42
- task_coro = self._run_with_retries(name, func, *args, queue=queue, completion_event=completion_event)
41
+ task_coro = self._run_with_retries_and_timeout(name, func, args, kwargs, queue, completion_event)
43
42
  task = asyncio.create_task(task_coro)
44
-
45
- # Start the heartbeat coroutine
46
43
  heartbeat_coro = self._send_heartbeat(name, completion_event, queue)
47
44
  heartbeat_task = asyncio.create_task(heartbeat_coro)
48
-
49
- # Store task information for management
50
45
  task_infos.append({
51
46
  'name': name,
52
47
  'task': task,
53
48
  'heartbeat_task': heartbeat_task,
54
49
  'completion_event': completion_event
55
50
  })
56
-
57
51
  log.info(f"Started task '{name}' and its heartbeat")
58
52
 
59
53
  log.info(f"Started async run with {len(self.tasks)} tasks and heartbeats")
60
-
61
- # Create a monitor task to detect when all tasks and heartbeats are done
62
54
  monitor = asyncio.create_task(self._monitor_tasks(task_infos, queue))
63
55
 
64
- # Continuously yield messages from the queue until sentinel is received
65
56
  while True:
66
57
  message = await queue.get()
67
58
  if message is None:
68
59
  log.info("Received sentinel. Exiting message loop.")
69
- break # Sentinel received, all tasks and heartbeats are done
60
+ break
70
61
  log.info(f"Received message from queue: {message}")
71
62
  yield message
72
63
 
73
- # Wait for the monitor to finish
74
64
  await monitor
75
-
76
65
  log.info("All tasks and heartbeats have completed")
77
66
 
78
67
  async def _monitor_tasks(self, task_infos, queue):
@@ -94,15 +83,18 @@ class AsyncTaskRunner:
94
83
  pass
95
84
  log.info(f"Monitor: Heartbeat for task '{info['name']}' has been canceled")
96
85
 
97
- # Send a sentinel to indicate completion
98
86
  await queue.put(None)
99
87
  log.info("Monitor: Sent sentinel to queue")
100
88
 
101
- async def _run_with_retries(self, name: str, func: Callable[..., Any], *args: Any, queue: asyncio.Queue, completion_event: asyncio.Event) -> None:
102
- """
103
- Executes a task with optional retries and sends completion or error messages to the queue.
104
- """
89
+ async def _run_with_retries_and_timeout(self,
90
+ name: str,
91
+ func: Callable[..., Any],
92
+ args: tuple,
93
+ kwargs: dict,
94
+ queue: asyncio.Queue,
95
+ completion_event: asyncio.Event) -> None:
105
96
  try:
97
+ log.info(f"run_with_retries_and_timeout: {name=}, {func=} with args: {args}, kwargs: {kwargs}")
106
98
  if self.retry_enabled:
107
99
  retry_kwargs = {
108
100
  'wait': wait_random_exponential(multiplier=1, max=60),
@@ -113,39 +105,41 @@ class AsyncTaskRunner:
113
105
  async for attempt in AsyncRetrying(**retry_kwargs):
114
106
  with attempt:
115
107
  log.info(f"Starting task '{name}' with retry")
116
- result = await self._execute_task(func, *args)
108
+ result = await asyncio.wait_for(self._execute_task(func, *args, **kwargs), timeout=self.timeout)
117
109
  await queue.put({'type': 'task_complete', 'func_name': name, 'result': result})
118
110
  log.info(f"Sent 'task_complete' message for task '{name}'")
119
111
  return
120
112
  else:
121
113
  log.info(f"Starting task '{name}' with no retry")
122
- result = await self._execute_task(func, *args)
114
+ result = await asyncio.wait_for(self._execute_task(func, *args, **kwargs), timeout=self.timeout)
123
115
  await queue.put({'type': 'task_complete', 'func_name': name, 'result': result})
124
116
  log.info(f"Sent 'task_complete' message for task '{name}'")
117
+ except asyncio.TimeoutError:
118
+ log.error(f"Task '{name}' timed out after {self.timeout} seconds")
119
+ await queue.put({'type': 'task_error', 'func_name': name, 'error': f'Task timed out after {self.timeout} seconds'})
125
120
  except Exception as e:
126
121
  log.error(f"Error in task '{name}': {e}\n{traceback.format_exc()}")
127
122
  await queue.put({'type': 'task_error', 'func_name': name, 'error': f'{e}\n{traceback.format_exc()}'})
128
- log.info(f"Sent 'task_error' message for task '{name}'")
129
123
  finally:
130
124
  log.info(f"Task '{name}' completed.")
131
- # Set the completion event after sending the message
132
125
  completion_event.set()
133
126
 
134
- async def _execute_task(self, func: Callable[..., Any], *args: Any) -> Any:
127
+ async def _execute_task(self, func: Callable[..., Any], *args: Any, **kwargs: Any) -> Any:
135
128
  """
136
129
  Executes the given task function and returns its result.
137
130
 
138
131
  Args:
139
132
  func (Callable): The callable to execute.
140
- *args: Arguments to pass to the callable.
133
+ *args: Positional arguments to pass to the callable.
134
+ **kwargs: Keyword arguments to pass to the callable.
141
135
 
142
136
  Returns:
143
137
  Any: The result of the task.
144
138
  """
145
139
  if asyncio.iscoroutinefunction(func):
146
- return await func(*args)
140
+ return await func(*args, **kwargs)
147
141
  else:
148
- return await asyncio.to_thread(func, *args)
142
+ return await asyncio.to_thread(func, *args, **kwargs)
149
143
 
150
144
  async def _send_heartbeat(self, func_name: str, completion_event: asyncio.Event, queue: asyncio.Queue, interval: int = 2):
151
145
  """
@@ -174,5 +168,4 @@ class AsyncTaskRunner:
174
168
  except asyncio.CancelledError:
175
169
  log.info(f"Heartbeat for task '{func_name}' has been canceled")
176
170
  finally:
177
- log.info(f"Heartbeat for task '{func_name}' stopped")
178
-
171
+ log.info(f"Heartbeat for task '{func_name}' stopped")
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: sunholo
3
- Version: 0.101.2
3
+ Version: 0.101.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.101.2.tar.gz
6
+ Download-URL: https://github.com/sunholo-data/sunholo-py/archive/refs/tags/v0.101.5.tar.gz
7
7
  Author: Holosun ApS
8
8
  Author-email: multivac@sunholo.com
9
9
  License: Apache License, Version 2.0
@@ -33,6 +33,10 @@ def format_token_output(func_name, tokens, result=None, error=None):
33
33
  async def count_tokens(result):
34
34
  return len(result.split())
35
35
 
36
+ async def kwargs_function(required_arg, **kwargs):
37
+ await asyncio.sleep(3) # Simulate a medium-running task
38
+ return f"Required arg: {required_arg}, Optional args: {kwargs}"
39
+
36
40
  # Example usage
37
41
  async def main():
38
42
  runner = AsyncTaskRunner(retry_enabled=True)
@@ -41,6 +45,7 @@ async def main():
41
45
  runner.add_task(google_search, "<original user question>...", "<config>")
42
46
  runner.add_task(use_pdfs, "<original user question>...", None, None)
43
47
  runner.add_task(process_urls, "please give me a forecast of ppas for spain using wind energy")
48
+ runner.add_task(kwargs_function, "required_value", optional_arg1="test", optional_arg2=42)
44
49
 
45
50
  callback = MockCallback()
46
51
  answers = {}
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes