sunholo 0.84.11__tar.gz → 0.85.2__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 (156) hide show
  1. {sunholo-0.84.11 → sunholo-0.85.2}/PKG-INFO +7 -2
  2. {sunholo-0.84.11 → sunholo-0.85.2}/setup.py +8 -2
  3. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/__init__.py +2 -0
  4. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/chunker/loaders.py +1 -1
  5. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/cli/cli.py +3 -0
  6. sunholo-0.85.2/sunholo/excel/__init__.py +1 -0
  7. sunholo-0.85.2/sunholo/excel/plugin.py +97 -0
  8. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/invoke/async_class.py +60 -1
  9. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/invoke/direct_vac_func.py +22 -25
  10. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/qna/parsers.py +8 -0
  11. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/utils/config_class.py +2 -0
  12. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo.egg-info/PKG-INFO +7 -2
  13. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo.egg-info/SOURCES.txt +2 -0
  14. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo.egg-info/requires.txt +6 -0
  15. {sunholo-0.84.11 → sunholo-0.85.2}/LICENSE.txt +0 -0
  16. {sunholo-0.84.11 → sunholo-0.85.2}/MANIFEST.in +0 -0
  17. {sunholo-0.84.11 → sunholo-0.85.2}/README.md +0 -0
  18. {sunholo-0.84.11 → sunholo-0.85.2}/setup.cfg +0 -0
  19. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/agents/__init__.py +0 -0
  20. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/agents/chat_history.py +0 -0
  21. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/agents/dispatch_to_qa.py +0 -0
  22. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/agents/fastapi/__init__.py +0 -0
  23. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/agents/fastapi/base.py +0 -0
  24. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/agents/fastapi/qna_routes.py +0 -0
  25. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/agents/flask/__init__.py +0 -0
  26. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/agents/flask/base.py +0 -0
  27. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/agents/flask/qna_routes.py +0 -0
  28. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/agents/flask/vac_routes.py +0 -0
  29. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/agents/langserve.py +0 -0
  30. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/agents/pubsub.py +0 -0
  31. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/agents/route.py +0 -0
  32. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/agents/special_commands.py +0 -0
  33. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/agents/swagger.py +0 -0
  34. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/archive/__init__.py +0 -0
  35. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/archive/archive.py +0 -0
  36. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/auth/__init__.py +0 -0
  37. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/auth/gcloud.py +0 -0
  38. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/auth/refresh.py +0 -0
  39. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/auth/run.py +0 -0
  40. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/azure/__init__.py +0 -0
  41. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/azure/auth.py +0 -0
  42. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/azure/blobs.py +0 -0
  43. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/azure/event_grid.py +0 -0
  44. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/bots/__init__.py +0 -0
  45. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/bots/discord.py +0 -0
  46. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/bots/github_webhook.py +0 -0
  47. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/bots/webapp.py +0 -0
  48. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/chunker/__init__.py +0 -0
  49. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/chunker/azure.py +0 -0
  50. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/chunker/doc_handling.py +0 -0
  51. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/chunker/encode_metadata.py +0 -0
  52. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/chunker/images.py +0 -0
  53. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/chunker/message_data.py +0 -0
  54. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/chunker/pdfs.py +0 -0
  55. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/chunker/process_chunker_data.py +0 -0
  56. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/chunker/publish.py +0 -0
  57. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/chunker/pubsub.py +0 -0
  58. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/chunker/splitter.py +0 -0
  59. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/cli/__init__.py +0 -0
  60. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/cli/chat_vac.py +0 -0
  61. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/cli/cli_init.py +0 -0
  62. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/cli/configs.py +0 -0
  63. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/cli/deploy.py +0 -0
  64. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/cli/embedder.py +0 -0
  65. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/cli/merge_texts.py +0 -0
  66. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/cli/run_proxy.py +0 -0
  67. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/cli/sun_rich.py +0 -0
  68. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/cli/swagger.py +0 -0
  69. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/cli/vertex.py +0 -0
  70. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/components/__init__.py +0 -0
  71. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/components/llm.py +0 -0
  72. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/components/retriever.py +0 -0
  73. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/components/vectorstore.py +0 -0
  74. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/custom_logging.py +0 -0
  75. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/database/__init__.py +0 -0
  76. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/database/alloydb.py +0 -0
  77. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/database/alloydb_client.py +0 -0
  78. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/database/database.py +0 -0
  79. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/database/lancedb.py +0 -0
  80. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/database/sql/sb/create_function.sql +0 -0
  81. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/database/sql/sb/create_function_time.sql +0 -0
  82. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/database/sql/sb/create_table.sql +0 -0
  83. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/database/sql/sb/delete_source_row.sql +0 -0
  84. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/database/sql/sb/return_sources.sql +0 -0
  85. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/database/sql/sb/setup.sql +0 -0
  86. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/database/static_dbs.py +0 -0
  87. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/database/uuid.py +0 -0
  88. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/discovery_engine/__init__.py +0 -0
  89. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/discovery_engine/chunker_handler.py +0 -0
  90. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/discovery_engine/create_new.py +0 -0
  91. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/discovery_engine/discovery_engine_client.py +0 -0
  92. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/discovery_engine/get_ai_search_chunks.py +0 -0
  93. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/embedder/__init__.py +0 -0
  94. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/embedder/embed_chunk.py +0 -0
  95. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/gcs/__init__.py +0 -0
  96. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/gcs/add_file.py +0 -0
  97. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/gcs/download_folder.py +0 -0
  98. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/gcs/download_url.py +0 -0
  99. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/gcs/metadata.py +0 -0
  100. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/genai/__init__.py +0 -0
  101. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/genai/process_funcs_cls.py +0 -0
  102. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/genai/safety.py +0 -0
  103. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/invoke/__init__.py +0 -0
  104. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/invoke/invoke_vac_utils.py +0 -0
  105. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/langfuse/__init__.py +0 -0
  106. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/langfuse/callback.py +0 -0
  107. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/langfuse/prompts.py +0 -0
  108. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/llamaindex/__init__.py +0 -0
  109. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/llamaindex/get_files.py +0 -0
  110. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/llamaindex/import_files.py +0 -0
  111. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/llamaindex/llamaindex_class.py +0 -0
  112. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/llamaindex/user_history.py +0 -0
  113. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/lookup/__init__.py +0 -0
  114. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/lookup/model_lookup.yaml +0 -0
  115. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/patches/__init__.py +0 -0
  116. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/patches/langchain/__init__.py +0 -0
  117. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/patches/langchain/lancedb.py +0 -0
  118. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/patches/langchain/vertexai.py +0 -0
  119. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/pubsub/__init__.py +0 -0
  120. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/pubsub/process_pubsub.py +0 -0
  121. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/pubsub/pubsub_manager.py +0 -0
  122. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/qna/__init__.py +0 -0
  123. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/qna/retry.py +0 -0
  124. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/streaming/__init__.py +0 -0
  125. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/streaming/content_buffer.py +0 -0
  126. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/streaming/langserve.py +0 -0
  127. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/streaming/stream_lookup.py +0 -0
  128. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/streaming/streaming.py +0 -0
  129. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/summarise/__init__.py +0 -0
  130. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/summarise/summarise.py +0 -0
  131. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/tools/__init__.py +0 -0
  132. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/tools/web_browser.py +0 -0
  133. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/utils/__init__.py +0 -0
  134. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/utils/api_key.py +0 -0
  135. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/utils/big_context.py +0 -0
  136. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/utils/config.py +0 -0
  137. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/utils/config_schema.py +0 -0
  138. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/utils/gcp.py +0 -0
  139. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/utils/gcp_project.py +0 -0
  140. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/utils/parsers.py +0 -0
  141. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/utils/timedelta.py +0 -0
  142. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/utils/user_ids.py +0 -0
  143. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/utils/version.py +0 -0
  144. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/vertex/__init__.py +0 -0
  145. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/vertex/extensions_call.py +0 -0
  146. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/vertex/extensions_class.py +0 -0
  147. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/vertex/genai_functions.py +0 -0
  148. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/vertex/init.py +0 -0
  149. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/vertex/memory_tools.py +0 -0
  150. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/vertex/safety.py +0 -0
  151. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo/vertex/type_dict_to_json.py +0 -0
  152. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo.egg-info/dependency_links.txt +0 -0
  153. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo.egg-info/entry_points.txt +0 -0
  154. {sunholo-0.84.11 → sunholo-0.85.2}/sunholo.egg-info/top_level.txt +0 -0
  155. {sunholo-0.84.11 → sunholo-0.85.2}/tests/test_chat_history.py +0 -0
  156. {sunholo-0.84.11 → sunholo-0.85.2}/tests/test_config.py +0 -0
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: sunholo
3
- Version: 0.84.11
3
+ Version: 0.85.2
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.84.11.tar.gz
6
+ Download-URL: https://github.com/sunholo-data/sunholo-py/archive/refs/tags/v0.85.2.tar.gz
7
7
  Author: Holosun ApS
