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.
- asksql-2.1.0.dist-info/METADATA +517 -0
- asksql-2.1.0.dist-info/RECORD +291 -0
- asksql-2.1.0.dist-info/WHEEL +4 -0
- asksql-2.1.0.dist-info/entry_points.txt +4 -0
- asksql-2.1.0.dist-info/licenses/LICENSE +21 -0
- vanna/__init__.py +172 -0
- vanna/agents/__init__.py +7 -0
- vanna/capabilities/__init__.py +17 -0
- vanna/capabilities/agent_memory/__init__.py +21 -0
- vanna/capabilities/agent_memory/base.py +103 -0
- vanna/capabilities/agent_memory/models.py +53 -0
- vanna/capabilities/file_system/__init__.py +14 -0
- vanna/capabilities/file_system/base.py +71 -0
- vanna/capabilities/file_system/models.py +25 -0
- vanna/capabilities/sql_runner/__init__.py +13 -0
- vanna/capabilities/sql_runner/base.py +37 -0
- vanna/capabilities/sql_runner/models.py +13 -0
- vanna/components/__init__.py +92 -0
- vanna/components/base.py +11 -0
- vanna/components/rich/__init__.py +83 -0
- vanna/components/rich/containers/__init__.py +7 -0
- vanna/components/rich/containers/card.py +20 -0
- vanna/components/rich/data/__init__.py +9 -0
- vanna/components/rich/data/chart.py +17 -0
- vanna/components/rich/data/dataframe.py +93 -0
- vanna/components/rich/feedback/__init__.py +21 -0
- vanna/components/rich/feedback/badge.py +16 -0
- vanna/components/rich/feedback/icon_text.py +14 -0
- vanna/components/rich/feedback/log_viewer.py +41 -0
- vanna/components/rich/feedback/notification.py +19 -0
- vanna/components/rich/feedback/progress.py +37 -0
- vanna/components/rich/feedback/status_card.py +28 -0
- vanna/components/rich/feedback/status_indicator.py +14 -0
- vanna/components/rich/interactive/__init__.py +21 -0
- vanna/components/rich/interactive/button.py +95 -0
- vanna/components/rich/interactive/task_list.py +58 -0
- vanna/components/rich/interactive/ui_state.py +93 -0
- vanna/components/rich/specialized/__init__.py +7 -0
- vanna/components/rich/specialized/artifact.py +20 -0
- vanna/components/rich/text.py +16 -0
- vanna/components/simple/__init__.py +15 -0
- vanna/components/simple/image.py +15 -0
- vanna/components/simple/link.py +15 -0
- vanna/components/simple/text.py +11 -0
- vanna/core/__init__.py +193 -0
- vanna/core/_compat.py +19 -0
- vanna/core/agent/__init__.py +10 -0
- vanna/core/agent/agent.py +1407 -0
- vanna/core/agent/config.py +123 -0
- vanna/core/audit/__init__.py +28 -0
- vanna/core/audit/base.py +299 -0
- vanna/core/audit/models.py +131 -0
- vanna/core/component_manager.py +329 -0
- vanna/core/components.py +53 -0
- vanna/core/enhancer/__init__.py +11 -0
- vanna/core/enhancer/base.py +94 -0
- vanna/core/enhancer/default.py +118 -0
- vanna/core/enricher/__init__.py +10 -0
- vanna/core/enricher/base.py +59 -0
- vanna/core/errors.py +47 -0
- vanna/core/evaluation/__init__.py +81 -0
- vanna/core/evaluation/base.py +186 -0
- vanna/core/evaluation/dataset.py +254 -0
- vanna/core/evaluation/evaluators.py +376 -0
- vanna/core/evaluation/report.py +289 -0
- vanna/core/evaluation/runner.py +313 -0
- vanna/core/filter/__init__.py +10 -0
- vanna/core/filter/base.py +67 -0
- vanna/core/lifecycle/__init__.py +10 -0
- vanna/core/lifecycle/base.py +83 -0
- vanna/core/llm/__init__.py +16 -0
- vanna/core/llm/base.py +40 -0
- vanna/core/llm/models.py +61 -0
- vanna/core/middleware/__init__.py +10 -0
- vanna/core/middleware/base.py +69 -0
- vanna/core/observability/__init__.py +11 -0
- vanna/core/observability/base.py +88 -0
- vanna/core/observability/models.py +47 -0
- vanna/core/recovery/__init__.py +11 -0
- vanna/core/recovery/base.py +84 -0
- vanna/core/recovery/models.py +32 -0
- vanna/core/registry.py +278 -0
- vanna/core/rich_component.py +156 -0
- vanna/core/simple_component.py +27 -0
- vanna/core/storage/__init__.py +14 -0
- vanna/core/storage/base.py +46 -0
- vanna/core/storage/models.py +46 -0
- vanna/core/system_prompt/__init__.py +13 -0
- vanna/core/system_prompt/base.py +36 -0
- vanna/core/system_prompt/default.py +157 -0
- vanna/core/tool/__init__.py +18 -0
- vanna/core/tool/base.py +70 -0
- vanna/core/tool/models.py +84 -0
- vanna/core/user/__init__.py +17 -0
- vanna/core/user/base.py +29 -0
- vanna/core/user/models.py +25 -0
- vanna/core/user/request_context.py +70 -0
- vanna/core/user/resolver.py +42 -0
- vanna/core/validation.py +164 -0
- vanna/core/workflow/__init__.py +12 -0
- vanna/core/workflow/base.py +254 -0
- vanna/core/workflow/default.py +789 -0
- vanna/examples/__init__.py +1 -0
- vanna/examples/__main__.py +44 -0
- vanna/examples/anthropic_quickstart.py +80 -0
- vanna/examples/artifact_example.py +293 -0
- vanna/examples/claude_sqlite_example.py +236 -0
- vanna/examples/coding_agent_example.py +300 -0
- vanna/examples/custom_system_prompt_example.py +174 -0
- vanna/examples/default_workflow_handler_example.py +208 -0
- vanna/examples/email_auth_example.py +340 -0
- vanna/examples/evaluation_example.py +269 -0
- vanna/examples/extensibility_example.py +262 -0
- vanna/examples/minimal_example.py +67 -0
- vanna/examples/mock_auth_example.py +227 -0
- vanna/examples/mock_custom_tool.py +311 -0
- vanna/examples/mock_quickstart.py +79 -0
- vanna/examples/mock_quota_example.py +145 -0
- vanna/examples/mock_rich_components_demo.py +396 -0
- vanna/examples/mock_sqlite_example.py +223 -0
- vanna/examples/openai_quickstart.py +83 -0
- vanna/examples/primitive_components_demo.py +305 -0
- vanna/examples/quota_lifecycle_example.py +139 -0
- vanna/examples/visualization_example.py +251 -0
- vanna/integrations/__init__.py +17 -0
- vanna/integrations/anthropic/__init__.py +9 -0
- vanna/integrations/anthropic/llm.py +270 -0
- vanna/integrations/azureopenai/__init__.py +9 -0
- vanna/integrations/azureopenai/llm.py +329 -0
- vanna/integrations/azuresearch/__init__.py +7 -0
- vanna/integrations/azuresearch/agent_memory.py +413 -0
- vanna/integrations/bigquery/__init__.py +5 -0
- vanna/integrations/bigquery/sql_runner.py +81 -0
- vanna/integrations/chromadb/__init__.py +104 -0
- vanna/integrations/chromadb/agent_memory.py +488 -0
- vanna/integrations/clickhouse/__init__.py +5 -0
- vanna/integrations/clickhouse/sql_runner.py +82 -0
- vanna/integrations/duckdb/__init__.py +5 -0
- vanna/integrations/duckdb/sql_runner.py +65 -0
- vanna/integrations/faiss/__init__.py +7 -0
- vanna/integrations/faiss/agent_memory.py +435 -0
- vanna/integrations/google/__init__.py +9 -0
- vanna/integrations/google/gemini.py +370 -0
- vanna/integrations/hive/__init__.py +5 -0
- vanna/integrations/hive/sql_runner.py +87 -0
- vanna/integrations/local/__init__.py +17 -0
- vanna/integrations/local/agent_memory/__init__.py +7 -0
- vanna/integrations/local/agent_memory/in_memory.py +285 -0
- vanna/integrations/local/audit.py +59 -0
- vanna/integrations/local/file_system.py +242 -0
- vanna/integrations/local/file_system_conversation_store.py +255 -0
- vanna/integrations/local/storage.py +62 -0
- vanna/integrations/marqo/__init__.py +7 -0
- vanna/integrations/marqo/agent_memory.py +354 -0
- vanna/integrations/milvus/__init__.py +7 -0
- vanna/integrations/milvus/agent_memory.py +458 -0
- vanna/integrations/mock/__init__.py +9 -0
- vanna/integrations/mock/llm.py +65 -0
- vanna/integrations/mssql/__init__.py +5 -0
- vanna/integrations/mssql/sql_runner.py +66 -0
- vanna/integrations/mysql/__init__.py +5 -0
- vanna/integrations/mysql/sql_runner.py +92 -0
- vanna/integrations/ollama/__init__.py +7 -0
- vanna/integrations/ollama/llm.py +252 -0
- vanna/integrations/openai/__init__.py +10 -0
- vanna/integrations/openai/llm.py +267 -0
- vanna/integrations/openai/responses.py +163 -0
- vanna/integrations/opensearch/__init__.py +7 -0
- vanna/integrations/opensearch/agent_memory.py +411 -0
- vanna/integrations/oracle/__init__.py +5 -0
- vanna/integrations/oracle/sql_runner.py +75 -0
- vanna/integrations/pinecone/__init__.py +7 -0
- vanna/integrations/pinecone/agent_memory.py +329 -0
- vanna/integrations/plotly/__init__.py +5 -0
- vanna/integrations/plotly/chart_generator.py +313 -0
- vanna/integrations/postgres/__init__.py +9 -0
- vanna/integrations/postgres/sql_runner.py +112 -0
- vanna/integrations/premium/agent_memory/__init__.py +7 -0
- vanna/integrations/premium/agent_memory/premium.py +186 -0
- vanna/integrations/presto/__init__.py +5 -0
- vanna/integrations/presto/sql_runner.py +107 -0
- vanna/integrations/qdrant/__init__.py +7 -0
- vanna/integrations/qdrant/agent_memory.py +466 -0
- vanna/integrations/snowflake/__init__.py +5 -0
- vanna/integrations/snowflake/sql_runner.py +147 -0
- vanna/integrations/sqlite/__init__.py +9 -0
- vanna/integrations/sqlite/sql_runner.py +65 -0
- vanna/integrations/weaviate/__init__.py +7 -0
- vanna/integrations/weaviate/agent_memory.py +428 -0
- vanna/legacy/ZhipuAI/ZhipuAI_Chat.py +233 -0
- vanna/legacy/ZhipuAI/ZhipuAI_embeddings.py +79 -0
- vanna/legacy/ZhipuAI/__init__.py +2 -0
- vanna/legacy/__init__.py +403 -0
- vanna/legacy/adapter.py +468 -0
- vanna/legacy/advanced/__init__.py +28 -0
- vanna/legacy/anthropic/__init__.py +1 -0
- vanna/legacy/anthropic/anthropic_chat.py +80 -0
- vanna/legacy/azuresearch/__init__.py +1 -0
- vanna/legacy/azuresearch/azuresearch_vector.py +274 -0
- vanna/legacy/base/__init__.py +1 -0
- vanna/legacy/base/base.py +2133 -0
- vanna/legacy/base/safe_exec.py +190 -0
- vanna/legacy/bedrock/__init__.py +1 -0
- vanna/legacy/bedrock/bedrock_converse.py +86 -0
- vanna/legacy/chromadb/__init__.py +1 -0
- vanna/legacy/chromadb/chromadb_vector.py +259 -0
- vanna/legacy/cohere/__init__.py +2 -0
- vanna/legacy/cohere/cohere_chat.py +99 -0
- vanna/legacy/cohere/cohere_embeddings.py +77 -0
- vanna/legacy/deepseek/__init__.py +1 -0
- vanna/legacy/deepseek/deepseek_chat.py +59 -0
- vanna/legacy/exceptions/__init__.py +46 -0
- vanna/legacy/faiss/__init__.py +1 -0
- vanna/legacy/faiss/faiss.py +230 -0
- vanna/legacy/flask/__init__.py +1355 -0
- vanna/legacy/flask/assets.py +58 -0
- vanna/legacy/flask/auth.py +56 -0
- vanna/legacy/google/__init__.py +2 -0
- vanna/legacy/google/bigquery_vector.py +293 -0
- vanna/legacy/google/gemini_chat.py +78 -0
- vanna/legacy/hf/__init__.py +1 -0
- vanna/legacy/hf/hf.py +80 -0
- vanna/legacy/local.py +8 -0
- vanna/legacy/marqo/__init__.py +1 -0
- vanna/legacy/marqo/marqo.py +168 -0
- vanna/legacy/milvus/__init__.py +1 -0
- vanna/legacy/milvus/milvus_vector.py +328 -0
- vanna/legacy/mistral/__init__.py +1 -0
- vanna/legacy/mistral/mistral.py +51 -0
- vanna/legacy/mock/__init__.py +3 -0
- vanna/legacy/mock/embedding.py +11 -0
- vanna/legacy/mock/llm.py +18 -0
- vanna/legacy/mock/vectordb.py +67 -0
- vanna/legacy/ollama/__init__.py +1 -0
- vanna/legacy/ollama/ollama.py +110 -0
- vanna/legacy/openai/__init__.py +2 -0
- vanna/legacy/openai/openai_chat.py +124 -0
- vanna/legacy/openai/openai_embeddings.py +46 -0
- vanna/legacy/opensearch/__init__.py +2 -0
- vanna/legacy/opensearch/opensearch_vector.py +369 -0
- vanna/legacy/opensearch/opensearch_vector_semantic.py +200 -0
- vanna/legacy/oracle/__init__.py +1 -0
- vanna/legacy/oracle/oracle_vector.py +584 -0
- vanna/legacy/pgvector/__init__.py +1 -0
- vanna/legacy/pgvector/pgvector.py +282 -0
- vanna/legacy/pinecone/__init__.py +3 -0
- vanna/legacy/pinecone/pinecone_vector.py +275 -0
- vanna/legacy/qdrant/__init__.py +3 -0
- vanna/legacy/qdrant/qdrant.py +329 -0
- vanna/legacy/qianfan/Qianfan_Chat.py +170 -0
- vanna/legacy/qianfan/Qianfan_embeddings.py +36 -0
- vanna/legacy/qianfan/__init__.py +2 -0
- vanna/legacy/qianwen/QianwenAI_chat.py +132 -0
- vanna/legacy/qianwen/QianwenAI_embeddings.py +46 -0
- vanna/legacy/qianwen/__init__.py +2 -0
- vanna/legacy/remote.py +79 -0
- vanna/legacy/types/__init__.py +292 -0
- vanna/legacy/utils.py +72 -0
- vanna/legacy/vannadb/__init__.py +1 -0
- vanna/legacy/vannadb/vannadb_vector.py +468 -0
- vanna/legacy/vllm/__init__.py +1 -0
- vanna/legacy/vllm/vllm.py +97 -0
- vanna/legacy/weaviate/__init__.py +1 -0
- vanna/legacy/weaviate/weaviate_vector.py +194 -0
- vanna/legacy/xinference/__init__.py +1 -0
- vanna/legacy/xinference/xinference.py +53 -0
- vanna/py.typed +0 -0
- vanna/servers/__init__.py +16 -0
- vanna/servers/__main__.py +8 -0
- vanna/servers/base/__init__.py +18 -0
- vanna/servers/base/chat_handler.py +65 -0
- vanna/servers/base/models.py +111 -0
- vanna/servers/base/rich_chat_handler.py +141 -0
- vanna/servers/base/templates.py +331 -0
- vanna/servers/cli/__init__.py +7 -0
- vanna/servers/cli/server_runner.py +204 -0
- vanna/servers/fastapi/__init__.py +7 -0
- vanna/servers/fastapi/app.py +163 -0
- vanna/servers/fastapi/routes.py +183 -0
- vanna/servers/flask/__init__.py +7 -0
- vanna/servers/flask/app.py +132 -0
- vanna/servers/flask/routes.py +137 -0
- vanna/tools/__init__.py +41 -0
- vanna/tools/agent_memory.py +322 -0
- vanna/tools/file_system.py +879 -0
- vanna/tools/python.py +222 -0
- vanna/tools/run_sql.py +173 -0
- vanna/tools/visualize_data.py +195 -0
- vanna/utils/__init__.py +0 -0
- vanna/utils/sql_safety.py +84 -0
- 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
|