asksql 2.1.0__py3-none-any.whl

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 (291) hide show
  1. asksql-2.1.0.dist-info/METADATA +517 -0
  2. asksql-2.1.0.dist-info/RECORD +291 -0
  3. asksql-2.1.0.dist-info/WHEEL +4 -0
  4. asksql-2.1.0.dist-info/entry_points.txt +4 -0
  5. asksql-2.1.0.dist-info/licenses/LICENSE +21 -0
  6. vanna/__init__.py +172 -0
  7. vanna/agents/__init__.py +7 -0
  8. vanna/capabilities/__init__.py +17 -0
  9. vanna/capabilities/agent_memory/__init__.py +21 -0
  10. vanna/capabilities/agent_memory/base.py +103 -0
  11. vanna/capabilities/agent_memory/models.py +53 -0
  12. vanna/capabilities/file_system/__init__.py +14 -0
  13. vanna/capabilities/file_system/base.py +71 -0
  14. vanna/capabilities/file_system/models.py +25 -0
  15. vanna/capabilities/sql_runner/__init__.py +13 -0
  16. vanna/capabilities/sql_runner/base.py +37 -0
  17. vanna/capabilities/sql_runner/models.py +13 -0
  18. vanna/components/__init__.py +92 -0
  19. vanna/components/base.py +11 -0
  20. vanna/components/rich/__init__.py +83 -0
  21. vanna/components/rich/containers/__init__.py +7 -0
  22. vanna/components/rich/containers/card.py +20 -0
  23. vanna/components/rich/data/__init__.py +9 -0
  24. vanna/components/rich/data/chart.py +17 -0
  25. vanna/components/rich/data/dataframe.py +93 -0
  26. vanna/components/rich/feedback/__init__.py +21 -0
  27. vanna/components/rich/feedback/badge.py +16 -0
  28. vanna/components/rich/feedback/icon_text.py +14 -0
  29. vanna/components/rich/feedback/log_viewer.py +41 -0
  30. vanna/components/rich/feedback/notification.py +19 -0
  31. vanna/components/rich/feedback/progress.py +37 -0
  32. vanna/components/rich/feedback/status_card.py +28 -0
  33. vanna/components/rich/feedback/status_indicator.py +14 -0
  34. vanna/components/rich/interactive/__init__.py +21 -0
  35. vanna/components/rich/interactive/button.py +95 -0
  36. vanna/components/rich/interactive/task_list.py +58 -0
  37. vanna/components/rich/interactive/ui_state.py +93 -0
  38. vanna/components/rich/specialized/__init__.py +7 -0
  39. vanna/components/rich/specialized/artifact.py +20 -0
  40. vanna/components/rich/text.py +16 -0
  41. vanna/components/simple/__init__.py +15 -0
  42. vanna/components/simple/image.py +15 -0
  43. vanna/components/simple/link.py +15 -0
  44. vanna/components/simple/text.py +11 -0
  45. vanna/core/__init__.py +193 -0
  46. vanna/core/_compat.py +19 -0
  47. vanna/core/agent/__init__.py +10 -0
  48. vanna/core/agent/agent.py +1407 -0
  49. vanna/core/agent/config.py +123 -0
  50. vanna/core/audit/__init__.py +28 -0
  51. vanna/core/audit/base.py +299 -0
  52. vanna/core/audit/models.py +131 -0
  53. vanna/core/component_manager.py +329 -0
  54. vanna/core/components.py +53 -0
  55. vanna/core/enhancer/__init__.py +11 -0
  56. vanna/core/enhancer/base.py +94 -0
  57. vanna/core/enhancer/default.py +118 -0
  58. vanna/core/enricher/__init__.py +10 -0
  59. vanna/core/enricher/base.py +59 -0
  60. vanna/core/errors.py +47 -0
  61. vanna/core/evaluation/__init__.py +81 -0
  62. vanna/core/evaluation/base.py +186 -0
  63. vanna/core/evaluation/dataset.py +254 -0
  64. vanna/core/evaluation/evaluators.py +376 -0
  65. vanna/core/evaluation/report.py +289 -0
  66. vanna/core/evaluation/runner.py +313 -0
  67. vanna/core/filter/__init__.py +10 -0
  68. vanna/core/filter/base.py +67 -0
  69. vanna/core/lifecycle/__init__.py +10 -0
  70. vanna/core/lifecycle/base.py +83 -0
  71. vanna/core/llm/__init__.py +16 -0
  72. vanna/core/llm/base.py +40 -0
  73. vanna/core/llm/models.py +61 -0
  74. vanna/core/middleware/__init__.py +10 -0
  75. vanna/core/middleware/base.py +69 -0
  76. vanna/core/observability/__init__.py +11 -0
  77. vanna/core/observability/base.py +88 -0
  78. vanna/core/observability/models.py +47 -0
  79. vanna/core/recovery/__init__.py +11 -0
  80. vanna/core/recovery/base.py +84 -0
  81. vanna/core/recovery/models.py +32 -0
  82. vanna/core/registry.py +278 -0
  83. vanna/core/rich_component.py +156 -0
  84. vanna/core/simple_component.py +27 -0
  85. vanna/core/storage/__init__.py +14 -0
  86. vanna/core/storage/base.py +46 -0
  87. vanna/core/storage/models.py +46 -0
  88. vanna/core/system_prompt/__init__.py +13 -0
  89. vanna/core/system_prompt/base.py +36 -0
  90. vanna/core/system_prompt/default.py +157 -0
  91. vanna/core/tool/__init__.py +18 -0
  92. vanna/core/tool/base.py +70 -0
  93. vanna/core/tool/models.py +84 -0
  94. vanna/core/user/__init__.py +17 -0
  95. vanna/core/user/base.py +29 -0
  96. vanna/core/user/models.py +25 -0
  97. vanna/core/user/request_context.py +70 -0
  98. vanna/core/user/resolver.py +42 -0
  99. vanna/core/validation.py +164 -0
  100. vanna/core/workflow/__init__.py +12 -0
  101. vanna/core/workflow/base.py +254 -0
  102. vanna/core/workflow/default.py +789 -0
  103. vanna/examples/__init__.py +1 -0
  104. vanna/examples/__main__.py +44 -0
  105. vanna/examples/anthropic_quickstart.py +80 -0
  106. vanna/examples/artifact_example.py +293 -0
  107. vanna/examples/claude_sqlite_example.py +236 -0
  108. vanna/examples/coding_agent_example.py +300 -0
  109. vanna/examples/custom_system_prompt_example.py +174 -0
  110. vanna/examples/default_workflow_handler_example.py +208 -0
  111. vanna/examples/email_auth_example.py +340 -0
  112. vanna/examples/evaluation_example.py +269 -0
  113. vanna/examples/extensibility_example.py +262 -0
  114. vanna/examples/minimal_example.py +67 -0
  115. vanna/examples/mock_auth_example.py +227 -0
  116. vanna/examples/mock_custom_tool.py +311 -0
  117. vanna/examples/mock_quickstart.py +79 -0
  118. vanna/examples/mock_quota_example.py +145 -0
  119. vanna/examples/mock_rich_components_demo.py +396 -0
  120. vanna/examples/mock_sqlite_example.py +223 -0
  121. vanna/examples/openai_quickstart.py +83 -0
  122. vanna/examples/primitive_components_demo.py +305 -0
  123. vanna/examples/quota_lifecycle_example.py +139 -0
  124. vanna/examples/visualization_example.py +251 -0
  125. vanna/integrations/__init__.py +17 -0
  126. vanna/integrations/anthropic/__init__.py +9 -0
  127. vanna/integrations/anthropic/llm.py +270 -0
  128. vanna/integrations/azureopenai/__init__.py +9 -0
  129. vanna/integrations/azureopenai/llm.py +329 -0
  130. vanna/integrations/azuresearch/__init__.py +7 -0
  131. vanna/integrations/azuresearch/agent_memory.py +413 -0
  132. vanna/integrations/bigquery/__init__.py +5 -0
  133. vanna/integrations/bigquery/sql_runner.py +81 -0
  134. vanna/integrations/chromadb/__init__.py +104 -0
  135. vanna/integrations/chromadb/agent_memory.py +488 -0
  136. vanna/integrations/clickhouse/__init__.py +5 -0
  137. vanna/integrations/clickhouse/sql_runner.py +82 -0
  138. vanna/integrations/duckdb/__init__.py +5 -0
  139. vanna/integrations/duckdb/sql_runner.py +65 -0
  140. vanna/integrations/faiss/__init__.py +7 -0
  141. vanna/integrations/faiss/agent_memory.py +435 -0
  142. vanna/integrations/google/__init__.py +9 -0
  143. vanna/integrations/google/gemini.py +370 -0
  144. vanna/integrations/hive/__init__.py +5 -0
  145. vanna/integrations/hive/sql_runner.py +87 -0
  146. vanna/integrations/local/__init__.py +17 -0
  147. vanna/integrations/local/agent_memory/__init__.py +7 -0
  148. vanna/integrations/local/agent_memory/in_memory.py +285 -0
  149. vanna/integrations/local/audit.py +59 -0
  150. vanna/integrations/local/file_system.py +242 -0
  151. vanna/integrations/local/file_system_conversation_store.py +255 -0
  152. vanna/integrations/local/storage.py +62 -0
  153. vanna/integrations/marqo/__init__.py +7 -0
  154. vanna/integrations/marqo/agent_memory.py +354 -0
  155. vanna/integrations/milvus/__init__.py +7 -0
  156. vanna/integrations/milvus/agent_memory.py +458 -0
  157. vanna/integrations/mock/__init__.py +9 -0
  158. vanna/integrations/mock/llm.py +65 -0
  159. vanna/integrations/mssql/__init__.py +5 -0
  160. vanna/integrations/mssql/sql_runner.py +66 -0
  161. vanna/integrations/mysql/__init__.py +5 -0
  162. vanna/integrations/mysql/sql_runner.py +92 -0
  163. vanna/integrations/ollama/__init__.py +7 -0
  164. vanna/integrations/ollama/llm.py +252 -0
  165. vanna/integrations/openai/__init__.py +10 -0
  166. vanna/integrations/openai/llm.py +267 -0
  167. vanna/integrations/openai/responses.py +163 -0
  168. vanna/integrations/opensearch/__init__.py +7 -0
  169. vanna/integrations/opensearch/agent_memory.py +411 -0
  170. vanna/integrations/oracle/__init__.py +5 -0
  171. vanna/integrations/oracle/sql_runner.py +75 -0
  172. vanna/integrations/pinecone/__init__.py +7 -0
  173. vanna/integrations/pinecone/agent_memory.py +329 -0
  174. vanna/integrations/plotly/__init__.py +5 -0
  175. vanna/integrations/plotly/chart_generator.py +313 -0
  176. vanna/integrations/postgres/__init__.py +9 -0
  177. vanna/integrations/postgres/sql_runner.py +112 -0
  178. vanna/integrations/premium/agent_memory/__init__.py +7 -0
  179. vanna/integrations/premium/agent_memory/premium.py +186 -0
  180. vanna/integrations/presto/__init__.py +5 -0
  181. vanna/integrations/presto/sql_runner.py +107 -0
  182. vanna/integrations/qdrant/__init__.py +7 -0
  183. vanna/integrations/qdrant/agent_memory.py +466 -0
  184. vanna/integrations/snowflake/__init__.py +5 -0
  185. vanna/integrations/snowflake/sql_runner.py +147 -0
  186. vanna/integrations/sqlite/__init__.py +9 -0
  187. vanna/integrations/sqlite/sql_runner.py +65 -0
  188. vanna/integrations/weaviate/__init__.py +7 -0
  189. vanna/integrations/weaviate/agent_memory.py +428 -0
  190. vanna/legacy/ZhipuAI/ZhipuAI_Chat.py +233 -0
  191. vanna/legacy/ZhipuAI/ZhipuAI_embeddings.py +79 -0
  192. vanna/legacy/ZhipuAI/__init__.py +2 -0
  193. vanna/legacy/__init__.py +403 -0
  194. vanna/legacy/adapter.py +468 -0
  195. vanna/legacy/advanced/__init__.py +28 -0
  196. vanna/legacy/anthropic/__init__.py +1 -0
  197. vanna/legacy/anthropic/anthropic_chat.py +80 -0
  198. vanna/legacy/azuresearch/__init__.py +1 -0
  199. vanna/legacy/azuresearch/azuresearch_vector.py +274 -0
  200. vanna/legacy/base/__init__.py +1 -0
  201. vanna/legacy/base/base.py +2133 -0
  202. vanna/legacy/base/safe_exec.py +190 -0
  203. vanna/legacy/bedrock/__init__.py +1 -0
  204. vanna/legacy/bedrock/bedrock_converse.py +86 -0
  205. vanna/legacy/chromadb/__init__.py +1 -0
  206. vanna/legacy/chromadb/chromadb_vector.py +259 -0
  207. vanna/legacy/cohere/__init__.py +2 -0
  208. vanna/legacy/cohere/cohere_chat.py +99 -0
  209. vanna/legacy/cohere/cohere_embeddings.py +77 -0
  210. vanna/legacy/deepseek/__init__.py +1 -0
  211. vanna/legacy/deepseek/deepseek_chat.py +59 -0
  212. vanna/legacy/exceptions/__init__.py +46 -0
  213. vanna/legacy/faiss/__init__.py +1 -0
  214. vanna/legacy/faiss/faiss.py +230 -0
  215. vanna/legacy/flask/__init__.py +1355 -0
  216. vanna/legacy/flask/assets.py +58 -0
  217. vanna/legacy/flask/auth.py +56 -0
  218. vanna/legacy/google/__init__.py +2 -0
  219. vanna/legacy/google/bigquery_vector.py +293 -0
  220. vanna/legacy/google/gemini_chat.py +78 -0
  221. vanna/legacy/hf/__init__.py +1 -0
  222. vanna/legacy/hf/hf.py +80 -0
  223. vanna/legacy/local.py +8 -0
  224. vanna/legacy/marqo/__init__.py +1 -0
  225. vanna/legacy/marqo/marqo.py +168 -0
  226. vanna/legacy/milvus/__init__.py +1 -0
  227. vanna/legacy/milvus/milvus_vector.py +328 -0
  228. vanna/legacy/mistral/__init__.py +1 -0
  229. vanna/legacy/mistral/mistral.py +51 -0
  230. vanna/legacy/mock/__init__.py +3 -0
  231. vanna/legacy/mock/embedding.py +11 -0
  232. vanna/legacy/mock/llm.py +18 -0
  233. vanna/legacy/mock/vectordb.py +67 -0
  234. vanna/legacy/ollama/__init__.py +1 -0
  235. vanna/legacy/ollama/ollama.py +110 -0
  236. vanna/legacy/openai/__init__.py +2 -0
  237. vanna/legacy/openai/openai_chat.py +124 -0
  238. vanna/legacy/openai/openai_embeddings.py +46 -0
  239. vanna/legacy/opensearch/__init__.py +2 -0
  240. vanna/legacy/opensearch/opensearch_vector.py +369 -0
  241. vanna/legacy/opensearch/opensearch_vector_semantic.py +200 -0
  242. vanna/legacy/oracle/__init__.py +1 -0
  243. vanna/legacy/oracle/oracle_vector.py +584 -0
  244. vanna/legacy/pgvector/__init__.py +1 -0
  245. vanna/legacy/pgvector/pgvector.py +282 -0
  246. vanna/legacy/pinecone/__init__.py +3 -0
  247. vanna/legacy/pinecone/pinecone_vector.py +275 -0
  248. vanna/legacy/qdrant/__init__.py +3 -0
  249. vanna/legacy/qdrant/qdrant.py +329 -0
  250. vanna/legacy/qianfan/Qianfan_Chat.py +170 -0
  251. vanna/legacy/qianfan/Qianfan_embeddings.py +36 -0
  252. vanna/legacy/qianfan/__init__.py +2 -0
  253. vanna/legacy/qianwen/QianwenAI_chat.py +132 -0
  254. vanna/legacy/qianwen/QianwenAI_embeddings.py +46 -0
  255. vanna/legacy/qianwen/__init__.py +2 -0
  256. vanna/legacy/remote.py +79 -0
  257. vanna/legacy/types/__init__.py +292 -0
  258. vanna/legacy/utils.py +72 -0
  259. vanna/legacy/vannadb/__init__.py +1 -0
  260. vanna/legacy/vannadb/vannadb_vector.py +468 -0
  261. vanna/legacy/vllm/__init__.py +1 -0
  262. vanna/legacy/vllm/vllm.py +97 -0
  263. vanna/legacy/weaviate/__init__.py +1 -0
  264. vanna/legacy/weaviate/weaviate_vector.py +194 -0
  265. vanna/legacy/xinference/__init__.py +1 -0
  266. vanna/legacy/xinference/xinference.py +53 -0
  267. vanna/py.typed +0 -0
  268. vanna/servers/__init__.py +16 -0
  269. vanna/servers/__main__.py +8 -0
  270. vanna/servers/base/__init__.py +18 -0
  271. vanna/servers/base/chat_handler.py +65 -0
  272. vanna/servers/base/models.py +111 -0
  273. vanna/servers/base/rich_chat_handler.py +141 -0
  274. vanna/servers/base/templates.py +331 -0
  275. vanna/servers/cli/__init__.py +7 -0
  276. vanna/servers/cli/server_runner.py +204 -0
  277. vanna/servers/fastapi/__init__.py +7 -0
  278. vanna/servers/fastapi/app.py +163 -0
  279. vanna/servers/fastapi/routes.py +183 -0
  280. vanna/servers/flask/__init__.py +7 -0
  281. vanna/servers/flask/app.py +132 -0
  282. vanna/servers/flask/routes.py +137 -0
  283. vanna/tools/__init__.py +41 -0
  284. vanna/tools/agent_memory.py +322 -0
  285. vanna/tools/file_system.py +879 -0
  286. vanna/tools/python.py +222 -0
  287. vanna/tools/run_sql.py +173 -0
  288. vanna/tools/visualize_data.py +195 -0
  289. vanna/utils/__init__.py +0 -0
  290. vanna/utils/sql_safety.py +84 -0
  291. vanna/web_components/__init__.py +44 -0