8
8
  Author-email: multivac@sunholo.com
9
9
  License: Apache License, Version 2.0
@@ -72,6 +72,7 @@ Requires-Dist: tabulate; extra == "all"
72
72
  Requires-Dist: tantivy; extra == "all"
73
73
  Requires-Dist: tiktoken; extra == "all"
74
74
  Requires-Dist: unstructured[local-inference]==0.14.9; extra == "all"
75
+ Requires-Dist: xlwings; extra == "all"
75
76
  Provides-Extra: azure
76
77
  Requires-Dist: azure-identity; extra == "azure"
77
78
  Requires-Dist: azure-storage-blob; extra == "azure"
@@ -130,6 +131,10 @@ Requires-Dist: httpx; extra == "http"
130
131
  Requires-Dist: langfuse; extra == "http"
131
132
  Requires-Dist: python-socketio; extra == "http"
132
133
  Requires-Dist: requests; extra == "http"
134
+ Provides-Extra: excel
135
+ Requires-Dist: xlwings; extra == "excel"
136
+ Requires-Dist: requests; extra == "excel"
137
+ Requires-Dist: rich; extra == "excel"
133
138
 
134
139
  ## Introduction
135
140
  This is the Sunholo Python project, a comprehensive toolkit for working with language models and vector stores on Google Cloud Platform. It provides a wide range of functionalities and utilities to facilitate the development and deployment of language model applications.
