sunholo 0.88.2__tar.gz → 0.88.4__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 (160) hide show
  1. {sunholo-0.88.2 → sunholo-0.88.4}/PKG-INFO +2 -2
  2. {sunholo-0.88.2 → sunholo-0.88.4}/setup.py +1 -1
  3. sunholo-0.88.4/sunholo/cli/cli_init.py +215 -0
  4. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/utils/parsers.py +34 -0
  5. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo.egg-info/PKG-INFO +2 -2
  6. sunholo-0.88.2/sunholo/cli/cli_init.py +0 -116
  7. {sunholo-0.88.2 → sunholo-0.88.4}/LICENSE.txt +0 -0
  8. {sunholo-0.88.2 → sunholo-0.88.4}/MANIFEST.in +0 -0
  9. {sunholo-0.88.2 → sunholo-0.88.4}/README.md +0 -0
  10. {sunholo-0.88.2 → sunholo-0.88.4}/setup.cfg +0 -0
  11. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/__init__.py +0 -0
  12. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/agents/__init__.py +0 -0
  13. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/agents/chat_history.py +0 -0
  14. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/agents/dispatch_to_qa.py +0 -0
  15. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/agents/fastapi/__init__.py +0 -0
  16. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/agents/fastapi/base.py +0 -0
  17. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/agents/fastapi/qna_routes.py +0 -0
  18. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/agents/flask/__init__.py +0 -0
  19. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/agents/flask/base.py +0 -0
  20. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/agents/flask/qna_routes.py +0 -0
  21. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/agents/flask/vac_routes.py +0 -0
  22. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/agents/langserve.py +0 -0
  23. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/agents/pubsub.py +0 -0
  24. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/agents/route.py +0 -0
  25. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/agents/special_commands.py +0 -0
  26. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/agents/swagger.py +0 -0
  27. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/archive/__init__.py +0 -0
  28. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/archive/archive.py +0 -0
  29. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/auth/__init__.py +0 -0
  30. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/auth/gcloud.py +0 -0
  31. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/auth/refresh.py +0 -0
  32. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/auth/run.py +0 -0
  33. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/azure/__init__.py +0 -0
  34. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/azure/auth.py +0 -0
  35. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/azure/blobs.py +0 -0
  36. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/azure/event_grid.py +0 -0
  37. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/bots/__init__.py +0 -0
  38. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/bots/discord.py +0 -0
  39. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/bots/github_webhook.py +0 -0
  40. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/bots/webapp.py +0 -0
  41. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/chunker/__init__.py +0 -0
  42. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/chunker/azure.py +0 -0
  43. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/chunker/doc_handling.py +0 -0
  44. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/chunker/encode_metadata.py +0 -0
  45. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/chunker/images.py +0 -0
  46. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/chunker/loaders.py +0 -0
  47. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/chunker/message_data.py +0 -0
  48. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/chunker/pdfs.py +0 -0
  49. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/chunker/process_chunker_data.py +0 -0
  50. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/chunker/publish.py +0 -0
  51. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/chunker/pubsub.py +0 -0
  52. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/chunker/splitter.py +0 -0
  53. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/cli/__init__.py +0 -0
  54. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/cli/chat_vac.py +0 -0
  55. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/cli/cli.py +0 -0
  56. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/cli/configs.py +0 -0
  57. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/cli/deploy.py +0 -0
  58. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/cli/embedder.py +0 -0
  59. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/cli/merge_texts.py +0 -0
  60. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/cli/run_proxy.py +0 -0
  61. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/cli/sun_rich.py +0 -0
  62. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/cli/swagger.py +0 -0
  63. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/cli/vertex.py +0 -0
  64. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/components/__init__.py +0 -0
  65. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/components/llm.py +0 -0
  66. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/components/retriever.py +0 -0
  67. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/components/vectorstore.py +0 -0
  68. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/custom_logging.py +0 -0
  69. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/database/__init__.py +0 -0
  70. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/database/alloydb.py +0 -0
  71. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/database/alloydb_client.py +0 -0
  72. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/database/database.py +0 -0
  73. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/database/lancedb.py +0 -0
  74. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/database/sql/sb/create_function.sql +0 -0
  75. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/database/sql/sb/create_function_time.sql +0 -0
  76. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/database/sql/sb/create_table.sql +0 -0
  77. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/database/sql/sb/delete_source_row.sql +0 -0
  78. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/database/sql/sb/return_sources.sql +0 -0
  79. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/database/sql/sb/setup.sql +0 -0
  80. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/database/static_dbs.py +0 -0
  81. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/database/uuid.py +0 -0
  82. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/discovery_engine/__init__.py +0 -0
  83. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/discovery_engine/chunker_handler.py +0 -0
  84. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/discovery_engine/create_new.py +0 -0
  85. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/discovery_engine/discovery_engine_client.py +0 -0
  86. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/discovery_engine/get_ai_search_chunks.py +0 -0
  87. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/embedder/__init__.py +0 -0
  88. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/embedder/embed_chunk.py +0 -0
  89. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/excel/__init__.py +0 -0
  90. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/excel/plugin.py +0 -0
  91. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/gcs/__init__.py +0 -0
  92. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/gcs/add_file.py +0 -0
  93. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/gcs/download_folder.py +0 -0
  94. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/gcs/download_url.py +0 -0
  95. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/gcs/metadata.py +0 -0
  96. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/genai/__init__.py +0 -0
  97. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/genai/init.py +0 -0
  98. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/genai/process_funcs_cls.py +0 -0
  99. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/genai/safety.py +0 -0
  100. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/invoke/__init__.py +0 -0
  101. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/invoke/async_class.py +0 -0
  102. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/invoke/direct_vac_func.py +0 -0
  103. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/invoke/invoke_vac_utils.py +0 -0
  104. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/langfuse/__init__.py +0 -0
  105. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/langfuse/callback.py +0 -0
  106. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/langfuse/prompts.py +0 -0
  107. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/llamaindex/__init__.py +0 -0
  108. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/llamaindex/get_files.py +0 -0
  109. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/llamaindex/import_files.py +0 -0
  110. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/llamaindex/llamaindex_class.py +0 -0
  111. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/llamaindex/user_history.py +0 -0
  112. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/lookup/__init__.py +0 -0
  113. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/lookup/model_lookup.yaml +0 -0
  114. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/patches/__init__.py +0 -0
  115. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/patches/langchain/__init__.py +0 -0
  116. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/patches/langchain/lancedb.py +0 -0
  117. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/patches/langchain/vertexai.py +0 -0
  118. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/pubsub/__init__.py +0 -0
  119. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/pubsub/process_pubsub.py +0 -0
  120. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/pubsub/pubsub_manager.py +0 -0
  121. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/qna/__init__.py +0 -0
  122. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/qna/parsers.py +0 -0
  123. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/qna/retry.py +0 -0
  124. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/streaming/__init__.py +0 -0
  125. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/streaming/content_buffer.py +0 -0
  126. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/streaming/langserve.py +0 -0
  127. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/streaming/stream_lookup.py +0 -0
  128. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/streaming/streaming.py +0 -0
  129. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/summarise/__init__.py +0 -0
  130. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/summarise/summarise.py +0 -0
  131. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/terraform/__init__.py +0 -0
  132. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/terraform/tfvars_editor.py +0 -0
  133. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/tools/__init__.py +0 -0
  134. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/tools/web_browser.py +0 -0
  135. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/utils/__init__.py +0 -0
  136. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/utils/api_key.py +0 -0
  137. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/utils/big_context.py +0 -0
  138. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/utils/config.py +0 -0
  139. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/utils/config_class.py +0 -0
  140. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/utils/config_schema.py +0 -0
  141. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/utils/gcp.py +0 -0
  142. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/utils/gcp_project.py +0 -0
  143. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/utils/timedelta.py +0 -0
  144. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/utils/user_ids.py +0 -0
  145. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/utils/version.py +0 -0
  146. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/vertex/__init__.py +0 -0
  147. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/vertex/extensions_call.py +0 -0
  148. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/vertex/extensions_class.py +0 -0
  149. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/vertex/genai_functions.py +0 -0
  150. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/vertex/init.py +0 -0
  151. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/vertex/memory_tools.py +0 -0
  152. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/vertex/safety.py +0 -0
  153. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo/vertex/type_dict_to_json.py +0 -0
  154. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo.egg-info/SOURCES.txt +0 -0
  155. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo.egg-info/dependency_links.txt +0 -0
  156. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo.egg-info/entry_points.txt +0 -0
  157. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo.egg-info/requires.txt +0 -0
  158. {sunholo-0.88.2 → sunholo-0.88.4}/sunholo.egg-info/top_level.txt +0 -0
  159. {sunholo-0.88.2 → sunholo-0.88.4}/tests/test_chat_history.py +0 -0
  160. {sunholo-0.88.2 → sunholo-0.88.4}/tests/test_config.py +0 -0
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: sunholo
3
- Version: 0.88.2
3
+ Version: 0.88.4
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.88.2.tar.gz
6
+ Download-URL: https://github.com/sunholo-data/sunholo-py/archive/refs/tags/v0.88.4.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.88.2'
3
+ version = '0.88.4'
4
4
 
5
5
  setup(
6
6
  name='sunholo',
@@ -0,0 +1,215 @@
1
+ import os
2
+ import yaml
3
+ import shutil
4
+ from ..utils.config import get_module_filepath
5
+ from ..utils.parsers import sanitize_cloudrun_name
6
+
7
+ def init_project(args):
8
+ """
9
+ Initializes a new sunholo project with a basic configuration file and directory structure.
10
+
11
+ **Template Files (`templates/project`):**
12
+
13
+ A `templates/project` directory is within the `sunholo` package with the following template files in it:
14
+
15
+ * **`config/llm_config.yaml`:** A basic configuration file with placeholders for LLM settings, vector stores, etc.
16
+ * **`config/cloud_run_urls.json`:** A template for Cloud Run URLs.
17
+ * **`app.py`:** A basic Flask app that can be customized for the project.
18
+ * **`.gitignore`:** A gitignore file to exclude unnecessary files from version control.
19
+ * **`README.md`:** A README file with instructions for setting up and running the project.
20
+
21
+ **Usage:**
22
+
23
+ Users can initialize a new project using the following command:
24
+
25
+ ```bash
26
+ sunholo init my_genai_project
27
+ ```
28
+
29
+ This will create a new directory named `my_genai_project` with the template files, allowing users to start building their GenAI application.
30
+ """
31
+ from .sun_rich import console
32
+
33
+ project_name = sanitize_cloudrun_name(args.project_name)
34
+ current_dir = os.getcwd() # This captures the current directory where the command is run
35
+ project_dir = os.path.join(current_dir, project_name)
36
+
37
+ console.rule(project_name)
38
+ console.print(f"Initializing in directory: {project_dir}")
39
+
40
+ # Create project directory
41
+ if os.path.exists(project_dir):
42
+ console.print(f"[bold red]ERROR: Directory {project_dir} already exists. Please choose a different project name.[/bold red]")
43
+ return
44
+
45
+ os.makedirs(project_dir)
46
+
47
+ # Copy template files
48
+ template_dir = get_module_filepath("templates/project")
49
+ for filename in os.listdir(template_dir):
50
+ src_path = os.path.join(template_dir, filename)
51
+ dest_path = os.path.join(project_dir, filename)
52
+ if os.path.isfile(src_path):
53
+ shutil.copy(src_path, dest_path)
54
+ elif os.path.isdir(src_path):
55
+ shutil.copytree(src_path, dest_path)
56
+
57
+
58
+
59
+ # Determine the location of the generated.tfvars file
60
+ terraform_dir = args.terraform_dir or os.getenv('MULTIVAC_TERRAFORM_DIR')
61
+ if terraform_dir is None:
62
+ raise ValueError("Must specify a terraform_dir or use the MULTIVAC_TERRAFORM_DIR environment variable")
63
+
64
+ tfvars_file = os.path.join(terraform_dir, 'generated.tfvars')
65
+
66
+ # Get the service account, either from the CLI argument or default
67
+ service_account = args.service_account or "sa-llmops" # Default service account
68
+
69
+ # Paths to be included in the cloud build (based on the current working directory)
70
+ # We want paths to start from 'application/system_services/{project_name}'
71
+ relative_base = os.path.relpath(current_dir, os.path.join(current_dir, "..", ".."))
72
+ included_path = os.path.join(relative_base, project_name, "**")
73
+ cloud_build_path = os.path.join(relative_base, project_name, "cloudbuild.yaml")
74
+
75
+ update_cloudbuild_template(project_dir, project_name, os.path.join(relative_base, project_name))
76
+ write_vac_config(project_dir, project_name)
77
+
78
+ # Define the cloud_run configuration for 'discord-server' with the correct project_dir path
79
+ cloud_run_config = {
80
+ project_name: {
81
+ "cpu": "1",
82
+ "memory": "2Gi",
83
+ "max_instance_count": 3,
84
+ "timeout_seconds": 1500,
85
+ "port": 8080,
86
+ "service_account": service_account,
87
+ "invokers": ["allUsers"],
88
+ "cloud_build": {
89
+ "included": [included_path],
90
+ "path": cloud_build_path,
91
+ "substitutions": {},
92
+ "repo_name": "",
93
+ "repo_owner": ""
94
+ }
95
+ }
96
+ }
97
+
98
+
99
+ # Initialize the TerraformVarsEditor and update the .tfvars file
100
+ try:
101
+ from ..terraform import TerraformVarsEditor
102
+ editor = TerraformVarsEditor(tfvars_file, terraform_dir)
103
+ editor.update_from_dict(cloud_run_config, 'cloud_run_autogenerated')
104
+ except ImportError as e:
105
+ console.print(f"Error initializing TerraformVarsEditor: {e}")
106
+
107
+ from rich.panel import Panel
108
+
109
+ console.print(
110
+ Panel((
111
+ "Next steps: \n"
112
+ f" - Navigate to [orange]{project_dir}/config[/orange] and customize VAC configuration files.\n"
113
+ f" - Add your own GenAI app logic to [orange]{project_dir}/vac_service.py[/orange]\n"
114
+ f" - Check terraform [orange]{terraform_dir}/generated.tfvars[/orange] for Multivac deployment"
115
+ ),
116
+ title=f"Project [bold orange]{project_name}[/bold orange] initialized successfully.",
117
+ subtitle=project_dir),
118
+ )
119
+ console.rule()
120
+
121
+ def update_cloudbuild_template(project_dir: str, service_name: str, build_folder: str):
122
+ """
123
+ Updates the cloudbuild.yaml template file by replacing the `CHANGE_ME` placeholders with actual values.
124
+
125
+ Args:
126
+ -----
127
+ project_dir : str
128
+ The directory where the project and cloudbuild.yaml are located.
129
+ service_name : str
130
+ The name of the service to be used in Cloud Run.
131
+ build_folder : str
132
+ The build folder where the Docker build will take place.
133
+
134
+ Example:
135
+ -------
136
+ update_cloudbuild_template('/path/to/project', 'my_service', 'src')
137
+ """
138
+ cloudbuild_path = os.path.join(project_dir, "cloudbuild.yaml")
139
+
140
+ # Define the substitutions to replace CHANGE_ME
141
+ substitutions = {
142
+ "_SERVICE_NAME": service_name,
143
+ "_BUILD_FOLDER": build_folder,
144
+ }
145
+
146
+ # Read the cloudbuild.yaml template
147
+ with open(cloudbuild_path, 'r') as file:
148
+ content = file.read()
149
+
150
+ # Replace each placeholder with its corresponding value
151
+ for placeholder, value in substitutions.items():
152
+ content = content.replace(f"{placeholder}: CHANGE_ME", f"{placeholder}: {value}")
153
+
154
+
155
+ # Write the updated content back to cloudbuild.yaml
156
+ with open(cloudbuild_path, 'w') as file:
157
+ file.write(content)
158
+
159
+ print(f"cloudbuild.yaml updated successfully with service name '{service_name}' and build folder '{build_folder}'.")
160
+
161
+ def write_vac_config(project_dir: str, service_name: str):
162
+ """
163
+ Writes the vac_config.yaml file with the provided service name as the key.
164
+ """
165
+ vac_config_content = {
166
+ 'kind': 'vacConfig',
167
+ 'apiVersion': 'v1',
168
+ 'vac': {
169
+ service_name: { # Use the service name here
170
+ 'llm': 'vertex',
171
+ 'model': 'gemini-1.5-pro-preview-0514',
172
+ 'agent': 'vertex-genai',
173
+ 'display_name': 'Template VAC',
174
+ 'memory': [
175
+ {
176
+ 'llamaindex-native': {
177
+ 'vectorstore': 'llamaindex'
178
+ }
179
+ }
180
+ ],
181
+ 'gcp_config': {
182
+ 'project_id': 'llamaindex_project',
183
+ 'location': 'europe-west1',
184
+ 'rag_id': '1234544343434' # Replace with actual RAG ID
185
+ },
186
+ 'chunker': {
187
+ 'chunk_size': 1000,
188
+ 'overlap': 200
189
+ }
190
+ }
191
+ }
192
+ }
193
+
194
+ config_dir = os.path.join(project_dir, 'config')
195
+ if not os.path.exists(config_dir):
196
+ os.makedirs(config_dir)
197
+
198
+ vac_config_path = os.path.join(config_dir, 'vac_config.yaml')
199
+
200
+ # Write the YAML configuration to the file
201
+ with open(vac_config_path, 'w') as file:
202
+ yaml.dump(vac_config_content, file, default_flow_style=False)
203
+
204
+ print(f"vac_config.yaml written successfully with service name '{service_name}'.")
205
+
206
+
207
+ def setup_init_subparser(subparsers):
208
+ """
209
+ Sets up an argparse subparser for the 'init' command.
210
+ """
211
+ init_parser = subparsers.add_parser('init', help='Initializes a new Multivac project.')
212
+ init_parser.add_argument('project_name', help='The name of the new project.')
213
+ init_parser.add_argument('--terraform-dir', help='The directory where Terraform files will be generated.')
214
+ init_parser.add_argument('--service-account', help='The service account to use for Cloud Run. Defaults to "sa-llmops"')
215
+ init_parser.set_defaults(func=init_project)
@@ -15,6 +15,40 @@ import re
15
15
  import hashlib
16
16
  import urllib.parse
17
17
 
18
+ def sanitize_cloudrun_name(name: str) -> str:
19
+ """
20
+ Sanitizes the project name to be a valid Cloud Run service name.
21
+
22
+ - Converts to lowercase.
23
+ - Replaces invalid characters with hyphens.
24
+ - Ensures the name starts with a letter.
25
+ - Trims the name to be less than 64 characters.
26
+ - Removes trailing hyphens.
27
+
28
+ Args:
29
+ name (str): The original project name.
30
+
31
+ Returns:
32
+ str: The sanitized project name.
33
+ """
34
+ # Convert to lowercase
35
+ name = name.lower()
36
+
37
+ # Replace invalid characters with hyphens
38
+ name = re.sub(r'[^a-z0-9-]', '-', name)
39
+
40
+ # Ensure the name starts with a letter
41
+ if not name[0].isalpha():
42
+ name = 'a' + name
43
+
44
+ # Trim to 63 characters to leave room for suffixes if needed
45
+ name = name[:63]
46
+
47
+ # Remove trailing hyphens
48
+ name = name.rstrip('-')
49
+
50
+ return name
51
+
18
52
  def validate_extension_id(ext_id):
19
53
  """
20
54
  Ensures the passed string fits the criteria for an extension ID.
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: sunholo
3
- Version: 0.88.2
3
+ Version: 0.88.4
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.88.2.tar.gz
6
+ Download-URL: https://github.com/sunholo-data/sunholo-py/archive/refs/tags/v0.88.4.tar.gz
7
7
  Author: Holosun ApS
8
8
  Author-email: multivac@sunholo.com
9
9
  License: Apache License, Version 2.0
@@ -1,116 +0,0 @@
1
- import os
2
- import shutil
3
- from ..utils.config import get_module_filepath
4
-
5
- def init_project(args):
6
- """
7
- Initializes a new sunholo project with a basic configuration file and directory structure.
8
-
9
- **Template Files (`templates/project`):**
10
-
11
- A `templates/project` directory is within the `sunholo` package with the following template files in it:
12
-
13
- * **`config/llm_config.yaml`:** A basic configuration file with placeholders for LLM settings, vector stores, etc.
14
- * **`config/cloud_run_urls.json`:** A template for Cloud Run URLs.
15
- * **`app.py`:** A basic Flask app that can be customized for the project.
16
- * **`.gitignore`:** A gitignore file to exclude unnecessary files from version control.
17
- * **`README.md`:** A README file with instructions for setting up and running the project.
18
-
19
- **Usage:**
20
-
21
- Users can initialize a new project using the following command:
22
-
23
- ```bash
24
- sunholo init my_genai_project
25
- ```
26
-
27
- This will create a new directory named `my_genai_project` with the template files, allowing users to start building their GenAI application.
28
- """
29
- project_name = args.project_name
30
- current_dir = os.getcwd() # This captures the current directory where the command is run
31
- project_dir = os.path.join(current_dir, project_name)
32
-
33
- print(f"Initializing project: {project_name} in directory: {project_dir}")
34
-
35
- # Create project directory
36
- if os.path.exists(project_dir):
37
- print(f"Directory {project_dir} already exists. Please choose a different project name.")
38
- return
39
-
40
- os.makedirs(project_dir)
41
-
42
- # Copy template files
43
- template_dir = get_module_filepath("templates/project")
44
- for filename in os.listdir(template_dir):
45
- src_path = os.path.join(template_dir, filename)
46
- dest_path = os.path.join(project_dir, filename)
47
- if os.path.isfile(src_path):
48
- shutil.copy(src_path, dest_path)
49
- elif os.path.isdir(src_path):
50
- shutil.copytree(src_path, dest_path)
51
-
52
- # Determine the location of the generated.tfvars file
53
- terraform_dir = args.terraform_dir or os.getenv('MULTIVAC_TERRAFORM_DIR')
54
- if terraform_dir is None:
55
- raise ValueError("Must specify a terraform_dir or use the MULTIVAC_TERRAFORM_DIR environment variable")
56
-
57
- tfvars_file = os.path.join(terraform_dir, 'generated.tfvars')
58
-
59
- # Get the service account, either from the CLI argument or default
60
- service_account = args.service_account or "sa-llmops" # Default service account
61
-
62
- # Determine the relative path for the cloud build included directories
63
- def get_relative_application_path(full_path: str, base_dir: str) -> str:
64
- application_base_index = full_path.find("application/")
65
- if application_base_index != -1:
66
- return full_path[application_base_index:]
67
- return os.path.relpath(full_path, base_dir)
68
-
69
- # Paths to be included in the cloud build (based on the current working directory)
70
- # We want paths to start from 'application/system_services/{project_name}'
71
- relative_base = os.path.relpath(current_dir, os.path.join(current_dir, "..", ".."))
72
- included_path = os.path.join(relative_base, project_name, "**")
73
- cloud_build_path = os.path.join(relative_base, project_name, "cloudbuild.yaml")
74
-
75
- # Define the cloud_run configuration for 'discord-server' with the correct project_dir path
76
- cloud_run_config = {
77
- project_name: {
78
- "cpu": "1",
79
- "memory": "2Gi",
80
- "max_instance_count": 3,
81
- "timeout_seconds": 1500,
82
- "port": 8080,
83
- "service_account": service_account,
84
- "invokers": ["allUsers"],
85
- "cloud_build": {
86
- "included": [included_path],
87
- "path": cloud_build_path,
88
- "substitutions": {},
89
- "repo_name": "",
90
- "repo_owner": ""
91
- }
92
- }
93
- }
94
-
95
-
96
- # Initialize the TerraformVarsEditor and update the .tfvars file
97
- try:
98
- from ..terraform import TerraformVarsEditor
99
- editor = TerraformVarsEditor(tfvars_file, terraform_dir)
100
- editor.update_from_dict(cloud_run_config, 'cloud_run')
101
- print(f"{tfvars_file} file initialized and updated successfully.")
102
- except ImportError as e:
103
- print(f"Error initializing TerraformVarsEditor: {e}")
104
-
105
- print(f"Project {project_name} initialized successfully.")
106
- print(f"Navigate to {project_dir} and customize the configuration files in the 'config' directory.")
107
-
108
- def setup_init_subparser(subparsers):
109
- """
110
- Sets up an argparse subparser for the 'init' command.
111
- """
112
- init_parser = subparsers.add_parser('init', help='Initializes a new Multivac project.')
113
- init_parser.add_argument('project_name', help='The name of the new project.')
114
- init_parser.add_argument('--terraform-dir', help='The directory where Terraform files will be generated.')
115
- init_parser.add_argument('--service-account', help='The service account to use for Cloud Run. Defaults to "sa-llmops"')
116
- init_parser.set_defaults(func=init_project)
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
File without changes
File without changes
File without changes