@@ -0,0 +1,468 @@
1
+ import dataclasses
2
+ import json
3
+ from io import StringIO
4
+
5
+ import pandas as pd
6
+ import requests
7
+
8
+ from ..advanced import VannaAdvanced
9
+ from ..base import VannaBase
10
+ from ..types import (
11
+ DataFrameJSON,
12
+ NewOrganization,
13
+ OrganizationList,
14
+ Question,
15
+ QuestionSQLPair,
16
+ Status,
17
+ StatusWithId,
18
+ StringData,
19
+ TrainingData,
20
+ )
21
+ from ..utils import sanitize_model_name
22
+
23
+
24
+ class VannaDB_VectorStore(VannaBase, VannaAdvanced):
25
+ def __init__(self, vanna_model: str, vanna_api_key: str, config=None):
26
+ VannaBase.__init__(self, config=config)
27
+
28
+ self._model = vanna_model
29
+ self._api_key = vanna_api_key
30
+
31
+ self._endpoint = (
32
+ "https://ask.vanna.ai/rpc"
33
+ if config is None or "endpoint" not in config
34
+ else config["endpoint"]
35
+ )
36
+ self.related_training_data = {}
37
+ self._graphql_endpoint = "https://functionrag.com/query"
38
+ self._graphql_headers = {
39
+ "Content-Type": "application/json",
40
+ "API-KEY": self._api_key,
41
+ "NAMESPACE": self._model,
42
+ }
43
+
44
+ def _rpc_call(self, method, params):
45
+ if method != "list_orgs":
46
+ headers = {
47
+ "Content-Type": "application/json",
48
+ "Vanna-Key": self._api_key,
49
+ "Vanna-Org": self._model,
50
+ }
51
+ else:
52
+ headers = {
53
+ "Content-Type": "application/json",
54
+ "Vanna-Key": self._api_key,
55
+ "Vanna-Org": "demo-tpc-h",
56
+ }
57
+
58
+ data = {
59
+ "method": method,
60
+ "params": [self._dataclass_to_dict(obj) for obj in params],
61
+ }
62
+
63
+ response = requests.post(self._endpoint, headers=headers, data=json.dumps(data))
64
+ return response.json()
65
+
66
+ def _dataclass_to_dict(self, obj):
67
+ return dataclasses.asdict(obj)
68
+
69
+ def get_all_functions(self) -> list:
70
+ query = """
71
+ {
72
+ get_all_sql_functions {
73
+ function_name
74
+ description
75
+ post_processing_code_template
76
+ arguments {
77
+ name
78
+ description
79
+ general_type
80
+ is_user_editable
81
+ available_values
82
+ }
83
+ sql_template
84
+ }
85
+ }
86
+ """
87
+
88
+ response = requests.post(
89
+ self._graphql_endpoint, headers=self._graphql_headers, json={"query": query}
90
+ )
91
+ response_json = response.json()
92
+ if (
93
+ response.status_code == 200
94
+ and "data" in response_json
95
+ and "get_all_sql_functions" in response_json["data"]
96
+ ):
97
+ self.log(response_json["data"]["get_all_sql_functions"])
98
+ resp = response_json["data"]["get_all_sql_functions"]
99
+
100
+ print(resp)
101
+
102
+ return resp
103
+ else:
104
+ raise Exception(
105
+ f"Query failed to run by returning code of {response.status_code}. {response.text}"
106
+ )
107
+
108
+ def get_function(self, question: str, additional_data: dict = {}) -> dict:
109
+ query = """
110
+ query GetFunction($question: String!, $staticFunctionArguments: [StaticFunctionArgument]) {
111
+ get_and_instantiate_function(question: $question, static_function_arguments: $staticFunctionArguments) {
112
+ ... on SQLFunction {
113
+ function_name
114
+ description
115
+ post_processing_code_template
116
+ instantiated_post_processing_code
117
+ arguments {
118
+ name
119
+ description
120
+ general_type
121
+ is_user_editable
122
+ instantiated_value
123
+ available_values
124
+ }
125
+ sql_template
126
+ instantiated_sql
127
+ }
128
+ }
129
+ }
130
+ """
131
+ static_function_arguments = [
132
+ {"name": key, "value": str(value)} for key, value in additional_data.items()
133
+ ]
134
+ variables = {
135
+ "question": question,
136
+ "staticFunctionArguments": static_function_arguments,
137
+ }
138
+ response = requests.post(
139
+ self._graphql_endpoint,
140
+ headers=self._graphql_headers,
141
+ json={"query": query, "variables": variables},
142
+ )
143
+ response_json = response.json()
144
+ if (
145
+ response.status_code == 200
146
+ and "data" in response_json
147
+ and "get_and_instantiate_function" in response_json["data"]
148
+ ):
149
+ self.log(response_json["data"]["get_and_instantiate_function"])
150
+ resp = response_json["data"]["get_and_instantiate_function"]
151
+
152
+ print(resp)
153
+
154
+ return resp
155
+ else:
156
+ raise Exception(
157
+ f"Query failed to run by returning code of {response.status_code}. {response.text}"
158
+ )
159
+
160
+ def create_function(
161
+ self, question: str, sql: str, plotly_code: str, **kwargs
162
+ ) -> dict:
163
+ query = """
164
+ mutation CreateFunction($question: String!, $sql: String!, $plotly_code: String!) {
165
+ generate_and_create_sql_function(question: $question, sql: $sql, post_processing_code: $plotly_code) {
166
+ function_name
167
+ description
168
+ arguments {
169
+ name
170
+ description
171
+ general_type
172
+ is_user_editable
173
+ }
174
+ sql_template
175
+ post_processing_code_template
176
+ }
177
+ }
178
+ """
179
+ variables = {"question": question, "sql": sql, "plotly_code": plotly_code}
180
+ response = requests.post(
181
+ self._graphql_endpoint,
182
+ headers=self._graphql_headers,
183
+ json={"query": query, "variables": variables},
184
+ )
185
+ response_json = response.json()
186
+ if (
187
+ response.status_code == 200
188
+ and "data" in response_json
189
+ and response_json["data"] is not None
190
+ and "generate_and_create_sql_function" in response_json["data"]
191
+ ):
192
+ resp = response_json["data"]["generate_and_create_sql_function"]
193
+
194
+ print(resp)
195
+
196
+ return resp
197
+ else:
198
+ raise Exception(
199
+ f"Query failed to run by returning code of {response.status_code}. {response.text}"
200
+ )
201
+
202
+ def update_function(self, old_function_name: str, updated_function: dict) -> bool:
203
+ """
204
+ Update an existing SQL function based on the provided parameters.
205
+
206
+ Args:
207
+ old_function_name (str): The current name of the function to be updated.
208
+ updated_function (dict): A dictionary containing the updated function details. Expected keys:
209
+ - 'function_name': The new name of the function.
210
+ - 'description': The new description of the function.
211
+ - 'arguments': A list of dictionaries describing the function arguments.
212
+ - 'sql_template': The new SQL template for the function.
213
+ - 'post_processing_code_template': The new post-processing code template.
214
+
215
+ Returns:
216
+ bool: True if the function was successfully updated, False otherwise.
217
+ """
218
+ mutation = """
219
+ mutation UpdateSQLFunction($input: SQLFunctionUpdate!) {
220
+ update_sql_function(input: $input)
221
+ }
222
+ """
223
+
224
+ SQLFunctionUpdate = {
225
+ "function_name",
226
+ "description",
227
+ "arguments",
228
+ "sql_template",
229
+ "post_processing_code_template",
230
+ }
231
+
232
+ # Define the expected keys for each argument in the arguments list
233
+ ArgumentKeys = {
234
+ "name",
235
+ "general_type",
236
+ "description",
237
+ "is_user_editable",
238
+ "available_values",
239
+ }
240
+
241
+ # Function to validate and transform arguments
242
+ def validate_arguments(args):
243
+ return [
244
+ {key: arg[key] for key in arg if key in ArgumentKeys} for arg in args
245
+ ]
246
+
247
+ # Keep only the keys that conform to the SQLFunctionUpdate GraphQL input type
248
+ updated_function = {
249
+ key: value
250
+ for key, value in updated_function.items()
251
+ if key in SQLFunctionUpdate
252
+ }
253
+
254
+ # Special handling for 'arguments' to ensure they conform to the spec
255
+ if "arguments" in updated_function:
256
+ updated_function["arguments"] = validate_arguments(
257
+ updated_function["arguments"]
258
+ )
259
+
260
+ variables = {
261
+ "input": {"old_function_name": old_function_name, **updated_function}
262
+ }
263
+
264
+ print("variables", variables)
265
+
266
+ response = requests.post(
267
+ self._graphql_endpoint,
268
+ headers=self._graphql_headers,
269
+ json={"query": mutation, "variables": variables},
270
+ )
271
+ response_json = response.json()
272
+ if (
273
+ response.status_code == 200
274
+ and "data" in response_json
275
+ and response_json["data"] is not None
276
+ and "update_sql_function" in response_json["data"]
277
+ ):
278
+ return response_json["data"]["update_sql_function"]
279
+ else:
280
+ raise Exception(
281
+ f"Mutation failed to run by returning code of {response.status_code}. {response.text}"
282
+ )
283
+
284
+ def delete_function(self, function_name: str) -> bool:
285
+ mutation = """
286
+ mutation DeleteSQLFunction($function_name: String!) {
287
+ delete_sql_function(function_name: $function_name)
288
+ }
289
+ """
290
+ variables = {"function_name": function_name}
291
+ response = requests.post(
292
+ self._graphql_endpoint,
293
+ headers=self._graphql_headers,
294
+ json={"query": mutation, "variables": variables},
295
+ )
296
+ response_json = response.json()
297
+ if (
298
+ response.status_code == 200
299
+ and "data" in response_json
300
+ and response_json["data"] is not None
301
+ and "delete_sql_function" in response_json["data"]
302
+ ):
303
+ return response_json["data"]["delete_sql_function"]
304
+ else:
305
+ raise Exception(
306
+ f"Mutation failed to run by returning code of {response.status_code}. {response.text}"
307
+ )
308
+
309
+ def create_model(self, model: str, **kwargs) -> bool:
310
+ """
311
+ **Example:**
312
+ ```python
313
+ success = vn.create_model("my_model")
314
+ ```
315
+ Create a new model.
316
+
317
+ Args:
318
+ model (str): The name of the model to create.
319
+
320
+ Returns:
321
+ bool: True if the model was created, False otherwise.
322
+ """
323
+ model = sanitize_model_name(model)
324
+ params = [NewOrganization(org_name=model, db_type="")]
325
+
326
+ d = self._rpc_call(method="create_org", params=params)
327
+
328
+ if "result" not in d:
329
+ return False
330
+
331
+ status = Status(**d["result"])
332
+
333
+ return status.success
334
+
335
+ def get_models(self) -> list:
336
+ """
337
+ **Example:**
338
+ ```python
339
+ models = vn.get_models()
340
+ ```
341
+
342
+ List the models that belong to the user.
343
+
344
+ Returns:
345
+ List[str]: A list of model names.
346
+ """
347
+ d = self._rpc_call(method="list_my_models", params=[])
348
+
349
+ if "result" not in d:
350
+ return []
351
+
352
+ orgs = OrganizationList(**d["result"])
353
+
354
+ return orgs.organizations
355
+
356
+ def generate_embedding(self, data: str, **kwargs) -> list[float]:
357
+ # This is done server-side
358
+ pass
359
+
360
+ def add_question_sql(self, question: str, sql: str, **kwargs) -> str:
361
+ if "tag" in kwargs:
362
+ tag = kwargs["tag"]
363
+ else:
364
+ tag = "Manually Trained"
365
+
366
+ params = [QuestionSQLPair(question=question, sql=sql, tag=tag)]
367
+
368
+ d = self._rpc_call(method="add_sql", params=params)
369
+
370
+ if "result" not in d:
371
+ raise Exception("Error adding question and SQL pair", d)
372
+
373
+ status = StatusWithId(**d["result"])
374
+
375
+ return status.id
376
+
377
+ def add_ddl(self, ddl: str, **kwargs) -> str:
378
+ params = [StringData(data=ddl)]
379
+
380
+ d = self._rpc_call(method="add_ddl", params=params)
381
+
382
+ if "result" not in d:
383
+ raise Exception("Error adding DDL", d)
384
+
385
+ status = StatusWithId(**d["result"])
386
+
387
+ return status.id
388
+
389
+ def add_documentation(self, documentation: str, **kwargs) -> str:
390
+ params = [StringData(data=documentation)]
391
+
392
+ d = self._rpc_call(method="add_documentation", params=params)
393
+
394
+ if "result" not in d:
395
+ raise Exception("Error adding documentation", d)
396
+
397
+ status = StatusWithId(**d["result"])
398
+
399
+ return status.id
400
+
401
+ def get_training_data(self, **kwargs) -> pd.DataFrame:
402
+ params = []
403
+
404
+ d = self._rpc_call(method="get_training_data", params=params)
405
+
406
+ if "result" not in d:
407
+ return None
408
+
409
+ # Load the result into a dataclass
410
+ training_data = DataFrameJSON(**d["result"])
411
+
412
+ df = pd.read_json(StringIO(training_data.data))
413
+
414
+ return df
415
+
416
+ def remove_training_data(self, id: str, **kwargs) -> bool:
417
+ params = [StringData(data=id)]
418
+
419
+ d = self._rpc_call(method="remove_training_data", params=params)
420
+
421
+ if "result" not in d:
422
+ raise Exception("Error removing training data")
423
+
424
+ status = Status(**d["result"])
425
+
426
+ if not status.success:
427
+ raise Exception(f"Error removing training data: {status.message}")
428
+
429
+ return status.success
430
+
431
+ def get_related_training_data_cached(self, question: str) -> TrainingData:
432
+ params = [Question(question=question)]
433
+
434
+ d = self._rpc_call(method="get_related_training_data", params=params)
435
+
436
+ if "result" not in d:
437
+ return None
438
+
439
+ # Load the result into a dataclass
440
+ training_data = TrainingData(**d["result"])
441
+
442
+ self.related_training_data[question] = training_data
443
+
444
+ return training_data
445
+
446
+ def get_similar_question_sql(self, question: str, **kwargs) -> list:
447
+ if question in self.related_training_data:
448
+ training_data = self.related_training_data[question]
449
+ else:
450
+ training_data = self.get_related_training_data_cached(question)
451
+
452
+ return training_data.questions
453
+
454
+ def get_related_ddl(self, question: str, **kwargs) -> list:
455
+ if question in self.related_training_data:
456
+ training_data = self.related_training_data[question]
457
+ else:
458
+ training_data = self.get_related_training_data_cached(question)
459
+
460
+ return training_data.ddl
461
+
462
+ def get_related_documentation(self, question: str, **kwargs) -> list:
463
+ if question in self.related_training_data:
464
+ training_data = self.related_training_data[question]
465
+ else:
466
+ training_data = self.get_related_training_data_cached(question)
467
+
468
+ return training_data.documentation
@@ -0,0 +1 @@
1
+ from .vllm import Vllm
@@ -0,0 +1,97 @@
1
+ import re
2
+
3
+ import requests
4
+
5
+ from ..base import VannaBase
6
+
7
+
8
+ class Vllm(VannaBase):
9
+ def __init__(self, config=None):
10
+ if config is None or "vllm_host" not in config:
11
+ self.host = "http://localhost:8000"
12
+ else:
13
+ self.host = config["vllm_host"]
14
+
15
+ if config is None or "model" not in config:
16
+ raise ValueError("check the config for vllm")
17
+ else:
18
+ self.model = config["model"]
19
+
20
+ if "auth-key" in config:
21
+ self.auth_key = config["auth-key"]
22
+ else:
23
+ self.auth_key = None
24
+
25
+ if "temperature" in config:
26
+ self.temperature = config["temperature"]
27
+ else:
28
+ # default temperature - can be overrided using config
29
+ self.temperature = 0.7
30
+
31
+ def system_message(self, message: str) -> any:
32
+ return {"role": "system", "content": message}
33
+
34
+ def user_message(self, message: str) -> any:
35
+ return {"role": "user", "content": message}
36
+
37
+ def assistant_message(self, message: str) -> any:
38
+ return {"role": "assistant", "content": message}
39
+
40
+ def extract_sql_query(self, text):
41
+ """
42
+ Extracts the first SQL statement after the word 'select', ignoring case,
43
+ matches until the first semicolon, three backticks, or the end of the string,
44
+ and removes three backticks if they exist in the extracted string.
45
+
46
+ Args:
47
+ - text (str): The string to search within for an SQL statement.
48
+
49
+ Returns:
50
+ - str: The first SQL statement found, with three backticks removed, or an empty string if no match is found.
51
+ """
52
+ # Regular expression to find 'select' (ignoring case) and capture until ';', '```', or end of string
53
+ pattern = re.compile(r"select.*?(?:;|```|$)", re.IGNORECASE | re.DOTALL)
54
+
55
+ match = pattern.search(text)
56
+ if match:
57
+ # Remove three backticks from the matched string if they exist
58
+ return match.group(0).replace("```", "")
59
+ else:
60
+ return text
61
+
62
+ def generate_sql(self, question: str, **kwargs) -> str:
63
+ # Use the super generate_sql
64
+ sql = super().generate_sql(question, **kwargs)
65
+
66
+ # Replace "\_" with "_"
67
+ sql = sql.replace("\\_", "_")
68
+
69
+ sql = sql.replace("\\", "")
70
+
71
+ return self.extract_sql_query(sql)
72
+
73
+ def submit_prompt(self, prompt, **kwargs) -> str:
74
+ url = f"{self.host}/v1/chat/completions"
75
+ data = {
76
+ "model": self.model,
77
+ "temperature": self.temperature,
78
+ "stream": False,
79
+ "messages": prompt,
80
+ }
81
+
82
+ if self.auth_key is not None:
83
+ headers = {
84
+ "Content-Type": "application/json",
85
+ "Authorization": f"Bearer {self.auth_key}",
86
+ }
87
+
88
+ response = requests.post(url, headers=headers, json=data)
89
+
90
+ else:
91
+ response = requests.post(url, json=data)
92
+
93
+ response_dict = response.json()
94
+
95
+ self.log(response.text)
96
+
97
+ return response_dict["choices"][0]["message"]["content"]
@@ -0,0 +1 @@
1
+ from .weaviate_vector import WeaviateDatabase