@@ -1,7 +1,7 @@
1
1
  from setuptools import setup, find_packages
2
2
 
3
3
  # Define your base version
4
- version = '0.84.11'
4
+ version = '0.85.2'
5
5
 
6
6
  setup(
7
7
  name='sunholo',
@@ -86,7 +86,7 @@ setup(
86
86
  "tantivy",
87
87
  "tiktoken",
88
88
  "unstructured[local-inference]==0.14.9",
89
-
89
+ "xlwings"
90
90
  ],
91
91
  'azure': [
92
92
  "azure-identity",
@@ -155,7 +155,13 @@ setup(
155
155
  "langfuse",
156
156
  "python-socketio",
157
157
  "requests"
158
+ ],
159
+ 'excel': [
160
+ 'xlwings',
161
+ 'requests',
162
+ 'rich'
158
163
  ]
164
+
159
165
  },
160
166
  classifiers=[
161
167
  'Development Status :: 3 - Alpha', # Chose either "3 - Alpha", "4 - Beta" or "5 - Production/Stable" as the current state of your package
@@ -8,6 +8,7 @@ from . import components
8
8
  from . import database
9
9
  from . import discovery_engine
10
10
  from . import embedder
11
+ from . import excel
11
12
  from . import gcs
12
13
  from . import genai
13
14
  from . import invoke
@@ -34,6 +35,7 @@ __all__ = ['agents',
34
35
  'database',
35
36
  'discovery_engine',
36
37
  'embedder',
38
+ 'excel',
37
39
  'gcs',
38
40
  'genai',
39
41
  'invoke',
@@ -185,7 +185,7 @@ def read_file_to_documents(gs_file: pathlib.Path, metadata: dict = None):
185
185
  return []
186
186
 
187
187
  log.info(f"Sending {pdf_path} to UnstructuredAPIFileLoader")
188
- UNSTRUCTURED_URL = os.getenv("UNSTRUCTURED_URL", None)
188
+ UNSTRUCTURED_URL = os.getenv("UNSTRUCTURED_URL")
189
189
  unstructured_kwargs = {"pdf_infer_table_structure": True,
190
190
  "extract_image_block_types": ["Image", "Table"]
191
191
  }
@@ -11,6 +11,7 @@ from .embedder import setup_embedder_subparser
11
11
  from .swagger import setup_swagger_subparser
12
12
  from .vertex import setup_vertex_subparser
13
13
  from ..llamaindex import setup_llamaindex_subparser
14
+ from ..excel import setup_excel_subparser
14
15
 
15
16
  from ..utils import ConfigManager
16
17
  from ..utils.version import sunholo_version
@@ -92,6 +93,8 @@ def main(args=None):
92
93
  setup_vertex_subparser(subparsers)
93
94
  # llamaindex
94
95
  setup_llamaindex_subparser(subparsers)
96
+ # excel
97
+ setup_excel_subparser(subparsers)
95
98
 
96
99
  #TODO: add database setup commands: alloydb and supabase
97
100
 
@@ -0,0 +1 @@
1
+ from .plugin import excel_plugin, setup_excel_subparser
@@ -0,0 +1,97 @@
1
+ import os
2
+ import sys
3
+ import subprocess
4
+ import shutil
5
+ from ..custom_logging import log
6
+ from ..invoke import direct_vac
7
+
8
+ def setup_excel_plugin(args):
9
+ """
10
+ Sets up the Excel plugin by copying the VBA file and creating the xlwings.conf file
11
+ with the correct Python interpreter path.
12
+ """
13
+ from rich.panel import Panel
14
+ from ..cli.sun_rich import console
15
+
16
+ # Define the source directory (where the sunholo.excel package is located)
17
+ library_folder = os.path.dirname(__file__)
18
+
19
+ # Define the destination directory (current working directory)
20
+ destination_folder = os.getcwd()
21
+
22
+ # Define the paths
23
+ vba_file_template = "call_vac.vba.template" # A template file with a placeholder for the path
24
+ vba_file_output = "call_vac.vba"
25
+ source_vba_file = os.path.join(library_folder, vba_file_template)
26
+ destination_vba_file = os.path.join(destination_folder, vba_file_output)
27
+
28
+ # Ensure the .venv directory exists
29
+ if not os.path.exists(os.path.join(destination_folder, ".venv")):
30
+ console.print(f"ERROR: Virtual environment not found in {destination_folder}. "
31
+ "Please ensure you are working in correct folder. "
32
+ " This command needs to be run from location where venv is created via `python -m venv .venv`"
33
+ " and has installed this library via `pip install sunholo[excel]`")
34
+ return None
35
+
36
+ # Create the xlwings.conf file with the correct Python interpreter path
37
+ conf_file_path = os.path.join(destination_folder, "xlwings.conf")
38
+ python_executable = sys.executable
39
+
40
+ # Ensure the .venv directory exists
41
+ if not os.path.exists(os.path.dirname(python_executable)):
42
+ console.print(f"[bold red]ERROR: Python environment not found at {python_executable}. Please ensure it is created.[/bold red]")
43
+ return None
44
+
45
+ # Check if xlwings is installed
46
+ try:
47
+ subprocess.run([python_executable, "-c", "import xlwings"], check=True, capture_output=True)
48
+ console.print("xlwings is installed in the Python environment.")
49
+ except subprocess.CalledProcessError:
50
+ console.print("[bold red]WARNING: xlwings is not installed in the Python environment. Please install it using 'pip install sunholo\[excel]'[/bold red]")
51
+
52
+
53
+ # Write the xlwings.conf file
54
+ try:
55
+ with open(conf_file_path, "w") as conf_file:
56
+ conf_file.write("[Interpreter]\n")
57
+ conf_file.write(f"PYTHONPATH={python_executable}\n")
58
+ console.print(f"Created {conf_file_path} with PYTHONPATH set to {python_executable}")
59
+ except IOError as e:
60
+ console.print(f"[bold red]ERROR:[/bold red] Failed to create xlwings.conf: {e}")
61
+ return None
62
+
63
+ # Copy the VBA template file to the destination as the VBA file
64
+ try:
65
+ shutil.copy2(source_vba_file, destination_vba_file)
66
+ console.print(f"Created {destination_vba_file}")
67
+ except IOError as e:
68
+ console.print(f"[bold red]ERROR:[/bold red] Failed to copy VBA file: {e}")
69
+ return None
70
+
71
+ console.print(
72
+ Panel(("1. Open your Excel workbook.\n"
73
+ "2. Press Alt + F11 to open the VBA editor.\n"
74
+ "3. Insert a new module (Insert -> Module).\n"
75
+ f"4. Add the VBA code from {destination_vba_file} into the module.\n"
76
+ "5. Use =MULTIVAC() within your Excel cells"),
77
+ title="Next Steps")
78
+ )
79
+
80
+
81
+ def excel_plugin(input_data, vac_name):
82
+ log.info(f"Calling multivac plugin for {vac_name} with {input_data}")
83
+ response = direct_vac(input_data, vac_name=vac_name)
84
+ log.info(f"Plugin got {response}")
85
+ return response['answer']
86
+
87
+ def setup_excel_subparser(subparsers):
88
+ """
89
+ Sets up an argparse subparser for the 'excel' command.
90
+
91
+ Example command:
92
+ ```bash
93
+ sunholo excel-init
94
+ ```
95
+ """
96
+ deploy_parser = subparsers.add_parser('excel-init', help='Create Excel integrations with Sunholo VACs')
97
+ deploy_parser.set_defaults(func=setup_excel_plugin)
@@ -8,7 +8,8 @@ logger = logging.getLogger(__name__)
8
8
 
9
9
  class AsyncTaskRunner:
10
10
  """
11
- # Example async functions for testing
11
+ Example async functions for testing
12
+ ```python
12
13
  async def api_call_1(url, params):
13
14
  await asyncio.sleep(1)
14
15
  if "fail" in params:
@@ -44,6 +45,64 @@ class AsyncTaskRunner:
44
45
  results = runner.run_sync()
45
46
  for result in results:
46
47
  print(result)
48
+ ```
49
+
50
+ Example streaming fast and slow
51
+
52
+ ```python
53
+ import asyncio
54
+ from typing import AsyncGenerator
55
+
56
+ # Example streaming function that simulates yielding chunks of data
57
+ async def stream_chunks(url: str, params: dict) -> AsyncGenerator[str, None]:
58
+ # Simulate streaming with a series of chunks
59
+ for i in range(5):
60
+ await asyncio.sleep(1) # Simulate delay between chunks
61
+ yield f"Chunk {i+1} from {url} with params {params}"
62
+
63
+ # Example slow API call function
64
+ async def slow_api_call(url: str, params: dict) -> str:
65
+ await asyncio.sleep(5) # Simulate a slow API response
66
+ return f"Slow API response from {url} with params {params}"
67
+
68
+ # Function to manage streaming and slow API call
69
+ async def process_api_calls(stream_url: str, stream_params: dict, slow_url: str, slow_params: dict) -> AsyncGenerator[str, None]:
70
+ # Create the AsyncTaskRunner instance
71
+ runner = AsyncTaskRunner()
72
+
73
+ # Add the slow API call as a task
74
+ runner.add_task(slow_api_call, slow_url, slow_params)
75
+
76
+ # Run the slow API call concurrently with the streaming
77
+ slow_api_result_task = asyncio.create_task(runner.run_async())
78
+
79
+ # Process the streaming chunks and yield them
80
+ async for chunk in stream_chunks(stream_url, stream_params):
81
+ yield chunk
82
+
83
+ # Wait for the slow API call to complete and get the result
84
+ slow_api_results = await slow_api_result_task
85
+
86
+ # Yield the slow API response after streaming is finished
87
+ for result in slow_api_results:
88
+ yield result
89
+
90
+ # Example usage in an existing async function
91
+ async def example_usage():
92
+ # Define the URLs and parameters for the calls
93
+ stream_url = "http://streaming.example.com"
94
+ stream_params = {"key": "stream_value"}
95
+ slow_url = "http://slowapi.example.com"
96
+ slow_params = {"key": "slow_value"}
97
+
98
+ # Process the API calls and stream the results
99
+ async for output in process_api_calls(stream_url, stream_params, slow_url, slow_params):
100
+ print(output)
101
+
102
+ # Running the example usage
103
+ if __name__ == "__main__":
104
+ asyncio.run(example_usage())
105
+ ```
47
106
  """
48
107
  def __init__(self):
49
108
  self.tasks = []
@@ -13,11 +13,7 @@ def direct_vac(vac_input: dict, vac_name: str, chat_history=[]):
13
13
  log.info(f"Invoking VAC Q&A endpoints for {vac_name}")
14
14
 
15
15
  if 'user_input' not in vac_input:
16
- raise ValueError('vac_input must contain at least "user_input" key - got {vac_input}')
17
-
18
- user_id = vac_input.get('user_id')
19
- session_id = vac_input.get('session_id')
20
- image_uri = vac_input.get('image_url') or vac_input.get('image_uri')
16
+ raise ValueError(f'vac_input must contain at least "user_input" key - got {vac_input}')
21
17
 
22
18
  global_config = ConfigManager('global')
23
19
  config = ConfigManager(vac_name)
@@ -41,28 +37,29 @@ def direct_vac(vac_input: dict, vac_name: str, chat_history=[]):
41
37
  override_endpoint = agent_url or override_endpoint
42
38
 
43
39
  print(f"Using {override_endpoint=}")
44
- log.warning(f'Batch invoke_vac_qa {vac_name} with {vac_input=}')
45
- vac_response = send_to_qa(
46
- vac_input["user_input"],
47
- vector_name=vac_name,
48
- chat_history=chat_history,
49
- message_author=user_id,
50
- #TODO: populate these
51
- image_url=image_uri,
52
- source_filters=None,
53
- search_kwargs=None,
54
- private_docs=None,
55
- whole_document=False,
56
- source_filters_and_or=False,
57
- # system kwargs
58
- configurable={
40
+
41
+ # Prepare the kwargs for send_to_qa by copying vac_input and adding more values
42
+ qa_kwargs = vac_input.copy()
43
+
44
+ # Add additional arguments
45
+ qa_kwargs.update({
46
+ 'vector_name': vac_name,
47
+ 'chat_history': chat_history,
48
+ 'image_url': vac_input.get('image_url') or vac_input.get('image_uri'),
49
+ 'override_endpoint': override_endpoint,
50
+ 'message_source': "sunholo.invoke_vac_qa.invoke",
51
+ 'stream': False,
52
+ 'configurable': {
59
53
  "vector_name": vac_name,
60
54
  },
61
- user_id=user_id,
62
- session_id=session_id,
63
- message_source="sunholo.invoke_vac_qa.invoke",
64
- override_endpoint=override_endpoint,
65
- stream=False)
55
+ })
56
+
57
+ log.info(f'Batch invoke_vac_qa {vac_name} with {qa_kwargs=}')
58
+
59
+ vac_response = send_to_qa(
60
+ vac_input["user_input"],
61
+ **qa_kwargs
62
+ )
66
63
 
67
64
  # ensures {'answer': answer}
68
65
  answer = parse_output(vac_response)
@@ -44,6 +44,14 @@ def parse_output(bot_output):
44
44
 
45
45
  return bot_output
46
46
 
47
+ elif isinstance(bot_output, dict) and 'output' in bot_output and isinstance(bot_output['output'], dict) and 'content' in bot_output['output']:
48
+ the_output = bot_output['output']
49
+
50
+ return {
51
+ 'answer': the_output.get('content'),
52
+ 'metadata': the_output.get('metadata')
53
+ }
54
+
47
55
  elif isinstance(bot_output, dict):
48
56
  if not bot_output.get("answer"):
49
57
  raise ValueError(f"VAC output was not a string or a dict with the key 'answer' - got: {bot_output}")
@@ -26,6 +26,8 @@ class ConfigManager:
26
26
  agent = config.vacConfig("agent")
27
27
  ```
28
28
  """
29
+ if os.getenv("VAC_CONFIG_FOLDER") is None:
30
+ print("WARNING: No VAC_CONFIG_FOLDER environment variable was specified")
29
31
  local_config_folder = os.path.join(os.getcwd(), "config")
30
32
  if os.path.isdir(local_config_folder):
31
33
  print(f"Found local config folder {local_config_folder} - will overwrite any global configurations")
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: sunholo
3
- Version: 0.84.11
3
+ Version: 0.85.2
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.84.11.tar.gz
6
+ Download-URL: https://github.com/sunholo-data/sunholo-py/archive/refs/tags/v0.85.2.tar.gz
7
7
  Author: Holosun ApS
8
8
  Author-email: multivac@sunholo.com
9
9
  License: Apache License, Version 2.0
@@ -72,6 +72,7 @@ Requires-Dist: tabulate; extra == "all"
72
72
  Requires-Dist: tantivy; extra == "all"
73
73
  Requires-Dist: tiktoken; extra == "all"
74
74
  Requires-Dist: unstructured[local-inference]==0.14.9; extra == "all"
75
+ Requires-Dist: xlwings; extra == "all"
75
76
  Provides-Extra: azure
76
77
  Requires-Dist: azure-identity; extra == "azure"
77
78
  Requires-Dist: azure-storage-blob; extra == "azure"
@@ -130,6 +131,10 @@ Requires-Dist: httpx; extra == "http"
130
131
  Requires-Dist: langfuse; extra == "http"
131
132
  Requires-Dist: python-socketio; extra == "http"
132
133
  Requires-Dist: requests; extra == "http"
134
+ Provides-Extra: excel
135
+ Requires-Dist: xlwings; extra == "excel"
136
+ Requires-Dist: requests; extra == "excel"
137
+ Requires-Dist: rich; extra == "excel"
133
138
 
134
139
  ## Introduction
135
140
  This is the Sunholo Python project, a comprehensive toolkit for working with language models and vector stores on Google Cloud Platform. It provides a wide range of functionalities and utilities to facilitate the development and deployment of language model applications.
@@ -88,6 +88,8 @@ sunholo/discovery_engine/discovery_engine_client.py
88
88
  sunholo/discovery_engine/get_ai_search_chunks.py
89
89
  sunholo/embedder/__init__.py
90
90
  sunholo/embedder/embed_chunk.py
91
+ sunholo/excel/__init__.py
92
+ sunholo/excel/plugin.py
91
93
  sunholo/gcs/__init__.py
92
94
  sunholo/gcs/add_file.py
93
95
  sunholo/gcs/download_folder.py
@@ -53,6 +53,7 @@ tabulate
53
53
  tantivy
54
54
  tiktoken
55
55
  unstructured[local-inference]==0.14.9
56
+ xlwings
56
57
 
57
58
  [anthropic]
58
59
  langchain-anthropic>=0.1.13
@@ -75,6 +76,11 @@ psycopg2-binary
75
76
  lancedb
76
77
  tantivy
77
78
 
79
+ [excel]
80
+ xlwings
81
+ requests
82
+ rich
83
+
78
84
  [gcp]
79
85
  google-api-python-client
80
86
  google-cloud-alloydb-connector[pg8000]
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes