sunholo 0.125.0__tar.gz → 0.125.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 (188) hide show
  1. {sunholo-0.125.0/src/sunholo.egg-info → sunholo-0.125.2}/PKG-INFO +1 -1
  2. {sunholo-0.125.0 → sunholo-0.125.2}/pyproject.toml +1 -1
  3. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/database/alloydb_client.py +99 -20
  4. {sunholo-0.125.0 → sunholo-0.125.2/src/sunholo.egg-info}/PKG-INFO +1 -1
  5. {sunholo-0.125.0 → sunholo-0.125.2}/LICENSE.txt +0 -0
  6. {sunholo-0.125.0 → sunholo-0.125.2}/MANIFEST.in +0 -0
  7. {sunholo-0.125.0 → sunholo-0.125.2}/README.md +0 -0
  8. {sunholo-0.125.0 → sunholo-0.125.2}/setup.cfg +0 -0
  9. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/__init__.py +0 -0
  10. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/agents/__init__.py +0 -0
  11. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/agents/chat_history.py +0 -0
  12. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/agents/dispatch_to_qa.py +0 -0
  13. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/agents/fastapi/__init__.py +0 -0
  14. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/agents/fastapi/base.py +0 -0
  15. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/agents/fastapi/qna_routes.py +0 -0
  16. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/agents/flask/__init__.py +0 -0
  17. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/agents/flask/base.py +0 -0
  18. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/agents/flask/qna_routes.py +0 -0
  19. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/agents/flask/vac_routes.py +0 -0
  20. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/agents/langserve.py +0 -0
  21. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/agents/pubsub.py +0 -0
  22. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/agents/route.py +0 -0
  23. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/agents/special_commands.py +0 -0
  24. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/agents/swagger.py +0 -0
  25. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/archive/__init__.py +0 -0
  26. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/archive/archive.py +0 -0
  27. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/auth/__init__.py +0 -0
  28. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/auth/gcloud.py +0 -0
  29. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/auth/refresh.py +0 -0
  30. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/auth/run.py +0 -0
  31. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/azure/__init__.py +0 -0
  32. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/azure/auth.py +0 -0
  33. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/azure/blobs.py +0 -0
  34. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/azure/event_grid.py +0 -0
  35. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/bots/__init__.py +0 -0
  36. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/bots/discord.py +0 -0
  37. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/bots/github_webhook.py +0 -0
  38. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/bots/webapp.py +0 -0
  39. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/chunker/__init__.py +0 -0
  40. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/chunker/azure.py +0 -0
  41. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/chunker/doc_handling.py +0 -0
  42. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/chunker/encode_metadata.py +0 -0
  43. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/chunker/images.py +0 -0
  44. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/chunker/loaders.py +0 -0
  45. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/chunker/message_data.py +0 -0
  46. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/chunker/pdfs.py +0 -0
  47. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/chunker/process_chunker_data.py +0 -0
  48. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/chunker/publish.py +0 -0
  49. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/chunker/pubsub.py +0 -0
  50. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/chunker/splitter.py +0 -0
  51. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/cli/__init__.py +0 -0
  52. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/cli/chat_vac.py +0 -0
  53. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/cli/cli.py +0 -0
  54. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/cli/cli_init.py +0 -0
  55. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/cli/configs.py +0 -0
  56. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/cli/deploy.py +0 -0
  57. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/cli/embedder.py +0 -0
  58. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/cli/merge_texts.py +0 -0
  59. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/cli/run_proxy.py +0 -0
  60. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/cli/sun_rich.py +0 -0
  61. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/cli/swagger.py +0 -0
  62. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/cli/vertex.py +0 -0
  63. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/components/__init__.py +0 -0
  64. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/components/llm.py +0 -0
  65. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/components/retriever.py +0 -0
  66. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/components/vectorstore.py +0 -0
  67. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/custom_logging.py +0 -0
  68. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/database/__init__.py +0 -0
  69. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/database/alloydb.py +0 -0
  70. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/database/database.py +0 -0
  71. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/database/lancedb.py +0 -0
  72. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/database/sql/sb/create_function.sql +0 -0
  73. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/database/sql/sb/create_function_time.sql +0 -0
  74. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/database/sql/sb/create_table.sql +0 -0
  75. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/database/sql/sb/delete_source_row.sql +0 -0
  76. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/database/sql/sb/return_sources.sql +0 -0
  77. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/database/sql/sb/setup.sql +0 -0
  78. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/database/static_dbs.py +0 -0
  79. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/database/uuid.py +0 -0
  80. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/discovery_engine/__init__.py +0 -0
  81. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/discovery_engine/chunker_handler.py +0 -0
  82. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/discovery_engine/cli.py +0 -0
  83. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/discovery_engine/create_new.py +0 -0
  84. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/discovery_engine/discovery_engine_client.py +0 -0
  85. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/discovery_engine/get_ai_search_chunks.py +0 -0
  86. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/embedder/__init__.py +0 -0
  87. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/embedder/embed_chunk.py +0 -0
  88. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/embedder/embed_metadata.py +0 -0
  89. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/excel/__init__.py +0 -0
  90. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/excel/plugin.py +0 -0
  91. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/gcs/__init__.py +0 -0
  92. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/gcs/add_file.py +0 -0
  93. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/gcs/download_folder.py +0 -0
  94. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/gcs/download_url.py +0 -0
  95. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/gcs/extract_and_sign.py +0 -0
  96. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/gcs/metadata.py +0 -0
  97. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/genai/__init__.py +0 -0
  98. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/genai/file_handling.py +0 -0
  99. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/genai/genaiv2.py +0 -0
  100. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/genai/images.py +0 -0
  101. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/genai/init.py +0 -0
  102. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/genai/process_funcs_cls.py +0 -0
  103. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/genai/safety.py +0 -0
  104. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/invoke/__init__.py +0 -0
  105. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/invoke/async_class.py +0 -0
  106. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/invoke/direct_vac_func.py +0 -0
  107. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/invoke/invoke_vac_utils.py +0 -0
  108. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/langchain_types.py +0 -0
  109. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/langfuse/__init__.py +0 -0
  110. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/langfuse/callback.py +0 -0
  111. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/langfuse/evals.py +0 -0
  112. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/langfuse/prompts.py +0 -0
  113. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/llamaindex/__init__.py +0 -0
  114. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/llamaindex/get_files.py +0 -0
  115. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/llamaindex/import_files.py +0 -0
  116. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/llamaindex/llamaindex_class.py +0 -0
  117. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/llamaindex/user_history.py +0 -0
  118. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/lookup/__init__.py +0 -0
  119. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/lookup/model_lookup.yaml +0 -0
  120. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/mcp/__init__.py +0 -0
  121. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/mcp/cli.py +0 -0
  122. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/ollama/__init__.py +0 -0
  123. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/ollama/ollama_images.py +0 -0
  124. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/pubsub/__init__.py +0 -0
  125. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/pubsub/process_pubsub.py +0 -0
  126. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/pubsub/pubsub_manager.py +0 -0
  127. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/qna/__init__.py +0 -0
  128. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/qna/parsers.py +0 -0
  129. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/qna/retry.py +0 -0
  130. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/senses/__init__.py +0 -0
  131. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/senses/stream_voice.py +0 -0
  132. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/streaming/__init__.py +0 -0
  133. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/streaming/content_buffer.py +0 -0
  134. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/streaming/langserve.py +0 -0
  135. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/streaming/stream_lookup.py +0 -0
  136. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/streaming/streaming.py +0 -0
  137. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/summarise/__init__.py +0 -0
  138. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/summarise/summarise.py +0 -0
  139. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/templates/agent/__init__.py +0 -0
  140. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/templates/agent/agent_service.py +0 -0
  141. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/templates/agent/app.py +0 -0
  142. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/templates/agent/my_log.py +0 -0
  143. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/templates/agent/tools/__init__.py +0 -0
  144. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/templates/agent/tools/your_agent.py +0 -0
  145. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/templates/agent/vac_service.py +0 -0
  146. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/templates/project/__init__.py +0 -0
  147. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/templates/project/app.py +0 -0
  148. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/templates/project/my_log.py +0 -0
  149. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/templates/project/vac_service.py +0 -0
  150. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/templates/system_services/__init__.py +0 -0
  151. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/templates/system_services/app.py +0 -0
  152. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/templates/system_services/my_log.py +0 -0
  153. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/terraform/__init__.py +0 -0
  154. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/terraform/tfvars_editor.py +0 -0
  155. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/tools/__init__.py +0 -0
  156. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/tools/web_browser.py +0 -0
  157. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/utils/__init__.py +0 -0
  158. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/utils/api_key.py +0 -0
  159. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/utils/big_context.py +0 -0
  160. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/utils/config.py +0 -0
  161. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/utils/config_class.py +0 -0
  162. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/utils/config_schema.py +0 -0
  163. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/utils/gcp.py +0 -0
  164. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/utils/gcp_project.py +0 -0
  165. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/utils/mime.py +0 -0
  166. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/utils/parsers.py +0 -0
  167. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/utils/timedelta.py +0 -0
  168. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/utils/user_ids.py +0 -0
  169. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/utils/version.py +0 -0
  170. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/vertex/__init__.py +0 -0
  171. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/vertex/extensions_call.py +0 -0
  172. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/vertex/extensions_class.py +0 -0
  173. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/vertex/genai_functions.py +0 -0
  174. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/vertex/init.py +0 -0
  175. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/vertex/memory_tools.py +0 -0
  176. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/vertex/safety.py +0 -0
  177. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo/vertex/type_dict_to_json.py +0 -0
  178. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo.egg-info/SOURCES.txt +0 -0
  179. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo.egg-info/dependency_links.txt +0 -0
  180. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo.egg-info/entry_points.txt +0 -0
  181. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo.egg-info/requires.txt +0 -0
  182. {sunholo-0.125.0 → sunholo-0.125.2}/src/sunholo.egg-info/top_level.txt +0 -0
  183. {sunholo-0.125.0 → sunholo-0.125.2}/tests/test_async.py +0 -0
  184. {sunholo-0.125.0 → sunholo-0.125.2}/tests/test_async_genai2.py +0 -0
  185. {sunholo-0.125.0 → sunholo-0.125.2}/tests/test_chat_history.py +0 -0
  186. {sunholo-0.125.0 → sunholo-0.125.2}/tests/test_config.py +0 -0
  187. {sunholo-0.125.0 → sunholo-0.125.2}/tests/test_genai2.py +0 -0
  188. {sunholo-0.125.0 → sunholo-0.125.2}/tests/test_unstructured.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sunholo
3
- Version: 0.125.0
3
+ Version: 0.125.2
4
4
  Summary: Large Language Model DevOps - a package to help deploy LLMs to the Cloud.
5
5
  Author-email: Holosun ApS <multivac@sunholo.com>
6
6
  License: Apache License, Version 2.0
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "sunholo"
7
- version = "0.125.0"
7
+ version = "0.125.2"
8
8
  description = "Large Language Model DevOps - a package to help deploy LLMs to the Cloud."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -584,7 +584,8 @@ class AlloyDBClient:
584
584
 
585
585
  async def create_table_from_schema(self, table_name: str, schema_data: dict, users: list = None):
586
586
  """
587
- Creates or ensures a table exists based on the structure of the provided schema data.
587
+ Creates or ensures a table exists based on the structure of the provided schema data,
588
+ with special handling for expandable lists.
588
589
 
589
590
  Args:
590
591
  table_name (str): Name of the table to create
@@ -596,22 +597,33 @@ class AlloyDBClient:
596
597
  """
597
598
  # Generate column definitions from schema data
598
599
  columns = []
600
+
599
601
  for key, value in schema_data.items():
600
- if isinstance(value, dict):
601
- # For nested objects, store as JSONB
602
- columns.append(f'"{key}" JSONB')
603
- elif isinstance(value, list):
604
- # For arrays, store as JSONB
605
- columns.append(f'"{key}" JSONB')
606
- elif isinstance(value, int):
607
- columns.append(f'"{key}" INTEGER')
608
- elif isinstance(value, float):
609
- columns.append(f'"{key}" NUMERIC')
610
- elif isinstance(value, bool):
611
- columns.append(f'"{key}" BOOLEAN')
602
+ # Check if this is a specially marked expandable list
603
+ if isinstance(value, dict) and value.get("__is_expandable_list__", False):
604
+ # Handle expandable lists - we need to examine the first item to determine column types
605
+ items = value.get("items", [])
606
+
607
+ # Add an index column for this list
608
+ columns.append(f'"{key}_index" INTEGER')
609
+
610
+ if items and isinstance(items[0], dict):
611
+ # If the first item is a dictionary, we need to create columns for all its keys
612
+ sample_item = items[0]
613
+
614
+ # Create columns for all keys in the sample item
615
+ for item_key, item_value in sample_item.items():
616
+ column_key = f"{key}_{item_key}"
617
+ column_type = self._get_sql_type(item_value)
618
+ columns.append(f'"{column_key}" {column_type}')
619
+ else:
620
+ # If items are simple values, just add a column for the list key itself
621
+ column_type = self._get_sql_type(items[0] if items else None)
622
+ columns.append(f'"{key}" {column_type}')
612
623
  else:
613
- # Default to TEXT for strings and other types
614
- columns.append(f'"{key}" TEXT')
624
+ # Regular handling for non-list fields
625
+ column_type = self._get_sql_type(value)
626
+ columns.append(f'"{key}" {column_type}')
615
627
 
616
628
  # Add metadata columns
617
629
  columns.extend([
@@ -645,13 +657,69 @@ class AlloyDBClient:
645
657
  for user in users:
646
658
  grant_sql = f'GRANT SELECT, INSERT, UPDATE, DELETE ON TABLE "{table_name}" TO "{user}";'
647
659
  if self.engine_type == "pg8000":
648
- self.execute_sql(grant_sql)
660
+ self._execute_sql_pg8000(grant_sql)
649
661
  else:
650
662
  await self._execute_sql_async_langchain(grant_sql)
651
663
 
652
664
  return result
653
665
 
654
- def flatten_dict(self, nested_dict, parent_key='', separator='.'):
666
+ def _get_sql_type(self, value):
667
+ """
668
+ Helper method to determine SQL type from a Python value.
669
+
670
+ Args:
671
+ value: The value to determine the column type
672
+
673
+ Returns:
674
+ str: SQL type
675
+ """
676
+ if value is None:
677
+ # For unknown types (None), default to TEXT
678
+ return "TEXT"
679
+ elif isinstance(value, dict):
680
+ # For nested objects, store as JSONB
681
+ return "JSONB"
682
+ elif isinstance(value, list):
683
+ # For arrays, store as JSONB
684
+ return "JSONB"
685
+ elif isinstance(value, int):
686
+ return "INTEGER"
687
+ elif isinstance(value, float):
688
+ return "NUMERIC"
689
+ elif isinstance(value, bool):
690
+ return "BOOLEAN"
691
+ else:
692
+ # Default to TEXT for strings and other types
693
+ return "TEXT"
694
+
695
+ def _flatten_dict_for_schema(self, nested_dict, parent_key='', separator='.'):
696
+ """
697
+ Flatten a nested dictionary for schema creation.
698
+
699
+ Args:
700
+ nested_dict (dict): The nested dictionary to flatten
701
+ parent_key (str): The parent key for the current recursion level
702
+ separator (str): The separator to use between key levels
703
+
704
+ Returns:
705
+ dict: A flattened dictionary
706
+ """
707
+ flattened = {}
708
+
709
+ for key, value in nested_dict.items():
710
+ # Create the new key with parent_key if it exists
711
+ new_key = f"{parent_key}{separator}{key}" if parent_key else key
712
+
713
+ # If value is a dictionary, recursively flatten it
714
+ if isinstance(value, dict):
715
+ flattened.update(self._flatten_dict_for_schema(value, new_key, separator))
716
+ else:
717
+ # For simple values, just add them with the new key
718
+ flattened[new_key] = value
719
+
720
+ return flattened
721
+
722
+ def _flatten_dict(self, nested_dict, parent_key='', separator='.'):
655
723
  """
656
724
  Flatten a nested dictionary into a single-level dictionary with dot notation for keys.
657
725
 
@@ -671,7 +739,7 @@ class AlloyDBClient:
671
739
 
672
740
  # If value is a dictionary, recursively flatten it
673
741
  if isinstance(value, dict):
674
- flattened.update(self.flatten_dict(value, new_key, separator))
742
+ flattened.update(self._flatten_dict(value, new_key, separator))
675
743
  # Handle lists containing dictionaries or other values
676
744
  elif isinstance(value, list):
677
745
  # Mark lists for special processing during database insertion
@@ -721,6 +789,8 @@ class AlloyDBClient:
721
789
  primary_list_key = next(iter(expandable_lists))
722
790
  primary_list = expandable_lists[primary_list_key]
723
791
 
792
+ log.info(f"Expanding list '{primary_list_key}' with {len(primary_list)} items into separate rows")
793
+
724
794
  # For each item in the primary list, create a new row
725
795
  for item_idx, item in enumerate(primary_list):
726
796
  # Create a copy of the regular data
@@ -729,7 +799,12 @@ class AlloyDBClient:
729
799
  # Add the current item from the primary list
730
800
  if isinstance(item, dict):
731
801
  # If it's a dictionary, flatten it with the primary key as prefix
732
- flattened_item = self.flatten_dict(item, primary_list_key, "_")
802
+ flattened_item = {}
803
+ for k, v in item.items():
804
+ flattened_key = f"{primary_list_key}_{k}"
805
+ flattened_item[flattened_key] = v
806
+
807
+ # Update row data with flattened item
733
808
  row_data.update(flattened_item)
734
809
  else:
735
810
  # If it's a simple value, just add it with the list key
@@ -741,8 +816,12 @@ class AlloyDBClient:
741
816
  # Insert this row
742
817
  result = await self._insert_single_row(table_name, row_data, metadata)
743
818
  results.append(result)
819
+
820
+ return results
744
821
 
745
- return results
822
+ # If we somehow get here (shouldn't happen), fall back to single row insert
823
+ return await self._insert_single_row(table_name, regular_data, metadata)
824
+
746
825
 
747
826
  async def _insert_single_row(self, table_name: str, data: dict, metadata: dict = None):
748
827
  """
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sunholo
3
- Version: 0.125.0
3
+ Version: 0.125.2
4
4
  Summary: Large Language Model DevOps - a package to help deploy LLMs to the Cloud.
5
5
  Author-email: Holosun ApS <multivac@sunholo.com>
6
6
  License: Apache License, Version 2.0
File without changes
File without changes
File without changes
File without changes
File without changes